From a5fdebc5f6375078ec1763850a4ca23ec7fe6458 Mon Sep 17 00:00:00 2001 From: levine Date: Mon, 21 Oct 1996 21:41:34 +0000 Subject: Initial revision --- ACE-categories | 430 ++ ACE-install.sh | 365 ++ BIBLIOGRAPHY | 618 +++ ChangeLog-93 | 52 + ChangeLog-94 | 1027 ++++ ChangeLog-95 | 4179 +++++++++++++++ ChangeLog-96a | 3888 ++++++++++++++ ChangeLog-96b | 2760 ++++++++++ FAQ | 1877 +++++++ INSTALL | 440 ++ Makefile | 80 + README | 615 +++ VERSION | 4 + ace/ACE.cpp | 738 +++ ace/ACE.h | 237 + ace/ACE.i | 61 + ace/ARGV.cpp | 202 + ace/ARGV.h | 80 + ace/ARGV.i | 32 + ace/Acceptor.cpp | 969 ++++ ace/Acceptor.h | 479 ++ ace/Acceptor.i | 4 + ace/Activation_Queue.cpp | 70 + ace/Activation_Queue.h | 63 + ace/Addr.cpp | 44 + ace/Addr.h | 93 + ace/Addr.i | 77 + ace/Auto_Ptr.cpp | 50 + ace/Auto_Ptr.h | 101 + ace/Auto_Ptr.i | 151 + ace/CORBA_Handler.cpp | 522 ++ ace/CORBA_Handler.h | 238 + ace/CORBA_Handler.i | 56 + ace/CORBA_Ref.cpp | 86 + ace/CORBA_Ref.h | 80 + ace/CORBA_Ref.i | 4 + ace/Connector.cpp | 533 ++ ace/Connector.h | 279 ++ ace/Connector.i | 4 + ace/DEV.cpp | 54 + ace/DEV.h | 71 + ace/DEV.i | 6 + ace/DEV_Addr.cpp | 65 + ace/DEV_Addr.h | 75 + ace/DEV_Addr.i | 65 + ace/DEV_Connector.cpp | 40 + ace/DEV_Connector.h | 86 + ace/DEV_Connector.i | 25 + ace/DEV_IO.cpp | 97 + ace/DEV_IO.h | 104 + ace/DEV_IO.i | 102 + ace/Date_Time.cpp | 5 + ace/Date_Time.h | 92 + ace/Date_Time.i | 140 + ace/Dump.cpp | 132 + ace/Dump.h | 166 + ace/Dump_T.cpp | 35 + ace/Dump_T.h | 61 + ace/Dynamic.cpp | 16 + ace/Dynamic.h | 52 + ace/Dynamic.i | 18 + ace/Dynamic_Service.cpp | 46 + ace/Dynamic_Service.h | 47 + ace/Dynamic_Service.i | 4 + ace/Event_Handler.cpp | 11 + ace/Event_Handler.h | 150 + ace/Event_Handler.i | 135 + ace/Event_Handler_T.cpp | 54 + ace/Event_Handler_T.h | 180 + ace/Event_Handler_T.i | 187 + ace/FIFO.cpp | 67 + ace/FIFO.h | 66 + ace/FIFO.i | 23 + ace/FIFO_Recv.cpp | 63 + ace/FIFO_Recv.h | 67 + ace/FIFO_Recv.i | 18 + ace/FIFO_Recv_Msg.cpp | 41 + ace/FIFO_Recv_Msg.h | 72 + ace/FIFO_Recv_Msg.i | 55 + ace/FIFO_Send.cpp | 36 + ace/FIFO_Send.h | 58 + ace/FIFO_Send.i | 18 + ace/FIFO_Send_Msg.cpp | 62 + ace/FIFO_Send_Msg.h | 72 + ace/FIFO_Send_Msg.i | 41 + ace/FILE.cpp | 72 + ace/FILE.h | 83 + ace/FILE.i | 6 + ace/FILE_Addr.cpp | 23 + ace/FILE_Addr.h | 75 + ace/FILE_Addr.i | 93 + ace/FILE_Connector.cpp | 43 + ace/FILE_Connector.h | 87 + ace/FILE_Connector.i | 25 + ace/FILE_IO.cpp | 100 + ace/FILE_IO.h | 109 + ace/FILE_IO.i | 101 + ace/Future.cpp | 346 ++ ace/Future.h | 167 + ace/Get_Opt.cpp | 133 + ace/Get_Opt.h | 161 + ace/Get_Opt.i | 23 + ace/Handle_Set.cpp | 213 + ace/Handle_Set.h | 153 + ace/Handle_Set.i | 107 + ace/High_Res_Timer.cpp | 74 + ace/High_Res_Timer.h | 86 + ace/High_Res_Timer.i | 37 + ace/INET_Addr.cpp | 413 ++ ace/INET_Addr.h | 169 + ace/INET_Addr.i | 56 + ace/IO_Cntl_Msg.cpp | 34 + ace/IO_Cntl_Msg.h | 85 + ace/IO_Cntl_Msg.i | 4 + ace/IO_SAP.cpp | 124 + ace/IO_SAP.h | 70 + ace/IO_SAP.i | 33 + ace/IPC_SAP.cpp | 148 + ace/IPC_SAP.h | 67 + ace/IPC_SAP.i | 31 + ace/LSOCK.cpp | 121 + ace/LSOCK.h | 70 + ace/LSOCK.i | 39 + ace/LSOCK_Acceptor.cpp | 98 + ace/LSOCK_Acceptor.h | 84 + ace/LSOCK_Acceptor.i | 4 + ace/LSOCK_CODgram.cpp | 54 + ace/LSOCK_CODgram.h | 65 + ace/LSOCK_CODgram.i | 27 + ace/LSOCK_Connector.cpp | 49 + ace/LSOCK_Connector.h | 97 + ace/LSOCK_Connector.i | 29 + ace/LSOCK_Dgram.cpp | 60 + ace/LSOCK_Dgram.h | 61 + ace/LSOCK_Dgram.i | 20 + ace/LSOCK_Stream.cpp | 69 + ace/LSOCK_Stream.h | 57 + ace/LSOCK_Stream.i | 25 + ace/Local_Name_Space.cpp | 155 + ace/Local_Name_Space.h | 113 + ace/Local_Name_Space_T.cpp | 673 +++ ace/Local_Name_Space_T.h | 219 + ace/Local_Tokens.cpp | 1408 ++++++ ace/Local_Tokens.h | 974 ++++ ace/Local_Tokens.i | 363 ++ ace/Local_Tokens_T.cpp | 56 + ace/Local_Tokens_T.h | 95 + ace/Local_Tokens_T.i | 65 + ace/Log_Msg.cpp | 895 ++++ ace/Log_Msg.h | 359 ++ ace/Log_Msg.i | 6 + ace/Log_Priority.h | 73 + ace/Log_Record.cpp | 136 + ace/Log_Record.h | 135 + ace/Log_Record.i | 88 + ace/Makefile | 2107 ++++++++ ace/Malloc.cpp | 81 + ace/Malloc.h | 217 + ace/Malloc.i | 4 + ace/Malloc_T.cpp | 574 +++ ace/Malloc_T.h | 337 ++ ace/Malloc_T.i | 150 + ace/Map_Manager.cpp | 575 +++ ace/Map_Manager.h | 262 + ace/Map_Manager.i | 4 + ace/Mem_Map.cpp | 218 + ace/Mem_Map.h | 179 + ace/Mem_Map.i | 166 + ace/Memory_Pool.cpp | 587 +++ ace/Memory_Pool.h | 352 ++ ace/Memory_Pool.i | 181 + ace/Message_Block.cpp | 249 + ace/Message_Block.h | 268 + ace/Message_Block.i | 234 + ace/Message_Queue.cpp | 508 ++ ace/Message_Queue.h | 217 + ace/Message_Queue.i | 122 + ace/Method_Object.cpp | 14 + ace/Method_Object.h | 43 + ace/Module.cpp | 168 + ace/Module.h | 139 + ace/Module.i | 62 + ace/Multiplexor.cpp | 13 + ace/Multiplexor.h | 76 + ace/Multiplexor.i | 88 + ace/Name_Proxy.cpp | 175 + ace/Name_Proxy.h | 82 + ace/Name_Request_Reply.cpp | 491 ++ ace/Name_Request_Reply.h | 253 + ace/Name_Space.cpp | 60 + ace/Name_Space.h | 145 + ace/Naming_Context.cpp | 531 ++ ace/Naming_Context.h | 312 ++ ace/OS.cpp | 1224 +++++ ace/OS.h | 2174 ++++++++ ace/OS.i | 5297 ++++++++++++++++++++ ace/Obstack.cpp | 119 + ace/Obstack.h | 79 + ace/Obstack.i | 4 + ace/Parse_Node.cpp | 545 ++ ace/Parse_Node.h | 256 + ace/Parse_Node.i | 6 + ace/Pipe.cpp | 132 + ace/Pipe.h | 73 + ace/Pipe.i | 18 + ace/Proactor.cpp | 536 ++ ace/Proactor.h | 256 + ace/Proactor.i | 54 + ace/Process.cpp | 197 + ace/Process.h | 106 + ace/Process.i | 19 + ace/Process_Manager.cpp | 331 ++ ace/Process_Manager.h | 250 + ace/Process_Manager.i | 4 + ace/Profile_Timer.cpp | 226 + ace/Profile_Timer.h | 142 + ace/Profile_Timer.i | 48 + ace/README | 784 +++ ace/Reactor.cpp | 1614 ++++++ ace/Reactor.h | 642 +++ ace/Reactor.i | 135 + ace/ReactorEx.cpp | 282 ++ ace/ReactorEx.h | 231 + ace/ReactorEx.i | 28 + ace/Read_Buffer.cpp | 155 + ace/Read_Buffer.h | 93 + ace/Read_Buffer.i | 23 + ace/Remote_Name_Space.cpp | 312 ++ ace/Remote_Name_Space.h | 126 + ace/Remote_Tokens.cpp | 445 ++ ace/Remote_Tokens.h | 283 ++ ace/Remote_Tokens.i | 98 + ace/SOCK.cpp | 97 + ace/SOCK.h | 95 + ace/SOCK.i | 28 + ace/SOCK_Acceptor.cpp | 125 + ace/SOCK_Acceptor.h | 81 + ace/SOCK_Acceptor.i | 8 + ace/SOCK_CODgram.cpp | 100 + ace/SOCK_CODgram.h | 55 + ace/SOCK_CODgram.i | 12 + ace/SOCK_Connector.cpp | 152 + ace/SOCK_Connector.h | 101 + ace/SOCK_Connector.i | 35 + ace/SOCK_Dgram.cpp | 118 + ace/SOCK_Dgram.h | 92 + ace/SOCK_Dgram.i | 45 + ace/SOCK_Dgram_Bcast.cpp | 243 + ace/SOCK_Dgram_Bcast.h | 106 + ace/SOCK_Dgram_Bcast.i | 23 + ace/SOCK_Dgram_Mcast.cpp | 108 + ace/SOCK_Dgram_Mcast.h | 112 + ace/SOCK_Dgram_Mcast.i | 31 + ace/SOCK_IO.cpp | 114 + ace/SOCK_IO.h | 74 + ace/SOCK_IO.i | 85 + ace/SOCK_Stream.cpp | 16 + ace/SOCK_Stream.h | 69 + ace/SOCK_Stream.i | 81 + ace/SPIPE.cpp | 58 + ace/SPIPE.h | 76 + ace/SPIPE.i | 6 + ace/SPIPE_Acceptor.cpp | 212 + ace/SPIPE_Acceptor.h | 78 + ace/SPIPE_Acceptor.i | 4 + ace/SPIPE_Addr.cpp | 110 + ace/SPIPE_Addr.h | 101 + ace/SPIPE_Addr.i | 70 + ace/SPIPE_Connector.cpp | 68 + ace/SPIPE_Connector.h | 88 + ace/SPIPE_Connector.i | 7 + ace/SPIPE_Stream.cpp | 93 + ace/SPIPE_Stream.h | 117 + ace/SPIPE_Stream.i | 160 + ace/SString.cpp | 596 +++ ace/SString.h | 265 + ace/SString.i | 141 + ace/SV_Message.cpp | 18 + ace/SV_Message.h | 51 + ace/SV_Message.i | 31 + ace/SV_Message_Queue.cpp | 34 + ace/SV_Message_Queue.h | 86 + ace/SV_Message_Queue.i | 78 + ace/SV_Semaphore_Complex.cpp | 240 + ace/SV_Semaphore_Complex.h | 149 + ace/SV_Semaphore_Complex.i | 83 + ace/SV_Semaphore_Simple.cpp | 179 + ace/SV_Semaphore_Simple.h | 138 + ace/SV_Semaphore_Simple.i | 132 + ace/SV_Shared_Memory.cpp | 82 + ace/SV_Shared_Memory.h | 107 + ace/SV_Shared_Memory.i | 105 + ace/Service_Config.cpp | 928 ++++ ace/Service_Config.h | 353 ++ ace/Service_Config.i | 32 + ace/Service_Main.cpp | 37 + ace/Service_Manager.cpp | 267 + ace/Service_Manager.h | 74 + ace/Service_Manager.i | 4 + ace/Service_Object.cpp | 71 + ace/Service_Object.h | 94 + ace/Service_Object.i | 26 + ace/Service_Record.cpp | 340 ++ ace/Service_Record.h | 153 + ace/Service_Record.i | 91 + ace/Service_Repository.cpp | 281 ++ ace/Service_Repository.h | 130 + ace/Service_Repository.i | 27 + ace/Set.cpp | 502 ++ ace/Set.h | 321 ++ ace/Set.i | 24 + ace/Shared_Memory.h | 43 + ace/Shared_Memory_MM.cpp | 52 + ace/Shared_Memory_MM.h | 95 + ace/Shared_Memory_MM.i | 81 + ace/Shared_Memory_SV.cpp | 29 + ace/Shared_Memory_SV.h | 87 + ace/Shared_Memory_SV.i | 73 + ace/Shared_Object.cpp | 46 + ace/Shared_Object.h | 45 + ace/Shared_Object.i | 4 + ace/Signal.cpp | 632 +++ ace/Signal.h | 350 ++ ace/Signal.i | 213 + ace/Singleton.cpp | 78 + ace/Singleton.h | 65 + ace/Singleton.i | 4 + ace/Stack.cpp | 428 ++ ace/Stack.h | 280 ++ ace/Stack.i | 100 + ace/Strategies.cpp | 504 ++ ace/Strategies.h | 445 ++ ace/Strategies.i | 4 + ace/Stream.cpp | 512 ++ ace/Stream.h | 185 + ace/Stream.i | 35 + ace/Stream_Modules.cpp | 330 ++ ace/Stream_Modules.h | 118 + ace/Stream_Modules.i | 4 + ace/Svc_Conf.h | 81 + ace/Svc_Conf.l | 77 + ace/Svc_Conf.y | 342 ++ ace/Svc_Conf_Tokens.h | 23 + ace/Svc_Conf_l.cpp | 1504 ++++++ ace/Svc_Conf_y.cpp | 923 ++++ ace/Svc_Handler.cpp | 282 ++ ace/Svc_Handler.h | 178 + ace/Svc_Handler.i | 5 + ace/Synch.cpp | 839 ++++ ace/Synch.h | 1019 ++++ ace/Synch.i | 421 ++ ace/Synch_Options.cpp | 93 + ace/Synch_Options.h | 135 + ace/Synch_Options.i | 4 + ace/Synch_T.cpp | 626 +++ ace/Synch_T.h | 613 +++ ace/Synch_T.i | 176 + ace/System_Time.cpp | 86 + ace/System_Time.h | 73 + ace/TLI.cpp | 172 + ace/TLI.h | 98 + ace/TLI.i | 41 + ace/TLI_Acceptor.cpp | 456 ++ ace/TLI_Acceptor.h | 109 + ace/TLI_Acceptor.i | 5 + ace/TLI_Connector.cpp | 211 + ace/TLI_Connector.h | 104 + ace/TLI_Connector.i | 29 + ace/TLI_Stream.cpp | 99 + ace/TLI_Stream.h | 93 + ace/TLI_Stream.i | 105 + ace/TTY_IO.cpp | 211 + ace/TTY_IO.h | 67 + ace/Task.cpp | 305 ++ ace/Task.h | 299 ++ ace/Task.i | 160 + ace/Thread.cpp | 68 + ace/Thread.h | 183 + ace/Thread.i | 266 + ace/Thread_Manager.cpp | 767 +++ ace/Thread_Manager.h | 403 ++ ace/Thread_Manager.i | 83 + ace/Time_Request_Reply.cpp | 187 + ace/Time_Request_Reply.h | 119 + ace/Time_Value.cpp | 231 + ace/Time_Value.h | 247 + ace/Time_Value.i | 166 + ace/Timer_Queue.cpp | 332 ++ ace/Timer_Queue.h | 154 + ace/Timer_Queue.i | 4 + ace/Token.cpp | 346 ++ ace/Token.h | 173 + ace/Token.i | 41 + ace/Token_Collection.cpp | 292 ++ ace/Token_Collection.h | 216 + ace/Token_Collection.i | 11 + ace/Token_Invariants.cpp | 338 ++ ace/Token_Invariants.h | 217 + ace/Token_Invariants.i | 4 + ace/Token_Manager.cpp | 259 + ace/Token_Manager.h | 124 + ace/Token_Manager.i | 19 + ace/Token_Request_Reply.cpp | 167 + ace/Token_Request_Reply.h | 230 + ace/Token_Request_Reply.i | 190 + ace/Trace.cpp | 115 + ace/Trace.h | 77 + ace/Trace.i | 7 + ace/Typed_SV_Message.cpp | 21 + ace/Typed_SV_Message.h | 88 + ace/Typed_SV_Message.i | 91 + ace/Typed_SV_Message_Queue.cpp | 46 + ace/Typed_SV_Message_Queue.h | 78 + ace/Typed_SV_Message_Queue.i | 63 + ace/UNIX_Addr.cpp | 104 + ace/UNIX_Addr.h | 85 + ace/UNIX_Addr.i | 61 + ace/UPIPE_Acceptor.cpp | 115 + ace/UPIPE_Acceptor.h | 81 + ace/UPIPE_Acceptor.i | 11 + ace/UPIPE_Addr.h | 25 + ace/UPIPE_Connector.cpp | 86 + ace/UPIPE_Connector.h | 92 + ace/UPIPE_Connector.i | 30 + ace/UPIPE_Stream.cpp | 206 + ace/UPIPE_Stream.h | 117 + ace/UPIPE_Stream.i | 12 + ace/XtReactor.cpp | 327 ++ ace/XtReactor.h | 96 + ace/ace.mak | 2197 ++++++++ ace/ace.mdp | Bin 0 -> 47104 bytes ace/config-aix-3.2.5.h | 47 + ace/config-aix-4.1.x.h | 105 + ace/config-hpux-10.x-g++.h | 99 + ace/config-hpux-10.x.h | 110 + ace/config-hpux-9.x-orbix.h | 89 + ace/config-hpux-9.x.h | 83 + ace/config-irix5.2.h | 62 + ace/config-irix5.3-g++.h | 121 + ace/config-irix5.3-sgic++.h | 118 + ace/config-irix6.2-sgic++.h | 151 + ace/config-linux-pthread.h | 99 + ace/config-linux.h | 91 + ace/config-m88k.h | 223 + ace/config-osf1-3.2.h | 165 + ace/config-osf1-4.0.h | 182 + ace/config-sco-4.2-nothread.h | 105 + ace/config-sunos4-g++.h | 94 + ace/config-sunos4-lucid3.2.h | 83 + ace/config-sunos4-sun3.x.h | 71 + ace/config-sunos4-sun4.1.4.h | 82 + ace/config-sunos4-sun4.x-orbix.h | 82 + ace/config-sunos4-sun4.x.h | 76 + ace/config-sunos5.4-centerline-2.x.h | 152 + ace/config-sunos5.4-g++.h | 180 + ace/config-sunos5.4-sunc++-4.x-orbix.h | 168 + ace/config-sunos5.4-sunc++-4.x.h | 165 + ace/config-sunos5.5-g++.h | 171 + ace/config-sunos5.5-sunc++-4.x-orbix.h | 166 + ace/config-sunos5.5-sunc++-4.x.h | 161 + ace/config-sunx86-sunc++-4.x.h | 142 + ace/config-unixware-2.01-g++.h | 95 + ace/config-vxworks-ghs-1.8.h | 46 + ace/config-win32-msvc2.0.h | 133 + ace/config-win32-msvc4.0.h | 167 + ace/makefile-light | 883 ++++ apps/Gateway/Gateway/Channel.cpp | 713 +++ apps/Gateway/Gateway/Channel.h | 281 ++ apps/Gateway/Gateway/Channel_Connector.cpp | 92 + apps/Gateway/Gateway/Channel_Connector.h | 41 + apps/Gateway/Gateway/Config_Files.cpp | 170 + apps/Gateway/Gateway/Config_Files.h | 91 + apps/Gateway/Gateway/File_Parser.cpp | 142 + apps/Gateway/Gateway/File_Parser.h | 76 + apps/Gateway/Gateway/Gateway.cpp | 561 +++ apps/Gateway/Gateway/Gateway.h | 30 + apps/Gateway/Gateway/Makefile | 505 ++ apps/Gateway/Gateway/Peer_Message.h | 89 + apps/Gateway/Gateway/README | 22 + apps/Gateway/Gateway/Routing_Entry.cpp | 47 + apps/Gateway/Gateway/Routing_Entry.h | 53 + apps/Gateway/Gateway/Routing_Table.cpp | 69 + apps/Gateway/Gateway/Routing_Table.h | 67 + apps/Gateway/Gateway/Thr_Channel.cpp | 204 + apps/Gateway/Gateway/Thr_Channel.h | 65 + apps/Gateway/Gateway/cc_config | 10 + apps/Gateway/Gateway/gatewayd.cpp | 34 + apps/Gateway/Gateway/rt_config | 7 + apps/Gateway/Gateway/svc.conf | 3 + apps/Gateway/Makefile | 26 + apps/Gateway/Peer/Gateway_Handler.cpp | 653 +++ apps/Gateway/Peer/Gateway_Handler.h | 154 + apps/Gateway/Peer/Makefile | 137 + apps/Gateway/Peer/Peer_Message.h | 44 + apps/Gateway/Peer/peerd.cpp | 36 + apps/Gateway/Peer/svc.conf | 3 + apps/Gateway/README | 80 + apps/Makefile | 30 + .../Event_Comm/Consumer/Input_Handler.cpp | 130 + .../Event_Comm/Consumer/Input_Handler.h | 71 + apps/Orbix-Examples/Event_Comm/Consumer/Makefile | 165 + .../Consumer/Notification_Receiver_Handler.cpp | 114 + .../Consumer/Notification_Receiver_Handler.h | 62 + .../Event_Comm/Consumer/consumer.cpp | 114 + apps/Orbix-Examples/Event_Comm/Makefile | 26 + apps/Orbix-Examples/Event_Comm/README | 109 + .../Event_Comm/Supplier/Input_Handler.cpp | 120 + .../Event_Comm/Supplier/Input_Handler.h | 70 + apps/Orbix-Examples/Event_Comm/Supplier/Makefile | 164 + .../Event_Comm/Supplier/Notifier_Handler.cpp | 66 + .../Event_Comm/Supplier/Notifier_Handler.h | 57 + .../Event_Comm/Supplier/supplier.cpp | 116 + .../Event_Comm/include/Event_Comm.hh | 887 ++++ .../Event_Comm/include/Event_Comm_i.h | 37 + .../Event_Comm/include/Notification_Receiver_i.h | 48 + .../Orbix-Examples/Event_Comm/include/Notifier_i.h | 82 + .../Orbix-Examples/Event_Comm/libsrc/Event_Comm.hh | 887 ++++ .../Event_Comm/libsrc/Event_Comm.idl | 92 + .../Event_Comm/libsrc/Event_CommC.cpp | 351 ++ .../Event_Comm/libsrc/Event_CommS.cpp | 166 + .../Event_Comm/libsrc/Event_Comm_i.h | 38 + apps/Orbix-Examples/Event_Comm/libsrc/Makefile | 113 + .../Event_Comm/libsrc/Notification.idl | 42 + .../Event_Comm/libsrc/Notification_Receiver.idl | 42 + .../Event_Comm/libsrc/Notification_Receiver_i.cpp | 39 + .../Event_Comm/libsrc/Notification_Receiver_i.h | 48 + apps/Orbix-Examples/Event_Comm/libsrc/Notifier.idl | 49 + .../Event_Comm/libsrc/Notifier_i.cpp | 324 ++ apps/Orbix-Examples/Event_Comm/libsrc/Notifier_i.h | 82 + apps/Orbix-Examples/Logger/Logger.cpp | 131 + apps/Orbix-Examples/Logger/Logger.h | 56 + apps/Orbix-Examples/Logger/Makefile | 63 + apps/Orbix-Examples/Logger/Orbix.hostgroups | 1 + apps/Orbix-Examples/Logger/Orbix.hosts | 3 + apps/Orbix-Examples/Logger/README | 35 + apps/Orbix-Examples/Logger/a1.tex | 232 + apps/Orbix-Examples/Logger/client.cpp | 142 + apps/Orbix-Examples/Logger/logger.hh | 434 ++ apps/Orbix-Examples/Logger/logger.idl | 56 + apps/Orbix-Examples/Logger/loggerS.cpp | 141 + apps/Orbix-Examples/Logger/logger_i.cpp | 120 + apps/Orbix-Examples/Logger/logger_i.h | 75 + apps/Orbix-Examples/Logger/server.cpp | 40 + apps/Orbix-Examples/Makefile | 25 + apps/README | 19 + apps/gperf/COPYING | 249 + apps/gperf/ChangeLog | 1335 +++++ apps/gperf/Makefile | 25 + apps/gperf/README | 24 + apps/gperf/gperf.1 | 23 + apps/gperf/gperf.info | 1127 +++++ apps/gperf/gperf.texi | 1184 +++++ apps/gperf/src/Bool_Array.cpp | 89 + apps/gperf/src/Bool_Array.h | 65 + apps/gperf/src/Gen_Perf.cpp | 345 ++ apps/gperf/src/Gen_Perf.h | 65 + apps/gperf/src/Hash_Table.cpp | 84 + apps/gperf/src/Hash_Table.h | 50 + apps/gperf/src/Iterator.cpp | 90 + apps/gperf/src/Iterator.h | 67 + apps/gperf/src/Key_List.cpp | 1345 +++++ apps/gperf/src/Key_List.h | 116 + apps/gperf/src/List_Node.cpp | 110 + apps/gperf/src/List_Node.h | 65 + apps/gperf/src/Makefile | 155 + apps/gperf/src/Options.cpp | 616 +++ apps/gperf/src/Options.h | 140 + apps/gperf/src/Vectors.cpp | 33 + apps/gperf/src/Vectors.h | 44 + apps/gperf/src/Version.cpp | 25 + apps/gperf/src/gperf.cpp | 66 + apps/gperf/src/new.cpp | 75 + apps/gperf/tests/Makefile.in | 72 + apps/gperf/tests/ada-pred.exp | 54 + apps/gperf/tests/ada-res.exp | 63 + apps/gperf/tests/ada.gperf | 63 + apps/gperf/tests/adadefs.gperf | 54 + apps/gperf/tests/c++.gperf | 47 + apps/gperf/tests/c-parse.gperf | 56 + apps/gperf/tests/c.exp | 32 + apps/gperf/tests/c.gperf | 32 + apps/gperf/tests/configure.in | 26 + apps/gperf/tests/gpc.gperf | 48 + apps/gperf/tests/gplus.gperf | 76 + apps/gperf/tests/irc.gperf | 63 + apps/gperf/tests/makeinfo.gperf | 116 + apps/gperf/tests/modula.exp | 106 + apps/gperf/tests/modula2.gperf | 40 + apps/gperf/tests/modula3.gperf | 106 + apps/gperf/tests/pascal.exp | 36 + apps/gperf/tests/pascal.gperf | 36 + apps/gperf/tests/test-1.exp | 140 + apps/gperf/tests/test-2.exp | 183 + apps/gperf/tests/test-3.exp | 169 + apps/gperf/tests/test-4.exp | 138 + apps/gperf/tests/test-5.exp | 111 + apps/gperf/tests/test-6.exp | 74 + apps/gperf/tests/test-7.exp | 32 + apps/gperf/tests/test.c | 28 + bin/Makefile | 37 + bin/README.html | 136 + bin/class2hxxcxx | 80 + bin/class2hxxcxxsingle | 80 + bin/class2info | 197 + bin/class2info.awk | 1594 ++++++ bin/class2man | 78 + bin/class2mml | 79 + bin/class2src | 79 + bin/classinfo.ps | 868 ++++ bin/clone.1 | 297 ++ bin/clone.cpp | 955 ++++ bin/clone.csh | 26 + bin/g++dep | 80 + bin/hiding.fmt | 20 + bin/html-windex | 33 + bin/info2doc.awk | 2181 ++++++++ bin/info2doc.fmt | 23 + bin/info2head | 166 + bin/info2head.fmt | 23 + bin/info2headsrc | 326 ++ bin/info2man | 169 + bin/info2mml | 166 + bin/info2src | 133 + bin/info2src.awk | 630 +++ bin/man2html | 88 + bin/man2html1.awk | 139 + bin/man2html2.awk | 18 + bin/rename-ace.pl | 175 + bin/vendor.fmt | 101 + examples/ASX/CCM_App/CCM_App.cpp | 123 + examples/ASX/CCM_App/Makefile | 176 + examples/ASX/CCM_App/SC_Client.cpp | 9 + examples/ASX/CCM_App/SC_Server.cpp | 63 + examples/ASX/CCM_App/svc.conf | 21 + .../Event_Server/Event_Server/Consumer_Router.cpp | 132 + .../Event_Server/Event_Server/Consumer_Router.h | 46 + .../Event_Server/Event_Server/Event_Analyzer.cpp | 68 + .../ASX/Event_Server/Event_Server/Event_Analyzer.h | 34 + examples/ASX/Event_Server/Event_Server/Makefile | 433 ++ examples/ASX/Event_Server/Event_Server/Options.cpp | 186 + examples/ASX/Event_Server/Event_Server/Options.h | 75 + examples/ASX/Event_Server/Event_Server/Options.i | 137 + .../ASX/Event_Server/Event_Server/Peer_Router.cpp | 279 ++ .../ASX/Event_Server/Event_Server/Peer_Router.h | 121 + .../Event_Server/Event_Server/Supplier_Router.cpp | 134 + .../Event_Server/Event_Server/Supplier_Router.h | 51 + .../ASX/Event_Server/Event_Server/event_server.cpp | 125 + examples/ASX/Event_Server/Makefile | 23 + examples/ASX/Event_Server/README | 38 + examples/ASX/Event_Server/Transceiver/Makefile | 135 + .../ASX/Event_Server/Transceiver/transceiver.cpp | 187 + examples/ASX/Makefile | 25 + examples/ASX/Message_Queue/Makefile | 218 + examples/ASX/Message_Queue/bounded_buffer.cpp | 130 + examples/ASX/Message_Queue/buffer_stream.cpp | 215 + examples/ASX/Message_Queue/priority_buffer.cpp | 139 + .../ASX/UPIPE_Event_Server/Consumer_Router.cpp | 126 + examples/ASX/UPIPE_Event_Server/Consumer_Router.h | 48 + examples/ASX/UPIPE_Event_Server/Event_Analyzer.cpp | 68 + examples/ASX/UPIPE_Event_Server/Event_Analyzer.h | 34 + examples/ASX/UPIPE_Event_Server/Makefile | 455 ++ examples/ASX/UPIPE_Event_Server/Options.cpp | 191 + examples/ASX/UPIPE_Event_Server/Options.h | 83 + examples/ASX/UPIPE_Event_Server/Options.i | 161 + examples/ASX/UPIPE_Event_Server/Peer_Router.cpp | 273 + examples/ASX/UPIPE_Event_Server/Peer_Router.h | 116 + .../ASX/UPIPE_Event_Server/Supplier_Router.cpp | 126 + examples/ASX/UPIPE_Event_Server/Supplier_Router.h | 52 + examples/ASX/UPIPE_Event_Server/event_server.cpp | 252 + examples/CORBA/Makefile | 65 + examples/CORBA/Test.idl | 6 + examples/CORBA/Test_i.cpp | 10 + examples/CORBA/Test_i.h | 14 + examples/CORBA/client.cpp | 26 + examples/CORBA/server.cpp | 37 + examples/Connection/Makefile | 26 + examples/Connection/blocking/Makefile | 414 ++ examples/Connection/blocking/README | 36 + examples/Connection/blocking/SPIPE-acceptor.cpp | 179 + examples/Connection/blocking/SPIPE-acceptor.h | 63 + examples/Connection/blocking/SPIPE-connector.cpp | 182 + examples/Connection/blocking/SPIPE-connector.h | 75 + .../Connection/blocking/test_spipe_acceptor.cpp | 22 + .../Connection/blocking/test_spipe_connector.cpp | 22 + examples/Connection/misc/Makefile | 0 examples/Connection/misc/test_upipe.cpp | 176 + examples/Connection/non_blocking/CPP-acceptor.cpp | 172 + examples/Connection/non_blocking/CPP-acceptor.h | 70 + examples/Connection/non_blocking/CPP-connector.cpp | 219 + examples/Connection/non_blocking/CPP-connector.h | 77 + examples/Connection/non_blocking/Makefile | 756 +++ examples/Connection/non_blocking/README | 24 + .../Connection/non_blocking/test_sock_acceptor.cpp | 25 + .../non_blocking/test_sock_connector.cpp | 25 + .../non_blocking/test_spipe_acceptor.cpp | 25 + .../non_blocking/test_spipe_connector.cpp | 25 + .../Connection/non_blocking/test_tli_acceptor.cpp | 33 + .../Connection/non_blocking/test_tli_connector.cpp | 33 + examples/IPC_SAP/DEV_SAP/Makefile | 22 + examples/IPC_SAP/DEV_SAP/README | 23 + examples/IPC_SAP/DEV_SAP/reader/Makefile | 71 + examples/IPC_SAP/DEV_SAP/reader/reader.cpp | 49 + examples/IPC_SAP/DEV_SAP/writer/Makefile | 71 + examples/IPC_SAP/DEV_SAP/writer/writer.cpp | 54 + examples/IPC_SAP/FIFO_SAP/FIFO-Msg-client.cpp | 36 + examples/IPC_SAP/FIFO_SAP/FIFO-Msg-server.cpp | 40 + examples/IPC_SAP/FIFO_SAP/FIFO-client.cpp | 24 + examples/IPC_SAP/FIFO_SAP/FIFO-server.cpp | 25 + examples/IPC_SAP/FIFO_SAP/FIFO-test.cpp | 92 + examples/IPC_SAP/FIFO_SAP/Makefile | 132 + examples/IPC_SAP/FILE_SAP/Makefile | 62 + examples/IPC_SAP/FILE_SAP/client.cpp | 57 + examples/IPC_SAP/FILE_SAP/testfile | 1 + examples/IPC_SAP/Makefile | 27 + examples/IPC_SAP/SOCK_SAP/C-inclient.cpp | 60 + examples/IPC_SAP/SOCK_SAP/C-inserver.cpp | 84 + examples/IPC_SAP/SOCK_SAP/CPP-inclient.cpp | 73 + examples/IPC_SAP/SOCK_SAP/CPP-inserver-poll.cpp | 101 + examples/IPC_SAP/SOCK_SAP/CPP-inserver.cpp | 136 + examples/IPC_SAP/SOCK_SAP/CPP-unclient.cpp | 50 + examples/IPC_SAP/SOCK_SAP/CPP-unserver.cpp | 78 + examples/IPC_SAP/SOCK_SAP/FD-unclient.cpp | 51 + examples/IPC_SAP/SOCK_SAP/FD-unserver.cpp | 60 + examples/IPC_SAP/SOCK_SAP/Makefile | 246 + examples/IPC_SAP/SOCK_SAP/README | 35 + examples/IPC_SAP/SOCK_SAP/local_data | 1 + examples/IPC_SAP/SPIPE_SAP/Makefile | 218 + examples/IPC_SAP/SPIPE_SAP/NPClient.cpp | 46 + examples/IPC_SAP/SPIPE_SAP/NPServer.cpp | 54 + examples/IPC_SAP/SPIPE_SAP/client.cpp | 42 + examples/IPC_SAP/SPIPE_SAP/consumer_msg.cpp | 53 + examples/IPC_SAP/SPIPE_SAP/consumer_read.cpp | 50 + examples/IPC_SAP/SPIPE_SAP/producer_msg.cpp | 52 + examples/IPC_SAP/SPIPE_SAP/producer_read.cpp | 49 + examples/IPC_SAP/SPIPE_SAP/server.cpp | 116 + examples/IPC_SAP/SPIPE_SAP/shared.h | 6 + examples/IPC_SAP/TLI_SAP/CPP-client.cpp | 68 + examples/IPC_SAP/TLI_SAP/CPP-server.cpp | 68 + examples/IPC_SAP/TLI_SAP/Makefile | 197 + examples/IPC_SAP/TLI_SAP/db-client.cpp | 52 + examples/IPC_SAP/TLI_SAP/db-server.cpp | 111 + examples/IPC_SAP/TLI_SAP/ftp-client.cpp | 45 + examples/IPC_SAP/TLI_SAP/ftp-server.cpp | 75 + examples/IPC_SAP/TLI_SAP/signal_thread.c | 53 + examples/IPC_SAP/UPIPE_SAP/Makefile | 300 ++ examples/IPC_SAP/UPIPE_SAP/auto_builtin_ptr.h | 20 + examples/IPC_SAP/UPIPE_SAP/ex1.cpp | 155 + examples/IPC_SAP/UPIPE_SAP/ex2.cpp | 153 + examples/IPC_SAP/UPIPE_SAP/ex3.cpp | 147 + examples/Log_Msg/Makefile | 55 + examples/Log_Msg/test_log_msg.cpp | 105 + examples/Logger/Acceptor-server/Makefile | 107 + examples/Logger/Acceptor-server/server_loggerd.cpp | 268 + examples/Logger/Makefile | 27 + examples/Logger/README | 32 + examples/Logger/client/Makefile | 43 + examples/Logger/client/logging_app.cpp | 53 + examples/Logger/simple-server/Logging_Acceptor.cpp | 64 + examples/Logger/simple-server/Logging_Acceptor.h | 49 + examples/Logger/simple-server/Logging_Handler.cpp | 139 + examples/Logger/simple-server/Logging_Handler.h | 64 + examples/Logger/simple-server/Makefile | 116 + examples/Logger/simple-server/Reactor_Singleton.h | 27 + examples/Logger/simple-server/server_loggerd.cpp | 61 + examples/Makefile | 39 + examples/Mem_Map/IO-tests/IO_Test.cpp | 186 + examples/Mem_Map/IO-tests/IO_Test.h | 71 + examples/Mem_Map/IO-tests/Makefile | 63 + examples/Mem_Map/IO-tests/test_io.cpp | 155 + examples/Mem_Map/Makefile | 22 + examples/Mem_Map/file-reverse/Makefile | 58 + examples/Mem_Map/file-reverse/file-reverse.cpp | 45 + examples/Misc/Makefile | 283 ++ examples/Misc/test_XtReactor1.cpp | 138 + examples/Misc/test_XtReactor2.cpp | 70 + examples/Misc/test_dump.cpp | 71 + examples/Misc/test_profile_timer.cpp | 33 + examples/Misc/test_read_buffer.cpp | 30 + examples/Misc/test_sstring.cpp | 22 + examples/Misc/test_trace.cpp | 52 + examples/OS/Makefile | 21 + examples/OS/Process/Makefile | 47 + examples/OS/Process/Process.mak | 311 ++ examples/OS/Process/Process.mdp | Bin 0 -> 44032 bytes examples/OS/Process/README | 10 + examples/OS/Process/process.cpp | 64 + examples/README | 74 + examples/Reactor/Dgram/CODgram.cpp | 121 + examples/Reactor/Dgram/Dgram.cpp | 121 + examples/Reactor/Dgram/Makefile | 135 + examples/Reactor/Makefile | 24 + examples/Reactor/Misc/Makefile | 378 ++ examples/Reactor/Misc/notification.cpp | 249 + examples/Reactor/Misc/pingpong.cpp | 241 + examples/Reactor/Misc/signal_tester.cpp | 221 + examples/Reactor/Misc/test_event_handler_t.cpp | 45 + examples/Reactor/Misc/test_handle_set.cpp | 75 + examples/Reactor/Misc/test_reactors.cpp | 205 + examples/Reactor/Misc/test_signals.cpp | 226 + examples/Reactor/Misc/test_time_value.cpp | 69 + examples/Reactor/Misc/test_timer_queue.cpp | 47 + examples/Reactor/Multicast/Log_Wrapper.cpp | 75 + examples/Reactor/Multicast/Log_Wrapper.h | 59 + examples/Reactor/Multicast/Makefile | 69 + examples/Reactor/Multicast/README | 15 + examples/Reactor/Multicast/client.cpp | 110 + examples/Reactor/Multicast/server.cpp | 157 + examples/Reactor/Ntalker/Makefile | 91 + examples/Reactor/Ntalker/ntalker.cpp | 188 + examples/Reactor/README | 20 + examples/Reactor/ReactorEx/README | 204 + examples/Reactor/ReactorEx/reactorex.mak | 535 ++ examples/Reactor/ReactorEx/reactorex.mdp | Bin 0 -> 51200 bytes examples/Reactor/ReactorEx/test_reactorEx.cpp | 444 ++ examples/Reactor/ReactorEx/test_remove_handler.cpp | 94 + examples/Reactor/WFMO_Reactor/README | 204 + examples/Reactor/WFMO_Reactor/reactorex.mak | 535 ++ examples/Reactor/WFMO_Reactor/reactorex.mdp | Bin 0 -> 51200 bytes examples/Reactor/WFMO_Reactor/test_reactorEx.cpp | 444 ++ .../Reactor/WFMO_Reactor/test_remove_handler.cpp | 94 + examples/Service_Configurator/IPC-tests/Makefile | 24 + examples/Service_Configurator/IPC-tests/README | 112 + .../Service_Configurator/IPC-tests/client/Makefile | 306 ++ .../IPC-tests/client/broadcast_client_test.cpp | 56 + .../IPC-tests/client/local_data | 22 + .../IPC-tests/client/local_dgram_client_test.cpp | 94 + .../IPC-tests/client/local_fifo_client_test.cpp | 85 + .../IPC-tests/client/local_pipe_client_test.cpp | 122 + .../IPC-tests/client/local_spipe_client_test.cpp | 88 + .../IPC-tests/client/local_stream_client_test.cpp | 85 + .../IPC-tests/client/remote_data | 22 + .../IPC-tests/client/remote_data1 | 22 + .../IPC-tests/client/remote_data2 | 22 + .../IPC-tests/client/remote_data3 | 22 + .../IPC-tests/client/remote_data4 | 22 + .../IPC-tests/client/remote_dgram_client_test.cpp | 78 + .../client/remote_service_directory_test.cpp | 80 + .../IPC-tests/client/remote_stream_client_test.cpp | 105 + .../client/remote_thr_stream_client_test.cpp | 96 + .../IPC-tests/server/Handle_Broadcast.cpp | 36 + .../IPC-tests/server/Handle_Broadcast.h | 41 + .../IPC-tests/server/Handle_Broadcast.i | 110 + .../IPC-tests/server/Handle_L_CODgram.cpp | 36 + .../IPC-tests/server/Handle_L_CODgram.h | 41 + .../IPC-tests/server/Handle_L_CODgram.i | 113 + .../IPC-tests/server/Handle_L_Dgram.cpp | 15 + .../IPC-tests/server/Handle_L_Dgram.h | 43 + .../IPC-tests/server/Handle_L_Dgram.i | 109 + .../IPC-tests/server/Handle_L_FIFO.cpp | 36 + .../IPC-tests/server/Handle_L_FIFO.h | 42 + .../IPC-tests/server/Handle_L_FIFO.i | 94 + .../IPC-tests/server/Handle_L_Pipe.cpp | 36 + .../IPC-tests/server/Handle_L_Pipe.h | 44 + .../IPC-tests/server/Handle_L_Pipe.i | 136 + .../IPC-tests/server/Handle_L_SPIPE.cpp | 16 + .../IPC-tests/server/Handle_L_SPIPE.h | 45 + .../IPC-tests/server/Handle_L_SPIPE.i | 118 + .../IPC-tests/server/Handle_L_Stream.cpp | 17 + .../IPC-tests/server/Handle_L_Stream.h | 48 + .../IPC-tests/server/Handle_L_Stream.i | 134 + .../IPC-tests/server/Handle_R_Dgram.cpp | 36 + .../IPC-tests/server/Handle_R_Dgram.h | 40 + .../IPC-tests/server/Handle_R_Dgram.i | 106 + .../IPC-tests/server/Handle_R_Stream.cpp | 39 + .../IPC-tests/server/Handle_R_Stream.h | 46 + .../IPC-tests/server/Handle_R_Stream.i | 124 + .../IPC-tests/server/Handle_Thr_Stream.cpp | 200 + .../IPC-tests/server/Handle_Thr_Stream.h | 76 + .../IPC-tests/server/Handle_Thr_Stream.i | 1 + .../IPC-tests/server/Handle_Timeout.cpp | 34 + .../IPC-tests/server/Handle_Timeout.h | 36 + .../IPC-tests/server/Handle_Timeout.i | 74 + .../Service_Configurator/IPC-tests/server/Makefile | 1016 ++++ .../IPC-tests/server/server_test.cpp | 31 + .../Service_Configurator/IPC-tests/server/svc.conf | 19 + examples/Service_Configurator/Makefile | 22 + examples/Service_Configurator/Misc/Makefile | 105 + .../Service_Configurator/Misc/Timer_Service.cpp | 40 + examples/Service_Configurator/Misc/Timer_Service.h | 16 + examples/Service_Configurator/Misc/main.cpp | 24 + examples/Service_Configurator/Misc/svc.conf | 1 + examples/Shared_Malloc/Makefile | 96 + examples/Shared_Malloc/Malloc.cpp | 80 + examples/Shared_Malloc/Malloc.h | 25 + examples/Shared_Malloc/Options.cpp | 186 + examples/Shared_Malloc/Options.h | 81 + examples/Shared_Malloc/test_malloc.cpp | 195 + examples/Shared_Malloc/test_persistence.cpp | 246 + examples/Shared_Memory/Makefile | 76 + examples/Shared_Memory/test_MM.cpp | 63 + examples/Shared_Memory/test_SV.cpp | 60 + examples/System_V_IPC/Makefile | 26 + examples/System_V_IPC/README | 13 + .../System_V_IPC/SV_Message_Queues/MQ_Client.cpp | 29 + .../System_V_IPC/SV_Message_Queues/MQ_Server.cpp | 51 + examples/System_V_IPC/SV_Message_Queues/Makefile | 101 + .../System_V_IPC/SV_Message_Queues/TMQ_Client.cpp | 43 + .../System_V_IPC/SV_Message_Queues/TMQ_Server.cpp | 59 + examples/System_V_IPC/SV_Message_Queues/test.h | 42 + examples/System_V_IPC/SV_Semaphores/Makefile | 116 + .../SV_Semaphores/Semaphore_Client.cpp | 31 + .../SV_Semaphores/Semaphore_Server.cpp | 41 + .../System_V_IPC/SV_Semaphores/Semaphore_Test.h | 11 + examples/System_V_IPC/SV_Semaphores/Semaphores.cpp | 94 + examples/System_V_IPC/SV_Shared_Memory/Makefile | 54 + .../SV_Shared_Memory/SV_Shared_Memory_Test.cpp | 60 + .../SV_Shared_Memory/SV_Shared_Memory_Test.h | 7 + examples/Threads/Makefile | 1004 ++++ examples/Threads/test_auto_event.cpp | 106 + examples/Threads/test_barrier1.cpp | 84 + examples/Threads/test_barrier2.cpp | 272 + examples/Threads/test_cancel.cpp | 72 + examples/Threads/test_future1.cpp | 420 ++ examples/Threads/test_future2.cpp | 524 ++ examples/Threads/test_manual_event.cpp | 99 + examples/Threads/test_process_mutex.cpp | 66 + examples/Threads/test_process_semaphore.cpp | 56 + examples/Threads/test_reader_writer.cpp | 187 + examples/Threads/test_recursive_mutex.cpp | 110 + examples/Threads/test_task.cpp | 104 + examples/Threads/test_task_three.cpp | 229 + examples/Threads/test_task_two.cpp | 156 + examples/Threads/test_thread_manager.cpp | 105 + examples/Threads/test_thread_pool.cpp | 214 + examples/Threads/test_thread_specific.cpp | 208 + examples/Threads/test_token.cpp | 76 + examples/Threads/test_tss.cpp | 235 + include/makeinclude/macros.GNU | 22 + include/makeinclude/platform_aix.GNU | 30 + include/makeinclude/platform_hpux.GNU | 21 + include/makeinclude/platform_hpux_orbix.GNU | 23 + include/makeinclude/platform_irix5.2.GNU | 11 + include/makeinclude/platform_irix5.3_g++.GNU | 13 + include/makeinclude/platform_irix5.3_sgic++.GNU | 19 + include/makeinclude/platform_irix6.2_sgic++.GNU | 24 + include/makeinclude/platform_linux.GNU | 18 + include/makeinclude/platform_linux_pthread.GNU | 24 + include/makeinclude/platform_m88k.GNU | 24 + include/makeinclude/platform_osf1_3.2.GNU | 13 + include/makeinclude/platform_osf1_4.0.GNU | 16 + include/makeinclude/platform_sco-nothread.GNU | 20 + include/makeinclude/platform_sunos4_g++.GNU | 22 + include/makeinclude/platform_sunos4_lucid.GNU | 13 + include/makeinclude/platform_sunos4_sunc++3.x.GNU | 17 + include/makeinclude/platform_sunos4_sunc++4.x.GNU | 12 + .../platform_sunos4_sunc++4.x_orbix.GNU | 14 + include/makeinclude/platform_sunos5_centerline.GNU | 13 + .../platform_sunos5_centerline_orbix.GNU | 14 + include/makeinclude/platform_sunos5_g++.GNU | 22 + include/makeinclude/platform_sunos5_sunc++.GNU | 14 + include/makeinclude/platform_sunos5_sunc++_4.1.GNU | 14 + .../makeinclude/platform_sunos5_sunc++_orbix.GNU | 15 + include/makeinclude/platform_sunos5_x86_g++.GNU | 22 + include/makeinclude/platform_unixware_g++.GNU | 21 + include/makeinclude/rules.bin.GNU | 12 + include/makeinclude/rules.common.GNU | 17 + include/makeinclude/rules.lib.GNU | 113 + include/makeinclude/rules.local.GNU | 151 + include/makeinclude/rules.nested.GNU | 15 + include/makeinclude/rules.nolocal.GNU | 8 + include/makeinclude/rules.nonested.GNU | 8 + include/makeinclude/wrapper_macros.GNU | 116 + netsvcs/ACE-netsvcs.html | 895 ++++ netsvcs/Makefile | 27 + netsvcs/README | 20 + netsvcs/clients/Logger/Makefile | 77 + netsvcs/clients/Logger/README | 18 + netsvcs/clients/Logger/direct_logging.cpp | 42 + netsvcs/clients/Logger/indirect_logging.cpp | 34 + netsvcs/clients/Makefile | 24 + netsvcs/clients/Naming/Client/Client_Test.cpp | 561 +++ netsvcs/clients/Naming/Client/Client_Test.h | 9 + netsvcs/clients/Naming/Client/Makefile | 175 + netsvcs/clients/Naming/Client/main.cpp | 42 + netsvcs/clients/Naming/Client/svc.conf | 6 + netsvcs/clients/Naming/Client/svc2.conf | 9 + .../clients/Naming/Dump_Restore/Dump_Restore.cpp | 388 ++ netsvcs/clients/Naming/Dump_Restore/Dump_Restore.h | 74 + netsvcs/clients/Naming/Dump_Restore/Makefile | 176 + netsvcs/clients/Naming/Dump_Restore/README | 67 + netsvcs/clients/Naming/Dump_Restore/createfile.cpp | 32 + netsvcs/clients/Naming/Dump_Restore/main.cpp | 22 + netsvcs/clients/Naming/Dump_Restore/nametest.cpp | 112 + netsvcs/clients/Naming/Dump_Restore/nametest.h | 15 + netsvcs/clients/Naming/Makefile | 25 + netsvcs/clients/Naming/README | 124 + netsvcs/clients/README | 8 + netsvcs/clients/Tokens/Makefile | 26 + netsvcs/clients/Tokens/README | 34 + netsvcs/clients/Tokens/collection/Makefile | 108 + netsvcs/clients/Tokens/collection/README | 25 + netsvcs/clients/Tokens/collection/collection.cpp | 217 + netsvcs/clients/Tokens/collection/rw_locks.cpp | 175 + netsvcs/clients/Tokens/deadlock/Makefile | 87 + netsvcs/clients/Tokens/deadlock/README | 98 + .../Tokens/deadlock/deadlock_detection_test.cpp | 342 ++ netsvcs/clients/Tokens/invariant/Makefile | 72 + netsvcs/clients/Tokens/invariant/README | 27 + netsvcs/clients/Tokens/invariant/invariant.cpp | 199 + netsvcs/clients/Tokens/manual/Makefile | 109 + netsvcs/clients/Tokens/manual/README | 67 + netsvcs/clients/Tokens/manual/manual.cpp | 347 ++ netsvcs/clients/Tokens/mutex/Makefile | 85 + netsvcs/clients/Tokens/mutex/README | 23 + netsvcs/clients/Tokens/mutex/test_mutex.cpp | 144 + netsvcs/clients/Tokens/rw_lock/Makefile | 86 + netsvcs/clients/Tokens/rw_lock/README | 40 + netsvcs/clients/Tokens/rw_lock/rw_locks.cpp | 255 + netsvcs/lib/Client_Logging_Handler.cpp | 373 ++ netsvcs/lib/Client_Logging_Handler.h | 25 + netsvcs/lib/Client_Logging_Handler.i | 4 + netsvcs/lib/Logging_Strategy.cpp | 145 + netsvcs/lib/Logging_Strategy.h | 25 + netsvcs/lib/Makefile | 465 ++ netsvcs/lib/Name_Handler.cpp | 738 +++ netsvcs/lib/Name_Handler.h | 24 + netsvcs/lib/README | 270 + netsvcs/lib/Server_Logging_Handler.cpp | 453 ++ netsvcs/lib/Server_Logging_Handler.h | 26 + netsvcs/lib/Server_Logging_Handler.i | 4 + netsvcs/lib/TS_Clerk_Handler.cpp | 826 +++ netsvcs/lib/TS_Clerk_Handler.h | 23 + netsvcs/lib/TS_Server_Handler.cpp | 324 ++ netsvcs/lib/TS_Server_Handler.h | 25 + netsvcs/lib/Token_Handler.cpp | 882 ++++ netsvcs/lib/Token_Handler.h | 26 + netsvcs/lib/netsvcs.mak | 1082 ++++ netsvcs/lib/netsvcs.mdp | Bin 0 -> 47104 bytes netsvcs/servers/Makefile | 51 + netsvcs/servers/README | 29 + netsvcs/servers/cli.conf | 11 + netsvcs/servers/main.cpp | 77 + netsvcs/servers/ntsvc.conf | 12 + netsvcs/servers/servers.mak | 402 ++ netsvcs/servers/servers.mdp | Bin 0 -> 41984 bytes netsvcs/servers/svc.conf | 15 + performance-tests/Makefile | 30 + performance-tests/Misc/Makefile | 146 + performance-tests/Misc/test_mutex.cpp | 230 + performance-tests/Misc/test_naming.cpp | 169 + performance-tests/Misc/test_singleton.cpp | 183 + performance-tests/Synch-Benchmarks/Benchmark.cpp | 95 + performance-tests/Synch-Benchmarks/Benchmark.h | 73 + performance-tests/Synch-Benchmarks/Makefile | 1192 +++++ performance-tests/Synch-Benchmarks/Makefile.driver | 41 + .../Synch-Benchmarks/Makefile.synch_tests | 948 ++++ performance-tests/Synch-Benchmarks/Options.cpp | 391 ++ performance-tests/Synch-Benchmarks/Options.h | 126 + performance-tests/Synch-Benchmarks/Options.i | 264 + performance-tests/Synch-Benchmarks/README | 29 + performance-tests/Synch-Benchmarks/benchmarks | 19 + performance-tests/Synch-Benchmarks/condb_test.cpp | 71 + performance-tests/Synch-Benchmarks/conds_test.cpp | 74 + performance-tests/Synch-Benchmarks/context.c | 72 + performance-tests/Synch-Benchmarks/context.csh | 16 + .../Synch-Benchmarks/context_test.cpp | 40 + performance-tests/Synch-Benchmarks/memory_test.cpp | 42 + performance-tests/Synch-Benchmarks/mutex_test.cpp | 46 + performance-tests/Synch-Benchmarks/orig-results | 73 + .../Synch-Benchmarks/pipe_proc_test.cpp | 85 + .../Synch-Benchmarks/pipe_thr_test.cpp | 81 + .../Synch-Benchmarks/recursive_lock_test.cpp | 45 + performance-tests/Synch-Benchmarks/rwrd_test.cpp | 46 + performance-tests/Synch-Benchmarks/rwwr_test.cpp | 46 + performance-tests/Synch-Benchmarks/sema_test.cpp | 46 + performance-tests/Synch-Benchmarks/svc.conf | 14 + .../Synch-Benchmarks/synch_driver.cpp | 166 + .../Synch-Benchmarks/sysvsema_test.cpp | 47 + performance-tests/TTCP/ACE-C++/How_to_run_tests | 29 + performance-tests/TTCP/ACE-C++/Makefile | 52 + performance-tests/TTCP/ACE-C++/run_test | 35 + .../TTCP/ACE-C++/wrapper-new-ttcp.cpp | 947 ++++ performance-tests/TTCP/C/How_to_run_tests | 30 + performance-tests/TTCP/C/Makefile | 52 + performance-tests/TTCP/C/README | 38 + performance-tests/TTCP/C/new-ttcp.cpp | 981 ++++ performance-tests/TTCP/C/run_test | 35 + performance-tests/TTCP/Makefile | 27 + performance-tests/TTCP/ORBeline/How_to_run_tests | 57 + performance-tests/TTCP/ORBeline/Makefile | 33 + performance-tests/TTCP/ORBeline/run_test | 30 + performance-tests/TTCP/ORBeline/ser | 4 + performance-tests/TTCP/ORBeline/stdmk | 34 + performance-tests/TTCP/ORBeline/tango_clt | 6 + performance-tests/TTCP/ORBeline/ttcp.idl | 23 + performance-tests/TTCP/ORBeline/ttcp_c.cc | 302 ++ performance-tests/TTCP/ORBeline/ttcp_c.hh | 181 + performance-tests/TTCP/ORBeline/ttcp_i.cpp | 1028 ++++ performance-tests/TTCP/ORBeline/ttcp_i.h | 45 + performance-tests/TTCP/ORBeline/ttcp_s.cc | 168 + performance-tests/TTCP/ORBeline/ttcp_s.hh | 89 + performance-tests/TTCP/Orbix/How_to_run_tests | 59 + performance-tests/TTCP/Orbix/Makefile | 30 + performance-tests/TTCP/Orbix/README | 13 + performance-tests/TTCP/Orbix/orbix_defaults.mk | 85 + performance-tests/TTCP/Orbix/run_test | 30 + performance-tests/TTCP/Orbix/ttcp.hh | 376 ++ performance-tests/TTCP/Orbix/ttcp.idl | 22 + performance-tests/TTCP/Orbix/ttcpC.cpp | 343 ++ performance-tests/TTCP/Orbix/ttcpS.cpp | 159 + performance-tests/TTCP/Orbix/ttcp_i.cpp | 1013 ++++ performance-tests/TTCP/Orbix/ttcp_i.h | 46 + rpc++/.dependencies | 131 + rpc++/COPYING | 481 ++ rpc++/Makefile | 55 + rpc++/Proj.make | 68 + rpc++/README | 18 + rpc++/README.ORIG | 9 + rpc++/StdHdrs/Makefile | 13 + rpc++/StdHdrs/README | 3 + rpc++/StdHdrs/rpc/auth.h | 171 + rpc++/StdHdrs/rpc/c_types.h | 79 + rpc++/StdHdrs/rpc/clnt.h | 347 ++ rpc++/StdHdrs/rpc/pmap_clnt.h | 82 + rpc++/StdHdrs/rpc/svc.h | 286 ++ rpc++/StdHdrs/rpc/xdr.h | 275 + rpc++/callback.cc | 38 + rpc++/example/Makefile | 40 + rpc++/example/calcsvc.cc | 30 + rpc++/example/calcsvc.h | 34 + rpc++/example/client.cc | 64 + rpc++/example/server.cc | 112 + rpc++/gcc-2.2.fix | 252 + rpc++/request.cc | 165 + rpc++/rpc++.cp | 13 + rpc++/rpc++.fn | 63 + rpc++/rpc++.ky | 0 rpc++/rpc++.pg | 0 rpc++/rpc++.texi | 1519 ++++++ rpc++/rpc++.toc | 23 + rpc++/rpc++.tp | 7 + rpc++/rpc++.vr | 13 + rpc++/rpc++/callback.h | 533 ++ rpc++/rpc++/request.h | 121 + rpc++/rpc++/service.h | 132 + rpc++/rpc++/stub.h | 145 + rpc++/rpc++/xdr++.h | 98 + rpc++/service.cc | 316 ++ rpc++/stub.cc | 207 + rpc++/version.h | 4 + rpc++/xdr++.cc | 75 + tests/Barrier_Test.cpp | 98 + tests/Buffer_Stream_Test.cpp | 234 + tests/CPP_Test.cpp | 263 + tests/Future_Test.cpp | 427 ++ tests/Handle_Set_Test.cpp | 78 + tests/Makefile | 1105 ++++ tests/Mem_Map_Test.cpp | 157 + tests/Mutex_Test.cpp | 48 + tests/Naming_Test.cpp | 146 + tests/Priority_Buffer_Test.cpp | 158 + tests/README | 51 + tests/Reactor_Timer_Test.cpp | 95 + tests/Reactors_Test.cpp | 215 + tests/Reader_Writer_Test.cpp | 216 + tests/Recursive_Mutex_Test.cpp | 88 + tests/SPIPE_Test.cpp | 146 + tests/SString_Test.cpp | 45 + tests/SV_Shared_Memory_Test.cpp | 86 + tests/Shared_Memory_MM_Test.cpp | 132 + tests/Shared_Memory_SV_Test.cpp | 81 + tests/TSS_Test.cpp | 218 + tests/Task_Test.cpp | 117 + tests/Thread_Manager_Test.cpp | 123 + tests/Thread_Pool_Test.cpp | 221 + tests/Time_Service_Test.cpp | 77 + tests/Time_Value_Test.cpp | 49 + tests/Timer_Queue_Test.cpp | 65 + tests/Tokens_Test.cpp | 251 + tests/UNIXclerk.conf | 3 + tests/UNIXserver.conf | 10 + tests/UNIXtokens.conf | 6 + tests/UPIPE_SAP_Test.cpp | 168 + tests/Win32clerk.conf | 3 + tests/Win32server.conf | 10 + tests/Win32tokens.conf | 6 + tests/run_tests.bat | 32 + tests/run_tests.sh | 66 + tests/test_config.h | 95 + tests/tests.mak | 3941 +++++++++++++++ tests/tests.mdp | Bin 0 -> 120320 bytes 1181 files changed, 202920 insertions(+) create mode 100644 ACE-categories create mode 100644 ACE-install.sh create mode 100644 BIBLIOGRAPHY create mode 100644 ChangeLog-93 create mode 100644 ChangeLog-94 create mode 100644 ChangeLog-95 create mode 100644 ChangeLog-96a create mode 100644 ChangeLog-96b create mode 100644 FAQ create mode 100644 INSTALL create mode 100644 Makefile create mode 100644 README create mode 100644 VERSION create mode 100644 ace/ACE.cpp create mode 100644 ace/ACE.h create mode 100644 ace/ACE.i create mode 100644 ace/ARGV.cpp create mode 100644 ace/ARGV.h create mode 100644 ace/ARGV.i create mode 100644 ace/Acceptor.cpp create mode 100644 ace/Acceptor.h create mode 100644 ace/Acceptor.i create mode 100644 ace/Activation_Queue.cpp create mode 100644 ace/Activation_Queue.h create mode 100644 ace/Addr.cpp create mode 100644 ace/Addr.h create mode 100644 ace/Addr.i create mode 100644 ace/Auto_Ptr.cpp create mode 100644 ace/Auto_Ptr.h create mode 100644 ace/Auto_Ptr.i create mode 100644 ace/CORBA_Handler.cpp create mode 100644 ace/CORBA_Handler.h create mode 100644 ace/CORBA_Handler.i create mode 100644 ace/CORBA_Ref.cpp create mode 100644 ace/CORBA_Ref.h create mode 100644 ace/CORBA_Ref.i create mode 100644 ace/Connector.cpp create mode 100644 ace/Connector.h create mode 100644 ace/Connector.i create mode 100644 ace/DEV.cpp create mode 100644 ace/DEV.h create mode 100644 ace/DEV.i create mode 100644 ace/DEV_Addr.cpp create mode 100644 ace/DEV_Addr.h create mode 100644 ace/DEV_Addr.i create mode 100644 ace/DEV_Connector.cpp create mode 100644 ace/DEV_Connector.h create mode 100644 ace/DEV_Connector.i create mode 100644 ace/DEV_IO.cpp create mode 100644 ace/DEV_IO.h create mode 100644 ace/DEV_IO.i create mode 100644 ace/Date_Time.cpp create mode 100644 ace/Date_Time.h create mode 100644 ace/Date_Time.i create mode 100644 ace/Dump.cpp create mode 100644 ace/Dump.h create mode 100644 ace/Dump_T.cpp create mode 100644 ace/Dump_T.h create mode 100644 ace/Dynamic.cpp create mode 100644 ace/Dynamic.h create mode 100644 ace/Dynamic.i create mode 100644 ace/Dynamic_Service.cpp create mode 100644 ace/Dynamic_Service.h create mode 100644 ace/Dynamic_Service.i create mode 100644 ace/Event_Handler.cpp create mode 100644 ace/Event_Handler.h create mode 100644 ace/Event_Handler.i create mode 100644 ace/Event_Handler_T.cpp create mode 100644 ace/Event_Handler_T.h create mode 100644 ace/Event_Handler_T.i create mode 100644 ace/FIFO.cpp create mode 100644 ace/FIFO.h create mode 100644 ace/FIFO.i create mode 100644 ace/FIFO_Recv.cpp create mode 100644 ace/FIFO_Recv.h create mode 100644 ace/FIFO_Recv.i create mode 100644 ace/FIFO_Recv_Msg.cpp create mode 100644 ace/FIFO_Recv_Msg.h create mode 100644 ace/FIFO_Recv_Msg.i create mode 100644 ace/FIFO_Send.cpp create mode 100644 ace/FIFO_Send.h create mode 100644 ace/FIFO_Send.i create mode 100644 ace/FIFO_Send_Msg.cpp create mode 100644 ace/FIFO_Send_Msg.h create mode 100644 ace/FIFO_Send_Msg.i create mode 100644 ace/FILE.cpp create mode 100644 ace/FILE.h create mode 100644 ace/FILE.i create mode 100644 ace/FILE_Addr.cpp create mode 100644 ace/FILE_Addr.h create mode 100644 ace/FILE_Addr.i create mode 100644 ace/FILE_Connector.cpp create mode 100644 ace/FILE_Connector.h create mode 100644 ace/FILE_Connector.i create mode 100644 ace/FILE_IO.cpp create mode 100644 ace/FILE_IO.h create mode 100644 ace/FILE_IO.i create mode 100644 ace/Future.cpp create mode 100644 ace/Future.h create mode 100644 ace/Get_Opt.cpp create mode 100644 ace/Get_Opt.h create mode 100644 ace/Get_Opt.i create mode 100644 ace/Handle_Set.cpp create mode 100644 ace/Handle_Set.h create mode 100644 ace/Handle_Set.i create mode 100644 ace/High_Res_Timer.cpp create mode 100644 ace/High_Res_Timer.h create mode 100644 ace/High_Res_Timer.i create mode 100644 ace/INET_Addr.cpp create mode 100644 ace/INET_Addr.h create mode 100644 ace/INET_Addr.i create mode 100644 ace/IO_Cntl_Msg.cpp create mode 100644 ace/IO_Cntl_Msg.h create mode 100644 ace/IO_Cntl_Msg.i create mode 100644 ace/IO_SAP.cpp create mode 100644 ace/IO_SAP.h create mode 100644 ace/IO_SAP.i create mode 100644 ace/IPC_SAP.cpp create mode 100644 ace/IPC_SAP.h create mode 100644 ace/IPC_SAP.i create mode 100644 ace/LSOCK.cpp create mode 100644 ace/LSOCK.h create mode 100644 ace/LSOCK.i create mode 100644 ace/LSOCK_Acceptor.cpp create mode 100644 ace/LSOCK_Acceptor.h create mode 100644 ace/LSOCK_Acceptor.i create mode 100644 ace/LSOCK_CODgram.cpp create mode 100644 ace/LSOCK_CODgram.h create mode 100644 ace/LSOCK_CODgram.i create mode 100644 ace/LSOCK_Connector.cpp create mode 100644 ace/LSOCK_Connector.h create mode 100644 ace/LSOCK_Connector.i create mode 100644 ace/LSOCK_Dgram.cpp create mode 100644 ace/LSOCK_Dgram.h create mode 100644 ace/LSOCK_Dgram.i create mode 100644 ace/LSOCK_Stream.cpp create mode 100644 ace/LSOCK_Stream.h create mode 100644 ace/LSOCK_Stream.i create mode 100644 ace/Local_Name_Space.cpp create mode 100644 ace/Local_Name_Space.h create mode 100644 ace/Local_Name_Space_T.cpp create mode 100644 ace/Local_Name_Space_T.h create mode 100644 ace/Local_Tokens.cpp create mode 100644 ace/Local_Tokens.h create mode 100644 ace/Local_Tokens.i create mode 100644 ace/Local_Tokens_T.cpp create mode 100644 ace/Local_Tokens_T.h create mode 100644 ace/Local_Tokens_T.i create mode 100644 ace/Log_Msg.cpp create mode 100644 ace/Log_Msg.h create mode 100644 ace/Log_Msg.i create mode 100644 ace/Log_Priority.h create mode 100644 ace/Log_Record.cpp create mode 100644 ace/Log_Record.h create mode 100644 ace/Log_Record.i create mode 100644 ace/Makefile create mode 100644 ace/Malloc.cpp create mode 100644 ace/Malloc.h create mode 100644 ace/Malloc.i create mode 100644 ace/Malloc_T.cpp create mode 100644 ace/Malloc_T.h create mode 100644 ace/Malloc_T.i create mode 100644 ace/Map_Manager.cpp create mode 100644 ace/Map_Manager.h create mode 100644 ace/Map_Manager.i create mode 100644 ace/Mem_Map.cpp create mode 100644 ace/Mem_Map.h create mode 100644 ace/Mem_Map.i create mode 100644 ace/Memory_Pool.cpp create mode 100644 ace/Memory_Pool.h create mode 100644 ace/Memory_Pool.i create mode 100644 ace/Message_Block.cpp create mode 100644 ace/Message_Block.h create mode 100644 ace/Message_Block.i create mode 100644 ace/Message_Queue.cpp create mode 100644 ace/Message_Queue.h create mode 100644 ace/Message_Queue.i create mode 100644 ace/Method_Object.cpp create mode 100644 ace/Method_Object.h create mode 100644 ace/Module.cpp create mode 100644 ace/Module.h create mode 100644 ace/Module.i create mode 100644 ace/Multiplexor.cpp create mode 100644 ace/Multiplexor.h create mode 100644 ace/Multiplexor.i create mode 100644 ace/Name_Proxy.cpp create mode 100644 ace/Name_Proxy.h create mode 100644 ace/Name_Request_Reply.cpp create mode 100644 ace/Name_Request_Reply.h create mode 100644 ace/Name_Space.cpp create mode 100644 ace/Name_Space.h create mode 100644 ace/Naming_Context.cpp create mode 100644 ace/Naming_Context.h create mode 100644 ace/OS.cpp create mode 100644 ace/OS.h create mode 100644 ace/OS.i create mode 100644 ace/Obstack.cpp create mode 100644 ace/Obstack.h create mode 100644 ace/Obstack.i create mode 100644 ace/Parse_Node.cpp create mode 100644 ace/Parse_Node.h create mode 100644 ace/Parse_Node.i create mode 100644 ace/Pipe.cpp create mode 100644 ace/Pipe.h create mode 100644 ace/Pipe.i create mode 100644 ace/Proactor.cpp create mode 100644 ace/Proactor.h create mode 100644 ace/Proactor.i create mode 100644 ace/Process.cpp create mode 100644 ace/Process.h create mode 100644 ace/Process.i create mode 100644 ace/Process_Manager.cpp create mode 100644 ace/Process_Manager.h create mode 100644 ace/Process_Manager.i create mode 100644 ace/Profile_Timer.cpp create mode 100644 ace/Profile_Timer.h create mode 100644 ace/Profile_Timer.i create mode 100644 ace/README create mode 100644 ace/Reactor.cpp create mode 100644 ace/Reactor.h create mode 100644 ace/Reactor.i create mode 100644 ace/ReactorEx.cpp create mode 100644 ace/ReactorEx.h create mode 100644 ace/ReactorEx.i create mode 100644 ace/Read_Buffer.cpp create mode 100644 ace/Read_Buffer.h create mode 100644 ace/Read_Buffer.i create mode 100644 ace/Remote_Name_Space.cpp create mode 100644 ace/Remote_Name_Space.h create mode 100644 ace/Remote_Tokens.cpp create mode 100644 ace/Remote_Tokens.h create mode 100644 ace/Remote_Tokens.i create mode 100644 ace/SOCK.cpp create mode 100644 ace/SOCK.h create mode 100644 ace/SOCK.i create mode 100644 ace/SOCK_Acceptor.cpp create mode 100644 ace/SOCK_Acceptor.h create mode 100644 ace/SOCK_Acceptor.i create mode 100644 ace/SOCK_CODgram.cpp create mode 100644 ace/SOCK_CODgram.h create mode 100644 ace/SOCK_CODgram.i create mode 100644 ace/SOCK_Connector.cpp create mode 100644 ace/SOCK_Connector.h create mode 100644 ace/SOCK_Connector.i create mode 100644 ace/SOCK_Dgram.cpp create mode 100644 ace/SOCK_Dgram.h create mode 100644 ace/SOCK_Dgram.i create mode 100644 ace/SOCK_Dgram_Bcast.cpp create mode 100644 ace/SOCK_Dgram_Bcast.h create mode 100644 ace/SOCK_Dgram_Bcast.i create mode 100644 ace/SOCK_Dgram_Mcast.cpp create mode 100644 ace/SOCK_Dgram_Mcast.h create mode 100644 ace/SOCK_Dgram_Mcast.i create mode 100644 ace/SOCK_IO.cpp create mode 100644 ace/SOCK_IO.h create mode 100644 ace/SOCK_IO.i create mode 100644 ace/SOCK_Stream.cpp create mode 100644 ace/SOCK_Stream.h create mode 100644 ace/SOCK_Stream.i create mode 100644 ace/SPIPE.cpp create mode 100644 ace/SPIPE.h create mode 100644 ace/SPIPE.i create mode 100644 ace/SPIPE_Acceptor.cpp create mode 100644 ace/SPIPE_Acceptor.h create mode 100644 ace/SPIPE_Acceptor.i create mode 100644 ace/SPIPE_Addr.cpp create mode 100644 ace/SPIPE_Addr.h create mode 100644 ace/SPIPE_Addr.i create mode 100644 ace/SPIPE_Connector.cpp create mode 100644 ace/SPIPE_Connector.h create mode 100644 ace/SPIPE_Connector.i create mode 100644 ace/SPIPE_Stream.cpp create mode 100644 ace/SPIPE_Stream.h create mode 100644 ace/SPIPE_Stream.i create mode 100644 ace/SString.cpp create mode 100644 ace/SString.h create mode 100644 ace/SString.i create mode 100644 ace/SV_Message.cpp create mode 100644 ace/SV_Message.h create mode 100644 ace/SV_Message.i create mode 100644 ace/SV_Message_Queue.cpp create mode 100644 ace/SV_Message_Queue.h create mode 100644 ace/SV_Message_Queue.i create mode 100644 ace/SV_Semaphore_Complex.cpp create mode 100644 ace/SV_Semaphore_Complex.h create mode 100644 ace/SV_Semaphore_Complex.i create mode 100644 ace/SV_Semaphore_Simple.cpp create mode 100644 ace/SV_Semaphore_Simple.h create mode 100644 ace/SV_Semaphore_Simple.i create mode 100644 ace/SV_Shared_Memory.cpp create mode 100644 ace/SV_Shared_Memory.h create mode 100644 ace/SV_Shared_Memory.i create mode 100644 ace/Service_Config.cpp create mode 100644 ace/Service_Config.h create mode 100644 ace/Service_Config.i create mode 100644 ace/Service_Main.cpp create mode 100644 ace/Service_Manager.cpp create mode 100644 ace/Service_Manager.h create mode 100644 ace/Service_Manager.i create mode 100644 ace/Service_Object.cpp create mode 100644 ace/Service_Object.h create mode 100644 ace/Service_Object.i create mode 100644 ace/Service_Record.cpp create mode 100644 ace/Service_Record.h create mode 100644 ace/Service_Record.i create mode 100644 ace/Service_Repository.cpp create mode 100644 ace/Service_Repository.h create mode 100644 ace/Service_Repository.i create mode 100644 ace/Set.cpp create mode 100644 ace/Set.h create mode 100644 ace/Set.i create mode 100644 ace/Shared_Memory.h create mode 100644 ace/Shared_Memory_MM.cpp create mode 100644 ace/Shared_Memory_MM.h create mode 100644 ace/Shared_Memory_MM.i create mode 100644 ace/Shared_Memory_SV.cpp create mode 100644 ace/Shared_Memory_SV.h create mode 100644 ace/Shared_Memory_SV.i create mode 100644 ace/Shared_Object.cpp create mode 100644 ace/Shared_Object.h create mode 100644 ace/Shared_Object.i create mode 100644 ace/Signal.cpp create mode 100644 ace/Signal.h create mode 100644 ace/Signal.i create mode 100644 ace/Singleton.cpp create mode 100644 ace/Singleton.h create mode 100644 ace/Singleton.i create mode 100644 ace/Stack.cpp create mode 100644 ace/Stack.h create mode 100644 ace/Stack.i create mode 100644 ace/Strategies.cpp create mode 100644 ace/Strategies.h create mode 100644 ace/Strategies.i create mode 100644 ace/Stream.cpp create mode 100644 ace/Stream.h create mode 100644 ace/Stream.i create mode 100644 ace/Stream_Modules.cpp create mode 100644 ace/Stream_Modules.h create mode 100644 ace/Stream_Modules.i create mode 100644 ace/Svc_Conf.h create mode 100644 ace/Svc_Conf.l create mode 100644 ace/Svc_Conf.y create mode 100644 ace/Svc_Conf_Tokens.h create mode 100644 ace/Svc_Conf_l.cpp create mode 100644 ace/Svc_Conf_y.cpp create mode 100644 ace/Svc_Handler.cpp create mode 100644 ace/Svc_Handler.h create mode 100644 ace/Svc_Handler.i create mode 100644 ace/Synch.cpp create mode 100644 ace/Synch.h create mode 100644 ace/Synch.i create mode 100644 ace/Synch_Options.cpp create mode 100644 ace/Synch_Options.h create mode 100644 ace/Synch_Options.i create mode 100644 ace/Synch_T.cpp create mode 100644 ace/Synch_T.h create mode 100644 ace/Synch_T.i create mode 100644 ace/System_Time.cpp create mode 100644 ace/System_Time.h create mode 100644 ace/TLI.cpp create mode 100644 ace/TLI.h create mode 100644 ace/TLI.i create mode 100644 ace/TLI_Acceptor.cpp create mode 100644 ace/TLI_Acceptor.h create mode 100644 ace/TLI_Acceptor.i create mode 100644 ace/TLI_Connector.cpp create mode 100644 ace/TLI_Connector.h create mode 100644 ace/TLI_Connector.i create mode 100644 ace/TLI_Stream.cpp create mode 100644 ace/TLI_Stream.h create mode 100644 ace/TLI_Stream.i create mode 100644 ace/TTY_IO.cpp create mode 100644 ace/TTY_IO.h create mode 100644 ace/Task.cpp create mode 100644 ace/Task.h create mode 100644 ace/Task.i create mode 100644 ace/Thread.cpp create mode 100644 ace/Thread.h create mode 100644 ace/Thread.i create mode 100644 ace/Thread_Manager.cpp create mode 100644 ace/Thread_Manager.h create mode 100644 ace/Thread_Manager.i create mode 100644 ace/Time_Request_Reply.cpp create mode 100644 ace/Time_Request_Reply.h create mode 100644 ace/Time_Value.cpp create mode 100644 ace/Time_Value.h create mode 100644 ace/Time_Value.i create mode 100644 ace/Timer_Queue.cpp create mode 100644 ace/Timer_Queue.h create mode 100644 ace/Timer_Queue.i create mode 100644 ace/Token.cpp create mode 100644 ace/Token.h create mode 100644 ace/Token.i create mode 100644 ace/Token_Collection.cpp create mode 100644 ace/Token_Collection.h create mode 100644 ace/Token_Collection.i create mode 100644 ace/Token_Invariants.cpp create mode 100644 ace/Token_Invariants.h create mode 100644 ace/Token_Invariants.i create mode 100644 ace/Token_Manager.cpp create mode 100644 ace/Token_Manager.h create mode 100644 ace/Token_Manager.i create mode 100644 ace/Token_Request_Reply.cpp create mode 100644 ace/Token_Request_Reply.h create mode 100644 ace/Token_Request_Reply.i create mode 100644 ace/Trace.cpp create mode 100644 ace/Trace.h create mode 100644 ace/Trace.i create mode 100644 ace/Typed_SV_Message.cpp create mode 100644 ace/Typed_SV_Message.h create mode 100644 ace/Typed_SV_Message.i create mode 100644 ace/Typed_SV_Message_Queue.cpp create mode 100644 ace/Typed_SV_Message_Queue.h create mode 100644 ace/Typed_SV_Message_Queue.i create mode 100644 ace/UNIX_Addr.cpp create mode 100644 ace/UNIX_Addr.h create mode 100644 ace/UNIX_Addr.i create mode 100644 ace/UPIPE_Acceptor.cpp create mode 100644 ace/UPIPE_Acceptor.h create mode 100644 ace/UPIPE_Acceptor.i create mode 100644 ace/UPIPE_Addr.h create mode 100644 ace/UPIPE_Connector.cpp create mode 100644 ace/UPIPE_Connector.h create mode 100644 ace/UPIPE_Connector.i create mode 100644 ace/UPIPE_Stream.cpp create mode 100644 ace/UPIPE_Stream.h create mode 100644 ace/UPIPE_Stream.i create mode 100644 ace/XtReactor.cpp create mode 100644 ace/XtReactor.h create mode 100644 ace/ace.mak create mode 100644 ace/ace.mdp create mode 100644 ace/config-aix-3.2.5.h create mode 100644 ace/config-aix-4.1.x.h create mode 100644 ace/config-hpux-10.x-g++.h create mode 100644 ace/config-hpux-10.x.h create mode 100644 ace/config-hpux-9.x-orbix.h create mode 100644 ace/config-hpux-9.x.h create mode 100644 ace/config-irix5.2.h create mode 100644 ace/config-irix5.3-g++.h create mode 100644 ace/config-irix5.3-sgic++.h create mode 100644 ace/config-irix6.2-sgic++.h create mode 100644 ace/config-linux-pthread.h create mode 100644 ace/config-linux.h create mode 100644 ace/config-m88k.h create mode 100644 ace/config-osf1-3.2.h create mode 100644 ace/config-osf1-4.0.h create mode 100644 ace/config-sco-4.2-nothread.h create mode 100644 ace/config-sunos4-g++.h create mode 100644 ace/config-sunos4-lucid3.2.h create mode 100644 ace/config-sunos4-sun3.x.h create mode 100644 ace/config-sunos4-sun4.1.4.h create mode 100644 ace/config-sunos4-sun4.x-orbix.h create mode 100644 ace/config-sunos4-sun4.x.h create mode 100644 ace/config-sunos5.4-centerline-2.x.h create mode 100644 ace/config-sunos5.4-g++.h create mode 100644 ace/config-sunos5.4-sunc++-4.x-orbix.h create mode 100644 ace/config-sunos5.4-sunc++-4.x.h create mode 100644 ace/config-sunos5.5-g++.h create mode 100644 ace/config-sunos5.5-sunc++-4.x-orbix.h create mode 100644 ace/config-sunos5.5-sunc++-4.x.h create mode 100644 ace/config-sunx86-sunc++-4.x.h create mode 100644 ace/config-unixware-2.01-g++.h create mode 100644 ace/config-vxworks-ghs-1.8.h create mode 100644 ace/config-win32-msvc2.0.h create mode 100644 ace/config-win32-msvc4.0.h create mode 100644 ace/makefile-light create mode 100644 apps/Gateway/Gateway/Channel.cpp create mode 100644 apps/Gateway/Gateway/Channel.h create mode 100644 apps/Gateway/Gateway/Channel_Connector.cpp create mode 100644 apps/Gateway/Gateway/Channel_Connector.h create mode 100644 apps/Gateway/Gateway/Config_Files.cpp create mode 100644 apps/Gateway/Gateway/Config_Files.h create mode 100644 apps/Gateway/Gateway/File_Parser.cpp create mode 100644 apps/Gateway/Gateway/File_Parser.h create mode 100644 apps/Gateway/Gateway/Gateway.cpp create mode 100644 apps/Gateway/Gateway/Gateway.h create mode 100644 apps/Gateway/Gateway/Makefile create mode 100644 apps/Gateway/Gateway/Peer_Message.h create mode 100644 apps/Gateway/Gateway/README create mode 100644 apps/Gateway/Gateway/Routing_Entry.cpp create mode 100644 apps/Gateway/Gateway/Routing_Entry.h create mode 100644 apps/Gateway/Gateway/Routing_Table.cpp create mode 100644 apps/Gateway/Gateway/Routing_Table.h create mode 100644 apps/Gateway/Gateway/Thr_Channel.cpp create mode 100644 apps/Gateway/Gateway/Thr_Channel.h create mode 100644 apps/Gateway/Gateway/cc_config create mode 100644 apps/Gateway/Gateway/gatewayd.cpp create mode 100644 apps/Gateway/Gateway/rt_config create mode 100644 apps/Gateway/Gateway/svc.conf create mode 100644 apps/Gateway/Makefile create mode 100644 apps/Gateway/Peer/Gateway_Handler.cpp create mode 100644 apps/Gateway/Peer/Gateway_Handler.h create mode 100644 apps/Gateway/Peer/Makefile create mode 100644 apps/Gateway/Peer/Peer_Message.h create mode 100644 apps/Gateway/Peer/peerd.cpp create mode 100644 apps/Gateway/Peer/svc.conf create mode 100644 apps/Gateway/README create mode 100644 apps/Makefile create mode 100644 apps/Orbix-Examples/Event_Comm/Consumer/Input_Handler.cpp create mode 100644 apps/Orbix-Examples/Event_Comm/Consumer/Input_Handler.h create mode 100644 apps/Orbix-Examples/Event_Comm/Consumer/Makefile create mode 100644 apps/Orbix-Examples/Event_Comm/Consumer/Notification_Receiver_Handler.cpp create mode 100644 apps/Orbix-Examples/Event_Comm/Consumer/Notification_Receiver_Handler.h create mode 100644 apps/Orbix-Examples/Event_Comm/Consumer/consumer.cpp create mode 100644 apps/Orbix-Examples/Event_Comm/Makefile create mode 100644 apps/Orbix-Examples/Event_Comm/README create mode 100644 apps/Orbix-Examples/Event_Comm/Supplier/Input_Handler.cpp create mode 100644 apps/Orbix-Examples/Event_Comm/Supplier/Input_Handler.h create mode 100644 apps/Orbix-Examples/Event_Comm/Supplier/Makefile create mode 100644 apps/Orbix-Examples/Event_Comm/Supplier/Notifier_Handler.cpp create mode 100644 apps/Orbix-Examples/Event_Comm/Supplier/Notifier_Handler.h create mode 100644 apps/Orbix-Examples/Event_Comm/Supplier/supplier.cpp create mode 100644 apps/Orbix-Examples/Event_Comm/include/Event_Comm.hh create mode 100644 apps/Orbix-Examples/Event_Comm/include/Event_Comm_i.h create mode 100644 apps/Orbix-Examples/Event_Comm/include/Notification_Receiver_i.h create mode 100644 apps/Orbix-Examples/Event_Comm/include/Notifier_i.h create mode 100644 apps/Orbix-Examples/Event_Comm/libsrc/Event_Comm.hh create mode 100644 apps/Orbix-Examples/Event_Comm/libsrc/Event_Comm.idl create mode 100644 apps/Orbix-Examples/Event_Comm/libsrc/Event_CommC.cpp create mode 100644 apps/Orbix-Examples/Event_Comm/libsrc/Event_CommS.cpp create mode 100644 apps/Orbix-Examples/Event_Comm/libsrc/Event_Comm_i.h create mode 100644 apps/Orbix-Examples/Event_Comm/libsrc/Makefile create mode 100644 apps/Orbix-Examples/Event_Comm/libsrc/Notification.idl create mode 100644 apps/Orbix-Examples/Event_Comm/libsrc/Notification_Receiver.idl create mode 100644 apps/Orbix-Examples/Event_Comm/libsrc/Notification_Receiver_i.cpp create mode 100644 apps/Orbix-Examples/Event_Comm/libsrc/Notification_Receiver_i.h create mode 100644 apps/Orbix-Examples/Event_Comm/libsrc/Notifier.idl create mode 100644 apps/Orbix-Examples/Event_Comm/libsrc/Notifier_i.cpp create mode 100644 apps/Orbix-Examples/Event_Comm/libsrc/Notifier_i.h create mode 100644 apps/Orbix-Examples/Logger/Logger.cpp create mode 100644 apps/Orbix-Examples/Logger/Logger.h create mode 100644 apps/Orbix-Examples/Logger/Makefile create mode 100644 apps/Orbix-Examples/Logger/Orbix.hostgroups create mode 100644 apps/Orbix-Examples/Logger/Orbix.hosts create mode 100644 apps/Orbix-Examples/Logger/README create mode 100644 apps/Orbix-Examples/Logger/a1.tex create mode 100644 apps/Orbix-Examples/Logger/client.cpp create mode 100644 apps/Orbix-Examples/Logger/logger.hh create mode 100644 apps/Orbix-Examples/Logger/logger.idl create mode 100644 apps/Orbix-Examples/Logger/loggerS.cpp create mode 100644 apps/Orbix-Examples/Logger/logger_i.cpp create mode 100644 apps/Orbix-Examples/Logger/logger_i.h create mode 100644 apps/Orbix-Examples/Logger/server.cpp create mode 100644 apps/Orbix-Examples/Makefile create mode 100644 apps/README create mode 100644 apps/gperf/COPYING create mode 100644 apps/gperf/ChangeLog create mode 100644 apps/gperf/Makefile create mode 100644 apps/gperf/README create mode 100644 apps/gperf/gperf.1 create mode 100644 apps/gperf/gperf.info create mode 100644 apps/gperf/gperf.texi create mode 100644 apps/gperf/src/Bool_Array.cpp create mode 100644 apps/gperf/src/Bool_Array.h create mode 100644 apps/gperf/src/Gen_Perf.cpp create mode 100644 apps/gperf/src/Gen_Perf.h create mode 100644 apps/gperf/src/Hash_Table.cpp create mode 100644 apps/gperf/src/Hash_Table.h create mode 100644 apps/gperf/src/Iterator.cpp create mode 100644 apps/gperf/src/Iterator.h create mode 100644 apps/gperf/src/Key_List.cpp create mode 100644 apps/gperf/src/Key_List.h create mode 100644 apps/gperf/src/List_Node.cpp create mode 100644 apps/gperf/src/List_Node.h create mode 100644 apps/gperf/src/Makefile create mode 100644 apps/gperf/src/Options.cpp create mode 100644 apps/gperf/src/Options.h create mode 100644 apps/gperf/src/Vectors.cpp create mode 100644 apps/gperf/src/Vectors.h create mode 100644 apps/gperf/src/Version.cpp create mode 100644 apps/gperf/src/gperf.cpp create mode 100644 apps/gperf/src/new.cpp create mode 100644 apps/gperf/tests/Makefile.in create mode 100644 apps/gperf/tests/ada-pred.exp create mode 100644 apps/gperf/tests/ada-res.exp create mode 100644 apps/gperf/tests/ada.gperf create mode 100644 apps/gperf/tests/adadefs.gperf create mode 100644 apps/gperf/tests/c++.gperf create mode 100644 apps/gperf/tests/c-parse.gperf create mode 100644 apps/gperf/tests/c.exp create mode 100644 apps/gperf/tests/c.gperf create mode 100644 apps/gperf/tests/configure.in create mode 100644 apps/gperf/tests/gpc.gperf create mode 100644 apps/gperf/tests/gplus.gperf create mode 100644 apps/gperf/tests/irc.gperf create mode 100644 apps/gperf/tests/makeinfo.gperf create mode 100644 apps/gperf/tests/modula.exp create mode 100644 apps/gperf/tests/modula2.gperf create mode 100644 apps/gperf/tests/modula3.gperf create mode 100644 apps/gperf/tests/pascal.exp create mode 100644 apps/gperf/tests/pascal.gperf create mode 100644 apps/gperf/tests/test-1.exp create mode 100644 apps/gperf/tests/test-2.exp create mode 100644 apps/gperf/tests/test-3.exp create mode 100644 apps/gperf/tests/test-4.exp create mode 100644 apps/gperf/tests/test-5.exp create mode 100644 apps/gperf/tests/test-6.exp create mode 100644 apps/gperf/tests/test-7.exp create mode 100644 apps/gperf/tests/test.c create mode 100644 bin/Makefile create mode 100644 bin/README.html create mode 100755 bin/class2hxxcxx create mode 100755 bin/class2hxxcxxsingle create mode 100755 bin/class2info create mode 100644 bin/class2info.awk create mode 100755 bin/class2man create mode 100755 bin/class2mml create mode 100755 bin/class2src create mode 100755 bin/classinfo.ps create mode 100644 bin/clone.1 create mode 100644 bin/clone.cpp create mode 100644 bin/clone.csh create mode 100755 bin/g++dep create mode 100644 bin/hiding.fmt create mode 100755 bin/html-windex create mode 100755 bin/info2doc.awk create mode 100644 bin/info2doc.fmt create mode 100755 bin/info2head create mode 100644 bin/info2head.fmt create mode 100755 bin/info2headsrc create mode 100755 bin/info2man create mode 100755 bin/info2mml create mode 100755 bin/info2src create mode 100755 bin/info2src.awk create mode 100755 bin/man2html create mode 100644 bin/man2html1.awk create mode 100644 bin/man2html2.awk create mode 100755 bin/rename-ace.pl create mode 100755 bin/vendor.fmt create mode 100644 examples/ASX/CCM_App/CCM_App.cpp create mode 100644 examples/ASX/CCM_App/Makefile create mode 100644 examples/ASX/CCM_App/SC_Client.cpp create mode 100644 examples/ASX/CCM_App/SC_Server.cpp create mode 100644 examples/ASX/CCM_App/svc.conf create mode 100644 examples/ASX/Event_Server/Event_Server/Consumer_Router.cpp create mode 100644 examples/ASX/Event_Server/Event_Server/Consumer_Router.h create mode 100644 examples/ASX/Event_Server/Event_Server/Event_Analyzer.cpp create mode 100644 examples/ASX/Event_Server/Event_Server/Event_Analyzer.h create mode 100644 examples/ASX/Event_Server/Event_Server/Makefile create mode 100644 examples/ASX/Event_Server/Event_Server/Options.cpp create mode 100644 examples/ASX/Event_Server/Event_Server/Options.h create mode 100644 examples/ASX/Event_Server/Event_Server/Options.i create mode 100644 examples/ASX/Event_Server/Event_Server/Peer_Router.cpp create mode 100644 examples/ASX/Event_Server/Event_Server/Peer_Router.h create mode 100644 examples/ASX/Event_Server/Event_Server/Supplier_Router.cpp create mode 100644 examples/ASX/Event_Server/Event_Server/Supplier_Router.h create mode 100644 examples/ASX/Event_Server/Event_Server/event_server.cpp create mode 100644 examples/ASX/Event_Server/Makefile create mode 100644 examples/ASX/Event_Server/README create mode 100644 examples/ASX/Event_Server/Transceiver/Makefile create mode 100644 examples/ASX/Event_Server/Transceiver/transceiver.cpp create mode 100644 examples/ASX/Makefile create mode 100644 examples/ASX/Message_Queue/Makefile create mode 100644 examples/ASX/Message_Queue/bounded_buffer.cpp create mode 100644 examples/ASX/Message_Queue/buffer_stream.cpp create mode 100644 examples/ASX/Message_Queue/priority_buffer.cpp create mode 100644 examples/ASX/UPIPE_Event_Server/Consumer_Router.cpp create mode 100644 examples/ASX/UPIPE_Event_Server/Consumer_Router.h create mode 100644 examples/ASX/UPIPE_Event_Server/Event_Analyzer.cpp create mode 100644 examples/ASX/UPIPE_Event_Server/Event_Analyzer.h create mode 100644 examples/ASX/UPIPE_Event_Server/Makefile create mode 100644 examples/ASX/UPIPE_Event_Server/Options.cpp create mode 100644 examples/ASX/UPIPE_Event_Server/Options.h create mode 100644 examples/ASX/UPIPE_Event_Server/Options.i create mode 100644 examples/ASX/UPIPE_Event_Server/Peer_Router.cpp create mode 100644 examples/ASX/UPIPE_Event_Server/Peer_Router.h create mode 100644 examples/ASX/UPIPE_Event_Server/Supplier_Router.cpp create mode 100644 examples/ASX/UPIPE_Event_Server/Supplier_Router.h create mode 100644 examples/ASX/UPIPE_Event_Server/event_server.cpp create mode 100644 examples/CORBA/Makefile create mode 100644 examples/CORBA/Test.idl create mode 100644 examples/CORBA/Test_i.cpp create mode 100644 examples/CORBA/Test_i.h create mode 100644 examples/CORBA/client.cpp create mode 100644 examples/CORBA/server.cpp create mode 100644 examples/Connection/Makefile create mode 100644 examples/Connection/blocking/Makefile create mode 100644 examples/Connection/blocking/README create mode 100644 examples/Connection/blocking/SPIPE-acceptor.cpp create mode 100644 examples/Connection/blocking/SPIPE-acceptor.h create mode 100644 examples/Connection/blocking/SPIPE-connector.cpp create mode 100644 examples/Connection/blocking/SPIPE-connector.h create mode 100644 examples/Connection/blocking/test_spipe_acceptor.cpp create mode 100644 examples/Connection/blocking/test_spipe_connector.cpp create mode 100644 examples/Connection/misc/Makefile create mode 100644 examples/Connection/misc/test_upipe.cpp create mode 100644 examples/Connection/non_blocking/CPP-acceptor.cpp create mode 100644 examples/Connection/non_blocking/CPP-acceptor.h create mode 100644 examples/Connection/non_blocking/CPP-connector.cpp create mode 100644 examples/Connection/non_blocking/CPP-connector.h create mode 100644 examples/Connection/non_blocking/Makefile create mode 100644 examples/Connection/non_blocking/README create mode 100644 examples/Connection/non_blocking/test_sock_acceptor.cpp create mode 100644 examples/Connection/non_blocking/test_sock_connector.cpp create mode 100644 examples/Connection/non_blocking/test_spipe_acceptor.cpp create mode 100644 examples/Connection/non_blocking/test_spipe_connector.cpp create mode 100644 examples/Connection/non_blocking/test_tli_acceptor.cpp create mode 100644 examples/Connection/non_blocking/test_tli_connector.cpp create mode 100644 examples/IPC_SAP/DEV_SAP/Makefile create mode 100644 examples/IPC_SAP/DEV_SAP/README create mode 100644 examples/IPC_SAP/DEV_SAP/reader/Makefile create mode 100644 examples/IPC_SAP/DEV_SAP/reader/reader.cpp create mode 100644 examples/IPC_SAP/DEV_SAP/writer/Makefile create mode 100644 examples/IPC_SAP/DEV_SAP/writer/writer.cpp create mode 100644 examples/IPC_SAP/FIFO_SAP/FIFO-Msg-client.cpp create mode 100644 examples/IPC_SAP/FIFO_SAP/FIFO-Msg-server.cpp create mode 100644 examples/IPC_SAP/FIFO_SAP/FIFO-client.cpp create mode 100644 examples/IPC_SAP/FIFO_SAP/FIFO-server.cpp create mode 100644 examples/IPC_SAP/FIFO_SAP/FIFO-test.cpp create mode 100644 examples/IPC_SAP/FIFO_SAP/Makefile create mode 100644 examples/IPC_SAP/FILE_SAP/Makefile create mode 100644 examples/IPC_SAP/FILE_SAP/client.cpp create mode 100644 examples/IPC_SAP/FILE_SAP/testfile create mode 100644 examples/IPC_SAP/Makefile create mode 100644 examples/IPC_SAP/SOCK_SAP/C-inclient.cpp create mode 100644 examples/IPC_SAP/SOCK_SAP/C-inserver.cpp create mode 100644 examples/IPC_SAP/SOCK_SAP/CPP-inclient.cpp create mode 100644 examples/IPC_SAP/SOCK_SAP/CPP-inserver-poll.cpp create mode 100644 examples/IPC_SAP/SOCK_SAP/CPP-inserver.cpp create mode 100644 examples/IPC_SAP/SOCK_SAP/CPP-unclient.cpp create mode 100644 examples/IPC_SAP/SOCK_SAP/CPP-unserver.cpp create mode 100644 examples/IPC_SAP/SOCK_SAP/FD-unclient.cpp create mode 100644 examples/IPC_SAP/SOCK_SAP/FD-unserver.cpp create mode 100644 examples/IPC_SAP/SOCK_SAP/Makefile create mode 100644 examples/IPC_SAP/SOCK_SAP/README create mode 100644 examples/IPC_SAP/SOCK_SAP/local_data create mode 100644 examples/IPC_SAP/SPIPE_SAP/Makefile create mode 100644 examples/IPC_SAP/SPIPE_SAP/NPClient.cpp create mode 100644 examples/IPC_SAP/SPIPE_SAP/NPServer.cpp create mode 100644 examples/IPC_SAP/SPIPE_SAP/client.cpp create mode 100644 examples/IPC_SAP/SPIPE_SAP/consumer_msg.cpp create mode 100644 examples/IPC_SAP/SPIPE_SAP/consumer_read.cpp create mode 100644 examples/IPC_SAP/SPIPE_SAP/producer_msg.cpp create mode 100644 examples/IPC_SAP/SPIPE_SAP/producer_read.cpp create mode 100644 examples/IPC_SAP/SPIPE_SAP/server.cpp create mode 100644 examples/IPC_SAP/SPIPE_SAP/shared.h create mode 100644 examples/IPC_SAP/TLI_SAP/CPP-client.cpp create mode 100644 examples/IPC_SAP/TLI_SAP/CPP-server.cpp create mode 100644 examples/IPC_SAP/TLI_SAP/Makefile create mode 100644 examples/IPC_SAP/TLI_SAP/db-client.cpp create mode 100644 examples/IPC_SAP/TLI_SAP/db-server.cpp create mode 100644 examples/IPC_SAP/TLI_SAP/ftp-client.cpp create mode 100644 examples/IPC_SAP/TLI_SAP/ftp-server.cpp create mode 100644 examples/IPC_SAP/TLI_SAP/signal_thread.c create mode 100644 examples/IPC_SAP/UPIPE_SAP/Makefile create mode 100644 examples/IPC_SAP/UPIPE_SAP/auto_builtin_ptr.h create mode 100644 examples/IPC_SAP/UPIPE_SAP/ex1.cpp create mode 100644 examples/IPC_SAP/UPIPE_SAP/ex2.cpp create mode 100644 examples/IPC_SAP/UPIPE_SAP/ex3.cpp create mode 100644 examples/Log_Msg/Makefile create mode 100644 examples/Log_Msg/test_log_msg.cpp create mode 100644 examples/Logger/Acceptor-server/Makefile create mode 100644 examples/Logger/Acceptor-server/server_loggerd.cpp create mode 100644 examples/Logger/Makefile create mode 100644 examples/Logger/README create mode 100644 examples/Logger/client/Makefile create mode 100644 examples/Logger/client/logging_app.cpp create mode 100644 examples/Logger/simple-server/Logging_Acceptor.cpp create mode 100644 examples/Logger/simple-server/Logging_Acceptor.h create mode 100644 examples/Logger/simple-server/Logging_Handler.cpp create mode 100644 examples/Logger/simple-server/Logging_Handler.h create mode 100644 examples/Logger/simple-server/Makefile create mode 100644 examples/Logger/simple-server/Reactor_Singleton.h create mode 100644 examples/Logger/simple-server/server_loggerd.cpp create mode 100644 examples/Makefile create mode 100644 examples/Mem_Map/IO-tests/IO_Test.cpp create mode 100644 examples/Mem_Map/IO-tests/IO_Test.h create mode 100644 examples/Mem_Map/IO-tests/Makefile create mode 100644 examples/Mem_Map/IO-tests/test_io.cpp create mode 100644 examples/Mem_Map/Makefile create mode 100644 examples/Mem_Map/file-reverse/Makefile create mode 100644 examples/Mem_Map/file-reverse/file-reverse.cpp create mode 100644 examples/Misc/Makefile create mode 100644 examples/Misc/test_XtReactor1.cpp create mode 100644 examples/Misc/test_XtReactor2.cpp create mode 100644 examples/Misc/test_dump.cpp create mode 100644 examples/Misc/test_profile_timer.cpp create mode 100644 examples/Misc/test_read_buffer.cpp create mode 100644 examples/Misc/test_sstring.cpp create mode 100644 examples/Misc/test_trace.cpp create mode 100644 examples/OS/Makefile create mode 100644 examples/OS/Process/Makefile create mode 100644 examples/OS/Process/Process.mak create mode 100644 examples/OS/Process/Process.mdp create mode 100644 examples/OS/Process/README create mode 100644 examples/OS/Process/process.cpp create mode 100644 examples/README create mode 100644 examples/Reactor/Dgram/CODgram.cpp create mode 100644 examples/Reactor/Dgram/Dgram.cpp create mode 100644 examples/Reactor/Dgram/Makefile create mode 100644 examples/Reactor/Makefile create mode 100644 examples/Reactor/Misc/Makefile create mode 100644 examples/Reactor/Misc/notification.cpp create mode 100644 examples/Reactor/Misc/pingpong.cpp create mode 100644 examples/Reactor/Misc/signal_tester.cpp create mode 100644 examples/Reactor/Misc/test_event_handler_t.cpp create mode 100644 examples/Reactor/Misc/test_handle_set.cpp create mode 100644 examples/Reactor/Misc/test_reactors.cpp create mode 100644 examples/Reactor/Misc/test_signals.cpp create mode 100644 examples/Reactor/Misc/test_time_value.cpp create mode 100644 examples/Reactor/Misc/test_timer_queue.cpp create mode 100644 examples/Reactor/Multicast/Log_Wrapper.cpp create mode 100644 examples/Reactor/Multicast/Log_Wrapper.h create mode 100644 examples/Reactor/Multicast/Makefile create mode 100644 examples/Reactor/Multicast/README create mode 100644 examples/Reactor/Multicast/client.cpp create mode 100644 examples/Reactor/Multicast/server.cpp create mode 100644 examples/Reactor/Ntalker/Makefile create mode 100644 examples/Reactor/Ntalker/ntalker.cpp create mode 100644 examples/Reactor/README create mode 100644 examples/Reactor/ReactorEx/README create mode 100644 examples/Reactor/ReactorEx/reactorex.mak create mode 100644 examples/Reactor/ReactorEx/reactorex.mdp create mode 100644 examples/Reactor/ReactorEx/test_reactorEx.cpp create mode 100644 examples/Reactor/ReactorEx/test_remove_handler.cpp create mode 100644 examples/Reactor/WFMO_Reactor/README create mode 100644 examples/Reactor/WFMO_Reactor/reactorex.mak create mode 100644 examples/Reactor/WFMO_Reactor/reactorex.mdp create mode 100644 examples/Reactor/WFMO_Reactor/test_reactorEx.cpp create mode 100644 examples/Reactor/WFMO_Reactor/test_remove_handler.cpp create mode 100644 examples/Service_Configurator/IPC-tests/Makefile create mode 100644 examples/Service_Configurator/IPC-tests/README create mode 100644 examples/Service_Configurator/IPC-tests/client/Makefile create mode 100644 examples/Service_Configurator/IPC-tests/client/broadcast_client_test.cpp create mode 100644 examples/Service_Configurator/IPC-tests/client/local_data create mode 100644 examples/Service_Configurator/IPC-tests/client/local_dgram_client_test.cpp create mode 100644 examples/Service_Configurator/IPC-tests/client/local_fifo_client_test.cpp create mode 100644 examples/Service_Configurator/IPC-tests/client/local_pipe_client_test.cpp create mode 100644 examples/Service_Configurator/IPC-tests/client/local_spipe_client_test.cpp create mode 100644 examples/Service_Configurator/IPC-tests/client/local_stream_client_test.cpp create mode 100644 examples/Service_Configurator/IPC-tests/client/remote_data create mode 100644 examples/Service_Configurator/IPC-tests/client/remote_data1 create mode 100644 examples/Service_Configurator/IPC-tests/client/remote_data2 create mode 100644 examples/Service_Configurator/IPC-tests/client/remote_data3 create mode 100644 examples/Service_Configurator/IPC-tests/client/remote_data4 create mode 100644 examples/Service_Configurator/IPC-tests/client/remote_dgram_client_test.cpp create mode 100644 examples/Service_Configurator/IPC-tests/client/remote_service_directory_test.cpp create mode 100644 examples/Service_Configurator/IPC-tests/client/remote_stream_client_test.cpp create mode 100644 examples/Service_Configurator/IPC-tests/client/remote_thr_stream_client_test.cpp create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_Broadcast.cpp create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_Broadcast.h create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_Broadcast.i create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_L_CODgram.cpp create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_L_CODgram.h create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_L_CODgram.i create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_L_Dgram.cpp create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_L_Dgram.h create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_L_Dgram.i create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_L_FIFO.cpp create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_L_FIFO.h create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_L_FIFO.i create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_L_Pipe.cpp create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_L_Pipe.h create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_L_Pipe.i create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_L_SPIPE.cpp create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_L_SPIPE.h create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_L_SPIPE.i create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_L_Stream.cpp create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_L_Stream.h create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_L_Stream.i create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_R_Dgram.cpp create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_R_Dgram.h create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_R_Dgram.i create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_R_Stream.cpp create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_R_Stream.h create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_R_Stream.i create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_Thr_Stream.cpp create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_Thr_Stream.h create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_Thr_Stream.i create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_Timeout.cpp create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_Timeout.h create mode 100644 examples/Service_Configurator/IPC-tests/server/Handle_Timeout.i create mode 100644 examples/Service_Configurator/IPC-tests/server/Makefile create mode 100644 examples/Service_Configurator/IPC-tests/server/server_test.cpp create mode 100644 examples/Service_Configurator/IPC-tests/server/svc.conf create mode 100644 examples/Service_Configurator/Makefile create mode 100644 examples/Service_Configurator/Misc/Makefile create mode 100644 examples/Service_Configurator/Misc/Timer_Service.cpp create mode 100644 examples/Service_Configurator/Misc/Timer_Service.h create mode 100644 examples/Service_Configurator/Misc/main.cpp create mode 100644 examples/Service_Configurator/Misc/svc.conf create mode 100644 examples/Shared_Malloc/Makefile create mode 100644 examples/Shared_Malloc/Malloc.cpp create mode 100644 examples/Shared_Malloc/Malloc.h create mode 100644 examples/Shared_Malloc/Options.cpp create mode 100644 examples/Shared_Malloc/Options.h create mode 100644 examples/Shared_Malloc/test_malloc.cpp create mode 100644 examples/Shared_Malloc/test_persistence.cpp create mode 100644 examples/Shared_Memory/Makefile create mode 100644 examples/Shared_Memory/test_MM.cpp create mode 100644 examples/Shared_Memory/test_SV.cpp create mode 100644 examples/System_V_IPC/Makefile create mode 100644 examples/System_V_IPC/README create mode 100644 examples/System_V_IPC/SV_Message_Queues/MQ_Client.cpp create mode 100644 examples/System_V_IPC/SV_Message_Queues/MQ_Server.cpp create mode 100644 examples/System_V_IPC/SV_Message_Queues/Makefile create mode 100644 examples/System_V_IPC/SV_Message_Queues/TMQ_Client.cpp create mode 100644 examples/System_V_IPC/SV_Message_Queues/TMQ_Server.cpp create mode 100644 examples/System_V_IPC/SV_Message_Queues/test.h create mode 100644 examples/System_V_IPC/SV_Semaphores/Makefile create mode 100644 examples/System_V_IPC/SV_Semaphores/Semaphore_Client.cpp create mode 100644 examples/System_V_IPC/SV_Semaphores/Semaphore_Server.cpp create mode 100644 examples/System_V_IPC/SV_Semaphores/Semaphore_Test.h create mode 100644 examples/System_V_IPC/SV_Semaphores/Semaphores.cpp create mode 100644 examples/System_V_IPC/SV_Shared_Memory/Makefile create mode 100644 examples/System_V_IPC/SV_Shared_Memory/SV_Shared_Memory_Test.cpp create mode 100644 examples/System_V_IPC/SV_Shared_Memory/SV_Shared_Memory_Test.h create mode 100644 examples/Threads/Makefile create mode 100644 examples/Threads/test_auto_event.cpp create mode 100644 examples/Threads/test_barrier1.cpp create mode 100644 examples/Threads/test_barrier2.cpp create mode 100644 examples/Threads/test_cancel.cpp create mode 100644 examples/Threads/test_future1.cpp create mode 100644 examples/Threads/test_future2.cpp create mode 100644 examples/Threads/test_manual_event.cpp create mode 100644 examples/Threads/test_process_mutex.cpp create mode 100644 examples/Threads/test_process_semaphore.cpp create mode 100644 examples/Threads/test_reader_writer.cpp create mode 100644 examples/Threads/test_recursive_mutex.cpp create mode 100644 examples/Threads/test_task.cpp create mode 100644 examples/Threads/test_task_three.cpp create mode 100644 examples/Threads/test_task_two.cpp create mode 100644 examples/Threads/test_thread_manager.cpp create mode 100644 examples/Threads/test_thread_pool.cpp create mode 100644 examples/Threads/test_thread_specific.cpp create mode 100644 examples/Threads/test_token.cpp create mode 100644 examples/Threads/test_tss.cpp create mode 100644 include/makeinclude/macros.GNU create mode 100644 include/makeinclude/platform_aix.GNU create mode 100644 include/makeinclude/platform_hpux.GNU create mode 100644 include/makeinclude/platform_hpux_orbix.GNU create mode 100644 include/makeinclude/platform_irix5.2.GNU create mode 100644 include/makeinclude/platform_irix5.3_g++.GNU create mode 100644 include/makeinclude/platform_irix5.3_sgic++.GNU create mode 100644 include/makeinclude/platform_irix6.2_sgic++.GNU create mode 100644 include/makeinclude/platform_linux.GNU create mode 100644 include/makeinclude/platform_linux_pthread.GNU create mode 100644 include/makeinclude/platform_m88k.GNU create mode 100644 include/makeinclude/platform_osf1_3.2.GNU create mode 100644 include/makeinclude/platform_osf1_4.0.GNU create mode 100644 include/makeinclude/platform_sco-nothread.GNU create mode 100644 include/makeinclude/platform_sunos4_g++.GNU create mode 100644 include/makeinclude/platform_sunos4_lucid.GNU create mode 100644 include/makeinclude/platform_sunos4_sunc++3.x.GNU create mode 100644 include/makeinclude/platform_sunos4_sunc++4.x.GNU create mode 100644 include/makeinclude/platform_sunos4_sunc++4.x_orbix.GNU create mode 100644 include/makeinclude/platform_sunos5_centerline.GNU create mode 100644 include/makeinclude/platform_sunos5_centerline_orbix.GNU create mode 100644 include/makeinclude/platform_sunos5_g++.GNU create mode 100644 include/makeinclude/platform_sunos5_sunc++.GNU create mode 100644 include/makeinclude/platform_sunos5_sunc++_4.1.GNU create mode 100644 include/makeinclude/platform_sunos5_sunc++_orbix.GNU create mode 100644 include/makeinclude/platform_sunos5_x86_g++.GNU create mode 100644 include/makeinclude/platform_unixware_g++.GNU create mode 100644 include/makeinclude/rules.bin.GNU create mode 100644 include/makeinclude/rules.common.GNU create mode 100644 include/makeinclude/rules.lib.GNU create mode 100644 include/makeinclude/rules.local.GNU create mode 100644 include/makeinclude/rules.nested.GNU create mode 100644 include/makeinclude/rules.nolocal.GNU create mode 100644 include/makeinclude/rules.nonested.GNU create mode 100644 include/makeinclude/wrapper_macros.GNU create mode 100644 netsvcs/ACE-netsvcs.html create mode 100644 netsvcs/Makefile create mode 100644 netsvcs/README create mode 100644 netsvcs/clients/Logger/Makefile create mode 100644 netsvcs/clients/Logger/README create mode 100644 netsvcs/clients/Logger/direct_logging.cpp create mode 100644 netsvcs/clients/Logger/indirect_logging.cpp create mode 100644 netsvcs/clients/Makefile create mode 100644 netsvcs/clients/Naming/Client/Client_Test.cpp create mode 100644 netsvcs/clients/Naming/Client/Client_Test.h create mode 100644 netsvcs/clients/Naming/Client/Makefile create mode 100644 netsvcs/clients/Naming/Client/main.cpp create mode 100644 netsvcs/clients/Naming/Client/svc.conf create mode 100644 netsvcs/clients/Naming/Client/svc2.conf create mode 100644 netsvcs/clients/Naming/Dump_Restore/Dump_Restore.cpp create mode 100644 netsvcs/clients/Naming/Dump_Restore/Dump_Restore.h create mode 100644 netsvcs/clients/Naming/Dump_Restore/Makefile create mode 100644 netsvcs/clients/Naming/Dump_Restore/README create mode 100644 netsvcs/clients/Naming/Dump_Restore/createfile.cpp create mode 100644 netsvcs/clients/Naming/Dump_Restore/main.cpp create mode 100644 netsvcs/clients/Naming/Dump_Restore/nametest.cpp create mode 100644 netsvcs/clients/Naming/Dump_Restore/nametest.h create mode 100644 netsvcs/clients/Naming/Makefile create mode 100644 netsvcs/clients/Naming/README create mode 100644 netsvcs/clients/README create mode 100644 netsvcs/clients/Tokens/Makefile create mode 100644 netsvcs/clients/Tokens/README create mode 100644 netsvcs/clients/Tokens/collection/Makefile create mode 100644 netsvcs/clients/Tokens/collection/README create mode 100644 netsvcs/clients/Tokens/collection/collection.cpp create mode 100644 netsvcs/clients/Tokens/collection/rw_locks.cpp create mode 100644 netsvcs/clients/Tokens/deadlock/Makefile create mode 100644 netsvcs/clients/Tokens/deadlock/README create mode 100644 netsvcs/clients/Tokens/deadlock/deadlock_detection_test.cpp create mode 100644 netsvcs/clients/Tokens/invariant/Makefile create mode 100644 netsvcs/clients/Tokens/invariant/README create mode 100644 netsvcs/clients/Tokens/invariant/invariant.cpp create mode 100644 netsvcs/clients/Tokens/manual/Makefile create mode 100644 netsvcs/clients/Tokens/manual/README create mode 100644 netsvcs/clients/Tokens/manual/manual.cpp create mode 100644 netsvcs/clients/Tokens/mutex/Makefile create mode 100644 netsvcs/clients/Tokens/mutex/README create mode 100644 netsvcs/clients/Tokens/mutex/test_mutex.cpp create mode 100644 netsvcs/clients/Tokens/rw_lock/Makefile create mode 100644 netsvcs/clients/Tokens/rw_lock/README create mode 100644 netsvcs/clients/Tokens/rw_lock/rw_locks.cpp create mode 100644 netsvcs/lib/Client_Logging_Handler.cpp create mode 100644 netsvcs/lib/Client_Logging_Handler.h create mode 100644 netsvcs/lib/Client_Logging_Handler.i create mode 100644 netsvcs/lib/Logging_Strategy.cpp create mode 100644 netsvcs/lib/Logging_Strategy.h create mode 100644 netsvcs/lib/Makefile create mode 100644 netsvcs/lib/Name_Handler.cpp create mode 100644 netsvcs/lib/Name_Handler.h create mode 100644 netsvcs/lib/README create mode 100644 netsvcs/lib/Server_Logging_Handler.cpp create mode 100644 netsvcs/lib/Server_Logging_Handler.h create mode 100644 netsvcs/lib/Server_Logging_Handler.i create mode 100644 netsvcs/lib/TS_Clerk_Handler.cpp create mode 100644 netsvcs/lib/TS_Clerk_Handler.h create mode 100644 netsvcs/lib/TS_Server_Handler.cpp create mode 100644 netsvcs/lib/TS_Server_Handler.h create mode 100644 netsvcs/lib/Token_Handler.cpp create mode 100644 netsvcs/lib/Token_Handler.h create mode 100644 netsvcs/lib/netsvcs.mak create mode 100644 netsvcs/lib/netsvcs.mdp create mode 100644 netsvcs/servers/Makefile create mode 100644 netsvcs/servers/README create mode 100644 netsvcs/servers/cli.conf create mode 100644 netsvcs/servers/main.cpp create mode 100644 netsvcs/servers/ntsvc.conf create mode 100644 netsvcs/servers/servers.mak create mode 100644 netsvcs/servers/servers.mdp create mode 100644 netsvcs/servers/svc.conf create mode 100644 performance-tests/Makefile create mode 100644 performance-tests/Misc/Makefile create mode 100644 performance-tests/Misc/test_mutex.cpp create mode 100644 performance-tests/Misc/test_naming.cpp create mode 100644 performance-tests/Misc/test_singleton.cpp create mode 100644 performance-tests/Synch-Benchmarks/Benchmark.cpp create mode 100644 performance-tests/Synch-Benchmarks/Benchmark.h create mode 100644 performance-tests/Synch-Benchmarks/Makefile create mode 100644 performance-tests/Synch-Benchmarks/Makefile.driver create mode 100644 performance-tests/Synch-Benchmarks/Makefile.synch_tests create mode 100644 performance-tests/Synch-Benchmarks/Options.cpp create mode 100644 performance-tests/Synch-Benchmarks/Options.h create mode 100644 performance-tests/Synch-Benchmarks/Options.i create mode 100644 performance-tests/Synch-Benchmarks/README create mode 100644 performance-tests/Synch-Benchmarks/benchmarks create mode 100644 performance-tests/Synch-Benchmarks/condb_test.cpp create mode 100644 performance-tests/Synch-Benchmarks/conds_test.cpp create mode 100644 performance-tests/Synch-Benchmarks/context.c create mode 100644 performance-tests/Synch-Benchmarks/context.csh create mode 100644 performance-tests/Synch-Benchmarks/context_test.cpp create mode 100644 performance-tests/Synch-Benchmarks/memory_test.cpp create mode 100644 performance-tests/Synch-Benchmarks/mutex_test.cpp create mode 100644 performance-tests/Synch-Benchmarks/orig-results create mode 100644 performance-tests/Synch-Benchmarks/pipe_proc_test.cpp create mode 100644 performance-tests/Synch-Benchmarks/pipe_thr_test.cpp create mode 100644 performance-tests/Synch-Benchmarks/recursive_lock_test.cpp create mode 100644 performance-tests/Synch-Benchmarks/rwrd_test.cpp create mode 100644 performance-tests/Synch-Benchmarks/rwwr_test.cpp create mode 100644 performance-tests/Synch-Benchmarks/sema_test.cpp create mode 100644 performance-tests/Synch-Benchmarks/svc.conf create mode 100644 performance-tests/Synch-Benchmarks/synch_driver.cpp create mode 100644 performance-tests/Synch-Benchmarks/sysvsema_test.cpp create mode 100644 performance-tests/TTCP/ACE-C++/How_to_run_tests create mode 100644 performance-tests/TTCP/ACE-C++/Makefile create mode 100644 performance-tests/TTCP/ACE-C++/run_test create mode 100644 performance-tests/TTCP/ACE-C++/wrapper-new-ttcp.cpp create mode 100644 performance-tests/TTCP/C/How_to_run_tests create mode 100644 performance-tests/TTCP/C/Makefile create mode 100644 performance-tests/TTCP/C/README create mode 100644 performance-tests/TTCP/C/new-ttcp.cpp create mode 100644 performance-tests/TTCP/C/run_test create mode 100644 performance-tests/TTCP/Makefile create mode 100644 performance-tests/TTCP/ORBeline/How_to_run_tests create mode 100644 performance-tests/TTCP/ORBeline/Makefile create mode 100644 performance-tests/TTCP/ORBeline/run_test create mode 100644 performance-tests/TTCP/ORBeline/ser create mode 100644 performance-tests/TTCP/ORBeline/stdmk create mode 100644 performance-tests/TTCP/ORBeline/tango_clt create mode 100644 performance-tests/TTCP/ORBeline/ttcp.idl create mode 100644 performance-tests/TTCP/ORBeline/ttcp_c.cc create mode 100644 performance-tests/TTCP/ORBeline/ttcp_c.hh create mode 100644 performance-tests/TTCP/ORBeline/ttcp_i.cpp create mode 100644 performance-tests/TTCP/ORBeline/ttcp_i.h create mode 100644 performance-tests/TTCP/ORBeline/ttcp_s.cc create mode 100644 performance-tests/TTCP/ORBeline/ttcp_s.hh create mode 100644 performance-tests/TTCP/Orbix/How_to_run_tests create mode 100644 performance-tests/TTCP/Orbix/Makefile create mode 100644 performance-tests/TTCP/Orbix/README create mode 100644 performance-tests/TTCP/Orbix/orbix_defaults.mk create mode 100644 performance-tests/TTCP/Orbix/run_test create mode 100644 performance-tests/TTCP/Orbix/ttcp.hh create mode 100644 performance-tests/TTCP/Orbix/ttcp.idl create mode 100644 performance-tests/TTCP/Orbix/ttcpC.cpp create mode 100644 performance-tests/TTCP/Orbix/ttcpS.cpp create mode 100644 performance-tests/TTCP/Orbix/ttcp_i.cpp create mode 100644 performance-tests/TTCP/Orbix/ttcp_i.h create mode 100644 rpc++/.dependencies create mode 100644 rpc++/COPYING create mode 100644 rpc++/Makefile create mode 100644 rpc++/Proj.make create mode 100644 rpc++/README create mode 100644 rpc++/README.ORIG create mode 100644 rpc++/StdHdrs/Makefile create mode 100644 rpc++/StdHdrs/README create mode 100644 rpc++/StdHdrs/rpc/auth.h create mode 100644 rpc++/StdHdrs/rpc/c_types.h create mode 100644 rpc++/StdHdrs/rpc/clnt.h create mode 100644 rpc++/StdHdrs/rpc/pmap_clnt.h create mode 100644 rpc++/StdHdrs/rpc/svc.h create mode 100644 rpc++/StdHdrs/rpc/xdr.h create mode 100644 rpc++/callback.cc create mode 100644 rpc++/example/Makefile create mode 100644 rpc++/example/calcsvc.cc create mode 100644 rpc++/example/calcsvc.h create mode 100644 rpc++/example/client.cc create mode 100644 rpc++/example/server.cc create mode 100644 rpc++/gcc-2.2.fix create mode 100644 rpc++/request.cc create mode 100644 rpc++/rpc++.cp create mode 100644 rpc++/rpc++.fn create mode 100644 rpc++/rpc++.ky create mode 100644 rpc++/rpc++.pg create mode 100644 rpc++/rpc++.texi create mode 100644 rpc++/rpc++.toc create mode 100644 rpc++/rpc++.tp create mode 100644 rpc++/rpc++.vr create mode 100644 rpc++/rpc++/callback.h create mode 100644 rpc++/rpc++/request.h create mode 100644 rpc++/rpc++/service.h create mode 100644 rpc++/rpc++/stub.h create mode 100644 rpc++/rpc++/xdr++.h create mode 100644 rpc++/service.cc create mode 100644 rpc++/stub.cc create mode 100644 rpc++/version.h create mode 100644 rpc++/xdr++.cc create mode 100644 tests/Barrier_Test.cpp create mode 100644 tests/Buffer_Stream_Test.cpp create mode 100644 tests/CPP_Test.cpp create mode 100644 tests/Future_Test.cpp create mode 100644 tests/Handle_Set_Test.cpp create mode 100644 tests/Makefile create mode 100644 tests/Mem_Map_Test.cpp create mode 100644 tests/Mutex_Test.cpp create mode 100644 tests/Naming_Test.cpp create mode 100644 tests/Priority_Buffer_Test.cpp create mode 100644 tests/README create mode 100644 tests/Reactor_Timer_Test.cpp create mode 100644 tests/Reactors_Test.cpp create mode 100644 tests/Reader_Writer_Test.cpp create mode 100644 tests/Recursive_Mutex_Test.cpp create mode 100644 tests/SPIPE_Test.cpp create mode 100644 tests/SString_Test.cpp create mode 100644 tests/SV_Shared_Memory_Test.cpp create mode 100644 tests/Shared_Memory_MM_Test.cpp create mode 100644 tests/Shared_Memory_SV_Test.cpp create mode 100644 tests/TSS_Test.cpp create mode 100644 tests/Task_Test.cpp create mode 100644 tests/Thread_Manager_Test.cpp create mode 100644 tests/Thread_Pool_Test.cpp create mode 100644 tests/Time_Service_Test.cpp create mode 100644 tests/Time_Value_Test.cpp create mode 100644 tests/Timer_Queue_Test.cpp create mode 100644 tests/Tokens_Test.cpp create mode 100644 tests/UNIXclerk.conf create mode 100644 tests/UNIXserver.conf create mode 100644 tests/UNIXtokens.conf create mode 100644 tests/UPIPE_SAP_Test.cpp create mode 100644 tests/Win32clerk.conf create mode 100644 tests/Win32server.conf create mode 100644 tests/Win32tokens.conf create mode 100644 tests/run_tests.bat create mode 100755 tests/run_tests.sh create mode 100644 tests/test_config.h create mode 100644 tests/tests.mak create mode 100644 tests/tests.mdp diff --git a/ACE-categories b/ACE-categories new file mode 100644 index 00000000000..84ab523b729 --- /dev/null +++ b/ACE-categories @@ -0,0 +1,430 @@ +-*- mode: outline; outline-regexp: " *\\[" -*- + +This file groups each file in $WRAPPER_ROOT/ace into its appropriate +class category. + +[ACE] + [ASX] + IO_Cntl_Msg.cpp + IO_Cntl_Msg.h + Map_Manager.cpp + Map_Manager.h + Map_Manager.i + Message_Block.cpp + Message_Block.h + Message_Block.i + Message_Queue.cpp + Message_Queue.h + Message_Queue.i + Module.cpp + Module.h + Module.i + Multiplexor.cpp + Multiplexor.h + Multiplexor.i + Stream.cpp + Stream.h + Stream.i + Stream_Modules.cpp + Stream_Modules.h + Stream_Modules.i + Task.cpp + Task.h + Task.i + [CORBA] + CORBA_Handler.cpp + CORBA_Handler.h + CORBA_Handler.i + CORBA_Ref.cpp + CORBA_Ref.h + CORBA_Ref.i + [Collections] + Set.cpp + Set.h + Set.i + Stack.cpp + Stack.h + Stack.i + SString.cpp + SString.h + SString.i + [Concurrency] + Activation_Queue.h + Activation_Queue.cpp + Future.h + Future.cpp + Method_Object.h + Method_Object.cpp + Process_Manager.h + Synch.cpp + Synch.h + Synch.i + Synch_Options.cpp + Synch_Options.h + Synch_Options.i + Synch_T.cpp + Synch_T.h + Synch_T.i + Thread.cpp + Thread.h + Thread.i + Thread_Manager.cpp + Thread_Manager.h + Thread_Manager.i + Token.cpp + Token.h + Token.i + [Config] + Str_Buf.h + config.h + msg_hack.h + [Connection] + Acceptor.cpp + Acceptor.h + Acceptor.i + Connector.cpp + Connector.h + Connector.i + Dynamic_Service.cpp + Dynamic_Service.h + Strategies.cpp + Strategies.h + Strategies.i + Svc_Handler.cpp + Svc_Handler.h + Svc_Handler.i + [Debugging] + Assert.h + Dump.cpp + Dump.h + Trace.cpp + Trace.h + Trace.i + [IPC] + [IO_SAP] + IO_SAP.cpp + IO_SAP.h + IO_SAP.i + [DEV_SAP] + DEV.cpp + DEV.h + DEV.i + DEV_Connector.cpp + DEV_Connector.h + DEV_Connector.i + DEV_IO.cpp + DEV_IO.h + DEV_IO.i + [FILE_SAP] + FILE.cpp + FILE.h + FILE.i + FILE_Connector.cpp + FILE_Connector.h + FILE_Connector.i + FILE_IO.cpp + FILE_IO.h + FILE_IO.i + [IPC_SAP] + IPC_SAP.cpp + IPC_SAP.h + IPC_SAP.i + [Addr] + Addr.cpp + Addr.h + Addr.i + DEV_Addr.cpp + DEV_Addr.h + DEV_Addr.i + FILE_Addr.cpp + FILE_Addr.h + FILE_Addr.i + INET_Addr.cpp + INET_Addr.h + INET_Addr.i + SPIPE_Addr.cpp + SPIPE_Addr.h + SPIPE_Addr.i + UNIX_Addr.cpp + UNIX_Addr.h + UNIX_Addr.i + UPIPE_Addr.h + [FIFO_SAP] + FIFO.cpp + FIFO.h + FIFO.i + FIFO_Recv.cpp + FIFO_Recv.h + FIFO_Recv.i + FIFO_Recv_Msg.cpp + FIFO_Recv_Msg.h + FIFO_Recv_Msg.i + FIFO_Send.cpp + FIFO_Send.h + FIFO_Send.i + FIFO_Send_Msg.cpp + FIFO_Send_Msg.h + FIFO_Send_Msg.i + [SOCK_SAP] + LSOCK.cpp + LSOCK.h + LSOCK.i + LSOCK_Acceptor.cpp + LSOCK_Acceptor.h + LSOCK_Acceptor.i + LSOCK_CODgram.cpp + LSOCK_CODgram.h + LSOCK_CODgram.i + LSOCK_Connector.cpp + LSOCK_Connector.h + LSOCK_Connector.i + LSOCK_Dgram.cpp + LSOCK_Dgram.h + LSOCK_Dgram.i + LSOCK_Stream.cpp + LSOCK_Stream.h + LSOCK_Stream.i + SOCK.cpp + SOCK.h + SOCK.i + SOCK_Acceptor.cpp + SOCK_Acceptor.h + SOCK_Acceptor.i + SOCK_CODgram.cpp + SOCK_CODgram.h + SOCK_CODgram.i + SOCK_Connector.cpp + SOCK_Connector.h + SOCK_Connector.i + SOCK_Dgram.cpp + SOCK_Dgram.h + SOCK_Dgram.i + SOCK_Dgram_Bcast.cpp + SOCK_Dgram_Bcast.h + SOCK_Dgram_Bcast.i + SOCK_Dgram_Mcast.cpp + SOCK_Dgram_Mcast.h + SOCK_Dgram_Mcast.i + SOCK_IO.cpp + SOCK_IO.h + SOCK_IO.i + SOCK_Stream.cpp + SOCK_Stream.h + SOCK_Stream.i + [SPIPE_SAP] + SPIPE.cpp + SPIPE.h + SPIPE.i + SPIPE_Acceptor.cpp + SPIPE_Acceptor.h + SPIPE_Acceptor.i + SPIPE_Connector.cpp + SPIPE_Connector.h + SPIPE_Connector.i + SPIPE_Stream.cpp + SPIPE_Stream.h + SPIPE_Stream.i + [TLI_SAP] + TLI.cpp + TLI.h + TLI.i + TLI_Acceptor.cpp + TLI_Acceptor.h + TLI_Acceptor.i + TLI_Connector.cpp + TLI_Connector.h + TLI_Connector.i + TLI_Stream.cpp + TLI_Stream.h + TLI_Stream.i + [UPIPE_SAP] + UPIPE_Acceptor.cpp + UPIPE_Acceptor.h + UPIPE_Acceptor.i + UPIPE_Connector.cpp + UPIPE_Connector.h + UPIPE_Connector.i + UPIPE_Stream.cpp + UPIPE_Stream.h + UPIPE_Stream.i + [Log_Msg] + Log_Msg.cpp + Log_Msg.h + Log_Msg.i + Log_Priority.h + Log_Record.cpp + Log_Record.h + Log_Record.i + [Memory] + [Mem_Map] + Mem_Map.cpp + Mem_Map.h + Mem_Map.i + [Shared_Malloc] + Malloc.cpp + Malloc.h + Malloc.i + Malloc_T.cpp + Malloc_T.h + Malloc_T.i + Memory_Pool.cpp + Memory_Pool.h + Memory_Pool.i + [Shared_Memory] + Shared_Memory.h + Shared_Memory_MM.cpp + Shared_Memory_MM.h + Shared_Memory_MM.i + Shared_Memory_SV.cpp + Shared_Memory_SV.h + Shared_Memory_SV.i + [Misc] + ARGV.cpp + ARGV.h + ARGV.i + Auto_Ptr.cpp + Auto_Ptr.h + Auto_Ptr.i + Date_Time.cpp + Date_Time.h + Date_Time.i + Dynamic.cpp + Dynamic.h + Dynamic.i + Get_Opt.cpp + Get_Opt.h + Get_Opt.i + Obstack.cpp + Obstack.h + Read_Buffer.cpp + Read_Buffer.h + Singleton.cpp + Singleton.h + Singleton.i + [Name_Service] + Local_Name_Space.cpp + Local_Name_Space.h + Name_Options.cpp + Name_Options.h + Name_Proxy.cpp + Name_Proxy.h + Name_Request_Reply.cpp + Name_Request_Reply.h + Name_Space.h + Naming_Context.cpp + Naming_Context.h + Remote_Name_Space.cpp + Remote_Name_Space.h + [OS] + ACE.cpp + ACE.h + ACE.i + OS.cpp + OS.h + OS.i + [Reactor] + Event_Handler.cpp + Event_Handler.h + Event_Handler.i + Event_Handler_T.cpp + Event_Handler_T.h + Event_Handler_T.i + Handle_Set.cpp + Handle_Set.h + Handle_Set.i + Proactor.h + Proactor.i + Proactor.cpp + Reactor.cpp + Reactor.h + Reactor.i + ReactorEx.cpp + ReactorEx.h + ReactorEx.i + Signal.cpp + Signal.h + Signal.i + Time_Value.cpp + Time_Value.h + Time_Value.i + Timer_Queue.cpp + Timer_Queue.h + Timer_Queue.i + [Service_Configurator] + Parse_Node.cpp + Parse_Node.h + Parse_Node.i + Service_Config.cpp + Service_Config.h + Service_Config.i + Service_Main.cpp + Service_Manager.cpp + Service_Manager.h + Service_Manager.i + Service_Object.cpp + Service_Object.h + Service_Object.i + Service_Record.cpp + Service_Record.h + Service_Record.i + Service_Repository.cpp + Service_Repository.h + Service_Repository.i + Shared_Object.cpp + Shared_Object.h + Shared_Object.i + Svc_Conf.h + Svc_Conf_l.cpp + Svc_Conf_y.cpp + sc_tokens.h + [System_V_IPC] + [System_V_Message_Queues] + SV_Message.cpp + SV_Message.h + SV_Message.i + SV_Message_Queue.cpp + SV_Message_Queue.h + SV_Message_Queue.i + Typed_SV_Message.cpp + Typed_SV_Message.h + Typed_SV_Message.i + Typed_SV_Message_Queue.cpp + Typed_SV_Message_Queue.h + Typed_SV_Message_Queue.i + [System_V_Semaphores] + SV_Semaphore_Complex.cpp + SV_Semaphore_Complex.h + SV_Semaphore_Complex.i + SV_Semaphore_Simple.cpp + SV_Semaphore_Simple.h + SV_Semaphore_Simple.i + [System_V_Shared_Memory] + SV_Shared_Memory.cpp + SV_Shared_Memory.h + SV_Shared_Memory.i + [Timers] + High_Res_Timer.cpp + High_Res_Timer.h + High_Res_Timer.i + Profile_Timer.cpp + Profile_Timer.h + Profile_Timer.i + [Token_Service] + Local_Tokens.cpp + Local_Tokens.h + Local_Tokens.i + Remote_Tokens.cpp + Remote_Tokens.h + Remote_Tokens.i + Token_Collection.cpp + Token_Collection.h + Token_Collection.i + Token_Manager.cpp + Token_Manager.h + Token_Manager.i + Token_Request_Reply.cpp + Token_Request_Reply.h + Token_Request_Reply.i + Token_Invariants.h + Token_Invariants.i + Token_Invariants.cpp diff --git a/ACE-install.sh b/ACE-install.sh new file mode 100644 index 00000000000..f0cf3f9967b --- /dev/null +++ b/ACE-install.sh @@ -0,0 +1,365 @@ +#!/bin/sh +########################## Begin Install Script ########################## +# +# NAME: ACE-install.sh +# +# PURPOSE: Bourne shell script to install ACE for UNIX platforms +# +# AUTHOR: Ajit Sagar +# +# HISTORY: 5/20/96 Ajit Sagar Created +# x/xx/xx xxxxxxxxxxxxxx Modified +# x/xx/xx xxxxxxxxxxxxxx Modified +# +# DESCRIPTION: This script installs the ACE toolkit for a Unix system. +# Before using this script, you must do the following: +# +# NOTES: 1) Download the gzipped version of ACE from +# http://www.cs.wustl.edu/~schmidt/ (Select "Obtaining ACE") +# OR +# ftp from wuarchive.wustl.edu in the /languages/c++/ACE directory +# +# The local directory to which this will be downloaded is +# refered to as the "MY_ACEDIR" in this script. +# +# 2) Make sure there is only one file that matches "ACE*tar*". +# This should be the one you just downloaded. +# remove older versions of tar files downloaded earlier. +# +# 3) At the end of this script, you should have: +# +# a) A compiled toolkit in the $WRAPPER_ROOT directory +# b) If you selected to save the existing installation, +# a file oldACE.tar.gz will be created in MY_ACEDIR +# c) The gzipped ACE source file that was initially downloaded. +# +# 4) This script may be executed without user interaction +# by using the "auto" option (see USAGE section below). +# It is advisable to execute it without the "auto" option the +# first time to make sure everything works. +# +# THE FOLLOWING NEED TO BE DONE ONLY THE FIRST TIME THIS +# SCRIPT IS RUN: +# +# 5) Read the README file in +# http://www.cs.wustl.edu/~schmidt/ACE.html directory +# +# 6) Define an environment variable WRAPPER_ROOT the +# defines which directory your ACE toolkit is to be +# installed in. +# +# DO NOT MAKE "WRAPPER_ROOT" THE SAME AS "MY_ACEDIR". +# +# 7) Redefine "MY_ACEDIR" in this script to default +# to the directory in which you have downloaded the ACE source. +# +# 8) This script has been tested on Solaris 2.x for the +# Sun C++4.0 compiler. To use this on some other UNIX +# platform, uncomment and redefine the following +# in this script: +# +# MY_ACE_CONFIG +# MY_ACE_GNU_MACROS +# +# Check the README file to define these variables. If +# these are not defined, the script will prompt you +# help you to change these variables. But in that case +# you cannot run with the "auto" option. +# +# +# USAGE: myacemaker [ auto ] +# +# auto automatic make (no user interaction) +# +# Under this option, the source will be +# extracted and compiled without any user interaction, +# i.e., you can kick off this script, go home, +# and check it in the morning. The following +# assumptions are made: +# +# 1) MY_ACE_DIR is properly defined in this script. +# 2) MY_ACE_CONFIG is properlly defined +# in this script. +# 3) MY_ACE_GNU_MACROS is properly defined in this +# script. +# 4) A backup of existing installation +# is to be made. +# +# COPYRIGHT INFORMATION: +# +# You are free to do anything you like with this script such as +# including it in commercial software. You may modify it and freely redistribute +# it. The author accepts no responsibility for any bugs or problems that +# arise as a consequence of using this code. +# +# -- Ajit Sagar +# +######################################################################### +# +ACE_ERRORFILE=/tmp/myacemaker.err +OLD_ACE_TAR_FILE=oldACE.tar +OLD_ACE_GZIPPED_TAR_FILE=oldACE.tar.gz +USAGE=" : myacemaker [ auto ]" +# +############################################################## +# +# Platform-specific definitions +# +############################################################## + +# Directory where ACE-x.x.xx.tar.gz is located + +MY_ACEDIR=~/aceconfig + +####################################################### +# Platform specific config file in ${WRAPPER_ROOT}/ace/ +# Uncomment and redefine this +####################################################### + +# MY_ACE_CONFIG=config-sunos5.4-sunc++-4.x.h + +####################################################### +# Platform specific GNU macros file in +# ${WRAPPER_ROOT}/include/makeinclude/ +# Uncomment and redefine this +####################################################### + +# MY_ACE_GNU_MACROS=platform_sunos5_sunc++.GNU + + +############################################################## +# +# Main Script For Installing ACE +# +############################################################## + +AUTO="$#" + +WRAPPER_ROOT=${WRAPPER_ROOT:?"ERROR: Environment variable WRAPPER_ROOT not set"} +if [ ${AUTO} -gt 1 ] +then + echo "$USAGE" + exit 1 +fi + +if [ ${AUTO} -eq 1 ] +then + if [ $1 != "auto" ] + then + echo "$USAGE" + exit 2 + fi +fi + +echo "" +echo "ACE source in `ls ${MY_ACEDIR}/ACE*tar.gz`" +echo "ACE will be installed in ${WRAPPER_ROOT}" +echo "" + +if [ $AUTO -eq 0 ] +then + echo "OK to continue? [Y/N] : \c" + read choice +else + choice='Y' +fi + +if [ ${choice} != 'Y' -a ${choice} != 'y' ] +then + echo "" + echo "ACE installation aborted" + echo "" + exit 11 +fi + +cd ${MY_ACEDIR} + +echo "Uncomressing ACE archive ..." + +gunzip ACE*tar.gz || \ +{ + echo "gunzip failed. Aborting script !!" + echo "" + exit 22 +} + +echo "" +echo "Extracting ACE files into `pwd`/ACE_wrappers directory ..." +echo "" + +tar xvf ACE*tar || \ +{ + echo "" + echo "tar failed. Aborting script !!" + echo "" + exit 33 +} + +echo "" +echo "Re-compressing ACE source using ..." +gzip -9 ACE*tar +echo "" + +if [ -d ${WRAPPER_ROOT} ] +then + + if [ $AUTO -eq 0 ] + then + echo "Save a copy of existing ACE installation? [Y/N] : \c" + read choice + echo "" + else + choice='Y' + fi + + if [ ${choice} = 'Y' -o ${choice} = 'y' ] + then + + echo "Archiving ${WRAPPER_ROOT} to `pwd`/${OLD_ACE_TAR_FILE} using ..." + tar cvpf ${OLD_ACE_TAR_FILE} ${WRAPPER_ROOT} + echo "" + + if [ -f ${OLD_ACE_GZIPPED_TAR_FILE} ] + then + echo "Removing ${OLD_ACE_GZIPPED_TAR_FILE} ..." + rm ${OLD_ACE_GZIPPED_TAR_FILE} + echo "" + fi + + echo "Compressing ${OLD_ACE_TAR_FILE} using ..." + gzip -9 ${OLD_ACE_TAR_FILE} + echo "" + + fi + + echo "Removing ${WRAPPER_ROOT} ..." + rm -r ${WRAPPER_ROOT} + echo "" +fi + +echo "Moving `pwd`/ACE_wrappers to ${WRAPPER_ROOT} ..." +mv ./ACE_wrappers ${WRAPPER_ROOT} +echo "" + +cd ${WRAPPER_ROOT}/ace + +if [ ! $MY_ACE_CONFIG ] +then + + if [ $AUTO -eq 1 ] + then + if [ ! -f ${MY_ACE_CONFIG} ] + then + echo "" + echo "${MY_ACE_CONFIG} does not exist. Aborting script ..." + echo "" + exit 44 + fi + fi + + echo "Select one of the following files for linking to config.h" + echo "" + echo "`ls config*h`" + echo "" + + echo "Type the filename for your compiler: \c" + read MY_ACE_CONFIG + echo "" + + if [ ! -f ${MY_ACE_CONFIG} ] + then + echo "" + echo "${MY_ACE_CONFIG} does not exist. Aborting script ..." + echo "" + exit 55 + fi + +fi + + +echo "Creating link config.h for ${MY_ACE_CONFIG} in directory `pwd` ..." + +rm ./config.h +ln -s ${MY_ACE_CONFIG} config.h + +echo "" + +cd ${WRAPPER_ROOT}/include/makeinclude + +if [ ! $MY_ACE_GNU_MACROS ] +then + + if [ $AUTO -eq 1 ] + then + if [ ! -f ${MY_ACE_GNU_MACROS} ] + then + echo "" + echo "${MY_ACE_GNU_MACROS} does not exist. Aborting script ..." + echo "" + exit 66 + fi + fi + + echo "Select one of the following files for linking to config.h" + echo "" + echo "`ls platform*GNU`" + echo "" + echo "Type the filename for your compiler: \c" + + read MY_ACE_GNU_MACROS + echo "" + + if [ ! -f ${MY_ACE_GNU_MACROS} ] + then + echo "" + echo "${MY_ACE_GNU_MACROS} does not exist. Aborting script ..." + echo "" + exit 77 + fi + +fi + +echo "Creating link platform_macros.GNU for ${MY_ACE_GNU_MACROS}" +echo "in directory `pwd` ..." + +rm ./platform_macros.GNU +ln -s ${MY_ACE_GNU_MACROS} platform_macros.GNU + +echo "" + +if [ ${AUTO} -eq 0 ] +then + echo "Make ACE now with default setup? [Y/N] : \c" + read choice + echo "" +else + choice='Y' +fi + +if [ ${choice} != 'Y' -a ${choice} != 'y' ] +then + echo "" + echo "ACE make skipped. You can use to make ACE later" + echo "" + exit 0 +fi + +echo "" +echo "Making ACE now. Examine file ${ACE_ERRFILE} for errors ..." +echo "" + +cd ${WRAPPER_ROOT} + +echo "" +echo "Executing ..." +echo "" +gmake | tee ${ACE_ERRFILE} 2>&1 + +echo "" +echo "Examine file ${ACE_ERRFILE} for possible errors ..." +echo "" +echo "********** End of myacemaker script !!! ***********" +echo "" + +# +######################################################################### diff --git a/BIBLIOGRAPHY b/BIBLIOGRAPHY new file mode 100644 index 00000000000..c3a143a6a8d --- /dev/null +++ b/BIBLIOGRAPHY @@ -0,0 +1,618 @@ +The following articles document and describe various aspects of the +ACE object-oriented network programming components (and the underlying +design patterns) included in this release. + +@incollection{Schmidt:96n, + AUTHOR = "Irfan Pyarali and Timothy H. Harrison and Douglas C. Schmidt", + TITLE="{Design and Performance of an Object-Oriented Framework + for High-Performance Electronic Medical Imaging}", + BOOKTITLE="USENIX Computing Systems", + PUBLISHER="MIT Press", + YEAR = 1996, + MONTH = "November/December", + EDITOR={Douglas C. Schmidt}, + ABSTRACT = "" +} + +@inproceedings{Schmidt:96k, + AUTHOR = " Douglas C. Schmidt and Tim Harrison", + TITLE = "{Double-Checked Locking -- An Object Behavioral + Pattern for Initializing and Accessing Thread-safe Objects + Efficiently}", + BOOKTITLE = "Proceedings of the $3^{rd}$ Pattern Languages of Programming + Conference", + LOCATION="Allerton Park, Illinois", + YEAR = 1996, + MONTH = "September", + ABSTRACT = "http://www.cs.wustl.edu/~schmidt/TSS-pattern.ps.gz" +} + +@inproceedings{Schmidt:96j, + AUTHOR = "Douglas C. Schmidt", + TITLE = "{Acceptor and Connector: + Design Patterns for Initializing Communication Services}", + BOOKTITLE = "Proceedings of the $1^{st}$ European Pattern Languages of Programming + Conference", + LOCATION="Kloster Irsee, Germany", + YEAR = 1996, + MONTH = "July", +} + +@inproceedings{Schmidt:96i, + AUTHOR = "Prashant Jain and Douglas C. Schmidt", + TITLE = "{Service Configurator: + A Pattern for Dynamic Configuration and Reconfiguration of Communication Services}", + BOOKTITLE = "Proceedings of the $3^{rd}$ Pattern Languages of Programming + Conference", + LOCATION="Allerton Park, Illinois", + YEAR = 1996, + MONTH = "September", +} + +@inproceedings{Schmidt:96h, + AUTHOR = "Timothy H. Harrison and Douglas C. Schmidt and Irfan Pyarali", + TITLE = "{Asynchronous Completion Token: an Object Behavioral Pattern for + Efficient Asynchronous Event Handling}", + BOOKTITLE = "Proceedings of the $3^{rd}$ + Annual Conference on the Pattern Languages of Programs", + ADDRESS={Monticello, Illinois}, + PAGES="1--7", + YEAR = 1996, + MONTH = "September" +} + +@inproceedings{Schmidt:96g, + AUTHOR = "Aniruddha Gokhale and Douglas C. Schmidt", + TITLE = "{Performance of the CORBA Dynamic Invocation Interface and + Internet Inter-ORB Protocol over High-Speed ATM Networks}", + BOOKTITLE="Proceedings of GLOBECOM '96", + ADDRESS={London, England}, + ORGANIZATION="IEEE", + YEAR = 1996, + MONTH = "November", + ABSTRACT = "" +} + +@inproceedings{Schmidt:96f, + AUTHOR = "Aniruddha Gokhale and Douglas C. Schmidt", + TITLE = "{Measuring the Performance of Communication Middleware on + High-Speed Networks}", + BOOKTITLE="Proceedings of SIGCOMM '96", + ADDRESS={Stanford, CA}, + ORGANIZATION="ACM", + YEAR = 1996, + MONTH = "August", + ABSTRACT = "" +} + +@inproceedings{Schmidt:96e, + AUTHOR = "Irfan Pyarali and Timothy H. Harrison and Douglas C. Schmidt", + TITLE="{Design and Performance of an Object-Oriented Framework + for High-Performance Electronic Medical Imaging}", + BOOKTITLE="Proceedings of the $2^{nd}$ Conference on + Object-Oriented Technologies and Systems", + ADDRESS={Toronto, Canada}, + ORGANIZATION="USENIX", + YEAR = 1996, + MONTH = "June", + ABSTRACT = "" +} + +@inproceedings{Schmidt:96d, + AUTHOR = "Douglas C. Schmidt", + TITLE = "{A Family of Design Patterns For Flexibly + Configuring Network Services in Distributed Systems}", + BOOKTITLE = "International Conference on Configurable + Distributed Systems", + LOCATION="Annapolis, Maryland", + YEAR = 1996, + MONTH = "May 6--8", +} + +@inproceedings{Schmidt:96c, + AUTHOR = "Tim Harrison and Douglas C. Schmidt", + TITLE = "{Thread-Specific Storage -- An Object Behavioral + Pattern for Accessing per-Thread State Efficiently}", + BOOKTITLE = "Submitted to the $3^{rd}$ Pattern Languages of Programming + Conference", + LOCATION="Allerton Park, Illinois", + YEAR = 1996, + MONTH = "September", + ABSTRACT = "http://www.cs.wustl.edu/~schmidt/TSS-pattern.ps.gz" +} + +@inproceedings{Schmidt:96b, + AUTHOR = "R. Greg Lavender and Douglas C. Schmidt", + TITLE = "{Active Object: an Object Behavioral Pattern for + Concurrent Programming}", + BOOKTITLE = "Pattern Languages of Program Design", + EDITOR="James O. Coplien and John Vlissides and Norm Kerth", + PUBLISHER = "Addison-Wesley", + ADDRESS={Reading, MA}, + YEAR = 1996, +} + +@inproceedings{Schmidt:96a, + AUTHOR = "Douglas C. Schmidt and Charles D. Cranor", + TITLE = "{Half-Sync/Half-Async: an Architectural Pattern for + Efficient and Well-structured Concurrent I/O}", + BOOKTITLE = "Pattern Languages of Program Design", + EDITOR="James O. Coplien and John Vlissides and Norm Kerth", + PUBLISHER = "Addison-Wesley", + ADDRESS={Reading, MA}, + YEAR = 1996, +} + +@article{Schmidt:95p, + AUTHOR = "Douglas C. Schmidt", + TITLE = "{Connector: a Design Pattern for Actively + Initializing Network Services}", + JOURNAL = "C++ Report", + YEAR = 1996, + VOLUME = 8, + NUMBER = 1, + MONTH = "January" +} + +@inproceedings{Schmidt:95o, + AUTHOR = "Douglas C. Schmidt and Timothy H. Harrison and Irfan Pyarali", + TITLE = "{Experience Developing an Object-Oriented Framework + for High-Performance Electronic Medical Imaging using CORBA + and C++}", + BOOKTITLE = "Proceedings of the ``Software Technology Applied to Imaging and Multimedia + Applications mini-conference'' at the Symposium on Electronic + Imaging in the International Symposia Photonics West", + ORGANIZATION={SPIE}, + LOCATION="San Jose, CA", + YEAR = 1996, + MONTH = "January" +} + +@article{Schmidt:95m, + AUTHOR = "Douglas C. Schmidt", + TITLE = "{Design Patterns for Initializing Network Services: + Introducing the Acceptor and Connector Patterns}", + JOURNAL = "C++ Report", + YEAR = 1995, + VOLUME = 7, + NUMBER = 9, + MONTH = "November/December" +} + +@inproceedings{Schmidt:95k, + AUTHOR = "Tim Harrison and Douglas C. Schmidt", + TITLE = "{Thread-Specific Storage: A Pattern for Reducing Locking Overhead in Concurrent Programs}", + BOOKTITLE = "OOPSLA Workshop on Design Patterns for Concurrent, Parallel, and Distributed Systems", + ORGANIZATION={ACM}, + LOCATION="Austin, TX", + YEAR = 1995, + MONTH = "October" +} + +@article{Schmidt:95j, + AUTHOR = "Douglas C. Schmidt", + TITLE = "{Experience Using Design Patterns to Develop + Reuseable Object-Oriented Communication Software}", + BOOKTITLE = "Communications of the ACM (Special Issue on + Object-Oriented Experiences)", + VOLUME = 38, + NUMBER = 10, + YEAR = 1995, + MONTH = "October" +} + +@inproceedings{Schmidt:95h, + AUTHOR = "Douglas C. Schmidt and Charles D. Cranor", + TITLE = "{Half-Sync/Half-Async: an Architectural Pattern for + Efficient and Well-structured Concurrent I/O}", + BOOKTITLE = "Proceedings of the $2^{nd}$ Annual Conference on + the Pattern Languages of Programs", + ADDRESS={Monticello, Illinois}, + PAGES="1--10", + YEAR = 1995, + MONTH = "September" +} + +@inproceedings{Schmidt:95i, + AUTHOR = "R. Greg Lavender and Douglas C. Schmidt", + TITLE = "{Active Object: an Object Behavioral Pattern for + Concurrent Programming}", + BOOKTITLE = "Proceedings of the $2^{nd}$ + Annual Conference on the Pattern Languages of Programs", + ADDRESS={Monticello, Illinois}, + PAGES="1--7", + YEAR = 1995, + MONTH = "September" +} + +@incollection{Schmidt:95g, + AUTHOR = "Douglas C. Schmidt", + TITLE="{A System of Reusable Design Patterns + for Communication Software}", + BOOKTITLE="The Theory and Practice of + Object Systems (Special Issue on Patterns and Pattern Languages)", + EDITOR={Stephen P. Berczuk}, + PUBLISHER="Wiley and Sons", + YEAR = 1995, + ABSTRACT = "" +} + +@book{Schmidt:95f, + TITLE = "{Pattern Languages of Program Design}", + EDITOR="James O. Coplien and Douglas C. Schmidt", + PUBLISHER = "Addison-Wesley", + ADDRESS={Reading, MA}, + YEAR = 1995, +} + +@inproceedings{Schmidt:95e, + AUTHOR = "Douglas C. Schmidt and Tim Harrison and Ehab Al-Shaer", + TITLE="{Object-Oriented Components for High-speed Network Programming}", + BOOKTITLE="Proceedings of the Conference on Object-Oriented Technologies", + ADDRESS={Monterey, CA}, + ORGANIZATION="USENIX", + YEAR = 1995, + MONTH = "June", +} + +@inproceedings{Schmidt:95d, + AUTHOR = "Douglas C. Schmidt", + TITLE="{Acceptor and Connector: Design Patterns for Active and Passive Establishment + of Network Connections}", + BOOKTITLE=" Workshop on Pattern Languages of Object-Oriented + Programs at ECOOP '95", + MONTH={August}, + YEAR=1995, + ADDRESS={Aarhus, Denmark}, + ABSTRACT = "" +} + +@article{Schmidt:95c, + AUTHOR = "Douglas C. Schmidt and Paul Stephenson", + TITLE="{Using Design Patterns to Evolve System Software from + UNIX to Windows NT}", + JOURNAL = "C++ Report", + YEAR = 1995, + VOLUME = 7, + NUMBER = 3, + MONTH = "March/April", + ABSTRACT = "This is a different version of the ECOOP paper that + goes into a lot more gory details about how the + Reactor and Acceptor patterns were implemented + on Windows NT and UNIX." +} + +@inproceedings{Schmidt:95b, + AUTHOR = "Douglas C. Schmidt and Paul Stephenson", + TITLE="{Experiences Using Design Patterns to + Evolve System Software Across Diverse OS Platforms}", + BOOKTITLE="Proceedings of the $9^{th}$ European Conference on + Object-Oriented Programming", + ADDRESS={Aarhus, Denmark}, + MONTH={August}, + YEAR=1995 +} + +@incollection{Schmidt:95a, + AUTHOR = "Douglas C. Schmidt", + TITLE = "{Reactor: An Object Behavioral Pattern for Concurrent + Event Demultiplexing and Event Handler Dispatching}", + BOOKTITLE = "Pattern Languages of Program Design", + EDITOR="James O. Coplien and Douglas C. Schmidt", + PUBLISHER = "Addison-Wesley", + ADDRESS={Reading, MA}, + YEAR = 1995, + MONTH = "June" + ABSTRACT = "This is a polished up version of the PLoP paper" +} + +@inproceedings{Schmidt:94l, + AUTHOR = "Douglas C. Schmidt and Paul Stephenson", + TITLE="{Achieving Reuse Through Design Patterns}", + BOOKTITLE="Proceedings of the Third C++ World Conference", + ORGANIZATION="SIGS", + ADDRESS={Austin, Texas}, + MONTH=Nov, + YEAR=1994 +} + +@inproceedings{Schmidt:94i, + AUTHOR = "Douglas C. Schmidt", + TITLE = "{Reactor: An Object Behavioral Pattern for Concurrent + Event Demultiplexing and Dispatching}", + BOOKTITLE = "Proceedings of the $1^{st}$ Annual Conference on the + Pattern Languages of Programs (PLoP)", + ADDRESS={Monticello, Illinois}, + YEAR = 1994, + MONTH = "August" +} + +@inproceedings{Schmidt:94j, + AUTHOR = "Douglas C. Schmidt", + TITLE="{The ADAPTIVE Communication Environment: + An Object-Oriented Network Programming Toolkit for Developing + Communication Software}", + BOOKTITLE="Proceedings of the $12^{th}$ Annual Sun Users Group + Conference", + ORGANIZATION="SUG", + ADDRESS={San Francisco, CA}, + PAGES="214-225", + MONTH={June}, + YEAR=1994, +} + +@article{Schmidt:94g, + AUTHOR = "Douglas C. Schmidt", + TITLE = "{Transparently Parameterizing Synchronization into a + Concurrent Distributed Application}", + JOURNAL = "C++ Report", + YEAR = 1994, + VOLUME = July/August, + NUMBER = 6, + MONTH = "March/April", +} + +@article{Schmidt:94d, + AUTHOR = "Douglas C. Schmidt", + TITLE = "{A Domain Analysis of Network Daemon Design Dimensions}", + JOURNAL = "C++ Report", + YEAR = 1994, + VOLUME = 6, + NUMBER = 3, + MONTH = "March/April", +} + +@inproceedings{Schmidt:94a, + AUTHOR = "Douglas C. Schmidt", + TITLE = "{ASX: an Object-Oriented Framework for Developing + Distributed Applications}", + BOOKTITLE = "Proceedings of the $6^{th}$ USENIX C++ Technical Conference", + ORGANIZATION="USENIX", + ADDRESS={Cambridge, Massachusetts}, + MONTH = "April", + YEAR = {1994} +} + +@inproceedings{Schmidt:93i, + AUTHOR = "Douglas C. Schmidt and Tatsuya Suda", + TITLE="{The Service Configurator Framework: An Extensible + Architecture for Dynamically Configuring Concurrent, Multi-Service + Network Daemons}", + BOOKTITLE="The Proceedings of the Second International Workshop on + Configurable Distributed Systems", + ORGANIZATION="IEEE", + ADDRESS={Pittsburgh, PA}, + MONTH=mar, + YEAR=1994, +} + +@inproceedings{Schmidt:93k, + AUTHOR = "Douglas C. Schmidt", + TITLE="{The ADAPTIVE Communication Environment: + Object-Oriented Network Programming Components for Developing + Client/Server Applications}", + BOOKTITLE="Proceedings of the $11^{th}$ Annual Sun Users Group Conference", + ORGANIZATION="SUG", + ADDRESS={San Jose, CA}, + MONTH=Dec, + YEAR=1993, +} + +@inproceedings{Schmidt:93j, + AUTHOR = "Douglas C. Schmidt", + TITLE="{Object-Oriented Techniques for Developing Extensible + Network Servers}", + BOOKTITLE="Proceedings of the Second C++ World Conference", + ORGANIZATION="SIGS", + ADDRESS={Dallas, Texas}, + MONTH=Oct, + YEAR=1993, +} + +@inproceedings{Schmidt:93h, + AUTHOR = "Douglas C. Schmidt and Paul Stephenson", + TITLE="{An Object-Oriented Framework for Developing + Network Server Daemons}", + BOOKTITLE="Proceedings of the Second C++ World Conference", + ORGANIZATION="SIGS", + ADDRESS={Dallas, Texas}, + MONTH=Oct, + YEAR=1993, +} + +@article{Schmidt:93c, + AUTHOR = "Douglas C. Schmidt", + TITLE = "{The Object-Oriented Design and Implementation of the + Reactor: A C++ Wrapper for UNIX I/O Multiplexing (Part 2 of 2)}", + JOURNAL = "C++ Report", + YEAR = 1993, + MONTH = "September/October", + ABSTRACT = "" +} + +@article{Schmidt:93b, + AUTHOR = "Douglas C. Schmidt", + TITLE = "{The Reactor: An Object-Oriented Interface for + Event-Driven UNIX I/O Multiplexing (Part 1 of 2)}", + JOURNAL = "C++ Report", + YEAR = 1993, + MONTH = "February", + ABSTRACT = "" +} + +@article{Schmidt:92e, + AUTHOR = "Douglas C. Schmidt", + TITLE = "{IPC_SAP: An Object-Oriented Interface to + Interprocess Communication Services}", + JOURNAL = "C++ Report", + YEAR = 1992, + MONTH = "November/December", + ABSTRACT = "" +} + +@article{Schmidt:92d, + AUTHOR = "Douglas C. Schmidt", + TITLE = "{Systems Programming with C++ Wrappers: Encapsulating + Interprocess Communication Services with Object-Oriented Interfaces}", + JOURNAL = "C++ Report", + YEAR = 1992, + MONTH = "September/October", + ABSTRACT = "" +} + +---------------------------------------- +In addition, here are some articles that discuss various aspects of +the ADAPTIVE project. + +@inproceedings{Schmidt:94r, + AUTHOR = {Douglas C. Schmidt}, + TITLE = "{High-Performance Event Filtering for Dynamic Multi-point Applications}", + BOOKTITLE= "$1^{st}$ Workshop on High Performance Protocol + Architectures (HIPPARCH)", + MONTH={December}, + YEAR = {1994}, + ADDRESS={Sophia Antipolis, France}, + ORGANIZATION = {INRIA} +} + +@inproceedings{Schmidt:94p, + AUTHOR = "Douglas C. Schmidt and Tatsuya Suda", + TITLE = "Measuring the Performance of Parallel Message-based + Process Architectures," + BOOKTITLE = "{\em Proceedings of the INFOCOM Conference on Computer Communications}", + ORGANIZATION= "IEEE", + ADDRESS="Boston, MA", + MONTH = "April", + YEAR = {1995} +} + +@article{Schmidt:94k, + AUTHOR = "Douglas C. Schmidt and Tatsuya Suda", + TITLE = "{An Object-Oriented Framework for Dynamically + Configuring Extensible Distributed Communication Systems}", + JOURNAL = "IEE Distributed Systems Engineering Journal + (Special Issue on Configurable Distributed Systems)", + YEAR = 1994, + MONTH = "December" +} + +@inproceedings{Schmidt:94e, + AUTHOR = "Douglas C. Schmidt", + TITLE = "{Experiences with an Object-Oriented Architecture for + Developing Extensible Network Management Software}", + BOOKTITLE = "Globecom Conference", + ORGANIZATION="IEEE", + ADDRESS={San Francisco, CA}, + MONTH = "November", + YEAR = {1994} +} + +@inproceedings{Schmidt:94h, + AUTHOR = "Douglas C. Schmidt and Tatsuya Suda", + TITLE = "{Measuring the Impact of Alternative Parallel Process + Architectures on Communication Subsystem Performance}", + BOOKTITLE = "Proceedings of the $4^{th}$ International Workshop + on Protocols for High-Speed Networks", + ORGANIZATION="IFIP", + ADDRESS={Vancouver, British Columbia}, + YEAR = 1994, + MONTH = "August" +} + +@inproceedings{Schmidt:94b, + AUTHOR = "Douglas C. Schmidt and Tatsuya Suda", + TITLE = "{The ADAPTIVE Service eXecutive: an Object-Oriented + Architecture for Configuring Concurrent Distributed Applications}", + BOOKTITLE = "The proceedings of the $8^{th}$ International Working + Conference on Upper Layer Protocols, Architectures, and + Applications", + ORGANIZATION="IFIP", + ADDRESS={Barcelona, Spain}, + MONTH = "June", + YEAR = {1994} +} + +@inproceedings{Schmidt:93g, + AUTHOR = "Douglas C. Schmidt and Tatsuya Suda", + TITLE="{A Framework for Developing and Experimenting with + Parallel Process Architectures to Support High-Performance + Transport Systems}", + ORGANIZATION="IEEE", + BOOKTITLE="Proceedings of the Second Workshop on the + Architecture and Implementation of High Performance + Communication Subsystems", + ADDRESS={Williamsburg, Virgina}, + MONTH={September}, + YEAR=1993, +} + +@inproceedings{Schmidt:93f, + AUTHOR = "Douglas C. Schmidt and Tatsuya Suda", + TITLE = "{ADAPTIVE: A Framework for Experimenting with + High-Performance Transport System Process Architectures}", + BOOKTITLE="{Proceedings of the $2^{\rm nd}$ International + Conference on Computer Communication Networks}", + ORGANIZATION="ISCA", + ADDRESS={San Diego, California}, + YEAR=1993, + MONTH=jun, + PAGES="", + ABSTRACT="" +} + +@article{Schmidt:93a, + AUTHOR = "Douglas C. Schmidt and Donald F. Box and Tatsuya Suda", + TITLE = "{ADAPTIVE: A Dynamically Assembled Protocol + Transformation, Integration, and eValuation Environment}", + JOURNAL="Journal of Concurrency: Practice and + Experience", + YEAR = 1993, + MONTH=jun, + ABSTRACT = "" +} + +@inproceedings{Box:93a, + AUTHOR="Donald F. Box and Douglas C. Schmidt and Tatsuya Suda", + TITLE="{ADAPTIVE: An Object-Oriented Framework for Flexible + and Adaptive Communication Protocols}", + BOOKTITLE="{Proceedings of the 4$^{th}$ IFIP Conference on High + Performance Networking}", + ORGANIZATION="IFIP", + ADDRESS="Liege, Belgium", + YEAR=1993, + ABSTRACT = "" +} + +@inproceedings{Schmidt:92f, + AUTHOR = "Douglas C. Schmidt", + TITLE = "{Hosting the ADAPTIVE System in the {\em + x}-Kernel and System V STREAMS}", + BOOKTITLE = "Proceedings of the {\em x}-kernel Workshop", + MONTH = {November}, + ADDRESS = {Tucson, Arizona}, + YEAR = 1992, +} + +@inproceedings{Schmidt:92c, + AUTHOR = "Douglas C. Schmidt and Donald F. Box and Tatsuya + Suda", + TITLE = "{ADAPTIVE: A Flexible and Adaptive Transport System + Architecture to Support Lightweight Protocols for Multimedia + Applications on High-Speed Networks}", + BOOKTITLE = "Proceedings of the First Symposium on High Performance + Distributed Computing", + MONTH = {September}, + ORGANIZATION = {IEEE}, + ADDRESS = {Syracuse, New York}, + YEAR = 1992, +} + +@article{Schmidt:92a, + AUTHOR = "Douglas C. Schmidt and Tatsuya Suda", + TITLE = "{Transport System Architecture Services for + High-Speed Communications Systems}", + JOURNAL="IEEE Journal on Selected Areas in Communication", + MONTH=may, + YEAR = 1993, +} + diff --git a/ChangeLog-93 b/ChangeLog-93 new file mode 100644 index 00000000000..0beb8e6321f --- /dev/null +++ b/ChangeLog-93 @@ -0,0 +1,52 @@ +Wed Dec 15 16:47:19 1993 Douglas C. Schmidt (schmidt@net4.ics.uci.edu) + + * Added a new parameter to the constructor and open() member + functions in the SOCK_Listener and LSOCK_Listener classes. This + parameter indicates that the SO_REUSEADDR option needs to be + applied before attempting to bind an address. + +Sun Nov 21 14:46:18 1993 Douglas C. Schmidt (schmidt@net4.ics.uci.edu) + + * Added a new file called "testconfig.h" in the include directory. + This file gives defaults for the hostname and server port + numbers used in the ./tests directory. + +Wed Nov 3 18:41:14 1993 Douglas C. Schmidt (schmidt@cupid.ics.uci.edu) + + * Released version 2.12. + + * Included Olaf Kruger's fix for templates/shared libs on Sun OS + 4. This solves a bunch of weird problems. Now, most of the + tests compile and run correctly on Sun OS 4! + +Mon Nov 1 17:47:30 1993 Douglas C. Schmidt (schmidt@cupid.ics.uci.edu) + + * Split the release into two parts: (1) the documentation and + papers and (2) the library source code and test examples. + + * Renamed and lightly redesigned the IPC_SAP* hierarchy. Now the + overall C++ wrapper abstraction for local and remote IPC is + called IPC_SAP. The specific wrappers for sockets, TLI, named + pipes, and STREAM pipes are called SOCK_SAP, TLI_SAP, FIFO_SAP, + and SPIPE_SAP, respectively. This cleans up the interfaces, + shares more code, and is much easier to explain. + + In addition, the Server_Daemon framework has been renamed the + Service Configurator framework, and the Server_Daemon class has + been renamed Service_Config. The documentation is being updated + to reflect these changes, as well. + + Note, the easiest way to upgrade existing apps is simply to use + perl as follows: + + % perl -p -i -e 's/Local_IPC/LSOCK/g;' *.[Chi] % perl -p -i -e + 's/IPC_SAP_FIFO/FIFO/g;' *.[Chi] % perl -p -i -e + 's/IPC_SAP_SPIPE/SPIPE/g;' *.[Chi] % perl -p -i -e + 's/IPC_SAP/SOCK_SAP/g;' *.[Chi] % perl -p -i -e 's/SAP_//g;' + *.[Chi] % perl -p -i -e 's/Server_Daemon/Service_Config/g;' + *.[Chi] + + etc. Note that the order in which you do this is important! In + addition, you need to check out your Makefiles, to be sure that + -lIPC_SAP linker lines are changed to include the appropriate + components. diff --git a/ChangeLog-94 b/ChangeLog-94 new file mode 100644 index 00000000000..09465ce823f --- /dev/null +++ b/ChangeLog-94 @@ -0,0 +1,1027 @@ +Fri Dec 23 01:50:50 1994 Douglas C. Schmidt (schmidt@tango) + + * libsrc/ASX: Changed the behavior of Map_Manager::Map_Manager() + to allocate a default-sized buffer. + + * libsrc/Reactor/Reactor.C (dispatch): Made the poll-based Reactor + smarter about detecting POLLERR error conditions. When POLLERR + is detected, the Reactor now shutdown down that fd... + +Wed Dec 21 18:29:15 1994 Douglas C. Schmidt (schmidt@tango) + + * libsrc/IPC_SAP/SPIPE_SAP: Changed the name of class SPIPE_Msg to + SPIPE_IO to reflect the fact that I/O over named pipes need not + be message-oriented... + + * Changed all occurrences of {SOCK,TLI,SPIPE}_Listener to + {SOCK,TLI,SPIPE}_Acceptor. This is a more accurate name for the + function these classes perform. In addition, it is easier to + explain in the context of the Acceptor and Connector patterns. + Note that the *.h files are also changed, as well. + + * Changed the implementation of {SOCK,TLI,SPIPE}_SAP so that there + is now a *_Connector class to go along with the *_Acceptor + class. The *_Connector is a factory that produces *_Stream + objects *actively*, in a similar way to how the *_Acceptor is a + factory that produces *_Stream objects *passively*. This makes + everything much more orthogonal, though it will break existing + code... The easiest way to fix existing code is to do the + following: + + 1. Find places in the code that define objects of + type SOCK_Stream, LSOCK_Stream, TLI_Stream, + or SPIPE_Msg (now called SPIPE_IO). + + 2. Replace #include "SOCK_Stream.h" with + #include "SOCK_Connector.h" (or whatever + C++ wrapper you have). + + 3. Replace definitions of the form: + + INET_Addr addr (port, host); + SOCK_Stream foo (addr); + + with + + INET_Addr addr (port, host); + SOCK_Stream foo; + SOCK_Connector con (foo, addr); + + If you don't want to have an extra variable named "con", + you can replace this with: + + INET_Addr addr (port, host); + SOCK_Stream foo; + SOCK_Connector (foo, addr); // Calls the constructor. + +Tue Dec 20 21:34:10 1994 Douglas C. Schmidt (schmidt@tango) + + * Renamed the ./{libsrc,tests}/{Semaphores,Message_Queues} + directories to SV_Semaphores and SV_Message_Queues to better + reflect their true behavior and in order to prevent clashes with + the new ASX names. + + * libsrc/ASX: Renamed Queue to Task to better reflect its true + functionality. In addition, renamed Message_List to + Message_Queue. + +Mon Dec 19 23:04:52 1994 Douglas C. Schmidt (schmidt@tango) + + * Changed "private" to "protected" in ASX/Message_List.h at the + request of Troy Warner (tnw1@core01.osi.com). + +Mon Dec 12 23:47:01 1994 Douglas C. Schmidt (schmidt@tango) + + * libsrc/IPC_SAP/SOCK_SAP: changed the name of the global utility + function "bind_port()" to ace_bind_port() to avoid polluting the + global symbol namespace. + + * Fixed a descriptor leak in SOCK_Dgram::shared_open() and + SOCK_CODgram::shared_open(). The original version didn't + automatically close down the socket descriptor if bind failed. + The new version does close the descriptor down. + +Sat Dec 10 00:53:20 1994 Douglas C. Schmidt (schmidt@tango) + + * libsrc/Reactor/Reactor.C (mask_ops): Fixed a stupid bug... The + test should have been + + if (this->invalid_handle (handle) || + this->poll_handles_[handle].fd == -1) + + rather than: + + if (this->invalid_handle (handle) || + this->poll_handles_[handle].fd != -1) + + * libsrc/Reactor/Reactor: Modified the semantics of + Reactor::remove_handler() such that calling it with a value of + Event_Handler::DONT_CALL or'd into the Reactor_Mask instructs + the Reactor to remove the handler *without* calling the object's + handle_close() method! + +Fri Dec 9 12:53:31 1994 Douglas C. Schmidt (schmidt@tango) + + * include/Synch: some C++ compilers (e.g., Centerline) barf when + the see the following in an inline function: + + if (foo == bar) + { + errno = result; + return -1; + } + result result; + + I fixed this by doing the following: + + if (foo == bar) + { + errno = result; + result = -1; + } + result result; + +Wed Dec 7 22:23:47 1994 Douglas C. Schmidt (schmidt@tango) + + * include/Synch.h: Added additional methods in the Null_Mutex + class in order to be consistent with the RW_Mutex interfaces... + + * libsrc/ASX/Message_List: Added new a set of methods called + "try_enqueue_head" and "try_enqueue_tail" that will only insert + a message into the queue if it is not already full. If it is + full, return EWOULDBLOCK. + +Tue Dec 6 13:58:28 1994 Douglas C. Schmidt (schmidt@tango) + + * libsrc/Reactor/Event_Handler: added default values of -1 to the + handle_input(), handle_output(), and handle_exception() methods. + +Mon Dec 5 23:30:28 1994 Douglas C. Schmidt (schmidt@tango) + + * libsrc/ASX/Message_List: Added a new method called set_length to + Message_Block. This method sets the length of the "active" + portion of the message. This is defined as the offset from + RD_PTR to WR_PTR. + +Sat Dec 3 20:40:53 1994 Douglas C. Schmidt (schmidt@tango) + + * libsrc/Threads/Synch: Added two new class called Write_Guard and + Read_Guard, which provide functionality a la the Guard class, + only that they acquire and release readers/writer locks. + + * libsrc/Threads/Synch: For interface uniformity with other + synchronization wrappers I added an acquire() method. This is + implemented as a write-lock to be on the safe-side... + +Fri Dec 2 13:33:39 1994 Douglas C. Schmidt (schmidt@tango) + + * include/Synch.i (Mutex::tryacquire): Modified the behavior of + Mutex::tryacquire so that it will return -1 and set errno to the + appropriate return value of tryacquire(3T) if various types of + "problems" occur (such as the Mutex already being held). + + * include/Message_List.i: Rearranged the order of the + Message_Block::get_rd_ptr and Message_Block::set_wr_ptr methods + to deal with inlining problems that some cfront-based C++ + compilers have... + + * libsrc/Reactor/Signal.[hi]: Changed set_handler/get_handler to + "handler" to avoid a collision with Rogue Wave libraries. This + new version is more consistent with other usage in ACE anyhow... + + * Modified the behavior of Service_Config::Service_Config() so + that it makes the initialize size of the Reactor be the same + size as the Service_Repository. This was done at the suggestion + of Bob Sayle and Steve Warwick at ARINC Research. + +Sun Nov 20 00:59:06 1994 Douglas C. Schmidt (schmidt@tango) + + * libsrc/ASX/Message_List: Added two new methods + (is_full() and is_empty()) to the public interface + of Message_List. These methods check whether the queue is full + or empty *while holding the lock*. + + * libsrc/ASX/Queue.h: Made the svc() method a pure virtual + function. This is much cleaner than not doing it, particularly + when we've already got to define open(), close(), and put()... + + * Added a new method to the IPC_SAP/Addr inheritance hierarchy. + The method is called addr_to_string() and it converts the + address of a subclass (e.g., either UNIX domain or Internet + domain) into a string. This functionality is particularly + useful in parameterized types (such as Acceptor), which should + be oblivious of the type of communication domain they are + using... + + * Reorganized the ./apps/Logger/Service_Configurator_Logger + directory in order to reuse more code. Now, all the Acceptor + pattern classes have been moved to a new subdirectory called + ./libsrc/Acceptor. In addition, this code has been generalized + to work with the ASX framework! + +Sat Nov 19 15:19:19 1994 Douglas C. Schmidt (schmidt@tango) + + * Released version 2.15.5 (added a couple of minor fixes and some + additional software to the release. In particular, I've added + the RPC++ C++ wrappers for Sun RPC. See the README file for + more info on this. + + * apps/Synch-Benchmarks: Reorganized all the synchronization tests + so that they would be easier to understand and extend. + + * include/sysincludes.h (ACE_NONBLOCK): Fixed a stupid typo in the + ./include/makeinclude/wrapper_macros.GNU file that accidentally + used ACE_NONBLOCKING instead of ACE_NONBLOCK... Jaysus + + * Fixed up the Service_Config.[Chi] source so that it no longer + allocates statically linked services via static variables. + Stacy Mahlon (mcs@contour.mayo.edu) recommended this change to + workaround bugs in compilers that fail to initialize static + objects appropriately. + +Tue Nov 15 11:55:03 1994 Douglas C. Schmidt (schmidt@tango) + + * Fixed a portability problem in the ./libsrc/Service_Configurator + that was caused by certain compilers failing to initialize + global variables correctly. In particular, the Obstack object + ace_obstack is now a pointer that is allocated dynamically by + Service_Config.process_directive(). Thanks to Stacy Mahlon + (mcs@contour.mayo.edu) for noticing this! + +Mon Nov 14 12:16:14 1994 Douglas C. Schmidt (schmidt@tango) + + * libsrc/Threads/Thread.h: added C++ wrappers for + thr_getconcurrency() and thr_setconcurrency(). + + * Fixed a dumb typo in ./tests/IPC_SAP/SOCK_SAP/CPP-nbclient.C + that failed to conditionally compile for different variants of + siginfo... + + * Added some test programs that benchmark the performance of + Solaris synchronization mechanisms. See ./apps/Synch-Benchmarks + for details... + + * Extended the methods of the Queue class to take advantage of the + new Message_List methods that perform timed waits! This + involves changing many of the existing methods in this class to + add an extra parameter of type timestruc_t *, which defaults to + 0. + + * Added some new comments in the + ./include/makeinclude/wrapper_macros.GNU file that indicate what + the various macros defined by the Makefile scheme actually mean. + This should help people who are porting to a new system... + + * Fixed a dumb bug in ./tests/Shared_Memory that directly included + system header files. Everything in ACE should include + "sysincludes.h" instead... Thanks to Stacy Mahlon + (mcs@contour.mayo.edu) for noticing this! + + * include/Memory_Pool.i (round_up): Fixed a typo where PAGESIZE + should have been ACE_PAGE_SIZE. + +Sat Nov 12 01:32:52 1994 Douglas C. Schmidt (schmidt@tango) + + * Generalized the Shared_Memory_Pool class for Malloc so that it + doesn't require the base addresses for multiple processes to all + start at the same location. + + * libsrc/Service_Configurator/Thread_Spawn.i (Thread_Spawn): + + Fixed a stupid bug in the constructor. Note that we should + be checking if this->tm_ == 0, rather than != 0... + +Fri Nov 11 00:11:41 1994 Douglas C. Schmidt (schmidt@tango) + + * Released version 2.15.4 (added a couple of minor fixes). + + * Added a new test program in the ./tests/ASX/Message_List + directory. This program illustrates how thread-safe + Message_Lists work using ASX. + + * libsrc/Threads/Thr_Manager.i: Added a new method called + insert_thr() to Thr_Manager that is used in conjunction with + Thr_Cntl::Thr_Cntl to make sure that a thread is added to the + Thr_Manager's table correctly. + +Thu Nov 10 20:14:11 1994 Douglas C. Schmidt (schmidt@tango) + + * libsrc/Log_Msg/Log_Record.C (print): Fixed the following very + subtle (and very stupid) bug: + + return ::fprintf (fp, this->msg_data_); + + if this->msg_data_ contains '%', then this call will + fail since fprintf tries to treat the percent sign as + a format code. The obvious fix is: + + return ::fprintf (fp, "%s", this->msg_data_); + + * libsrc/ASX/Message_List.i (is_empty): Fixed a braino that failed + to check if there was a 0-sized buffer in the list. It is now + possible to enqueue a 0-sized buffer, which is helpful for + things like signaling end of transmission by a producer. + + * libsrc/ASX/Message_List.C: Improved the robustness of the + Message_List abstraction by detecting the case where the newly + inserted Message_Block is a NULL pointer. Before, this would + crash the program, where now it returns -1 from the + enqueue_head() or enqueue_tail() methods. + + * libsrc/Threads/Synch.h: added timedwait_signal() and timedwait() + methods to class Condition. These are wrappers around the + cond_t cond_timedwait() function. + + * Improved the documentation of the class interfaces in the + Synch.h C++ wrapper for Solaris 2.x threads mechanisms. + + * Changed the name of class Condition methods wait_signal() and + timedwait_signal() to wait_alert() and timedwait_alert() to + remove confusion with UNIX signals and the regular condition + variable signal. + +Wed Nov 9 23:49:24 1994 Douglas C. Schmidt (schmidt@tango) + + * libsrc/IPC_SAP/Addr/UNIX_Addr.i (UNIX_Addr): Fixed another + couple brainos in UNIX_Addr.i (thanks for Irfan + (ip1@cs.wustl.edu) for noticing this). + + * libsrc/IPC_SAP/SOCK_SAP/SOCK.i (get_local_addr): Fixed a braino + that didn't reset the Addr size after a call to getsockname(). + +Tue Nov 8 00:25:02 1994 Douglas C. Schmidt (schmidt@tango) + + * libsrc/Service_Configurator/Svc_Conf.y (create_service_type): + Fixed a bug on lines 323 and 324, and 330 and 331. The "#if + defined" needs to be INSIDE the "case" statements. Thanks to + mcs@contour.mayo.edu for finding this! + + * Improved the interfaces for all the synchronization wrappers so + that they can be given all the parameters for the underlying + SunOS 5.x *_init calls. Default values are given to keep the + normal usage concise... + +Mon Nov 7 21:41:13 1994 Douglas C. Schmidt (schmidt@tango) + + * Changed all occurrences of Mutex_Rec to Recursive_Lock. This is + much more descriptive since by using templates, the recursive + logic applies to a number of synchronization mechanisms (e.g., + Semaphores, RW_Mutex, Mutex, Null_Mutex, etc.) rather than just + the Mutex class. + + * Changed all occurrences of Mutex_Block to Guard. This is more + standard terminology and reflects Booch's terms more closely, as + well. + +Sun Nov 6 14:31:44 1994 Douglas C. Schmidt (schmidt@tango) + + * Majorly improved the modularity and structure of the Reactor + class. Much duplicate code has been coalesced and several new + features have been added. + + * Changed the name of the Reactor method set_ready() to + ready_ops(). Added a new method called mask_ops(). These + methods make it possible to manipulate the "dispatch masks" and + the "ready masks" (e.g., READ_MASK, WRITE_MASK, etc.) at a much + finer level of granularity without loss of efficiency or + correctness. + +Sat Nov 5 16:48:55 1994 Douglas C. Schmidt (schmidt@tango) + + * Changed the name of three methods in the Semaphore class to + mirror the terms used for Mutex and RW_Mutex. This will help + support the use of semaphores along with templates (e.g., + Rec_Lock) much better... The old names were "wait", "trywait", + and "signal". The new names are "acquire", "tryacquire", and + "release." + + * Added a new class called Signal_Block in Signal.[hiC] This class + operates similar to Mutex_Block, in that it holds a set of + signals over the duration of a C++ statement block. The + constructor masks out the signals and the destructor restores + the signals. + + * Changed the name of files Signal_Handler.[hiC] to Signal.[hiC] + to reflect a broadening of the functionality of the ACE wrappers + for Signals. For example, the new C++ classes wrap the sigset_t + API, as well as the struct sigaction structure. + +Fri Nov 4 00:41:48 1994 Douglas C. Schmidt (schmidt@tango) + + * Yow, got the new Shared_Malloc/Malloc class to work correctly on + SunOS 4.x, as well as SunOS 5.x. It's a bit more clunky on + SunOS 4.x since we have to use System V semaphores rather than + Solaris synchronization mechanisms. However, it now seems to + function correctly! + + * Added a new method called "tryacquire" to Semaphore_Complex and + Semaphore_Simple. This method provides the same "non-blocking" + semantics as it does in the Mutex, Semaphore, and RW_Mutex + classes. + + * Added a new method called "remove()" to all the C++ wrappers in + the Synch.[hi] file. This improves the symmetry with the System + V semaphore wrappers, and also gets around a nasty bug with + cfront 3.x and its handling of templates and explicitly called + destructors... + + * Added a new C++ wrapper class for Threads (Thread.h). The + eventual purpose of this class is to hide the differences + between POSIX pthreads and Solaris threads. + + * Added new parameters to Thr_Manager::spawn to enable the stack + and stack_size to be passed in. + + * Modified the Synch.h file so that the Null_Mutex and Mutex_Block + classes will both be compiled, even if we are building ACE on a + platform that doesn't support threads! + + * Added a timed event-loop method to the public interface of the + Service_Config class. This basically forwards the request to + the underlying Reactor->handle_events method. Thanks to Brad + Needham (bneedham@arinc.com) of ARINC research for the + suggestion! + +Wed Nov 2 14:47:25 1994 Douglas C. Schmidt (schmidt@tango) + + * Changed the interface for one of the Reactor's + {register,remove}_handler methods. These methods + had previously taken a sigset_t &, but for some reason the Sun + C++ 3.0 compiler can't seem to recognize that this is different + from an int! Therefore, I changed the interface to take a + sigset_t *. + + * Fixed some portability bugs that crept into the SunOS 4 version + of ACE, particularly with the siginfo_t extended signal handler + stuff. + +Tue Nov 1 21:46:07 1994 Douglas C. Schmidt (schmidt@tango) + + * libsrc/Log_Msg/Log_Msg.C (log): Fixed a braino on line 175. + "int sig" was undefined outside the conditional (duhhh ;-)). + +Thu Oct 27 17:23:37 1994 Douglas C. Schmidt (schmidt@tango) + + * Fixed up some problems with Semaphore_Complex and + Semaphore_Simple. The new design should be more functional, + particularly for Semaphore_Complex, which now generalizes to + arrays of semaphores. + +Wed Oct 26 16:38:42 1994 Douglas C. Schmidt (schmidt@tango) + + * libsrc/Shared_Malloc/: Created a .i file for Malloc and + Memory_Pool to handle inlines. + + * Fixed a fence-post error in Mem_Map::map_it(). The new version + should correctly set the length of the file *and* also do the + appropriate memory mapping. + + * bin/clone.C: Fixed the clone program so that it now compiles + with the C++ compiler rather than the C compiler. + +Tue Oct 11 20:01:16 1994 Douglas C. Schmidt (schmidt@tango) + + * libsrc/Reactor/Reactor.h (Reactor): Changed the order of the + arguments to the Reactor's register_handler() method used to + register signal handler objects. The new order puts both "new" + components first, and any + (optional) old components following this. This is + a more natural set of default values... + + * libsrc/Shared_Malloc: split out the Local and Shared memory + pools for class Malloc into the Memory_Pool.[hC] files. + +Mon Oct 10 22:54:53 1994 Douglas C. Schmidt (schmidt@tango) + + * libsrc/Threads/Synch.i: Reworked the Thread_Mutex and + Process_Mutex classes to inherit their interface and + implementation code from Mutex... Thanks to Irfan Payrali for + the suggestion! + +Wed Sep 28 11:26:34 1994 Douglas C. Schmidt (schmidt@tango) + + * Moved some of the tests directories around to better reflect + precisely which ACE components are being tested. In particular, + the {client,server} directories that were originally under the + ./tests/Reactor subtree are now located in the + ./tests/Service_Configurator subtree. + +Tue Sep 27 23:05:32 1994 Douglas C. Schmidt (schmidt@tango) + + * Added a bunch of constructors/destructors for + ./tests/Reactor/server to make g++ happy. + + * libsrc/Service_Configurator/Service_Object.[ih] + (Service_Object): Added a constructor and destructor to + Service_Object to make g++ happy. Also, removed the #if for + broken versions of g++ 2.5.8. + + * include/Reactor: Added a constructor and destructor for + Null_Callback to make G++ happy... + + * libsrc/Message_Queues/: Added support for G++ templates. + + * Changed the handling of _sys_siglist in the sysincludes.h file + to try and handle the weird SunOS 4 header file problems... + + * libsrc/IPC_SAP/SOCK_SAP/SOCK_Dgram_Brdcast.C (mk_broadcast): + Removed the "struct" from new struct ifnode in order to + compile... + +Tue Sep 20 11:17:23 1994 Douglas C. Schmidt (schmidt@tango) + + * Fixed a couple of minor typos in the Windows NT C++ wrappers for + sockets. + + * Released version 2.15.2 so that Mark Frutig could have access to + the latest source in order to write man pages! + +Thu Sep 15 20:47:36 1994 Douglas C. Schmidt (schmidt@tango) + + * Extended the Event_Handler interface to support the additional + siginfo_t-style parameters for extended SVR4 signal handling. + Note that for backwards compatibility, this new interface only + enabled if the -DACE_HAS_SIGINFO flag is set in the + wrapper_macros.GNU config file. Making this change affected + several of the existing ACE classes such as Service_Config and + Signal_Handler. + +Mon Sep 12 17:07:10 1994 Douglas C. Schmidt (schmidt@tango) + + * Improved the modularity of the Reactor by creating a new class + called Signal_Handler. This new class basically encapsulates + the signal handling mechanism provided by UNIX within a nice OO + abstraction. The new arrangement is particularly useful since + the Signal_Handler class may be used in applications + (e.g., the Malloc class abstraction) that do not require the + other features of the Reactor. + +Sun Sep 11 14:40:06 1994 Douglas C. Schmidt (schmidt@tango) + + * Changed the default value for Semaphore_Simple and + Semaphore_Complex from OPEN to CREATE. This is more closely + related to how SunOS thread synchronization variables work. + + * Changed the methods of the Semaphore_Simple class to be + syntactically equivalent to the Process_Mutex and Thread_Mutex + classes. This makes it easier to write code that uses + parameterized types to instantiate the appropriate type of + synchronization primitive. + + * include/makeinclude/rules.local.GNU (OBJDIRS): Fixed the + "depend" target so that it generates the correct dependencies + for remaking .so files after they are changed. + + * Added a new pair of methods to the Reactor so that it is now + possible to register/remove a sigset_t of signals in one + operation. + +Sat Sep 10 03:11:34 1994 Douglas C. Schmidt (schmidt@tango) + + * libsrc/Mem_Map/Mem_Map.i (map_it): Fixed a few minor bugs with + how the Mem_Map::map() method handles lseek()'s. + + * Changed the name of the Mem_Map::open() methods to + Mem_Map::map(). This seems like a more reasonable name! Also, + removed the close() method. This is trivial to implement via + ::close (mmap.get_fd ()); + +Fri Sep 9 22:04:25 1994 Douglas C. Schmidt (schmidt@tango) + + * Provided a new implementation of a flexible memory allocation + scheme (Shared_Malloc/Malloc.[HiC]). This memory allocation can + be parameterized by the following: + + 1. The pool from which memory is allocated (e.g., + local memory vs. shared memory). + + 2. The type of synchronization used when allocating + the memory (e.g., no synchronization, thread-based + synchronization, process-based synchronization). + + * libsrc/Threads/Synch.i (Proc_Mutex): Added new classes to the + Synchronization library. These classes are wrappers around the + USYNC_PROCESS and USYNC_THREAD flags to mutex_init(). + +Wed Sep 7 20:29:00 1994 Douglas C. Schmidt (schmidt@tango) + + * include/sysincludes.h (MT): Added check to see if _REENTRANT was + already defined, and if so, avoid redefining it! + +Sun Sep 4 16:23:17 1994 Douglas C. Schmidt (schmidt@tango) + + * Released version 2.15.1 to the world... + + * Added support for the Windows NT version of SOCK_SAP. + + * Fixed a few minor bugs involved with the order of linking + libraries. + + * Fixed an oversight in ./testsReactor/server/server_test.C where + I was still including the "Server_Test.h" file (ugh). + +Wed Aug 31 13:27:10 1994 Douglas C. Schmidt (schmidt@tango) + + * libsrc/IPC_SAP/SOCK_SAP/SOCK_Stream.C (open): Fixed a bug + whereby the I/O descriptor wasn't being closed if connect() + failed. Thanks to Charles Eads + (eads@synoptics.com) for reporting this. + + + * Recompiled everything on SunOS 4.x using SunC++ 3.x and SunOS + 5.x using SunC++ 3.x and 4.x. Everything seems to compile fine + now. + + * Released version 2.15 + +Mon Aug 29 00:14:04 1994 Douglas C. Schmidt (schmidt@tango) + + * Finished up a preliminary set of tests for ASX. See the + $WRAPPER_ROOT/tests/ASX/Event_Server directory for more details. + + * wrapper_macros.GNU (CC): Removed the ARCHFLAG from the CCFLAGS + macro in the Makefile system. Henceforth, all conditional + compilation should be performed on a "per-feature" basis, rather + than a "per-platform" basis... + + * libsrc/IPC_SAP/SOCK_SAP/SOCK_Dgram_Brdcast.C (send): + Automatically convert the port number to htons format before + using it to initialize the sin_port field of the addressing + structure. This is consistent with the behavior of other parts + of IPC_SAP (particularly INET_Addr::set()). + +Sun Aug 28 00:02:53 1994 Douglas C. Schmidt (schmidt@tango) + + * Changed version number of 2.15 to reflect all the major + modifications to the structure of ACE. + + * include/sysincludes.h: Started to fix up the conditional + compilation scheme to be much smarter about the features that + are available from both the compiler and the OS environment. + + * Added a fix suggested by Leslee Xu (lxu@ics.uci.edu) to better + handle the normalization of Timer_Values. + + * Continued to make ACE coding conventions more consistent by + removing get_/set_ prefix from all the accessor/manipulator + methods. Also, added an underbar at the end of all class and + object instance variables. + +Sat Aug 27 20:28:13 1994 Douglas C. Schmidt (schmidt@tango) + + * Continued to improve error handling by replacing all uses of + perror with the Log_Msg macros. + + * include/sysincludes.h: Continued to improve the namespace + utilization in ACE by prefixing stand-along Misc functions with + ace_. + + * include/FD_Set.h: Changed the name FD_Set_Iter to + FD_Set_Iterator. + + * typedef'd int to HANDLE in Event_Handler.h in preparation for + merging in the Windows NT support along with the regular ACE + package. I need to update all the other code in the entire + release to be consist with this! + +Thu Aug 25 19:49:57 1994 Douglas C. Schmidt (schmidt@tango) + + * Fixed a bug with Thr_Manager.i that occurred if a thread created + by ::thr_create() exits prior to the acquisition of the lock and + the subsequent bookkeeping. + +Wed Aug 24 17:34:49 1994 Douglas C. Schmidt (schmidt@tango) + + * Updated SOCK_Dgram_Brdcast to return the average number of bytes + sent. This isn't necessarily the most useful info, but it + doesn't hurt either. Thanks to Mark Frutig (mfrutig@fnbc.com) + for the suggestion. + +Mon Aug 22 01:18:14 1994 Douglas C. Schmidt (schmidt@tango) + + * Added a new test for the Service Configurator framework. This + test illustrates the dynamic configuration of an entire stream + of Modules. + +Sun Aug 21 03:16:00 1994 Douglas C. Schmidt (schmidt@tango) + + * Cleaned up the ./tests/Reactor/server example to be more robust. + In particular, it doesn't really make sense to have the same + object be configured both statically and dynamically *at the + same time*! This was causing problems since each constructor + was getting called twice for the same object -- once when it was + created statically, and again when it was linked in + dynamically... Things work much better now. + +Sat Aug 20 01:07:24 1994 Douglas C. Schmidt (schmidt@tango) + + * Heavily revised the structure of the ./apps/Logger + subdirectories to test out the new Makefile scheme. Everything + is working fine on Solaris! + + * Updated all the ./apps/Logger subdirectories to use the Acceptor + name rather than the Client_Listener name. This is consistent + with recent papers... + + * Fixed all the Makefiles to utilize the new simplified build + strategy. The Makefiles are *far* more automated now! + + * Added support to all the libsrc Makefiles to produce both shared + libraries (*.so) and traditional archives + (*.a). + +Fri Aug 19 16:13:42 1994 Douglas C. Schmidt (schmidt@tango) + + * Majorly improved the Makefile support for building shared + objects that will be dynamically linked explicitly. No longer + will we have to do the horrible hack of compiling all the source + code using -pic. Instead, only that code that will be linked + dynamically must be compiled with -pic! Note that this only + works if the shared object is entirely self contained (i.e., it + does *not* reference any statically linked symbols that are not + defined in itself)! + + * Started to add changes to the source code to make its + configation driven by features rather than by OS. This should + make everything much more portable soon! + + * Fixed IPC_SAP.h so that the constructor is protected (prevents + accidental definition of an instance of this class). + +Thu Aug 11 08:31:33 1994 Douglas C. Schmidt (schmidt at valentine.ics.uci.edu) + + * Fixed Reactor::schedule_timer() so that it will unblock the + Reactor if it is currently blocked. This is necessary so that + the Reactor will recompute the amount of time that it needs to + wait before dispatching timer-based events. Thanks to Todd Hoff + for noticing this... + + * Fixed a stupid bug in the handle_input() method of + Client_Listener in both the Reactor and Service_Configurator + version of the Server Logging Daemon. This routine was not + explicitly returning 0 when it worked..., which might cause the + Reactor to deregister the listener handler! + + * Added casts to the ::select() call in the Reactor to ensure that + the FD_Set * -> fd_set * conversion operators are properly + involved. Thanks to Todd Hoff for this fix (thm@ictv.com). + Todd noticed that the DCE pthreads implementation on AIX was + confusing the compiler... + +Mon Aug 8 18:11:03 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Added a new constructor for the FD_Set class that will convert + an fd_set into an FD_Set. + + * Removed the default value for the Service_Repository constructor + since this was ambiguous with the default constructor. + +Tue Aug 2 18:25:28 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Fixed a bunch of minor "warning-causing" nits that were caused + by #endif __INLINE__ in certain header files... + + * Added a new set of interfaces to the Reactor to retrieve a + registered handler. These interfaces are also useful for + checking whether a handler is registered at a particular fd. + +Sun Jul 10 17:43:19 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Improved the implementation of the Profile_Timer and + High_Res_Timer classes. In particular, the High_Res_Timer class + now works quite nicely using SunC++ 4.0. + +Mon Jul 4 12:49:14 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Changed the order of the base class inheritance list for the + Service_Object class as a workaround for a bug in SunC++ 4.0's + handling of pointers to member functions (ugh). + +Sun Jul 3 18:07:16 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Added a bunch of changes (courtesy of + george@truffula.fp.trw.com). These changes fix minor + portability problems with the new SunC++ 4.0 compiler. + +Fri Jun 24 08:59:02 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Removed operator() from all the IPC_SAP listener classes. + Defining this operator was causing more trouble than it is worth + since C++ doesn't allow operator() to have default arguments + (ugh). The "right" thing to do is to simply use the accept() + method in those classes instead of operator(). + +Wed Jun 22 16:54:05 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Fixed some problems with TLI_Listener that involved lax scoping + of nested classes with cfront 3.x-based C++ compilers. + +Tue Jun 14 11:56:56 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Added a bunch of changes to get portions of ACE up and running + on SCO UNIX, on HP-UX, and on OSF/1. + +Tue Jun 7 14:32:50 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Added support for FLEX's <> symbol to properly cleanup when + a configuration file has been parsed by the Service + Configurator's lexer/parser. + +Sun May 22 10:37:14 1994 Douglas C. Schmidt (schmidt at valentine.ics.uci.edu) + + * Modified the semantics of explicit dynamic linking on SunOS 4.x. + Now, if there is no _init or _fini function defined in a shared + library, it isn't an error (we simply don't call the function!). + +Mon May 9 07:58:35 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Included more fixes for GNU G++ courtesy of Aniruddha Gokhale + . + +Thu May 5 16:47:25 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Reimplemented the ./apps/Logger/Reactor_Logger to provide an + illustration of how the Reactor works. + + * Added finishing touches to the new version of the Service + Configurator framework. This framework now permits completely + automated configuration and reconfiguration of Service_Objects + and Streams. The next step is to add some more complete + examples that illustrate how these features are used... + +Tue May 3 10:17:12 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Fixed a bug in the Service Repository that would cause an + extraneous dlclose on a shared library handle under some + circumstances... + +Mon May 2 11:07:52 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Modified the semantics of Service_Object_Type in the Service + Configurator framework so that it does not automagically + register the service object with the instance of the Reactor. + The original behavior involved too much "over-specification" of + the behavior of Service Objects. Moreover, I can finally omit + the crazy semantics of DONT_REGISTER_SVC and REGISTER_SVC! + + * Fixed some subtle bugs involved with pop'ing a remove'ing a + Module from a Stream. Note that we need to use Module::link + rather than Module::set_next in order to ensure that all the + necessary pointers get rearranged.... + + * Fixed a couple of minor problems with deleting const objects in + the Service_Repository.i file. These were caught by G++, but + not caught by SunC++! + +Sun May 1 11:43:52 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Fixed subtle bug in Server_Config::run_event_loop(). This bug + prevented reconfiguration from occurring under certain + circumstances. + + * Added a new feature to the Service_Manager class in the Service + Configurator framework. This new feature enables the Service + Configurator to be reconfigured remotely by clients. + + * Fixed a bug in Service_Manager that caused the Service + Configurator to crash if SIGPIPE occurred if a client closed + down ungracefully while retrieving information on active + services. + + * Added a new argument to the Reactor::register_handler() method + that is used to register signal handling Event_Handlers. This + new argument returns the current Event_Handler (if any) that is + registered for this signal. + + * Fixed a potential bug in Service_Config::process_directives that + behaved improperly when there was no svc.conf file present in a + directory. + +Wed Apr 27 12:55:46 1994 Douglas C. Schmidt (schmidt at mabillon.ics.uci.edu) + + * Changed the name of Service_Directory to Service_Manager to + reflect its intended functionality + +Mon Apr 25 10:53:01 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Updated the Service Configurator framework to use the new signal + handling facilities provided by the Reactor. This cleans up a + lot of the code in Service_Config.i and removes the need for + ugly non-reentrant static class variables. + + * Released version 2.14 + +Sat Apr 23 14:29:11 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Changed the representation of the select()-based Reactor to be + more similar with the poll()-based Reactor. In particular, + there is only one array of Event_Handlers rather than three... + +Sun Mar 13 16:49:59 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Fixed a bug with the select-based version of the Reactor. This + bug caused problems when dispatching the handle_output() member + function. + + * Fixed a bug with the select-based version of the Reactor. This + bug resulted in a failure to call the handle_close() member + function on the write_fds and except_fds. + + * Changed the interface for Event_Handler::handle_close() so that + the second parameter is a Reactor_Mask. This allows the + call-back routine to determine which side of a connection (i.e., + read-side vs. write-side or both) to close down. Be careful + since this change may break existing code that used the original + 1 argument handle_close() member function. + + * Changed the location of the Reactor_Mask. It was originally an + enum in Reactor.h. It is now a typedef in Event_Handler. This + change will break existing code but it easily spotted since the + compiler will give an error! + +Sat Mar 12 15:16:59 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Continued to modify the grammar of the svc.conf file language. + The latest version (illustrated in configuration files in the + ./tests/Reactor/server and + ./apps/Logger/Service_Configurator_Logger file) is both easier + to read and to parse automatically. + +Tue Mar 8 10:19:40 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Changed the behavior of the Get_Opt class so that it will + perform option processing starting from argv[0] rather than + argv[1] if the SKIP argument to the constructor is set to 0. + Note that the default value is 1, so the behavior is the same + for backwards compatibility. Incidentally, this new change is + necessary to support the Service Configurator stuff... + + * Changed the names of some of the Service_Record member functions + to conform to the new idiom for naming get/set-style of member + function accessors... + +Sun Mar 6 12:47:03 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Removed libGet_Opt.a and merged it in with libMisc.a + +Sat Mar 5 18:37:43 1994 Douglas C. Schmidt (schmidt at tango.ics.uci.edu) + + * Updated the Service_Config class to use a flex/yacc based parser + rather than an ad hoc parser and lexer. This is useful since + the new syntax for configuring a complete Stream into a Service + Configurator-based application is more complicated... + + * Made a small change to the syntax of a svc.conf file. Now any + parameters that are passed to the Service_Object::init() member + function of a dynamically linked service must be enclosed inside + of double quotes. In other words, service config entries such + as + + dynamic ./dev_adapter.so:_alloc () Device_Adapter -p 3000 + + now become + + dynamic ./dev_adapter.so:_alloc () Device_Adapter "-p 3000" + + This change makes it easier to parse the input using flex/yacc. + +Sat Feb 12 18:53:14 1994 Douglas C. Schmidt (schmidt@net4.ics.uci.edu) + + * Modified the Reactor so that it now also demultiplexes signals, + as well as timer events and I/O events. This required making a + few sections of the Reactor code signal-safe, as well as + thread-safe. + + * Changing the Reactor to handle signals also required a slight + change to its interface. For example, it is now mandatory to + give the Event_Handler::{READ_MASK,WRITE_MASK,EXCEPT_MASK} when + registering a handler... + +Sat Feb 5 12:10:53 1994 Douglas C. Schmidt (schmidt@net4.ics.uci.edu) + + * Changed the Condition and Monitor classes to use templates that + parameterize them with the appropriate type of Mutex (i.e., + either Mutex or Mutex_Rec). This greatly cleans up the code... + Made a number of changes in other files + (such as the Reactor) to account for the changes. + + * Added a new class called Mutex_Rec which implements a recursive + Mutex abstraction on SunOS 5.x. Recursive Mutexes may be + acquired multiple times from a single thread. Basically, this + supports an efficient and clean way of handling nested locking + conditions. + +Thu Feb 3 12:37:34 1994 Douglas C. Schmidt (schmidt@net4.ics.uci.edu) + + * Fixed a bug in Service_Config.i that was causing SIGHUP-driven + reconfiguration not to work correctly. + + * Added a set of new member functions to the Reactor class to + suspend() and resume() an event handler. Also added suspend() + and resume() member functions to the Server_Object class to take + advantage of these new facilities automagically... + +Mon Jan 31 09:47:06 1994 Douglas C. Schmidt (schmidt@net4.ics.uci.edu) + + * Modified the no-args constructor for the Reactor to initialize + it to the DEFAULT_SIZE. The prior behavior was *not* to + initialize it at all, which seems rather dumb in retrospect... + + * Improved the Reactor's support for multi-threading by adding a + pipe() call that is used to force the Reactor to reconfigure + itself everytime a new handler is registered or removed. + Previously, any new changes wouldn't take place until the + Reactor was triggered by some external event. This old behavior + was too non-deterministic... + +Sun Jan 2 12:35:39 1994 Douglas C. Schmidt (schmidt@net4.ics.uci.edu) + + * Modified the inheritance hierarchy for Service_Object so that it + derives from both Shared_Object and Event_Handler. + Shared_Object is a new abstract base class the provides an + interface for dynamic linking of objects. When RTTI is widely + available for C++ the Service Configurator will be much more + functional since we can automatically figure out whether an + object is a Service_Object or just a Shared_Object and do the + right thing with it! + diff --git a/ChangeLog-95 b/ChangeLog-95 new file mode 100644 index 00000000000..429e5681fdc --- /dev/null +++ b/ChangeLog-95 @@ -0,0 +1,4179 @@ +Sun Dec 31 01:02:01 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/OS (mmap): Added a new parameter to the argument list for + mmap(). This parameter is an ACE_HANDLE * and is used in the + Win32 implementation, which requires CreateFileMapping to open a + new HANDLE. This handle is passed back to the caller, which is + then responsible for freeing it... I'll probably need to modify + the ACE_Mem_Map class to manage this new handle for the WIN32 + version. + + * ace: Updated all the SPIPE files in preparation to porting them + to Windows NT, where they will be implemented using Win32 Named + Pipes! + + * ace/Typed_SV_Message: Fixed a mysterious braino where the method + definitions for Typed_SV_Message were actually within + Typed_SV_Message_Queue.cpp. I'm not sure why this happened, but + it's clearly been this way for eons... Also, changed the name + of the method "max" to "max_size" to avoid conflicts with macros + on Windows NT... + + * ace: Added a new config symbol: ACE_HAS_SYSV_IPC. If this is + *not* set (e.g., Win32) then don't try to compile any of the + System V IPC mechanisms (e.g., shared memory, message queues, + semaphores). + + * ace/Malloc: Reimplemented the Malloc-family to factor out common + code. Also added a new method called "trybind" which atomically + tries to bind a new void *pointer to a char *name. If there is + no name with the same value, the bind succeeds. Otherwise, the + bind "fails", but returns the existing pointer. + + * ace/Map_Manager: Reimplemented the Map_Manager to factor out + common code. Also added a new method called "trybind" which + atomically tries to bind a new int_id to an ext_id. If there is + no ext_id with the same name, the bind succeeds. Otherwise, the + bind "fails", but returns the existing int_id. + + * ace/Memory_Pool.cpp: Commented out all the diagnostic messages + in the various ACE_*_Memory_Pools. Now that we're actually + using this within ACE, they were distracting. + + * ace/CORBA_Handler.cpp (ACE_ST_CORBA_Handler): Gave iterations_ + an initial value of "5" for backwards compatibility. Thanks to + Irfan for doing this. + + * ace/Map_Manager.cpp (ACE_Map_Manager): Fixed some more braino in + the constructors of Map_Manager. During the recent changes I'd + forgotten to initialize the Map_Manager's instance variables to + 0. Thanks to Irfan for finding this out the hard way... ;-) + + * ace/OS.i (gettimeofday): Added a WIN32 implementation of + gettimeofday. This is pretty nasty, but it should centralize + all of this processing in one place in ACE! + +Sat Dec 30 00:50:20 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Timer_Queue: Removed the current_time() method from the + Timer_Queue class. All uses will be replaced with calls to + ACE_OS::gettimeofday(). Not only does this factor out more + code, but it is also reentrant! + + * ace/ACE.cpp (handle_timed_accept): Consolidated code so that + select() is always used, rather than poll(). + + * ace: Generalized the ACE file locking wrappers (both at the + Synch-level and the ACE_OS class level) to enable them to lock + arbitrary regions (aka "records") of a file. Before, they could + only lock the entire file (which remains the default behavior). + This new behavior works for both NT and UNIX. + + * ace/Synch: Removed the definition and use of the + ACE_SYNCH_ERROR_RETURN macro from all the ACE Synch* methods. + This behavior has been integrated into the ACE_OS class instead + since it cleans up lots of code that would otherwise have been + hard to write. + + * ace/INET_Addr.cpp (get_host_name): Fixed a bug that arose by + trying to use the reentrant version of gethostbyaddr all the + time. In order to fix this, I've added a new get_host_name() + method that allows the caller to supply a buffer for the + hostname. + + * ace: Cleaned up all the POSIX_TIMER junk that permeated ACE. + Now all platforms will have the POSIX timer structures (e.g., + timestruc_t and timespec), though only those that actually + support nano-second timing will be able to do anything useful + with this... As part of this cleanup, the poll, select, and + cond_timedwait method in ACE_OS now take ACE_Time_Value * rather + than int, timeval *, and timestruc_t, respectively. This + *greatly* cleans up the clutter throughout the rest of ACE. + + * ace/ACE: Added two new methods called tv2msec and msec2tv that + converts ACE_Time_Value format into millisecond format and vice + versa. This will make it easier to port code between NT and + UNIX. + + * ace/Reactor: Removed the code in the Reactor that previously + allowed it to be resized after it had been initialized. This + code no longer was used due to the recent enhancements that + ensure the Reactor is only initialized once per-process. + + * ace/Reactor: Modified the Reactor so that it now compiles on NT. + It doesn't work yet, but at least it compiles! + + * ace/Reactor: Moved the "max3" method from the Reactor to OS.h, + where it has become a template function usable throughout ACE. + + * ace/OS.cpp: Added extern "C" before the NT implementations of + readv() and writev(). + + * ace/OS.i: Fixed the declaration of ::readv() and ::writev() for + cases where the OS doesn't provide them natively. + + * ace/Event_Handler: Modified handle_signal() to take an int + rather than an ACE_HANDLE. The old way broke under NT... + + * ace: Made lots of minor changes to resolve signed int + vs. unsigned int mismatches. Thanks to the MSVC++ 4.0 compiler + for pointing these out. At least it's good for + something... ;-). + +Fri Dec 29 15:01:10 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/ACE.cpp (handle_timed_accept): Reimplemented the core + select() loop to make the code portable to Win32. + + * ace/Map_Manager.cpp (ACE_Map_Manager): Fixed a minor bug caused + by recent changes (forgot to initialize max_size_ in the + constructor...). + + * Updated all the manual pages to reflect the latest changes. + + * ace/ACE.cpp: Fixed up the ACE class so that all of the methods + should compile on both Windows NT and UNIX! + + * ace/OS: Moved the get_file_size() method from class ACE and put + it into class ACE_OS, where it's been renamed to filesize(). + This is really more of an "OS" function, e.g., it's supported on + Win32 directly. + + * ace/OS.cpp: added readv() and writev() implementations for those + platforms (e.g., Windows NT) that require them. + + * ace/Makefile: Added a new regex to the Svc_Conf_l.cpp target + that will substitute for . This should solve a + portability problem with Windows NT... + + * ace/Malloc: Modified the sync() and protect() methods to use + void * rather than char *. This is now consistent with the OS + classes. + + * ace/OS: Changed things so that all the mmap() related OS + wrappers use void * in their external interface. Any + discrepancies between platforms are now dealt with internally, + in the implementation of the methods. Thanks to Chris Lahey + (clahey@ix.netcom.com) for suggesting this. + + * ace/Local_Name_Space: Modified how ACE_NS_String is used to + instantiate ACE_Map_Manager in order to work around problems + with AIX C++. Thanks to Chris Lahey (clahey@ix.netcom.com) for + reporting this. + + * ace/Synch.i: Added a definition for ACE_RW_Mutex::acquire(). + +Fri Dec 29 00:34:16 1995 Chris Lahey (clahey@ix.netcom.com) + + * ace/OS.h: Changed the #ifdef for ACE_HAS_COMPLEX_LOCKS to + ACE_HAS_COMPLEX_LOCK. + + Changed prototypes for ACE_OS:mprotect(), msync(), and munmap() + to accept ACE_MMAP_TYPE for their first arg. The AIX versions + of these calls all expect void * for their pointer variable. + Note that madvise() takes a caddr_t for its 1st arg and + therefore does not need to be altered. (See related changes in + OS.i and Mem_Map.i) + + Changed prototype for ACE_OS::getsockname(), arg3 to int * (See + related change in OS.i) + + Changed prototype for ACE_OS::setsockopt(), arg4 to const char * + and arg 5 to int (See related change in OS.i) + + * ace/OS.i: Changed function definition for ACE_OS::mprotect(), + msync(), and munmap() to accept ACE_MMAP_TYPE as their 1st arg. + + The following changes relate to the inconsistencies in the + sockets calls on AIX. I thought it would make more sense to + leave the public interfaces alone and then handle the + differences internally. That way it won't break any exisiting + code. + + Changed function definition for ACE_OS::getsockname() to accept + arg3 as int *. Made similar changes in ACE_OS::setsockopt() - + change definition to accept const char * for arg4 and int for + arg5. Add the following code at the start of the function: + Also made changes to ACE_OS::recvfrom() - change arg 6 back so it is + int *. + + * ace/Mem_Map.i: In ACE_Mem_Map::advise(), cast 1st arg to + ACE_OS:madvise() to (caddr_t). + + * ace/Memory_Pool.cpp: In ACE_MMAP_Memory_Pool::acquire(), make + cast to char * in the return statement. In + ACE_MMAP_Memory_Pool::handle_signal(), also make same cast in + the ACE_DEBUG statement near the top of the function. + + * ace/Reactor.cpp and ace/Reactor.h: ACE_Reactor::handler_i() + doesn't return properly if *eh != 0. Remove last "else" so + function always returns 0 if handler != 0. + + In ACE_Reactor::owner(), we need to change signature since + thread_t is not an integer. This has been changed to int + ACE_Reactor::owner(thread_t *t_id); The last two lines have been + changed to: *t_id = this->owner_; return 0; + + * ace/Synch.cpp: In ACE_Condition_Mutex::wait(), the call to + cond_timedwait() does not exist, but ACE_OS::cond_timedwait() + does exist. It takes the same arguments. + + * ace/Synch.h and ace/Synch_T.h: At the end of both files, before + the #define INLINE check for this define's existence to avoid + causing compilers to choke. + + * ace/Mem_Map.i: In ACE_Mem_Map::operator(), the return statement + looked very odd. In the assignment to addr, why is the ", 0" in + the statement? + +Fri Dec 29 00:34:16 1995 Douglas C. Schmidt (schmidt@lambada.cs.wustl.edu) + + * ace: Fixed up many minor problems with the various types of + Shared_Memory wrappers. This mostly entailed changing from char + * to void * to be more consistent with the other parts of ACE. + In addition, I now only include the *.i files if __INLINE__ is + enabled. + + * ace/Memory_Pool.cpp (map_file): Fixed a minor bug by enabling + MAP_FIXED if we're trying to map a file using a fixed address. + +Thu Dec 28 18:39:16 1995 Douglas C. Schmidt (schmidt@merengue.cs.wustl.edu) + + * ace/Local_Name_Space.cpp: Finished implementing changes to the + ACE_Malloc stuff and the Local_Name_Space that Irfan had begun + last semester. + + * ace/SString.cpp: Added new optimizations to the assignment + operators of the ACE_[WCS]String classes to avoid + freeing/allocating memory if the current size is large enough. + + * ace/SString: Added copy constructors... + + * ace/Local_Name_Space.cpp: Modified the implementation of bind() + to avoid a race condition. + + * ace/Map_Manager.cpp (bind): Changed the semantics of bind() so + that callers can control whether or not INT_IDs are reassigned. + Also changed things so that callers can get back the existing + value if they choose not to reassign. + + * ace/SString.cpp: Removed the "P" (persistent) versions of all + these classes and merged them into the default versions. The + persistence is now determined by the type of allocator passed in + as a parameter to the constructor (or by using the "default" + allocator that is accessible via + ACE_Service_Config::allocator()). + + * ace/Map_Manager.cpp: Removed the "P" (persistent) versions of + all these classes and merged them into the default versions. + The persistence is now determined by the type of allocator + passed in as a parameter to the constructor (or by using the + "default" allocator that is accessible via + ACE_Service_Config::allocator()). + + * ace/Malloc_T: Modified the bind() algorithm so that it will + allow the caller to determine whether duplicates are allowed or + not... Also changed things so that callers can get back the + existing value if they choose not to allow duplicates. Irfan + questions the sanity of this... ;-) + + * ace/Synch: To be consistent, added acquire_write and + acquire_read methods to ACE_Mutex. These are useful for cases + where we are going to be parameterizing classes like ACE_Malloc + with some type of mutex wrapper (e.g., ACE_RW_Mutex, ACE_Mutex). + + * ace/Malloc_T.cpp (calloc): Added a new method called "calloc" + that will not only allocate the memory dynamically, but will + also give it an initial value (e.g., '\0'). + +Thu Dec 28 01:10:43 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/OS.i: Modified the implementation of the TLI methods so that + they are conditionally compiled away if the platform doesn't + support TLI... Thanks to Neil Cohen for pointing out the need + for this... + + * ace/OS.i: Modified the implementation of dlopen() and dlsym() to + account for limitations with SunOS 4.x... + + * ace/Service_Repository.cpp: Modified this class to use the + ACE_OS::dlclose method. + + * ace/Parse_Node.cpp: Modified this class to use the + ACE_OS::dlopen and ACE_OS::dlsym methods. + +Wed Dec 27 23:25:03 1995 Jesper S. M|ller (stophph@diku.dk) + + * Added appropriate flags in OS.h for successful inclusion of + several header files, such as Malloc.h and friends. Also added + mprotect to ACE_OS for Win32 to avoid linker errors. + + * Added a return value (from map_file) to + ACE_MMAP_Memory_Pool::handle_signal. The compiler was + complaining. Likewise on + ACE_MMAP_Memory_Pool::commit_backing_store (there 0 seemed like + the correct off-the-end return value). + + * Removed include of some SV semaphore file, if not needed in + Malloc.h. Worse for Memory_Pool.h, since the SV_Semaphore + wrappers consistently differ completely from the other + synchronization routines. I guess we'll need some variant of + ACE_Process_Semaphore that takes an integer as a key instead of + a string, and does not perform automatic init/destroy. + + * Also upgraded fd's from int to ACE_HANDLEs and changes -1 to + ACE_INVALID_HANDLE where appropriate. + + * By help of aggresive preprocessor conditionals, made Handle_Set + work with Win32. There is a fd_set abstraction with appropriate + FD_xxx macros for WinSock, and it requires no sync'ing. The + Handle_Set_Iterator should also work. The good looks of + Handle_Set was impaired, though. Right now, the trigger is the + ACE_WIN32 flag, although it should be something like + ACE_FD_SET_USES_BITS for the unix approach, or like + ACE_FD_SET_USES_VECTOR for the WinSock approach. + + * Reactor almost compiles now, but not quite: Handlers are + addressed by fd, this is no longer possible - what a mess - we + need to step through the handle indices somehow. This will + likely get into some nasty quadratic complexities when iterating + the handles to find the event_handler for each file + handle. Mabye we can circumvent this with a hash table lookup + for those opaque handles. + + * There was a problem with the Svc_Conf.l.cpp and the + Svc_Conf.y.cpp and the extremely lame MSVC++ 2.0. I had to + rename them to Svc_Conf_y.cpp, etc. Awful! + + * Added code to inquire the 'host' name for Win32 in the ACE_Client_Id + class. Another candidate for ACE_OS. + + * About 60 or so ACE .cpp files compile now, which reminds me that + I'll be working on some precompiled header scheme soon, since it + takes for ever and ever, even on my 32meg system with pretty + good SCSI drives. Mabye it's because I'm only running a 66MHz + i486 DX2 (yawn). + + * Dozens of other changes have been made to various files, all + pertaining to int vs. ACE_HANDLE. In Service_Manager.h, a signal + number was an ACE_HANDLE, but just close by, some fd's were + ints. Fixed that, too. + +Sat Dec 23 14:15:16 1995 Jesper S. M|ller (stophph@diku.dk) + + * I've also grouped the .i and .cpp functions by class, + and #if'ed the sbrk and SysV pools out, since + Win32 cannot support those. + + * Added 'inline' to day accessor functions in Date_Time. + + * Two things that missed me in Trace.cpp: + 1) The inclusion order was so that I couldn't + build Trace.o, since it didn't know the MALLOC_HOOK thing. + I moved the #include of Trace.h down below that of ACE.h. + 2) The declaration and definition of the ACE_Trace constructor + differed by a const, which I added. + 3) When linking, multiple symbols were found for some + OS calls like mutex_init, corresponding to the larger + OS Win32 functions. I has ACE_INLINED_OS_CALLS off, + so sometimes the OS functions were inlined, sometimes + not. + I disabled the inline hack in Trace.cpp for WIN32 for now. + This seemed to resolve matters. + + * There was a major problem in OS.i, where Synch.h was needed for + mutex support (in conjunction with TSS info linked list). I + chose to make thr_keycreate and some others non-inlined. + + * More 'is-it-a-handle-or-success' confusion in SOCK*.* Changed + ACE_SOCK_Dgram to use int status. Changed ACE_SOCK_CODgram to + use int status. Changed ACE_LSOCK to use int status. Also + changed a few derived classes + +Fri Dec 22 14:03:15 1995 Douglas C. Schmidt (schmidt@lambada.cs.wustl.edu) + + * ace/OS.h: Added a new type for rwlock_t for platforms that don't + support threading... Thanks to Neil Cohen for reporting this. + + * ace: Merged in all of Jesper's changes for NT and Chris Lahey's + changes for AIX. + + * ace: Merged tli.h into OS.h to avoid name conflicts on Win32. + + * Fixed duplicated names where case is the only difference. + ace/thread.cpp + ace/Thread.cpp + ace/TLI.h + ace/tli.h + apps/Token_Server/mutex_example/simple_token_client.cpp + apps/Token_Server/mutex_example/Simple_Token_Client.cpp + apps/Token_Server/script_example/scripting_token_client.cpp + apps/Token_Server/script_example/Scripting_Token_Client.cpp + tests/IPC_SAP/SOCK_SAP/FD-client.cpp + tests/IPC_SAP/SOCK_SAP/fd-client.cpp + tests/IPC_SAP/SOCK_SAP/FD-server.cpp + tests/IPC_SAP/SOCK_SAP/fd-server.cpp + +Wed Dec 20 22:26:24 1995 Jesper S. M|ller (stophph@diku.dk) + + * FIFO.cpp: One last comparison of 'open' return status where and + ACE_INVALID_HANDLE should be changed to -1. + + * One more last wrong comparison in FIFO_Recv_Msg.cpp. + (Never say never again!) + + * Put an appropriate conditional around the inclusion of + Handle_Set.h for ACE_WIN32 (for now). + + * Introduced a few backslashes in the macros of Dump.h that were + somehow left out... Had to add a really stupid constructor for + struct Tuple. I haven't a clue why MSVC++ wants this! Replaced + 'return ACE_ODB;' with 'return ACE_ODB::instance_;' in the + Singleton access function. + + * Added a constructor for ACE_ODB. It may be private, but it still + needs to be defined... + + * Stack and Set compiles fine for Win32 (not surprisingly) + + * If'ed out the guts of ACE_IPC_SAP enable/disable calls for + Win32, since async IO doesn't work that way on there. + + * Event_Handler now uses ACE_INVALID_HANDLE for default args. + + * SOCK compiles except for the ACE_SOCKET <> ACE_HANDLE + problem. Refer to issue #3 above. + + * We're swamping the ace directory with .mak files. I used the + winntace.mak file, which is compilable and linkable. + +Thu Dec 21 15:37:42 1995 Douglas C. Schmidt (schmidt@merengue.cs.wustl.edu) + + * ace: Greatly simplified the include files so that (1) compilers + are faster and (2) the ACE_Trace mechanism works correctly. + + * ace/Trace: Modified the ACE_Trace_TSS class so that it is no + longer a template. This was overkill since we know the type + head of time (i.e., ACE_Trace_State). + + * ace: Added a number of new changes to ACE to make things work on + AIX. Thanks to Chris Lahey for these + changes. + + * ace/Thread_Manager.cpp: Removed the get_max_thr_id() method + since it was not portable to NT or POSIX pthreads. Nothing in + ACE depended on it anyway... + + * ace/OS: Added a new static data member called NULL_thread that + is a "zero'd" out thread id. This is necessary to deal with the + POSIX pthread implementation of a thread id, which is not always + implemented as a number... By using this new approach, all the + special-case code in Synch.cpp disappears... + + * ace/OS: Added a new method to class ACE_OS called thr_equal() + that masks the differences between comparing thread ids using + the threading libraries. This simplifies the code in Synch.cpp + and Reactor.cpp. + + * ace: Updated all uses of mmap() to use the new ACE_MMAP_TYPE + typedef. This deals with the fact that different versions of + UNIX define mmap() inconsistently (e.g., some use void * and + some use char *...). + + * ace: Removed testconfig.h and merged all of those #defines into + OS.h. This centralizes changes in one place and also eliminates + the need for ./apps and ./tests to include extraneous files... + + * ace/testconfig.h: Changed all uses of 0666 to ACE_DEFAULT_PERMS. + Also, removed all PERMS enums and substituted ACE_DEFAULT_PERMS + instead. + +Wed Dec 20 17:29:55 1995 Tim H. Harrison (harrison@merengue.cs.wustl.edu) + + * Rewrote the Token deadlock detection algorithm. It now performs + "best-effort" detection of deadlock for remote acquires and + complete deadlock detection for local acquires. + +Wed Dec 20 02:37:39 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/OS.h: The select() system call has its own include file on + AIX: . We can wrap the #include with a variable + #if defined (ACE_HAS_SELECT_H). + + * include/makeinclude/platform_aix.GNU: Added new support for AIX. + Thanks to Chris Lahey for these changes. + Added a number of other minor changes, as well. + + * ace: Made a bunch of minor changes to get ACE to compile on + SunOS4.x, Linux, and SGI. + + * ace/config-linux.h: added ACE_HAS_MSG (thanks to Neil Cohen + for this). + + * ace/OS.h: Conditionally compile for ACE_HAS_UTIME for + . + + * Released an alpha version of ACE containing the new Windows NT + port. + + * Integrated and tested all the new Windows NT changes in class + ACE_OS, as well as the Synch* and Threads* classes. We're now + able to build Jesper's win32_test.cpp file in ./ace! A complete + NT port should be just around the corner... + +Tue Dec 19 17:59:04 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace: Move the remaining contents of sysincludes.h into ACE.h. + There is no more sysincludes.h (at long last!). + + * ace: Rearranged things so that the OS.[hi] files contain all the + OS-specific #defines and #includes that were previously in + sysincludes.h. + + * ace: Renamed the ACE_Misc class to class ACE, which is more + representative of what it does. + + * INSTALL: updated the installation instructions to explain how + the new directory structure works. Thanks to Neil Cohen for + pointing out the discrepancy beteen the source and the + documentation ;-). + + * Reorganized (by flattening) the ACE library directory structure + to make it work for both Windows NT and UNIX. Note that Windows + NT does not have symbolic links, so the old way of doing things + didn't port... The consequences of these changes is there is + now a single directory called $WRAPPER_ROOT/ace that contains + the *.[hi] and *.cpp source files. This is also where the + libACE.a and libACE.so libraries are built by default. Also, + note that the suffix used by ACE has been changed from *.C to + *.cpp to deal with the lame Visual C++ compiler... + +Tue Dec 19 01:26:54 1995 Douglas C. Schmidt (schmidt@merengue.cs.wustl.edu) + + * tests/ASX/Event_Server/Event_Server/Supplier_Router.cpp (put): + Fixed up a problem with the Event_Server. Somewhere along the + way it stopped being concurrent! The new version fixes this. + Thanks to Alex V Maclinvosky for + noticing this... + + * Added a billion new changes to class OS to integrate the Windows + NT port with the rest of ACE. We are getting very close... + +Mon Dec 18 12:45:13 1995 Jesper S. Møller (stophph@diku.dk) + + * Major problems in the IPC_SAP. First, I detected that some open + calls returned handles, some returned -1 or 0. For instance + ACE_SOCK has a constructor, that calls this->open and expects a + handle (which it even sets as the current handle + value!). Unfortunately, the return from open is either 0 or -1, + depending on how well the open went. ACE_HANDLE being + typedef'ed to a void* really reveals some problems! I have + solved the problem for the FIFO*.* family and for SOCK.* + +Mon Dec 18 12:43:46 1995 Douglas C. Schmidt (schmidt@merengue.cs.wustl.edu) + + * tests/Reactor/CODgram/CODgram.C (main): Fixed a bug in main() + caused by initializing the Reactor twice. Thanks to Aurelio + Nocerino for reporting + this. + + * libsrc/Service_Configurator/Service_Config.C Added a new + constructor to ACE_Service_Config that can be used to initialize + internal variables without performing a full configuration. + +Mon Dec 18 01:22:22 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Service_Config: renamed tokens.h to sc_tokens.h to avoid + file name collision on Win32. Thanks to Jesper S. M|ller + for reporting this. + + * tests/Mem_Map/IO_Test: renamed io_test.C to test_io.C to avoid + file name collision on Win32. Thanks to Jesper S. M|ller + for reporting this. + + * libsrc/Misc/OS: Implemented condition variables for Windows NT. + +Sun Dec 17 21:23:32 1995 Douglas C. Schmidt (schmidt@merengue.cs.wustl.edu) + + * libsrc/Misc/Trace: Fixed up the ACE_Trace class so that it + doesn't include any calls that will improperly trigger infinite + recursion! This allows the ACE library to be traced completely. + +Sat Dec 16 19:12:37 1995 Jesper S. Møller (stophph@diku.dk) + + * Changes to OS.*: + * Added conditionals to the OS.h for Win32, for the special ACE/Win32 + thr_destroy_tss(), which is automatic for Solaris. + * Changed declarations of thr_create, thr_suspend, thr_continue, + thr_join and thr_[gs]etprio to use hthread_t instead of thread_t. + * Changed return type of OS::open from int to ACE_HANDLE. + * Provided non-obtrusive handling of thr_handle in OS::thr_create + for non-Win32. + * Copied ACE::writev to OS::writev for Win32. Something similar + should happen for other systems... + + * Changes to Thread.*: + * Changed join, suspend and continue to take handles. + * Added thread handle return address to spawn. + + * Changes to Thread_Manager.*: + * Added thread handles to the Thread_Descriptor structure. + * Modified insert_thr and append_thr functions to also take + handles. + * Made ACE_Thread_Descriptor::Thread_State (a enum) public + so Thread_Manager::append_thr could use it as a formal + parameter (I suspect this is a bug in MSVC++). + * Changes the various flavours of suspend, continue, etc. to + use handles instead of id's. Keep in mind that none of this + is destructive for Unix, but vital for Win32. + * There is still a problem with ACE_Thread_Control registering + itself with the Thread_Manager - the thread does not have means + of finding it's own handle. In this particular case, we could + have the thread duplicate it's pseudohandle into a real one, + and pass that one along. I'd really, really, really rather not + have to maintain a thread id->handle mapping myself; It would + slow down thread manipulation and give some troublesome memory + overhead. + + * Changes to Log_Msg.*: + * OS::getpid instead of ::getpid. + + * Changes to Misc.*: + * Sections inappropriate for Win32 #if'd out... + * Provided naive timestamp function (No date) for Win32. + + * Changes to IPC_SAP.*: + * Uses OS::ioctl instead of ::ioctl + * Uses ACE_INVALID_HANDLE instead of ACE::INVALID_HANDLE + + * Changes to FIFO.*, : + * Uses ACE_INVALID_HANDLE instead of ACE::INVALID_HANDLE + + * Changes to FIFO_Send.*: + * open now returns an int insted of an ACE_HANDLE. + * Uses ACE_INVALID_HANDLE instead of ACE::INVALID_HANDLE + + * Changes to FIFO_Send_Msg.*: + * open now returns an int insted of an ACE_HANDLE. + * Uses ACE_INVALID_HANDLE instead of ACE::INVALID_HANDLE + * Uses OS::writev instead of ::writev + + * Changes to FIFO_Recv.*: + * open now returns an int insted of an ACE_HANDLE. + * Uses ACE_INVALID_HANDLE instead of ACE::INVALID_HANDLE + + * Changes to FIFO_Recv_Msg.*: + * open now returns an int insted of an ACE_HANDLE. + * Uses ACE_INVALID_HANDLE instead of ACE::INVALID_HANDLE + + * Changes to sysincludes.h: + * Uses ACE_INVALID_HANDLE instead of ACE::INVALID_HANDLE + +Sat Dec 16 12:29:06 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP/Addr/INET_Addr.C: Changed the implementation so + that the reentrant versions of the library calls are always used + (class OS sorts this all out). This reduces the amount of + clutter in the code. + + * libsrc/Threads/Synch: Added a new implementation of + "readers/writer" locks for both Windows NT and POSIX pthreads. + By default, these threads packages don't have this feature. + + * libsrc/Threads/Synch: Added a new macro called + ACE_SYNCH_ERROR_RETURN that greatly simplifies the definition of + the synchronization wrappers. + + * include/ace/sysincludes.h: Removed the pthreads_map.h file and + integrated this into sysincludes.h. + +Fri Dec 15 02:39:25 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Misc/OS.i: Finished updating class OS so that it will + compile correctly for OS platforms that don't support threads, + as well as platforms that support POSIX Pthreads vs. Solaris + threads, etc. + + * libsrc/Misc/OS: integrated Jesper S. M|ller + support for POSIX regular expressions (e.g., compile() and + step()) and sysinfo() into ACE. + + * Integrated and tested all of Irfan's changes to ACE to support + the new persistence Name_Server. This added some new classes in + various places that use the ACE_Allocator. + +Thu Dec 14 00:23:43 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * tests/ASX/Event_Server/Event_Server: Fixed an "off by 1" bug in + the declaration of char *argv[3] in the open() methods of + Supplier_Router.C and Consumer_Router.C. Thanks to the "ever + dissatisfied" Alex V Maclinvosky + for reporting this. + + * libsrc/Service_Configurator/Service_Config: Added a new + "Singleton" access point for the global ACE_Allocator. + + * libsrc/Naming/Name_Options.C (parse_args): Made it possible to + change the name of the process on the command line via the -P + option. The default is still to use argv[0] as the process + name. + + * include/ace/testconfig.h (ACE_DEFAULT_GLOBALNAME): Changed the + value from "/localnames" to "/globalnames" to avoid a conflict. + + * libsrc/Misc/SString.C: Added Irfan's new "persistent" string + mechanisms that use the ACE_Allocator_Manager. We may + eventually update the existing SS* stuff to use this. + + * Merged in Jesper S. M|ller updates for Windows + NT. + + * include/ace/Malloc.h: Added a forward declaration for + ACE_Malloc_Iterator right before ACE_Malloc. Thanks to Antonio + Tortorici for reporting it. + + * libsrc/Threads/Synch_T.h: Fixed a small typo in + ACE_Null_Condition. Thanks to Antonio Tortorici + for reporting it. + + * include: Added new config-linux.h and platform_macros.GNU config + files for Linux. Thanks to Timothy Newell + <910430n@dragon.acadiau.ca> for this stuff. + +Wed Dec 13 23:08:11 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP/Addr/INET_Addr.C (set): Fixed a small typo in the + ACE_INET_Addr::set (const char port_name[], ACE_UINT32 + inet_address) method where the test should be != rather than == + 0. Thanks to Bill Lear (rael@anarchy.cybercom.net) for + reporting this. + +Sun Dec 10 12:23:54 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Service_Configurator/Service_Record.C (init): Fixed a + small problem where a NULL pointer was being returned if a user + passes a non-existent config file (using the -f option) to + ACE_Service_Config::open(). Thanks to Dieter Quehl + (quehl@erlh.siemens.de) for noticing this. + + * libsrc/Log_Msg/Log_Msg.C (log): added a new option (%T) that + causes the current timestamp to be inserted into the log msg. + Thanks to Dieter Quehl (quehl@erlh.siemens.de) for suggesting + this. + + * libsrc/Misc/Misc: Added a new timestamp() method that returns + the current timestamp in the form + "hour:minute:second:microsecond." The month, day, and year are + also stored in the beginning of the date_and_time array. + + * tests/Shared_Malloc: Added Irfan Pyarali new + test program that exercises the new features of ACE_Malloc that + are described in the following bullet. + + * libsrc/Shared_Malloc: Added Irfan Pyarali + cool new versions of ACE_Malloc and ACE_MMAP_Memory_Pool. These + new versions provide the following enhancements: + + 1. Persistence -- via the sync() method + 2. Protection -- via the prot() method + 3. Named malloc chunks -- via bind(), find(), unbind(). + 4. Named iteration -- via ACE_Malloc_Iterator + +Thu Dec 7 00:31:26 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor/Signal.C: Replaced ACE_Guard with ACE_TSS_Guard + to ensure that locks are correctly released even if + Event_Handler::handle_signal() callbacks invoke + ACE_Thread::exit(). Thanks to Detlef Becker + (beckerd@erlh.siemens.de) for suggesting this. + + * libsrc/Threads/Synch_T: Used inheritance to factor out the + shared code between ACE_Guard, ACE_Read_Guard, and + ACE_Write_Guard in order to reduce unnecessary duplication. + + * libsrc/Threads/Synch_T: Changed the implementation of ACE_Guard + to keep a pointer to the LOCK rather than a reference. This + makes the code more flexible and aids in factorization. + + * libsrc/Threads/Synch_T: Changed the implementation of ACE_Guard + to incorporate ACE_Try_Guard semantics. This reduces the amount + of classes and duplicate code in ACE. + +Wed Dec 6 21:36:02 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * include/ace/Trace: Changed the type of the string passed into + ACE_Trace from char * to const char *. + + * libsrc/Reactor/Reactor.C: Had forgotten to initialize the + initialized_ and requeue_position_ members appropriately in the + constructor of the ACE_Reactor if ACE_MT_SAFE is *disabled*. + Thanks to Mark Zusman for pointing + this out. + + * libsrc/Threads/Synch_T.C: changed the order of some methods so + they would be properly defined if ACE_HAS_THREADS and + ACE_HAS_THREAD_SPECIFIC are *not* enabled. This should fix + remaining problems with ACE on SunOS 4 and SGI. Thanks to + Aniruddha Gokhale for noticing this. + +Tue Dec 5 01:06:14 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Changed things around so that the Name_Server and Token_Server + client interfaces are include in libACE. + + * libsrc/Shared_Malloc: added a const char *pool_name to + ACE_Malloc::ACE_Malloc. This is passed into the constructor of + the MEMORY_POOL to make it easier to dynamically name memory + pools. + +Mon Dec 4 21:20:28 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Threads/Synch_T: Modified the place that the + ACE_Thread_Specific methods are defined so that they will be + compiled correctly for platforms without threads or + thread-specific storage. + +Sun Dec 3 23:04:41 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/ASX/Message_Block: Modified clone() so that it takes an + extra parameter that specifies which flags SHOULD NOT BE + TRANSFERED to the clone. This defaults to + ACE_Message_Block::DONT_DELETE. Thanks to Alex V Maclinvosky + for suggesting this. + +Sun Dec 3 17:43:11 1995 Tim H. Harrison (harrison@lambada.cs.wustl.edu) + + * The number of files in the Token library has been reduced. As a + result, many of the files have been renamed. Also, the .i files + have been purged of relatively large methods (these have been + moved to the .C files.) Lastly, most uses of dynamic memory + allocation have been removed from the library. This was + important to reduce the amount of serialization in threaded + applications caused by the dynamic allocation. + +Sun Dec 3 17:29:54 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Threads/Synch: Modified all the synchronization classes + so that they disallow assignment and initialization! + + * libsrc/Threads/Synch: Moved the ACE_Thread_Specific class from + its own files into the Threads/Synch.[Chi] files. This should + eliminate a set of horrible interdependencies among files. + +Sat Dec 2 16:07:40 1995 Douglas C. Schmidt (schmidt@mambo.cs.wustl.edu) + + * libsrc/Misc/SString.C (ACE_CString): Added a destructor to + CString. Thanks to Tim for noticing this... + +Tue Nov 28 17:25:02 1995 Prashant Jain (pjain@tango.cs.wustl.edu) + + * apps/Name_Server/client/lib/Name_Proxy: Changed Name_Proxy to + inherit from ACE_Service_Object rather than ACE_Event_Handler. + This will allow a Name_Proxy to be dynamically linked into an + application via the svc.conf file. + + * apps/Name_Server/client/lib/Name_Proxy: Added new methods + init, fini, and info. + +Tue Nov 28 00:56:52 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * tests/Threads/test_thread_specific.C: Added code to test the new + ACE_TSS_Guard class... + + * libsrc/Threads/Synch_T: Added the new ACE_TSS_Guard class. This + class is similar to the existing ACE_Guard, except that it uses + thread-specific storage to ensure locks are released even if a + thread exits via thr_exit()! + +Mon Nov 27 20:39:58 1995 Prashant Jain (pjain@tango.cs.wustl.edu) + + * apps/Name_Server/{client,server}/tests: Added new tests to + exercise the key features of the name server. + + * apps/Name_Server/client/lib: Simplified access to the nameserver + database. For example, all the network-byte ordering code was + moved out of the Local and Remote Name_Spaces. This code is no + longer necessary since we'll be providing a different means to + get portable name service repositories via a tool that extracts + the "key/value/type" tuples and stores them in a + machine-independent format. The result of this change is that + the Name_Server code is much easier to understand and modify. + + * apps/Name_Server/client/lib: Split local and remote name spaces + into two classes to simplify usage. This approach uses the + Bridge pattern to have a baseclass called Binding and then have + subclasses called Local_Name_Space and Remote_Name_Space. The + constructor of Naming_Context then allocates the right one + (i.e., it serves as a factory). This approach remove all the + switch statements in the code and makes it much easier to use + and extend. + + * apps/Name_Server: updated all the Name_Server components to + use ACE naming conventions. + + * apps/Name_Server/client/lib: Changed ACE_Name_Options to use the + Singleton pattern rather than the global variable... + +Mon Nov 27 00:47:32 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Shared_Malloc/Malloc.h: Named the previously anonymous + struct inside of ACE_Malloc_Header to be + ACE_Malloc_Control_Block in order to keep the OSE tools working. + Thanks to Karlheinz for reporting this. + + * libsrc/Threads/Synch: Fixed a major bug in the ACE_Semaphore + wrappers. Apparently, these had slipped between the cracks and + were not correctly mapping onto the ACE return value scheme + where -1 corresponds to an error with errno set to indicate the + type of error. + + * tests: Cleaned up some files that mistakenly were defining + LSOCK* objects even for platforms (i.e., Linux) that don't + support them. Thanks to Timothy Newell + <910430n@dragon.acadiau.ca> for noticing this. + +Sun Nov 26 12:42:51 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Shared_Malloc/Malloc: Added a new accessor method + (memory_pool) that returns a reference to the MEMORY_POOL object + used to configure ACE_Malloc. + + * libsrc/Shared_Malloc/Malloc: Changed the constructor of + ACE_Malloc to take advantage of the new init_release method on + all the ACE_*_Memory_Pools. + + * libsrc/Shared_Malloc/Memory_Pool: Added a new method to all the + ACE_*_Memory_Pool classes called "init_release". This is called + when ACE_Malloc finishes initializing the dynamic memory + manager. This method is necessary in order to initialize the + ACE_MMAP_Memory_Pool correctly if there are multiple processes + that try to initialize ACE_Malloc simultaneously. In addition, + also added an ACE_SV_Semaphore_Complex to the + ACE_MMAP_Memory_Pool in order to serialize initialization + correctly. + + * libsrc/Shared_Malloc/Memory_Pool: Added sync() and protect() + methods to all of the ACE_*_Memory_Pool classes in order to + support a uniform interface for use with the "robust memory" + mechanism we're building. + + * libsrc/Mem_Map/Mem_Map: Added two new "protect" methods to + ACE_Map_Manager in order to allow clients to change the + protection of memory-mapped regions. + + * libsrc/ASX/Map_Manager: Changed Map_Manager methods to use + "const" for EXT_ID and INT_ID at request of Prashant Jain + (pjain@cs.wustl.edu). + + * libsrc/Shared_Malloc/Memory_Pool: Revised the + ACE_Shared_Memory_Pool so that it would actually work + correctly... This code hadn't been reviewed carefully before + and there were some bugs... + + * libsrc/Shared_Malloc/Malloc: added "INLINE" to the + ACE_Allocator_Adapter components. + + * libsrc/Shared_Malloc/Memory_Pool: Greatly simplified and + consolidated the mmap(2) code for ACE_MMAP_Memory_Pool. + + * libsrc/Shared_Malloc/Memory_Pool.i (release): Removed the + vestigal this->mmap_.remove() call in release(), but added the + appropriate code to close the fd and unmap the region. Thanks + to Irfan Pyarali for noticing this. + +Sat Nov 25 18:12:55 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/CORBA/CORBA_Handler.C (activate_service): + Modified activate_service so that + + if (service_name != 0 + && this->register_service (service_name, marker_name, + service_location) == -1) + return -1; + + is changed to + + if (service_name != 0 && service_location != 0 + && this->register_service (service_name, marker_name, + service_location) == -1) + return -1; + + Irfan Pyarali requested this. + +Sat Nov 25 16:41:15 1995 Douglas C. Schmidt (schmidt@lambada.cs.wustl.edu) + + * libsrc/Misc/Set: Changed all the find() and size() methods to + be const member functions. Thanks to Irfan Pyarali + (ip1@cec.wustl.edu) for requesting this. + +Fri Nov 24 02:51:59 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor/Reactor.C: Fixed the Reactor so that if we're + compiling with DEADLOCK_DETECTION enabled it will create a + uniquely named mutex by stringifying "this". + +Thu Nov 23 21:45:43 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP: Changed + + * libsrc/Service_Configurator/Service_Config: Added three new + methods to allow programmers to set the process-wide Singletons + for Reactor, Service_Repository, and Thread_Manager. + +Tue Nov 21 01:59:06 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Mem_Map/Mem_Map.C: Fixed a stupid typo in map_it() that + was causing problems due to unsigned arithmetic semantics... + This should make the file_reverse.C Mem_Map tests work correctly + now... Thanks to Bill Lear for + noticing the problem. + + * tests/Mem_Map/IO-tests/io_test.C (parse_args): Fixed a + classic C/C++ braino in io_test.C: + + The for loop in parse_args() + + for (int c; (c = get_opt () != -1); ) + + should be + + for (int c; ((c = get_opt ()) != -1); ) + + How embarrassing. Maybe Bertrand Meyer is right -- C++ is too + dangerous for its own good... ;-). Thanks to Bill Lear + for finding this! + + * Removed all traces of ACE_Condition from the library. + This should make life much easier for compilers (like G++) that + can't grok templates very well... + + * libsrc/Threads/Thread_Specific.C (ts_object): Added a new method + that allows you to simultaneously "test and set" thread-specific + data! This is used to support a neat new trick that ensures + locks are released even if a thr_exit() is called! + + * libsrc/Service_Configurator/Service_Repository: Removed the + Recursive_Mutex from Service_Repository and replaced it with a + regular (non-recursive) mutex. Had to rewrite the code a bit so + that it wouldn't try to call internal methods that acquired the + mutex (this leads to instant deadlock!) + +Mon Nov 20 01:05:47 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Threads/Synch: Finally gave in and accepted the fact that + GNU G++ is a horrible, horrible blight on mankind... Changed + the internals of Synch.[Chi] to completely remove any + dependencies on templates. I hope this fixes some portability + problems deep in the libraries... Added several new classes to + reflect this change: ACE_Mutex_Guard, ACE_Mutex_Condition, and + ACE_Recursive_Mutex. + + * libsrc/IPC_SAP/UPIPE_SAP/UPIPE_Acceptor.C (ACE_UPIPE_Acceptor): + Fixed a stupid typo that was causing the constructor of + UPIPE_Acceptor to become inlined!!! + + * apps/Gateway/Gateway: Fixed up the Makefile so that the gatewayd + executable would compile with G++. + + * include/ace/config-irix5.3-sgic++.h: Changed the SGI config.h + file so that it uses select() rather than poll() by default. + The select() version of the Reactor is implemented more + efficiently in ACE... + + * include: Added config files for AIX courtesy of Byron Walton + . + + * libsrc/Reactor/Signal.C: #ifdef'd out some code in Signal.[hC] + that was causing problems for the HPUX C++ compiler. What a + *horrible* compiler! + + * libsrc/Reactor/Event_Handler.h: Added two new methods to + ACE_Event_Handler: get_priority() and set_priority(). These + will be used to control the behavior of the ACE_Reactor's + dispatching. This also required added a new data member to + ACE_Event_Handler that stores the priority (which defaults to + MIN_PRIORITY). + + * libsrc/Misc/Stack.C (enqueue): Added a new class called + ACE_Unbounded_Queue. This is required for Tim's Token_Server + connection repository stuff... + + * libsrc/CORBA/CORBA_Handler.C: Added new support to both the + single-threaded and multi-threaded versions of CORBA_Handler so + that it will now suspend/resume the services associated with a + CORBA_Handler. + + * libsrc/CORBA/CORBA_Handler.C (ACE_MT_CORBA_Handler): Updated the + constructor to use the associated Thread_Manager to spawn a new + thread. This will allow the suspend() and resume() methods to + atomically resume and suspend the daemon thread and its event + handler. + + * libsrc/Threads/Synch.h: Fixed up the order of #includes to solve + problems with circular header dependencies! + + * Had to add zillions of little changes to avoid problems with + circular includes for G++... + + * tests/ASX/Event_Server/Event_Server/Peer_Router.C (bind_peer): + Fixed a typo that had been dormant for ages due to C++'s very + late binding of templates... G++ picked this right up! + +Sun Nov 19 11:55:02 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor/Signal: Replaced the static HANDLER_SET stuff + withing ACE_Sig_Handlers with a different implementation using + ACE_Fixed_Set. This should fix nasty problems with static + variables on HP/UX... + + * Fixed the entire library so that all occurrences of ace_log_msg + are changed to use the ACE_LOG_MSG macro. This macro has magic + properties that should greatly simplify the effort required to + compile ACE robustly on platforms with lame C++ compilers... + + * libsrc/Log_Msg/Log_Msg: Finally got my act together with respect + to thread-specific data and the ACE_Log_Msg class. The new + version can be conditionally compiled such that it won't use the + ACE_Thread_Specific smart-pointer wrapper mechanism unless the + platform supports thread-specific storage and threads. This + will make life much easier for lame C++ compilers that can't + handle static data member templates correctly... + + * apps/Name_Server/{client,server}/lib/Makefile (LIBS): Added a + reference to -lACE in the Makefiles of the ./lib directories in + order to get GCC to work correctly... + + * Added a bunch of fixes courtesy of Bill Lear + to make ACE compile more cleanly + with GNU GCC 2.7.x. + +Sat Nov 18 11:27:40 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Misc/Trace.C: Fixed up the ACE_Trace class so that it + will compile better on platforms that don't support + thread-specific storage. The trick was to make a new Singleton + called ACE_Nest_Depth and then conditionally compile it + according to whether the platform supports thread-specific data + or not! + + * include/makeinclude/platform_sunos5_g++.GNU: Added the new + config file that should allow ACE to build correctly with GCC + 2.7.x. Todd L. Montgomery deserves a big + round of applause for getting this stuff to work! If I had a + budget, I'd give him a raise ;-) + + * libsrc/Misc/Set.C (remove): Tightened up the semantics of all + the *Set::remove() methods so that they return 1 if they + succeed, 0 if the item isn't in the set, and -1 if they fail. + Thanks to Tim Harrison for noticing the inconsistencies. + +Fri Nov 17 01:34:51 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * apps/Logger/Reactor_Logger: Fixed up this example app so that it + would compile with GNU G++ correctly. There was a problem with + the order of include files! Thanks to Todd L. Montgomery + for reporting this. + + * libsrc/ASX/Module.C (writer): Fixed ACE_READER so that it is + properly qualified with ACE_Task_Flags::ACE_READER. Thanks to + Neil Cohen (nbc@metsci.com) for finding this! + + * apps/Gateway/Gateway/Routing_Entry: Replaced ACE_Fixed_Set with + ACE_Unbounded_Set to get around the seemingly endless problems + with HP/UX... + + * libsrc/Misc/Set: Fixed a braino in ACE_Unbounded_Set, where I'd + forgotten to define cur_size_. Thanks to Todd L. Montgomery + for reporting this. + + * libsrc/Connection/Acceptor.C: Change the #undefs of the + shorthand names PA_AC_1, PA_AC_2, and PA_AD in + libsrc/Connection/Acceptor.C to PR_AC_1, PR_AC_2, and PR_AD + (same as in Connector.C and Strategies.C). Thanks to + Dieter Quehl for reporting this. + +Thu Nov 16 02:14:22 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Misc/Trace: Fixed the ACE_Trace stuff by making the + "nesting_indent_" a static data member. This will undoubtedly + break some lame C++ compilers, but it's easy enough to remove + this stuff via conditional compilation using the ACE_NTRACE + #define in ./include/ace/config.h. + + * libsrc/Threads/Thread_Specific.C (cleanup): Under no + circumstances should ACE_Thread_Specific be allowed to + called ACE_Trace. Otherwise, chaos will result! + + * apps/Name_Server/{client,server}/tests/Makefile: Switched the + order of the -lACE and -lName* so that -lACE came *afterwards* + in order for the SGI linker to pick up the symbols correctly. + + * libsrc/Reactor/Signal: I'd accidentally put the "dump" methods + in the *.i file rather than the *.C file. This was causing + problems for G++. + + * libsrc/ASX/Task: Changed all "Q_" prefixes to "ACE_" prefixes in + order to work around a bug with HP/UX... + + * Recompiled everything on SunOS 4.x with SunC++ 4.0.1. It seems + to work! + +Thu Nov 16 18:05:03 1995 Tim H. Harrison (harrison@tango.cs.wustl.edu) + + * I moved around some class declarations so that g++ can properly + instantiate templates for ACE_Token_Collection and + ACE_Token_Manager. + +Wed Nov 15 00:26:40 1995 Tim H. Harrison (harrison@lambada.cs.wustl.edu) + + * The token library should now compile on platforms which do not + support threads. All token components will be compiled into the + library, but use null mutexes and condition variables. The + remote mutex library shall run properly on single-threaded + platforms, so it compiles as usual. + +Wed Nov 15 01:05:38 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Fixed a bunch of minor problems with the SGI port. Things + should work now on IRIX 5.3! + + * man/man3: Completely regenerated all the manual pages to + reflect all the recent updates. + + * libsrc: Added ACE_TRACE macros to every single method in ACE! + This will help with debugging... + +Wed Nov 15 00:26:40 1995 Tim H. Harrison (harrison@lambada.cs.wustl.edu) + + * The token library should now compile on platforms which do not + support threads. All token components will be compiled into the + library, but use null mutexes and condition variables. The + remote mutex library shall run properly on single-threaded + platforms, so it compiles as usual. + +Tue Nov 14 01:58:47 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * tests/CORBA: Added a new test to illustrate the + ACE_MT_CORBA_Handler. + + * libsrc/ASX/Task.C (ACE_Task_Exit): Fixed a niggling problem with + ACE_Task_Exit. Originally, if a thread exited via an implicit + ACE_Thread::exit() (i.e., "falling off the end of the + ACE_Task::svc_run function) then the ACE_Thread_Control on the + thread stack would automatically unregister the thread from the + ACE_Thread_Manager. However, this did *not* occur if a thread + explicitly called ACE_Thread::exit() since in that case the + destructor for ACE_Thread_Control never got called. The + solution to this is a trivial change to ACE_Task_Exit, which now + maintains an instance of ACE_Thread_Control internally, which + will automatically be released when the thread-specific + thread-exit-hook destructor gets called to cleanup upon thread + exit. Since this happens regardless of whether the thread + terminates implicitly or explicitly the ACE_Thread_Manager will + always be able to clean up it's internal resources (unless the + process exit()s, which is a whole different issue... ;-)). + + * Changed all occurrences of ACE_CORBA_Handler to + ACE_ST_CORBA_Handler. Now we've got two types of + CORBA_Handlers: single-threaded (ST) and multi-threaded (MT). + Take a look at ./apps/Orbix-examples/Event_Comm/{Supplier,Consumer} + for an example of how to leverage this in a portable manner! + + * libsrc/CORBA/CORBA_Handler: Totally redesigned the ACE + CORBA_Handler stuff so that it now uses the Singleton pattern + explicitly, rather than using the half-baked static method + version... Changed the test code to reflect this update! + + * libsrc/CORBA/CORBA_Handler.C (activate_service): Changed the + check so that if == 0 then we don't try to do a + putit (previously, this check used , which is less + useful...). + + * libsrc/CORBA/CORBA_Handler.C (activate_service): Removed the + flag from the constructor so that we can + make the CORBA_Handler and the MT_CORBA_Handler equivalent. + + * include/ace/sysincludes.h: Added a new macro called + ACE_THREAD_EXIT_HOOK that enables application threads + (including the main thread) to register a Task * who's + close method will automatically be called when the thread + exits, either implicitly (by falling off the end) or explicitly + (by a thread calling ACE_Thread::exit ()). + + * libsrc/ASX/Task: Moved ACE_Task_Exit into the interface part of + ACE_Task so that Irfan can maybe use this in his stuff ;-). + + * libsrc/Misc: Incorporated the ACE_Date_Time class into the + release. This is an *interface* for a system independent + representation of date and time. Implementation will follow... + + * libsrc/CORBA: Added a new MT_CORBA_Handler, which makes it + very straightforward to integrate the ACE_Reactor with + multi-threaded (MT) Orbix. + + * libsrc/Threads/Token.C: Yow, fixed a dumb problem in Tokens.C + where I was failing to include the *.i file if we weren't + compiling with inlining on!!!! + +Mon Nov 13 01:13:37 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/ASX/Message_Block: Added several new methods to + Message_Block to allow users to access and set various flags. + Thanks to Alex V Maclinvosky for + suggesting this and providing a prototype implementation. + + * include/ace/sysincludes.h: Added a new macro called ACE_NDEBUG + that can be used to toggle support for "live object dumping". + If this macro is enabled then + + * libsrc/Misc/Dump.h: Added support for "live object dumping" into + ACE. This technique is implemented with the "External + Polymorphism" pattern described in a paper available at + http://www.cs.wustl.edu/~schmidt/EuroPLoP-96.ps.Z. + + * libsrc/Threads: Added new classes called *_Process_* and + *_Thread_* for ACE_RW_Mutex, ACE_Barrier, ACE_Condition, and + ACE_Semphaore. This will allow programmers explicitly state the + scope of their locks more explicitly and will also facilitate + portability to Windows NT... + + * libsrc/Threads: Updated the constructors of all the Synch and + Synch_T classes to take an option const char * called "name." + At the moment, this doesn't do anything, but when we port to + Window NT it will be used to ensure that we can name our + process-global synchronization objects. + + * libsrc/Threads/Synch: Added a new tryacquire method to + ACE_RW_Mutex to be consistent with acquire and release... + + * libsrc/Threads/Synch.C (ACE_Mutex): Added a new "name" parameter + to an ACE_Mutex in order to support process-semantics on NT... + + * include/ace/sysincludes.h: Added a #define for EDEADLK in case + some systems don't support it (this is needed by the new + ACE_*_Token stuff). + +Sun Nov 12 14:17:01 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * apps/Name_Server: Modified the client and server test programs + so that they can both be linked statically and/or dynamically. + If svc.conf is present then dynamic linking is used, otherwise + static linking is used. This makes it much easier to test!!! + + * apps/Name_Server/client/lib/Naming_Context.C (local): Changed + things a bit so that if our server host name is "localhost" then + we assume we are local no matter what... + + * apps/Name_Server: Moved directories around a bit so that all the + tests and libs for the client/server portions of the + ACE_Name_Server build correctly... + + * apps/Name_Server/server: Replaced the ad hoc Name_Acceptor and + Name_Handler to use the official ACE_Acceptor and + ACE_Svc_Handler... This cleans up the code considerably... + + * libsrc/Threads/Synch: Added a new wrapper for the the UNIX file + locking mechanism called ACE_File_Lock. This has the same + interface as the other locking mechanisms (e.g., ACE_Mutex and + ACE_Semaphore). Therefore, it can be used in the ACE_Guard + class! + +Sat Nov 11 13:53:48 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Shared_Malloc/Memory_Pool: Improved MMAP_Memory_Pool so + that it will be smarter about remapping the file if we aren't + trying to force a fixed addr to be used for the mapping. In + particular, if we *aren't* forcing a particular address, the new + solution will be more flexible and allow the OS to determine + where to remap the memory should we need to grow the backing + store and the mapping range... + + * libsrc/Misc/Set: Implemented a simple version of the + Unbounded_Set class and its iterator. + + * libsrc/Misc/SString: Changed all the implementations of methods + in SString classes to use new/delete rather than + strdup()/free(). + + * apps/Name_Server/client/Name_Proxy: Changed rcv_reply() to + recv_reply(). + + * apps/Name_Server/client/Name_Proxy: Modified ACE_Name_Proxy so + that the constructor and open take an ACE_Synch_Options. + + * apps/Name_Server/client/Name_Options.C (ACE_Name_Options): Added + a default for the Name_Space directory called + (ACE_DEFAULT_NAMESPACE_DIR) to the testconfig.h file... + +Sat Nov 11 00:24:37 1995 Tim H. Harrison (harrison@lambada.cs.wustl.edu) + + * tests/Tokens/test_token_manager/test_token_manager.C: The token + manager has a working deadlock detection algorithm. + ACE_Local_Mutex uses this to report deadlock situations. + Changes were made to ACE_Local_Mutex to fix a couple bugs which + were causing deadlock. Also, a new test application has been + added to test deadlock detection using the local mutex. + +Fri Nov 10 17:16:06 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Mem_Map/Mem_Map.h: Changed the type of from + long to size_t. + + * tests/Threads/test_thread_manager.C (main): Added a main() for + the case when there's + + * tests/ASX/UPIPE_Event_Server/event_server.C (main): Fixed a + typo that was causing problems on SunOS 4.x. + + * tests/Service_Configurator/IPC-tests/client/local_spipe_client_test.C: + added #include "ace/Log_Msg.h" (why was this working?!). + + * include/makeinclude/rules.lib.GNU: Changed the order of operations + in rules.lib.GNU from + + $(AR) $(ARFLAGS) $@ $? + -$(RANLIB) $@ + -chmod a+r $@ + + to + + $(AR) $(ARFLAGS) $@ $? + -chmod a+r $@ + -$(RANLIB) $@ + + to keep ranlib happy on SunOS 4.x. + + * apps/Time_Server: Added a Makefile + + * include/ace/sysincludes.h: Removed the include + since it was causing major problems on SunOS 4.x... + + * apps/Name_Server/Naming_Context.C: Fixed up a couple of problems + with casts. Thanks to Jack Erickson for + pointing this out. + +Thu Nov 9 15:49:40 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Threads/Synch_T: moved Atomic_Op from ./Misc to ./Threads + and merged it into the Synch_T files. This makes more sense as + a place to put it... + + * libsrc/Misc/SString.C (operator +=): Fixed a typo that would + have caused mistakes when memcpy() was used. Thanks to Prashant + Jain for noticing this. + +Wed Nov 8 22:36:51 1995 Tim H. Harrison (harrison@lambada.cs.wustl.edu) + + * libsrc/Reactor/Reactor.C (TOKEN_GUARD): The reactor now uses the + TOKEN_GUARD macro. The Reactor can now be conditionally + compiled with ACE_REACTOR_HAS_DEADLOCK_DETECTION to use the new + ACE_Local_Mutex in conjunction with the ACE_Token_Manager to + detect deadlock. The deadlock detection algorithm has not yet + been implemented, but the hooks are now in place. + + * libsrc/Tokens: This subdir includes ACE's new Token library. + Check out libsrc/Tokens/README for more info. + + * tests/Tokens: There are a couple test applications for the new + Token library. See tests/Tokens/README for more info. + + * apps/Token_Server: This directory contains some new client + interfaces to the old ACE TokenServer, now Token_Server. There + are also some example use cases included in this directory. As + always, see apps/Token_Server/README for more info. + +Wed Nov 8 00:14:55 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP/IO_SAP: Added the new classes for IO_SAP from + Gerhard Lenzer (lenzer@csaserv.erlh.siemens.de). This + eliminates UNIX I/O-specific features from ACE. + + * libsrc/Misc/Set: Added a new find() method to each of the + ACE_*_Set classes... + + * include/ace/sysincludes.h (ACE_ALLOC_HOOK_DECLARE): Changed + enum __Ace { __ACE } to struct __ACE {}. I think this + will cause less problems with M.I... + + * libsrc/ASX/Message_Block: Added a new "allocator" parameter to a + Message_Block. This allows the memory stored by a Message_Block + to come from someplace besides the normal heap (e.g., a shared + memory segment!). + + * libsrc/ASX/Message_Block.C (ACE_Message_Block): Yow, fixed a bug + in the destructor where ACE_BIT_ENABLED was being used in place + of ACE_BIT_DISABLED! I think this was causing a memory leak... + + * libsrc/Reactor/Reactor: added a pair of methods that allow a + thread to set/get the notion of who "owns" the event loop. Only + the owner of the loop can do a handle_events() call. Also + changed things so that the requeue_position() are available for + both threaded and non-threaded implementations (just to have a + uniform interface...). + + * libsrc/ASX/Message_Block: added a new constructor and a new + init() method that just assume ownership of a char * passed + as the parameter. Note that this does *not* set any other + fields in the Message_Block and is only used to ferry around + totally opaque data in the Message Block! + +Tue Nov 7 00:52:15 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * tests/Log_Msg/test_log_msg.C (main): Added some new tests to + make sure that op_status() and errnum() work on ace_log_msg. + Thanks to Tim Harrison for these tests. + +Mon Nov 6 12:55:46 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Threads/Thread_Specific: Changed a couple of places in + the Thread_Specific code so that key_ is initialized to 0 and + the ts_obj * is initialized to 0. If these *aren't* 0 then + weird bugs happen on Solaris... Thanks to Tim Harrison for + noticing this and suggesting the fix! + + * libsrc/Threads/Synch_T: Added an accessor method to obtain + the underlying mutex within ACE_Condition. + + * libsrc/Threads/Synch.C (ACE_Process_Mutex): Added a dummy + argument of type const char * to ACE_Process_Mutex. This is in + anticipation of the info required in Windows NT to support a + named process-wide Mutex. On UNIX, this argument is ignored... + +Fri Nov 3 19:02:54 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP/SOCK_SAP: Back from C++ World... Fixed a couple + of typos in SOCK_Dgram_Bcast and SOCK_CODgram that included the + *.i files multiple times... Thanks to Alex V Maclinvosky + for reporting this. + +Tue Oct 31 02:12:13 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor/Reactor: Modifed the MT_SAFE Reactor so that the + its open() method keeps track of which thread originally created + it. This thread is then considered the "owner" of the Reactor. + If a different thread tries to run the handle_events() method + then an error is returned. + + * libsrc/ASX/Task.C: Added a "group id" field to the ACE_Task. + This can be used to suspend and resume a group of tasks + atomically. Also added default suspend() and resume() methods + that do just that! + + * libsrc/Reactor/Reactor: Made the open() method + thread-safe. Thanks to Detlef Becker (beckerd@erlh.siemens.de) + for pointing out the need for this. + +Mon Oct 30 00:02:53 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Shared_Malloc/Memory_Pool.C (ACE_MMAP_Memory_Pool): + Made it possible to configure the ACE_MMAP_Memory_Pool with a + (backing_store_) file name so that it is possible for multiple + processes to share one wellknown file, as well as to have + multiple pools per process. Check out the + ./tests/Shared_Malloc/test_malloc.C file for an example of how + this works (try the -p -e -L10000 -t3 options). + + * libsrc/Reactor/Reactor: Moved handler_i into the *.C file to + avoid problems with inline functions on HP/UX. + + * libsrc/Misc/SString: Added a new class called ACE_CString. This + class is similar to ACE_WString (which has "wide character" + size), though CString has regular "char" size. Note that both + of these classes are "true" string classes, unlike ACE_SString, + which is a very simple string class that is only to be used for + very specific purposes... + + * libsrc/Shared_Malloc/Memory_Pool.C (acquire): Fixed an + "off-by-one" error in ACE_MMAP_Memory_Pool::acquire() that was + causing an extra byte to be written to the backing store file... + This was causing the ./tests/Shared_Malloc/test_malloc.C program + to fail when -p was given. After this fix the test works + again... (thank God!). + +Sun Oct 29 22:43:25 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Shared_Malloc/Malloc: Added two new classes: + ACE_Allocator and ACE_Allocator_Adapter. ACE_Allocator uses + inheritance and dynamic binding to provide extensible mechanisms + for allocating and deallocating memory. ACE_Allocator_Adapter + implements the Adapter pattern to enable ACE_Allocator to be + used with instantiations of the ACE_Malloc<> template class. + +Sat Oct 28 13:51:07 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * tests/ASX/Event_Server: Added a new directory called + UPIPE_Event_Server, which tests a version of the Event_Server + that is instantiated with ACE_UPIPE_* IPC mechanisms, + rather than by the ACE_SOCK_* mechanisms. + + * libsrc/IPC_SAP/Addr: Created a new file called UPIPE_Addr.h. + This file contains a typedef of ACE_SPIPE_Addr to + ACE_UPIPE_Addr. The purpose of doing this is to "logically" + decouple the ACE_UPIPE* classes from the ACE_SPIPE* classes + (even though they share the same *physical* representation at + this point...). + + * libsrc/IPC_SAP: Fixed a small bug in TLI_Connector.connect() and + SOCK_Connector.connect() that failed to set the + new_stream::handle_ to ACE::INVALID_HANDLE when the connection + failed. Thanks to the ever-astute Mark Patton + (mark_patton@tx72.mot.com) for noticing this. + +Thu Oct 26 15:08:22 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * tests/Threads: created a new test program called + test_thread_manager.C that tests the new semantics for managing + groups of threads. + + * libsrc/Reactor/Signal.C (ACE_Sig_Action): Added a new method + that allows me to create a Sig_Action object that contains both + the handler and the signal to register for. This handler is + register to handle the signal in the constructor of the + object... + + * libsrc/Threads/Thread_Manager: enhanced the Thread_Manager to + add support for operations (i.e., suspend, resume, kill) on a + group of threads. + + * libsrc/Threads/Thread_Manager: Added a new method that allows + the Thread_Manager to resize itself automatically when it's + internal table gets full. + + * libsrc/Threads/Thread_Manager: Updated the return value of + Thread_Manager::spawn() and Thread_Manager::spawn_n() so that + they return -1 on failure *and the group id* on success. + Originally, they returned 0 on success, but this new return + value is more useful since it can be used to control groups of + threads atomically. + +Wed Oct 25 01:03:32 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * apps/Name_Server: Began integrating the newly donated name + server into ACE. There are a number of dependencies on + RogueWave that must be removed, but things are looking good so + far. + + * libsrc/Misc/Set: Changed the name of ACE_Unordered_Set to + ACE_Fixed_Set to be consistent with the ACE Stack classes... + + * libsrc/Misc/Set: Added new ACE classes called ACE_Unbounded_Set, + ACE_Bounded_Set, ACE_Unbounded_Set_Iterator, and + ACE_Bounded_Set_Iterator to deal with ACE name service + stuff. + + * libsrc/Misc/SString: Added a new class called ACE_WString that + gives a very simple "wide-character" string representation for + ACE. This is needed for the ACE name service stuff. + + * libsrc/Misc/SString.C (operator =): Fixed this so that ::strdup + is matched up with ::free, rather than with delete... + + * libsrc/Log_Msg/Log_Msg.C (log): Updated the ACE_Log_Msg class to + store an ostream * in thread-specific storage. This can be used + in conjunction with the dump() method on each ACE class, as well + as with the ACE_ERROR and ACE_DEBUG logging macros. + +Tue Oct 24 00:19:13 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Added a definition of the dump() method to every class in ACE in + anticipation of the changes requested for Siemens. + + * Changed all occurrences of ACE_Signal_* to ACE_Sig_* to make the + ACE naming of signal handling wrappers consistent. + + * libsrc/Threads/Thread: Fixed some obscure bugs with the way that + ACE_Thread was compiling on platforms that don't support + threads. + + * include/ace/config-irix*.h: Removed all TLI support from the SGI + platform. It seems to be totally screwed up from the tests that + I've run and there's no sense in bending over backwards to + support an IPC API that is brain-damaged to begin with... + + * apps/Logger/Service_Configurator_Logger/Thr_Server_Logger: Fixed + up the code so that the Thr_Logging_Server stuff will compile + correctly even for platforms that lack threads! + + * libsrc/Connection/Strategies: Added new strategies that provide + Singleton creation and Process concurrency policies. + + * libsrc/Connection/Connector.C (handle_close): Make sure that all + pending timer objects are removed from the Reactor's timer queue + when a Connector shuts down. In addition, make sure to remove + and delete all dynamically allocated ASTs, as well. Thanks to + Karl-Heinz Dorn (kdorn@erlh.siemens.de) for suggesting this. + + * libsrc/Threads/Thread_Manager.C (wait): Modified wait() so that + it now takes an ACE_Time_Value *, which can be used to wait + until all threads terminate or a timeout occurs... + + * libsrc/Threads/Thread_Manager: Moved Thr_Descriptor from within + the ACE_Thread_Manager class to become ACE_Thr_Descriptor at + file scope. This is in anticipation of the cool new thread + manager stuff on the way... + + * libsrc: Updated every class in ACE to include a "dump" method + with the signature "void dump (void);" This method soon will be + tied into the ACE_Dump mechanism to allow all live objects in + ACE to have their state dumped automagically on-demand. This is + useful for debugging and tracing etc. + + * libsrc: Updated every class in ACE to include a "Alloc hook." + This hook will enable all ACE classes to be allocated from a + particular memory pool. + + * include/makeinclude/rules.local.GNU: fixed the clean target to + delete the *.rpo files (else gcc -frepo can get some crazy + errors) and combines all rm-commands for the target realclean + into one command (in some cases the last two lines do not have + any files to delete, in which case rm produces an usage + message). Thanks to John Huchinson (hutchiso@epi.syr.ge.com) + for the patch. + + * libsrc/IPC_SAP/Addr/INET_Addr: Fixed all the uses of gethost* + and getserv* to use the reentrant get*_r functions if + ACE_HAS_REENTRANT_FUNCTIONS is set and ACE_MT_SAFE is set. + Thanks to Bill Tang for suggesting this. + + * libsrc/Misc/OS: Started adding support for the POSIX *_r + functions to the OS class. + + * include/ace: Added a new #define called + ACE_HAS_REENTRANT_FUNCTIONS. This indicates that the platform + supports reentrant functions (i.e., all the POSIX *_r functions + like gethostbyname_r). + +Mon Oct 23 21:15:50 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * include/makeinclude/platform_irix5.3.GNU (LIBS): Removed the + link of the nsl lib since it seems not to be present on this + platform. Thanks to Karel Zuiderveld + for noticing this. + + * libsrc/IPC_SAP/Addr/INET_Addr.i (operator ==): Enhanced the + semantics of comparison to check both the port number and IP + address. Thanks to Mark Patton (mark_patton@tx72.mot.com) for + suggesting this. + +Thu Oct 19 00:10:28 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP/Addr/INET_Addr.C (set): Fixed a stupid bug that + failed to set errno appropriately if things go wrong with this + method. Thanks to Mark Patton (mark_patton@tx72.mot.com) for + noticing this! + +Sat Oct 14 12:07:16 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Threads/Thread_Manager: Modified the Thread_Manager so + that even in the case where we are compiling for non-MT systems + the Thread_Manager still has the same method interface (all of + which are no-ops). + +Wed Oct 11 00:12:57 1995 Douglas C. Schmidt (schmidt@mambo.cs.wustl.edu) + + * Finished commenting all the classes in ACE. Updated all manual + pages accordingly. + +Fri Oct 6 14:17:17 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * tests/ASX/Event_Server/Event_Server: Changed + + ACE_SOCK_Acceptor &sa = (ACE_SOCK_Acceptor &) *this->acceptor_; + + to + + ACE_SOCK_Acceptor &sa = this->acceptor_->acceptor(); + + Thanks to Dieter Quehl (quehl@erlh.siemens.de) for suggesting + this. + +Thu Oct 5 00:22:56 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/ASX/Map_Manager: Added a new find() method to the + Map_Manager. This method only checks for the existence of an + EXTERNAL_ID, and doesn't return the INTERNAL_ID. + + * Introduced the new "trait"-based *_Connector, *_Acceptor, and + *_Stream interfaces for all the IPC_SAP classes. Basically, for + each class like + {SOCK,TLI,SPIPE,etc,}_{Acceptor,Connector,Stream}, there's now a + typedef for the appropriate type of ACE_*_Addr subclass and the + appropriate type of ACE_*_Stream class. For example, here's + what's in ACE_SOCK_Acceptor (same goes for ACE_SOCK_Connector): + + class ACE_SOCK_Acceptor + { + public: + // ... + + // = Traits. + typedef ACE_INET_Addr PEER_ADDR; + typedef ACE_SOCK_Stream PEER_STREAM; + }; + + Once C++ compilers can grok template typedefs correct, this new + approach will allow much greater simplification of code, so that + template classes like + + template + class ACE_Acceptor { /* ... */ + virtual int open (const PEER_ADDR &); + }; + + that are currently used like this: + + ACE_Acceptor acc; + + can be replaced with + + template + class ACE_Acceptor { /* ... */ + virtual int open (const PEER_ACCEPTOR::PEER_ADDR &); + }; + + that are used like this: + + ACE_Acceptor acc; + + i.e., the ACE_SOCK_Acceptor maintains a "trait" that the + ACE_Acceptor uses to determine the appropriate addr. This is + more concise and less error-prone than the current scheme that + requires you to pass into the ACE_INET_Addr separately (ugh). + + Note that the trick to making all this work is to typedef the + PEER_ADDR trait into the ACE_SOCK_Acceptor class, as follows: + + class ACE_SOCK_Acceptor { + public: + typedef ACE_INET_Addr PEER_ADDR; // Trait... + }; + + Unfortunately, none of the C++ compilers (e.g., SunC++ 4.0.1, + G++ 2.7.0) support this stuff yet... Therefore, I've added + a set of macros that that will toggle back and forth between + whichever approach works, depending on the setting of + ACE_HAS_TEMPLATE_TYPEDEFS. Hopefully, over time compilers will + support this stuff correctly and life will become easier. + + * libsrc/ASX/Message_Queue: Changed all occurrences of the S_MUTEX + and S_CONDITION macros to ACE_SYNCH_MUTEX and + ACE_SYNCH_CONDITION in order to conform to the new ACE namespace + control conventions. + + * libsrc/Connection/Acceptor: Modified the Acceptor class to split + it into two classes: ACE_Acceptor (which implements a very + simple, very concise version of the Acceptor pattern, without + all the extra strategy mechanisms, etc.). These strategies have + now been factored out into a new class called + ACE_Strategy_Acceptor. The point of these changes is to "keep + simple things simple, but enable powerful extensions when + necessary." All the test programs that utilized the earlier + strategy version of the Acceptor have been updated to the the + Strategy_Acceptor instead. + + * libsrc/Connection/Connector: added two new protected methods, + connect_svc_handler() and activate_svc_handler(). These methods + allow subclasses to override the Connector's strategies for + connection establishment and concurrency. In addition, it makes + the pattern much easier to explain via the Connector pattern and + also is more similar to the Acceptor. + +Wed Oct 4 18:45:58 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * apps/Orbix-Examples/Event_Comm: Fixed the examples in this + directory so that they compile with the new ACE. + +Tue Oct 3 17:33:46 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * include/makeinclude/rules.nested.GNU: Added support so that + ACE can now be built in parallel using the -jN option of GNU + make. To accomplish this, just type + + % make MAKEFLAGS=-j2 + + on the command line and the "-j2" flag will be passed through to + the make hierarchy. Once the SunC++ compiler supports parallel + makes correctly (Template.DB causes problems) this will allow me + to tke advantage of my new dual-CPU SPARCstation 20!!! + +Mon Oct 2 13:34:14 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Connection: Cleaned up some of the code related to + Time_Values * by adding a new method call time_value() to the + ACE_Synch_Options class. + + * libsrc/Service_Config/Service_Record: Changed things a bit so + that we don't have to include "ace/Stream.h" in + Service_Record.h, but instead use forward decls of the + appropriate types. This breaks a circular dependency that was + causing problems for GNU C++. Thanks to John Hutchinson + (hutchiso@epi.syr.ge.com) for finding this problem. + +Sat Sep 30 13:45:08 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Changed all uses of typedef PARENT to inherited, which is less + obtrusive. + +Fri Sep 29 01:33:54 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Misc: Completed the new OS class, which will be used + shortly to remove all direct UNIX system calls in ACE. + + * libsrc: Completed redocumented the header files for almost all + of ACE. The goal was to document all the methods in all the + classes. This has most been achieved (only a few minor changes + remain). The result is *much* better manual page entires in + ./man/man3, as well as much more consistent header files and + overall documentation for ACE. + + * libsrc/Reactor/Reactor: Changed all uses of get() to + handler_i(). Also changed the check_connections() method to + check_handles(). Note that all these changes are invisible to + apps... + +Thu Sep 28 01:22:36 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP/Addr/SPIPE_Addr: Changed all occurrences of + {get,set}_user_id() and {get,set}_group_id() to user_id() and + group_id() in order to be more consistent with other parts of + ACE. + + * libsrc/ASX/Task.C (module): Modified the implementation of + several Task helper methods (e.g., sibling()) so that they don't + crash if there is not Module associated with the Task. + + * libsrc/ASX/Stream: Removed the sync_ data member from the + private part of Stream since it didn't seem to be used for + anything. + + * libsrc/ASX/Map_Manager.C (bind): Changed the type of the INT_ID + to bind() from INT_ID to const INT_ID &. + + * libsrc/IPC_SAP/Addr/Addr: Moved some methods around in the *.i + file to the *.C file in order to be smarter about inlining. + + * libsrc/Misc/Auto_Ptr.h: Added a new pair of classes called + "auto_ptr" and "auto_array_ptr". These implement the ANSI/ISO + C++ standard auto_ptr mechanism, which helps to write + exception-safe code. The code is based on material from Jack + Reeves (jack@fx.com) and Dr. Harald M. Mueller + (mueller@garwein.hai.siemens.co.at). + + * libsrc/Threads/Synch_T.h (ACE_Null_Condition): Changed the + behavior of Null_Condition::{signal,broadcast} so that they + return 0 rather than setting errno = ETIME and returning -1. + +Wed Sep 27 00:16:01 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Threads/Synch: Fixed a bug with class ACE_Barrier: count_ + wasn't being set properly. + + * tests/Threads/test_barrier.C (main): Fixed a stupid bug + in the ACE_Barrier -- the main function was exiting, thereby + destroying the barrier! + + * tests/IPC_SAP/{SOCK,TLI}_SAP: Added test cases to exercise the + new reuse_addr feature of SOCK_Connector and TLI_Connector. + + * libsrc/IPC_SAP/{SOCK,TLI}_SAP/{SOCK,TLI}_Connector: Implemented + the new behavior for reusing a local address. Also fixed a few + error cases that would have lead to descriptor leaks. + + * libsrc/IPC_SAP/SOCK_SAP/SOCK.C (open): Modified a few return + values and comparisons to ease the transition to WIN32. + + * libsrc/ASX/Task.C (ACE_Task): Changed the behavior of + Task::activate() so that it uses the + ACE_Service_Config::thr_mgr() Singleton if no thread manager has + been associated with a Task when it becomes an active object. + + * libsrc/Service_Configurator/Service_Config: Added a new static + method to class Service_Config called thr_mgr(). This static + method behaves as a "Singleton" and provides a convenient + default thread manager that is available to all threads + throughout a process. + + * libsrc/IPC_SAP: Changed all the IPC_SAP/*_SAP/*_Connector.[hiC] + files and the Connection/Connector.[Chi] class in order to add + "reuse_addr" behavior consistent with the Reactor. This enables + the client to specify that the "local_addr" should be reused + (e.g., via SOCKREUSEADDR), even if its "2 minute wait" time + hasn't elapsed yet. The libsrc/Connection/Connector.[Chi] files + were also changed to support this new interface. + + * libsrc/Log_Msg/Log_Msg.C (log): Fixed a mistake in Log_Record + caused by the new thread-safe storage enhancement. The data + being logged was being rounded up incorrectly. Thanks to Daniel + Proulx (daproulx@qc.bell.ca) for reporting this. + + * libsrc/Reactor/Signal.i (operator): Made a minor change to the + definition of operator struct sigaction * to work around a bug + with the HP/UX C++ compiler (lame, lame, lame)... + + * libsrc/Service_Config: Changed all occurrences of + ACE_Service_Config::reactor (which was originally a globally + accessible public method of class ACE_Service_Config) to + ACE_Service_Config::reactor () (i.e., made the reactor a + Singleton implemented by a static method). This was long + overdue and will fix all sorts of niggling problems with order + of initialization since the reactor() method can do "lazy + creation" of Reactors now, i.e., create one the first time it is + referenced. In addition, changed the + ACE_Service_Config::svc_rep to ACE_Service_Config::svc_rep () in + the same manner. + + * Changed all occurrences of the form: + + *_Stream stream; + *_Connector con (stream, remote_addr); + + if (stream.get_handle () == ACE::INVALID_HANDLE) + ... + + To + + *_Stream stream; + *_Connector con; + + if (con.connect (stream, remote_addr) == -1) + ... + + which is cleaner and less error prone with respect to + UPIPE_Stream (which doesn't have a valid handle once it's + connected). + + * Changed all occurrences of get_handle () == -1 to get_handle () + == ACE::INVALID_HANDLE to help smooth the move to WIN32... + + * libsrc: Created a new directory called Shared_Memory and moved + the Shared_Malloc_MM and Shared_Malloc_SV classes from the + ./Shared_Malloc directory to here, where they are now called + Shared_Memory_MM and Shared_Memory_SV. This is a better + name/place for them since they never really had anything to do + with malloc in the first place! What remains the Shared_Malloc + is the Malloc.* and Memory_Pool.* classes, which are typically + used for truly shared malloc/free. + + * apps/Gateway/Gateway: added new logic to the Gateway to enable + it to specify which local port to bind() to. + +Tue Sep 26 21:17:29 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Connection/Strategies.C (open): Added a return 0; at the + end of the ACE_Thread_Strategy::open method. + + * tests/Service_Configurator/IPC-tests/server/Handle_Thr_Stream.C: + Made CLI_Stream a template so that we don't have to worry about + multiple includes of classes... + +Mon Sep 25 01:41:27 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP: Revised the close() method of TLI_SAP and + SOCK_SAP so that they don't try to close down a handle that == + ACE::INVALID_HANDLE. + + * Changed all uses of ::free ((char *) ...) to ::free + (ACE_MALLOC_T (...)) to work around inconsistent prototype + problems with some compilers. + + * include/ace/sysincludes.h: Changed ACE_MALLOC_TYPE to + ACE_MALLOC_T which is a bit less verbose... + + * libsrc/Service_Configurator/Makefile (BUILD): Fixed the argument + to sed from -s (which is invalid) to -e (which is valid). + Thanks to Doug Ritter (dougr@guilder.datalytics.com) for + noticing this. Also used sed to do a more elegant fix on the + age-old problem of inconsistent prototypes for free() and + realloc()... + + * libsrc/IPC_SAP/UPIPE_SAP: Rewrote all the UPIPE_* classes to + remove any dependencies on class UPIPE. This class appears to + be unnecessary since it mimics the behavior of class SPIPE. To + simplify the behavior of the UPIPE_* classes, they now inherit + from the SPIPE_* classes where appropriate. + + * libsrc/IPC_SAP/UPIPE_SAP: Changed the semantics of the + UPIPE_Connector and UPIPE_Acceptor connection methods so that + they close down the SPIPE_Stream after a connection is + established successfully. This is important to conserve + descriptors. + + * libsrc/Misc: Created a new class called OS, which encapsulates + *all* of the UNIX system calls and library routines within a + single class. The rest of ACE will program only to the methods + in this interface, which will make it much easier to port to + other versions of UNIX (and WIN32!). + +Sun Sep 24 11:49:47 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP/SOCK_SAP: Conditionally compile the LSOCK_* stuff + if the OS platform (e.g., Linux) doesn't support it. + + * Changed all occurrences of ACE_HAS_NO_... to ACE_LACKS_... in + all the config*.h files and the headers/source. This reads + better... + + * Changed all uses of (1) Acceptor::peer_acceptor_ to + Acceptor::acceptor(), (2) Svc_Handler::peer_ to + Svc_Handler::peer(), and (3) Connector::peer_connector_ to + Connector::connector() to make the code more abstract and + resilient to future changes. + + * include/ace/sysincludes.h: Added a new macro called + ACE_NEW_RETURN that provides a useful abstraction for + expressions involving operator new since we can change memory + allocation error handling policies (e.g., depending on whether + ANSI/ISO exception handling semantics are being used). + + * libsrc/Threads/Thread.C: Changed things a bit so that if + ACE_MT_SAFE == 0 then Thread::self() returns 1, regardless of + whether the platform supports threads. + + * Went through the entire library and (hopefully) made sure that + all calls to global system calls and library routines are + prefixed with "::". + + * libsrc/Misc/Get_Opt.C: Changed this class to use the Log_Msg + logging mechanism rather than stderr... + + * tests/Misc: Added a new test program to test the Profile_Timer. + + * tests/Reactor/misc: Added a new test program to test the + Handle_Set. + + * libsrc/Service_Configurator: Changed the error messages in + Svc_Conf.y and Svc_Conf.l to go to the ACE Log_Msg logging + mechanism rather than stderr... + + * libsrc/Connection/Acceptor: Modified the Acceptor and + Oneshot_Acceptor classes so that they take advantage of the new + ACE_Creation_Strategy, ACE_Accept_Strategy, and + ACE_Concurrency_Strategy components. This will make is easy to + define Acceptors that can be flexibly configured to use various + creation strategies (e.g., dynamic linking, singletons, dynamic + memory creation, etc.) for making Svc_Handlers. + + * libsrc/Connection/Svc_Handler: Added several new classes -- + ACE_Creation_Strategy, ACE_Accept_Strategy, and + ACE_Concurrency_Strategy -- that form the heart of the new + ACE_Acceptor implementation. These classes define the creation, + passive connection acceptance, and concurrency strategies + employed by the Acceptor factory when it receives a connection + from a client. + + * libsrc/Connection/Acceptor: Modified the implementation of the + Acceptor and the Oneshot_Acceptor. These classes are no longer + related by inheritance since they behave in fundamentally + different ways and sharing code was making it hard to write and + use these classes correctly. + + * libsrc/Misc/Misc: Moved the enum INVALID_HANDLE from IPC_SAP.h + to Misc.h since this is actually more general than just the + sockets stuff and we need to be portable to WIN32... Therefore, + any code that originally said ACE_IPC_SAP::INVALID_HANDLE should + now be ACE::INVALID_HANDLE. + + * Removed the ACE_OMIT_SERVICE_CONFIGURATOR flags. These are + annoying -- anyone who wants to subset ACE should be responsible + for doing this stuff. + +Fri Sep 22 22:36:33 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Threads/Thread_Spawn.C: Greatly simplified the + implementation of Thread_Spawn by leveraging the new class Task + semantics for activate(). Now, all the concurrency activation + mechanisms necessary to create active objects are associated + with a Task and all the Thread_Spawn needs to do is to define a + new make_svc_handler() Factory Method to create a SVC_HANDLER + and activate it! + + * libsrc/ASX/Task.C: Tightened up the semantics of Task::activate + (which turns a passive object into an active object, i.e., one + with its own thread). Now, if an object is activated more than + once it ignores the other requests, unless the force_active + parameter is enabled. Moreover, activate() now takes a + parameter that indicates the number of threads to allocate for + the Task. This makes it simple to have a "thread pool" + associated with a Task. + +Thu Sep 21 00:49:55 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * tests/Connection: Updated the CPP-acceptor and CPP-connector to + use the underlying Acceptor and Connector patterns more + robustly. Also added new hooks to include a Service_Config + component so that integrating this with the ACE dynamic linking + scheme will be a snap! + + * libsrc/Connection/Acceptor.C: Revised the Oneshot_Acceptor to be + robust in situations where it isn't given a Reactor *... + + * apps/Logger: Fixed a couple of minor problems with *.i files + being included when __INLINE__ is set. This should help G++ + compiler ACE better... + + * libsrc/Reactor/Reactor: Enhanced the Reactor::notify() method so + that it takes both an Event_Hander * and a Reactor_Mask, which + it passes to the Reactor's main event loop thread via the pipe. + The event loop thread uses this mask to determine which method + to invoke. This new feature is due to the insight of Karl-Heinz + Dorn (kdorn@erlh.siemens.de). + + * libsrc/Connection/Connector: Fixed a braino in + Connector::handle_output, which was using ::getpeername() to + check whether a connection has been established with a peer. + Naturally, this only works for sockets, and doesn't work at all + for TLI or SPIPEs... + + * libsrc/IPC_SAP/Addr/SPIPE_Addr.C (set): Changed the return type + of this method to "int" in order to conform to the types + expected by the Acceptor/Connector patterns. + + * Removed all uses of the global scope "::" for all variables and + methods that are not UNIX system calls or library calls in + preparation to change over to the new OS class (requested by + Siemens). + +Wed Sep 20 14:39:08 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP/SPIPE_SAP: Renamed the SPIPE_IO classes to + SPIPE_Stream to be consistent with the other parts of the ACE + library. Updated all parts of the library to reflect this + change. + + * tests/Service_Configurator: Moved the current contents of this + directory into a new directory called IPC-tests. Created a new + directory called Connection-tests where the dynamic linking + examples for Siemens will go. + + * libsrc/Reactor/Signal: Made a bunch of minor changes to support + signal handling on SunOS 4.x platforms. Thanks to Aniruddha + Gokhale for help with this. + + * libsrc/Threads/Synch.h: Modified the #ifdefs a bit so that + Synch_T.h gets included regardless of whether ACE_HAS_THREADS. + + * libsrc/Threads/Synch_Options: Added a new set() method to make + it possible to initialize the Synch_Options from outside the + constructor. + + * libsrc/Connection/Svc_Handler.C: Added checks within the + ACE_Svc_Handler so that if we are given a NULL Reactor we don't + crash! + + * libsrc/Mem_Map: Tidied up this class and added comments to the + header so that the class2man has something to generate manual + pages from! + + * libsrc/Misc/Misc: Added a new method called "round_to_pagesize", + which was previously in Mem_Map. This is a better place for it + since other parts of ACE (e.g., Shared_Memory) use it. + + * libsrc/Misc/Misc: Added a new method called "get_file_size", + which was previously in Mem_Map. This is a better place for it + since other parts of ACE might want to use it. + +Tue Sep 19 00:24:41 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released a beta version of ACE 3.3.1 for G++ testing. + + * libsrc/IPC_SAP/SOCK_SAP/SOCK_Dgram.C: Removed a stray INLINE + that was causing problems for G++. Thanks to E. Jason Scheck + for reporting this. + + * libsrc/IPC_SAP/Addr/INET_Addr: Improved the documentation for + this class and also added new semantics to the constructor and + set() method so that a "ip_addr:port_number" tuple can be given + as a single string (e.g., "1234:tango.cs.wustl.edu" or + "1234:128.252.166.57"). This is useful since it gives a uniform + interface for addressing for Internet domain, UNIX domain, and + SPIPE domain addresses... Updated the ./tests/Connection tests + to use this form (which is nice since now they are all very + orthogonal!) + + * tests/Connection: Created a whole new suite of tests that + exercise the connection patterns for all of the relevant IPC + mechanisms (e.g., SOCK_SAP, TLI_SAP, SPIPE_SAP, and UPIPE_SAP). + + * bin/clone.C: fixed the first #include so that it uses #include + "ace/sysincludes.h". Thanks to Alex V Maclinvosky + for noticing this. + +Mon Sep 18 01:52:07 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/ASX/Message_Queue.C (close): Fixed yet another problem + with variables being defined in for loops. G++ is good for + detecting this ;-). + + * libsrc/Threads: Moved all the template classes from Synch.* into + Synch_T.* in order to make it possible to compile templates with + G++. Thanks to E. Jason Scheck for suggesting + this. + + * libsrc/IPC_SAP/UPIPE_SAP: Make a number of changes to ensure + that all the UPIPE_SAP classes conform to the same interface as + all the other ACE IPC classes. + + * Changed all occurrences of THR_FUNC to ACE_THR_FUNC to protect + the global namespace better. + +Sun Sep 17 13:36:23 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * tests/ASX/Message_Queue: Fixed a typo in these test programs + that caused a segfault since a vararg parameter was omitted on a + call to the Log_Msg::log() method. Maybe iostreams isn't so bad + after all... ;-) + + * apps/Logger/Service_Configurator_Logger/Thr_Server_Logger: fixed + a stupid error that was caused by some mods I made after ECOOP + to update the threaded logging server. When I changed the + Thr_Logging_Acceptor so that it no longer inherited from the + Logging_Acceptor I forgot to redefine the init() method... + + * man: Totally regenerated the ACE manual pages using the new + versions of the OSE tools provided by Karl-Heinz Dorn + (kdorn@erlh.siemens.de). + + * Changed all occurrences of MT_SYNCH and NULL_SYNCH to + ACE_MT_SYNCH and ACE_NULL_SYNCH, respectively. This is + consistent with the ACE naming conventions and had been an + oversight when I renamed everything earlier. + + * Fully built and tested ACE with the __INLINE__ flag enabled. + This will generate code with many small methods in the library + inlined. Had to fix a bunch of minor things to allow this to + work without compilation-order dependency problems. + + * libsrc: Made a bunch of changes to the way that header files are + included internally to ACE in order to break compilation-order + dependencies. This is necessary to support GNU G++'s lame + handling of templates. None of this stuff should affect + application code. + + * tests: Added a whole new slew of tests for the remaining parts + of ACE that weren't currently included in ./tests. This stuff + exercises ACE components like the Log_Msg logger and factors all + the #if defined (DEBUGGING) code out of the ./libsrc directory + tree and puts it in the ./tests directory tree, where it + belongs. + + * Changed all uses of the error macros LM_* to ACE_* in order to + avoid name collisions with other libraries, frameworks, and + toolkits. In addition, changed all uses of the error enumerals + LOG_ to LM_ in order to avoid a conflict with system #defines in + . + + In order to change these automatically, I used the following + UNIX command sequence: + + % find . -type f -print | xargs perl -p -i -e 's/LM_/ACE_/g' + % find . -type f -print | xargs perl -p -i -e 's/LOG_/LM_/g' + +Sat Sep 16 11:55:18 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * tests/Threads: Added a new test for Thread_Specific storage. + + * Added a new platform/compiler configuration flag called + ACE_TEMPLATES_REQUIRE_SOURCE that must be set for compilers + (e.g., GNU G++) whose template mechanism must be able to + see the source code (i.e., the *.C files). Changed *lots* of + header files to enable this... Also had to change the + corresponding *.C files so that they wouldn't get included + twice... + + * libsrc/Connection: redid the implementation of Acceptor, + Connector, and Svc_Handler to get more control over the scope of + #defines like #define SH SVC_HANDLER, etc. + + * libsrc/Threads/Thread_Spawn: Totally redid the implementation of + Thread_Spawn to use the Acceptor class template. This greatly + reduces the amount of code to implement the Thread_Spawn! + + * libsrc/Threads/Thread_Spawn: Moved the Thread_Spawn + implementation into the ./libsrc/Threads directory rather than + in the ./libsrc/Service_Configurator directory since it deals + with threading and thus belongs in the other place. + +Fri Sep 15 00:25:51 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Threads/Token.i (tryacquire): Added a cast to fix passing + a const pointer to a function that was expecting a non-const. + Thanks to E. Jason Scheck for reporting this. + + * libsrc: Added a bunch of changes to enable G++ to compile ACE. + A lot of this involves moving around info in header files so + that templates can be dealt with using the relatively lame GNU + C++ repository scheme. Thanks to E. Jason Scheck + for all his help in this. + + * libsrc/Synch: created Synch_Options.C out of Svc_Handler.C, so + that Svc_Handler.C could be "template pure"; all the other files + were already separated. Thanks to E. Jason Scheck + for recommending this. + + * Makefile (clone): Added a tiny fix that solves a weird problem + that arises with symbolic links on HP/UX. Thanks to Jam Hamidi + (jh1@osi.com) for tips on how to fix this. + +Thu Sep 14 10:55:30 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * apps/Gateway/Gateway/Channel.C (route_message): Updated the main + routing code to check for whether a channel is_active() + (i.e., is actually connected) before trying to send messages + to it. This was originally done in the Set class iterator, but + I revised that to make it more reuseable and to workaround bugs + in the HP/UX compiler so I had to update the main code... + + * libsrc/Threads/Thread_Specific: Added a new method to called + ts_object () to class ACE_Thread_Specific that get the + thread-specific object for the key associated with this object. + Returns 0 if the data has never been initialized, otherwise + returns a pointer to the data. This is useful since now you can + query a thread-specific storage mechanism to see if there's ever + been a thread-specific object created *without* having to + actually create one if one hasn't been created yet! Thanks to + Detlef Becker (beckerd@erlh.siemens.de) for pointing this out. + + * include/makeinclude/platform_sunos5_sunc++_orbix.GNU (LIBS): + Changed the default compilation strategy for SunOS 5.x machines + to use -mt. This seems to be necessary to build robust + libraries that are thread-safe. Thanks to Phil Mesnier + and Chris Cleeland + for hounding me until I changed the + existing solution. If you *don't* want this behavior you need + to remove -mt from the platform_macros.GNU file and and remove + the ACE_HAS_THREADS and ACE_MT_SAFE flags, etc. from the + config-sunos5.*.h files. + + * libsrc/Shared_Malloc/Memory_Pool.C (ACE_MMAP_Memory_Pool): Added + a new parameter to the constructor called write_each_page that + if enabled forces a write to each page to ensure that space is + allocated from the file system (otherwise, we can end up failing + due to optimisitic resource allocation...). Thanks to Phil + Brooks for detecting this issue and + implementing a solution. + + * include/ace/sysincludes.h: Added #ifdef support for HP/UX, which + fails to properly wrap with an extern "C" block. + +Mon Sep 11 01:39:35 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Connection/Connector.C (handle_input): Changed the call + to Svc_Handler::close() to accept the default value of 0 rather + than -1... Thanks to Mark Seaborn + for noticing this. + + * libsrc/Connection: Changed all uses of ADDR to PEER_ADDR to + avoid a name clash in Linux... Thanks to James Morris + for finding this. + +Sun Sep 10 03:56:18 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Threads/Synch: Added support for "barrier + synchronization" to ACE in the form of ACE_Barrier. Thanks to + Bruce Worden (bruce@betsy.gps.caltech.edu) for suggesting this + and pointing me in the right direction. + + * tests/Threads: Added a test for the new barrier synchronization + mechanism. + +Sat Sep 9 11:58:16 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor/Reactor: Changed Reactor::max to Reactor::max3 to + avoid problems with conflicting names of macros in Sun header + files! + +Mon Sep 4 14:34:52 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor/Signal: The new ACE_Signal_Handlers mechanism + appears to be working! There's a test in ./tests/Reactor/misc + called test-signal.C that illustrates how all this works. + + * libsrc/Reactor/Signal: Added several new methods to + ACE_Sig_Action to make life easier to implement the new + ACE_Signal_Handler code... + + * libsrc/Reactor/Signal.C (ACE_Sig_Action): Changed the order of + the arguments to the ACE_Sig_Action constructor. It's almost + always the case that you want to vary the SignalHandler, but + only rarely do you want to vary the mask or flags. By + reordering this, it's easier to get the correct default values + without adding extra junk... + +Mon Sep 4 01:11:29 1995 Tim Harrison (harrison@tango.cs.wustl.edu) + + * libsrc/IPC_SAP/SOCK_SAP/SOCK_Dgram_Multicast: added support to + allow a port to be reused for multicast sockets. This is useful + if you are multicasting to multiple processes, some of which are + on the same host! + + * libsrc/ASX/Map_Manager: Fixed an odd bug that must have gone + undetected for a long time somehow. Basically, the "is_free_" + field of the ACE_Search_Structure struct was never being set to + it's correct initial value of 1. I don't know how this didn't + surface before... At any rate, it is fixed now... + + * include/ace/sysincludes.h: Changed the inline methods for + SET'ing and CLR'ing bits to be macros in order to get cheap + polymorphic behavior... Also changed them to use the prefix + "ACE_" to avoid namespace pollution. Changed all dependencies + in the source code (only a few...). + + * libsrc/Reactor/Signal: Added a new class called + ACE_Signal_Handlers, which subclasses from ACE_Signal_Handler. + This new class implements the semantics required for Siemens. + For example, this class allows multiple signal handlers to be + registered for the same signal. It also makes SA_RESTART the + default mode. Note that by default, the Reactor uses the + original ACE_Signal_Handler semantics. If you want the new + semantics, simply pass the Reactor a pointer to + ACE_Signal_Handlers. + + * include/ace/sysincludes.h: Removed the automatic inclusion of + ./libsrc/Misc/Misc.h from sysincludes.h since this was causing + problems with include file ordering. + +Sun Sep 3 00:22:11 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor/Signal.C (remove_handler): Moved a definition of + ACE_Sig_Action out of an inner block to avoid portability + problems. + + * libsrc/ASX/Map_Manager: Improved the documentation of this class + and fixed up a couple of problems with the scope of loop + indexes. + + * libsrc/Misc/{Stack,Set}: Added this new file that contains a set + of Stack and Unordered Set implementations. The Unordered Set + is used in various places in ACE (e.g., libsrc/Reactor/Signal + and apps/Gateway/Gateway/Routing_Entry). + + * libsrc/Log_Msg/Log_Msg: Moved the definition and declaration of + Thread_Specific ace_log_msg from this directory to + ./libsrc/Misc/Misc.h in order to cleanup the namespace and also + to help make this work on DEC platforms... + + * libsrc/Reactor/Signal: Changed ACE_Signal_Handler from a static + class to a non-static class in order to allow subclassing. This + is necessary to support the Siemens requirements. + + * libsrc/Shared_Malloc/Memory_Pool: Modified ACE_MMAP_Memory_Pool + so that it no longer stores the name of the backing store in a + static character array (which made it impossible to have more + than one of these at a time...). The new version stores the + name in each ACE_MMAP_Memory_Pool object. It also selects a + name that won't conflict with other names by using ::mktemp. + + * tests/Shared_Malloc/test_malloc.C (parse_args): Fixed two stupid + omissions of "break" when parsing command-line arguments. Isn't + C++ great?! (NOT)... + + * apps/Synch-Benchmarks: Came up with a killer solution to the + nagging problem of POSIX Pthread's lack of an integral thread id + (a la Solaris threads thr_self()). The solution leverages off + of our new ACE_Thread_Specific wrapper to provide the necessary + functionality. Thanks to Reginald S. Perry (perry@zso.dec.com) + for triggering the thoughts that lead to this solution... + +Sat Sep 2 17:00:46 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP/TLI_SAP/TLI_Acceptor: Changed the implementation + of ACE_TLI_Acceptor so that ACE_TLI_Request is defined inside + the TLI_Acceptor.C file (this is the so-called "Cheshire Cat" + technique). This clean up the code and the global namespace a + bit. + +Fri Sep 1 00:53:47 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released new version of ACE 3.3 + + * libsrc/IPC_SAP/UPIPE_SAP/UPIPE.C: Fixed a small problem with + failing to #ifdef this file correctly if we don't have + threads... Thanks to John Morey (jmorey@hitel.com) for + reporting this. + + * tests/ASX/CCM_App/svc.conf: Fixed the svc.conf file so that it + looked in the .shobj directory rather than the .obj directory. + + * Released new version of ACE 3.2.9... + + * libsrc/Log_Msg/Log_Msg: Added a new field called "restart_" to + the thread-specific storage. This will be used to control + whether system calls are restarted when interrupted. + + * Changed inheritance syntax from + + class xxx + : public yyyy + { + }; + + to + + class xxx : public yyyy + { + }; + + so that the OSE tools would work correctly. + +Thu Aug 31 00:12:40 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP/UPIPE_SAP: Changed all uses of UPIPE_Addr to + SPIPE_Addr since they were the same thing. This also allows + much reuse of code... + + * libsrc/IPC_SAP/{TLI_SAP,SOCK_SAP,SPIPE_SAP}: fixed the + "complete" method for these classes so that it uses the new + ACE::handle_timed_complete() method in libsrc/Misc. This cleans + up the code by merging common logic. + + * libsrc/IPC_SAP/{DEV_SAP,FILE_SAP,SPIPE_SAP}: fixed the "connect" + method for these classes to conform to the API used by the + SOCK_SAP and TLI_SAP wrappers. In addition, cleaned up the code + so that common logic was pushed into a new method in libsrc/Misc + called ACE::handle_timed_connect(). + +Wed Aug 30 00:20:18 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Connection/Acceptor.C (open): Fixed this method so that + it returns a value on all paths through the code... + + * libsrc/IPC_SAP/TLI_SAP/TLI.C (ACE_TLI): Moved the option + allocation code from the TLI::open() method into the TLI + constructor in order to make sure it is always called! + + * libsrc/IPC_SAP/DEV_SAP/DEV_Connector: Changed the signature of + the DEV_Connector::connect method to allow users to specify + flags, permissions, and timeouts (this is now consistent with + other parts of ACE). + + * libsrc/IPC_SAP/FILE_SAP/FILE_Connector: Changed the signature of + the FILE_Connector::connect method to allow users to specify + flags, permissions, and timeouts (this is now consistent with + other parts of ACE). + + * tests/IPC_SAP/TLI_SAP: Updated the test code to check the new + timer support for connection establishment. + + * libsrc/IPC_SAP/TLI_SAP: Updated the code to make it conform to + the interfaces provided by SOCK_SAP. This primarily affected + the TLI_Acceptor and TLI_Connector classes in order to add + support for timed connects and accepts. + + * libsrc/Reactor/Signal.C: Modified Signal_Handler::dispatch so + that it saves/restores errno to prevent it from being corrupted + by the handle_signal callback. Thanks to Detlef for suggesting + this. + + * libsrc/Shared_Malloc/Memory_Pool: Changed the name of + ACE_Local_Memory_Pool to ACE_Sbrk_Memory_Pool. Then added a new + version of ACE_Local_Memory_Pool that uses the C++ operator new + to acquire chunks of memory. This enables the ACE Malloc class + to integrate with existing programs that use new/delete. Thanks + to Karlheinz for suggesting this. + + * libsrc/IPC_SAP: Added the UPIPE mechanism donated by SIEMENS. + This provides an intra-process IPC mechanism that has the same + API as the interprocess and network mechanisms. + + * Reran catman on ./man/windex. Thanks to Dieter Quehl + (quehl@csaserv.erlh.siemens.de) for reporting the need for this. + + * Released new version of ACE 3.2.9... + + * tests: Fixed a bunch of minor problems that occurred when + building on HP/UX. Thanks to John Morey + (jmorey@hitel.com) for reporting these. + + * apps/Gateway/Gateway/Peer_Message.h: Changed the default values + of the parameters to Peer_Addr so they aren't trying to assign + negative values to unsigned chars! Thanks to John Morey + (jmorey@hitel.com) for noticing this... + +Tue Aug 29 18:52:17 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Thread/Thread_Specific: Changed the constructor so + that it will take an initial TYPE *, which will be used to + initialize the thread-specific object. This is necessary to + support the changes to ACE_Task described in the following + bullet. + + * libsrc/ASX/Task: Added a new class called ACE_Task_Exit to + Task.C. This class is used in conjunction with + ACE_Thread_Specific to keep exit information for a Task in + thread-specific storage. This ensures that the Task::close() + method will get called no matter how the thread exits (e.g., via + Thread::exit() or by "falling off the end of Task::svc_run"). + +Mon Aug 28 09:54:35 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released new version of ACE 3.2.9... + + * libsrc/Reactor/Handle_Set.C: changed the type of MSB_MASK from + u_long to ACE_UINT32 to handle problems with the Alpha's 64 bit + longs... + + * libsrc/Threads/Thread_Specific: Continued to try and get this + class to build correctly on other platforms... I think I've + just about got it working right now... + + * libsrc/IPC_SAP/IO_SAP/IO_SAP: Added installation flags that + indicate whether the platform has terminal ioctl flags like + TCGETS and TCSETS. I know that SunOS 5.x has these, but I'm not + sure about other platforms... + +Sat Aug 26 13:55:45 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released new version of ACE 3.2.9... + +Fri Aug 25 09:05:09 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Threads/Thread_Specific.h: Fixed a typo that was causing + this file to fail on HP/UX. Thanks to Neil Cohen + (nbc@metsci.com) for finding this! + + * libsrc/IPC_SAP/DEV_SAP/DEV_IO: Added conditional support for + getmsg/putmsg calls in the DEV_IO class. This will make things + work correctly for platforms that don't support SVR4 STREAM + pipes. + + * libsrc/IPC_SAP/FILE_SAP/FILE_IO: Added the same fixes to FILE_IO + that I added to DEV_IO... + + * include/ace/sysincludes.h (MAXNAMELEN): Fixed a typo in + sysincludes.h that caused problems for the G++ compiler. + + * libsrc/Connection/Acceptor.C (handle_close): Removed a + diagnostic message that was getting printed if a + Oneshot_Acceptor had already been removed from the reactor (it's + ok for this call to fail). Thanks to Irfan Pyarali + (ip1@cec.wustl.edu) for noticing this! + + * libsrc/ASX/Task.C (ACE_Task): Fixed a bug in the constructor + that prevented a Message_Queue from being allocated + automagically. + +Thu Aug 24 16:47:14 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * include/ace/sysincludes.h: added support for 64 bit machines so + that Internet addresses are 32 bits, as they must be! + + * libsrc/Shared_Malloc/Malloc: Changed things so that MALLOC_STATS + is now *off* by default... (also changed the name to + ACE_MALLOC_STATS). + +Wed Aug 23 15:21:25 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * include/ace/config-osf1.h: Added support for thread-specific + storage. Please let me know if this breaks on OSF/1! + + * libsrc/Threads/Thread: Added support for the thread-specific + storage wrappers for both Pthreads and Solaris threads. Also, + rearranged some of the code to emphasize similarities between + Pthreads and Solaris threads. + + * libsrc/Threads/Thread_Specific: Updated this to remove "static" + from all the data members in this class since those should be + specific to an *instance* rather than to an instantiation of the + particular template class. Tim claims this works... + + * libsrc/Threads/Token.C: Fixed a couple of typos that misspelled + "assert" (jaysus...). Thanks to David Trumble + (trumble@cvg.enet.dec.com) for noticing this. + + * libsrc/Threads/Token.C (release): Fixed a very stupid bug that + was causing the Token never to become "unused"... No excuses + for this, except that Pthreads is partly responsible ;-) + +Tue Aug 22 11:36:58 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/ASX/Task: Changed the behavior of task so that it doesn't + try to delete the Message_Queue or Thread_Manager if it didn't + allocate them! Thanks to Karl-Heinz Dorn + (kdorn@erlh.siemens.de) for suggesting this fix. + + * libsrc/ASX/Message_Block: Changed the semantics for + Message_Block::end() so that it returns a pointer to 1 past the + end of the data. This is more consistent with toolkits like + STL. Also changed the behavior of Message_Block::copy() so that + it checks to make sure the data will fit in its buffer. + + * tests and apps: Revised a bunch of files to add #ifdef so that + TLI tests and apps are not compiled if the platform doesn't + support it... + + * Fixed a bunch of minor problems for HP/UX (which lacks TLI and + other common OS features). Thanks to Mark Seaborn + (mseaborn@itthp1.comm.mot.com) for noticing these. + +Mon Aug 21 00:19:29 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Misc: Changed the name of the class Argument_Vector to + ACE_ARGV. This is a bit more concise... UNIX programmer will + know precisely what argv is... + + * Updated all of ACE to use the new naming scheme, which prepends + all ACE classes with "ACE_". This is an important change since + it prevents ACE from polluting the namespace of applications + (unless they also prefix "ACE_" in front of their classes, which + is not very likely!). + + Since this change basically affects every single file in the + entire release, as well as all existing user code I've written a + perl script called "rename-ace.pl" to automate all of this. + This script is in $WRAPPER_ROOT/bin. To use it, simply type: + + % find . -type f -print | egrep '[Chi]$' | xargs rename-ace.pl + + Note that you will need to change the first line of + rename-ace.pl to point it to whereever perl is located on your + system. + + I've tested this on the entire ACE source code base and it seems + to work fine. Please be careful using it on your code, however, + since it may conflict with names that you use. When in doubt, + remove the '-pi' from the first line of the rename-ace.pl perl + script and replace it with '-p' (which is non-destructive). + Then run the commands above and check the output carefully. + When you're convinced that everything is ok, add the '-pi' back + again. Let me know immediately if you find any problems with + this scheme! + + * libsrc/Connection/Acceptor.C: Added a virtual destructor to the + Oneshot_Acceptor to make sure that descriptors are closed down + correctly. Thanks to Irfan (irfan@wuerl.wustl.edu) for + suggesting this. + + * libsrc: Change all occurrences of Shared_Memory to + SV_Shared_Memory to firmly indicate the origins of this + wrapper... + +Sun Aug 20 23:12:03 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP: added the IO_SAP, DEV_SAP, and FILE_SAP + components donated by SIEMENS to the ACE release. + + * libsrc/ASX: Split the Message_Queue.* files into Message_Block.* + and Message_Queue.* in anticipation of the Windows NT port... + +Fri Aug 18 13:54:09 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Threads/Thread_Specific: Move the operator->() + method back into the *.C file in order to make HP/UX + happy... + + * apps/Gateway/Peer: Removed the Options.* files since they + weren't being used and they were causing problems on OSF/1... + + * libsrc/Misc/Profile_Timer: Factored common code together by + making a new typedef called Rusage that defaults to either + struct rusage or prusage_t, depending on installation flags. + Fixed a couple places in the code that were depending on the + prusage_t type (which is now the Profile_Timer::Rusage type...). + +Thu Aug 17 14:31:11 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Connection/Connector.h: Changed some typedefs in order to + keep the Centerline compiler from crapping out. I can't + *believe* how screwed up that compiler is when it comes to + templates... + + * Released new version of ACE 3.2.9... + + * libsrc/Threads/Synch: Fixed a bunch of typos that showed up + on OSF/1. Also tried to fix some other problems by removing + "const" from all the methods... + +Wed Aug 16 22:26:24 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Threads/Thread_Specific.h: Fixed another stupid bug + caused by a braino that failed to unconditionally include + Thread_Specific.i. Stuart Powell found this also... (thanks!). + + * libsrc/Threads/Thread_Specific.h: In Thread_Specific.h the + inlining macros were only included if threads were used. This + obviously didn't work for people without threads... I + moved the #endif for ACE_HAS_THREADS... back before the #ifdef + __INLINE__ stuff (e.g. to line 71). Thanks to Stuart Powell + (stuartp@ot.com.au) for suggesting this. + + * libsrc/Threads/Synch.h: Fixed a typo that manifested itself for + pthreads: Condition count_nonzero_ should obviously be + Condition count_nonzero_. Thanks to Rob Clairmont + (rclairmo@bnr.ca) for reporting this. + +Tue Aug 15 00:31:44 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Log_Msg/Log_Msg.C (log): Fixed a stupid typo (*format++ + should have been format++...). + + * libsrc/Misc/Trace.h: Move the class TSS_Int from within class + Trace to file scope and changed the name to ACE_TSS_Int to + handle problems with the HP/UX compiler. + + * include/ace/sysincludes.h: Added the word "struct" in front + of rusage to make things work on HP/UX. Thanks to Neil Cohen + (nbc@metsci.com) for reporting this fix. + + * apps/TokenServer/server/TokenMap.C: Fixed yet another problem + with scope of variables defined in for loops... + + * Released new version of ACE 3.2.9... + + * libsrc/Connector: Fixed a braino whereby I didn't use consistent + naming for my #defines (PA should have been PRC). Thanks to + Alex (alexey@ace.elektra.ru) for noticing this. + +Mon Aug 14 18:13:46 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP/SPIPE_Acceptor: Modified the interface of open() + and accept() so they would conform to the SOCK_Acceptor and + TLI_Acceptor. This makes it possible to use SPIPE_Acceptor in + similar situations (e.g., Acceptor and Connector patterns). + + * libsrc/ASX/Stream: Fix a bug that occurred when trying to dump() + a linked Stream. + + * libsrc/Connection/Acceptor: Moved the body of the init() method + out of this class since it was unnecessarily dependent on the + INET_Addr domain addressing types. This required changes to the + ./apps and ./tests directory in order to add the init() method + to classes that used the default behavior. + + * libsrc/IPC_SAP/SPIPE_SAP/SPIPE_Acceptor.C: Fixed close() so that + it will call fdetach(2) *before* closing down the descriptor. I + hope this will fix a problem noticed by people at SIEMENS. + + * tests/ASX/Event_Server/Event_Server/Options: Fixed a problem + with the default port numbers (they weren't using the values + from ./include/ace/testconfig.h). + + * include/ace/sysincludes.h (MAXNAMELEN): If MAXNAMELEN is not + defined by a platform then ACE sets it to be FILENAME_MAX, + which should be defined in stdio.h. Thanks to Todd Blanchard + (tblancha@evolving.com) for this suggestion. + +Sun Aug 13 17:02:57 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Service_Configurator/Parse_Node: Changed the name of + Function_Node::symbol (const void *) so that it won't give + those annoying warnings anymore... + + * libsrc/Reactor/Handle_Set: Moved the definition of MSB_MASK from + the header file into a static const within the .C file in order + to avoid overflow problems on certain compilers. + + * libsrc/Threads/Synch: Implemented bare-bones versions of + Semaphore and RW_Mutex for the POSIX Pthreads wrappers so that + they'll be more compatible with the Solaris threads wrappers. + The semaphore implementation uses a Condition object and a + Mutex, which should be a reasonable solution. The RW_Mutex is a + cop-out for now and just uses a Mutex (i.e., no extra + parallelism for readers...). If anyone has a good + implementation of RW_Mutex that they'd like to share please let + me know. + + * libsrc/Threads/Thread_Specific: Fixed the prototypes for copy + constructor and operator=, which were broken... Thanks to Alex + (alexey@ace.elektra.ru) for noticing this. + + * libsrc/Shared_Malloc/Memory_Pool.C: Added some casts to + MAP_FAILED to handle OSF/1. Thanks to Alex + (alexey@ace.elektra.ru) for noticing this. + + * libsrc/Threads/Token: Fixed things so that threads waiting for a + token wouldn't get screwed up by signals that occur... + + * include/ace/sysincludes.h: Changed the #ifdef + ACE_SELECT_USES_LONG to ACE_SELECT_USES_INT for HP/UX since + believe it or not, it really does use int, not long! + + * libsrc/SV_Semaphores: Fixed some weird problems that the HP/UX + compiler was having when trying to inline methods in this class. + As a consequence, I've rearranged the class to avoid inlining + non-trivial methods. Thanks to John Morey (jmorey@hitel.com) + for reporting these problems. + +Wed Aug 9 01:29:16 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Threads/Token: Added a tryacquire() method to become + interface compliant with other LOCK mechanisms. + +Sat Aug 5 09:18:29 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Connection: Fixed a couple of bugs when using + the Acceptor and Svc_Handler when ACE_OMIT_SERVICE_CONFIGURATOR + is enabled. Thanks to Stuart Powell (stuartp@ot.com.au) for + bringing this to my attention. + + * include/ace/sysincludes.h: Added a #ifdef for MAXNAMELEN to + handle systems (like HP/UX) that don't support it. + +Thu Aug 3 22:59:13 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released new version of ACE 3.2.9... + + * libsrc/Reactor/Time_Value.i (normalize): Added new code to + perform normalization of Time_Values. Thanks to Hans Rohnert + (Hans.Rohnert@zfe.siemens.de) of SIEMENS for the suggestion. + +Tue Aug 1 00:19:00 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Changed all code that used Log_Msg::log() directly to use + LM_ERROR or LM_DEBUG. This will ensure that logging will work + with the new thread-specific storage implementation. + + * libsrc/Threads/Thread_Manager.i (open): Fixed this method so + that it is thread-safe when a Thread_Manager is resized. + + * libsrc/ASX/Map_Manager.i (open): Fixed this method so that it is + thread-safe when a Map_Manager is resized. + +Mon Jul 31 12:56:17 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Misc/Trace: Reimplemented the ACE Trace class to use the + new thread-specific storage wrapper. + + * libsrc/Log_Msg: Reimplemented the Log_Msg class to use the new + thread-specific storage wrapper. This shouldn't affect any + existing code that was careful to only use the LM* macros... + + * libsrc/Threads: Added a new class called Thread_Specific which + implements a C++ wrapper for SunOS 5.x thread-specific data + (this will also work for POSIX pthreads I believe). Thanks to + Tim Harrison (harrison@cs.wustl.edu) for coming up with the idea + for using C++ "smart pointers" to implement this. + + * libsrc/Reactor/Timer_Queue.h: Moved Timer_Node from within + Timer_Queue to outside Timer_Queue and renamed it to + ACE_Timer_Node. Unfortunately, some compilers still don't like + nested classes (ugh)... + + * Changed ACE_Synch_Options to be simply Synch_Options since it + is *not* an ACE private class... + +Sun Jul 30 00:07:28 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * include/makeinclude/README: Added a new #define called + ACE_HAS_THREAD_SPECIFIC_STORAGE, which does exactly what it + sounds like! So far, I know that Solaris defines this. I'm not + sure which other platforms do (perhaps OSF/1 does?). + +Fri Jul 28 14:53:45 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Fixed a bunch more problems with loop variables that were + uncovered with GCC 2.7. Thanks to Matt Stevens + (mstevens@ent.mrj.com) for noticing this. + + * apps/Logger/Service_Configurator_Logger: Added a new flag called + ACE_HAS_NO_STATIC_DATA_MEMBER_TEMPLATES which is necessary to + workaround bugs with GNU G++... Thanks to Matt Stevens + (mstevens@ent.mrj.com) for noticing this. + + * libsrc/Connection/Connector.C (cleanup_AST): Changed the + parameter list just a tad to try and fix a problem with + G++ (which doesn't seem to like unscoped typedefs in + argument lists or return values. + + * libsrc/Misc/Profile_Timer.i: Changed ::getrusage to be getrusage + to avoid problems with macros and scope operators... + + * include/ace/testconfig.h (ACE_DEFAULT_RENDEZVOUS): Changed the + value from /tmp/foo to /tmp/fifo.ace. Thanks to Neil B. Cohen + (nbc@metsci.com) for suggesting this. + +Thu Jul 27 12:30:06 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * apps/TokenServer/server/TokenHandler.C (abandon): Fixed a minor + bug that caused assert() to fail when a client abandoned a + Token. + + * libsrc/Reactor: Fixed a bug with the design of the Reactor's + Timer_Queue cancellation mechanism. The new mechanism is much + more robust since it ensures that timer_ids (used to cancel + pending timers) are unique up to values of greater than 2 + billion timers! As long as timers don't stay around longer than + this there should be no problems with accidentally deleting the + wrong timer. Thanks to Bill Sears (wsears@world.std.com) for + noticing this problem. + + One nice consequence to this change is that legacy code that + would have broken with the previous change is now 100% + compatible! + + * Provided a definition of ACE_Synch_Options::arg(const void *), + which I'd forgotten to define before (darn templates...). + Thanks to Tim Harrison (harrison@cs.wustl.edu) for finding this! + + * include/ace/sysincludes.h: Added a total hack to get HP/UX to + understand getrusage(). The trick is to use the following + undocumented syscall: + + #define getrusage(a, b) syscall(SYS_GETRUSAGE, a, b); + + What a hack (but it works...). + +Tue Jul 25 13:20:58 1995 Douglas C. Schmidt (schmidt@kavita.cs.wustl.edu) + + * libsrc/Misc/Profile_Timer: Fixed a typo in Profile_Timer.h + (ACE_HAS_RUSAGE_T should have been ACE_HAS_GETRUSAGE). Thanks + to George Reynolds (george@dvcorp.com) for noticing this. + + * Changed all uses of ::getopt() to use the ACE class Get_Opt + get_opt. Also changed all uses of optarg to get_opt.optarg. + Thanks to Bob Vistica (robertv@ims.com) for detecting and + reporting some inconsistencies in my previous changes... + +Mon Jul 24 19:03:03 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * include: I've added config and platform support for SGI IRIX5.3 + for use with the SGI C++ compiler. Thanks to Stuart Powell + (stuartp@ot.com.au) for these config files. + + * libsrc/Connection/Acceptor.C (handle_input): Added the + Event_Handler::DONT_CALL flag when removing the Oneshot_Acceptor + from the Reactor so that we don't set it's peer_acceptor_ to -1. + +Mon Jul 24 12:46:10 1995 Douglas C. Schmidt (schmidt@kavita.cs.wustl.edu) + + * libsrc/Misc/Profile_Timer: Fixed problems stemming from the fact + that HP/UX doesn't seem to support getrusage() (how odd). + + * tests/Connection: a new test directory to test out the Connector + and Acceptor pattern implementations. + +Sun Jul 23 12:26:37 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Connection/Acceptor.C: Fixed a minor bug with the + Oneshot_Acceptor constructor. Thanks to John Morey + (jmorey@hitel.com) for noticing this and the one below. + + * libsrc/Reactor/Timer_Queue: Moved the static method current_time + from the Timer_Queue.i file to the Timer_Queue.C file. This + avoids a bug with HP/UX C++. + +Sat Jul 22 15:54:27 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released beta version 3.2.9. Once this compiles on all major + platforms then it's time to move to version 3.3. + + * Added a number of miscellaneous changes for OSF/1 courtesy of + David Trumble (trumble@cvg.enet.dec.com). One of these changes + involved changing all uses of Reactor::{ADD,SET,CLR,GET} to + Reactor::{ADD,SET,CLR,GET}_MASK in order to avoid a class with + some symbols in OSF/1. + +Fri Jul 21 00:21:02 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Finally was able to test ACE on the SunOS 4.x platform (using + the SunC++ 4.0.1 compiler). The entire release compiled + correctly! This is a great relief after fighting with this + stuff for months... If you are building ACE on SunOS 4.x I'd + *strongly* recommend you get SunC++ 4.0.1 since it is the only + compiler that seems to be able to grok the weirdness of SunOS + 4.x... + + * Finished updating all the ./tests and ./apps code so that it + works correctly with the new Acceptor/Connector modifications. + To see examples of these changes check out + ./tests/IPC_SAP/SOCK_SAP/CPP-{nbclient,inserver}.C. + + * libsrc/Misc/Profile_Timer: Merged in the new Profile_Timer + implementation from David Trumble (trumble@cvg.enet.dec.com). + This will work with basically the same interface as the current + scheme even if the OS platform doesn't support the prusage_t + type... + +Thu Jul 20 01:07:23 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Connection: Added a new class called ACE_Synch_Options + which is used in both the Acceptor and Connector classes to + consolidate options related to synchronous and asynchronous + behavior. + + * libsrc/Connection: Added a new class called Oneshot_Acceptor. + This class inherits from the Acceptor but it only accepts one + connection at a time (i.e., it doesn't keep itself registered + with the Reactor). Several examples in the tests/SOCK_SAP + directory have been added to illustrate how all this works. + + * libsrc/Connection/Connector: completely redid the Connector and + Acceptor class interfaces to incorporate the new changes for + asynchronous and synchronous behavior. The new scheme should be + much more general (and correct...). Thanks to Tim and Irfan for + helping out with this. + + * libsrc/Threads/Synch: Fixed the implementation of Recursive_Lock + so that it won't have race conditions when testing the thread id + and nesting level in parallel threads. + +Wed Jul 19 13:15:05 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor/Timer_Queue: Added new support for cancellation + of individual Event_Handlers in the Reactor. In addition, it is + now possible to cancel all Event_Handlers with a single call to + Timer_Queue::cancel(). Note that this new scheme will break + existing code since Timer_Queue::schedule() (and + Reactor::schedule_timer()) now return ACE_Timer_Node *'s rather + than ints... + + * libsrc/Service_Configurator/Service_Config: Fixed a problem + where the "-s" option didn't work since it was parsed when + "Service_Config::open" was called + (it sets Service_Config::signum_). However, previously the + signal handler was already setup by the constructor. By moving + this registration to the open() method the problem was solved. + Thanks to Bob Vistica (robertv@ims.com) for noticing this. + + * libsrc/Service_Configurator/Service_Manager: Changed the + Service_Manager::reconfigure_services to use this->signum_ + rather than to hard code SIGHUP. Thanks to Bob Vistica + (robertv@ims.com) for this insight. + +Mon Jul 17 12:08:08 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Threads/Token.C (renew): Fixed a typo so that we compare + this->head_ == 0 rather than this->head_->next_ == 0. + + * libsrc/Reactor/Reactor.h: Changed the Reactor to use the + Reactor_Token rather than the pure Token to make sure that the + sleep_hook() is called to unblock the Reactor. + +Fri Jul 14 14:12:07 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Connection: Changed the default behavior of the Connector + and Acceptor classes such that they pass a -1 to + svc_handler_->close() when things go wrong. This is useful as a + flag to close() (e.g., if it needs to figure out what to do if + is shuts down prematurely). + + * libsrc/Connection/Svc_Handler.C: Added a default definition of + the put() method, which is defined as a pure virtual method in + class Task. + +Thu Jul 13 23:10:35 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * include/ace/sysincludes.h: Added support for the SGI IRIX 5.3 + OS. More screwy gettimeofday() hacks (what a pain...). Thanks + to Matt Stevens (mstevens@kirk.softeng.infonautics.com) for + these fixes. + + * include/makeinclude/platform_sunos5_centerline.GNU: Fixed a + vexing problem that was causing the Centerline C++ compiler to + puke when compiling ACE. Thanks to Chandra Venkatapathy + (cvenkat@develop.bsis.com) for finding a solution! + +Tue Jul 11 00:01:15 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released version 3.2.6 for use by Karl and Detlef. + +Mon Jul 10 00:28:51 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * apps/TTCP: Added support for benchmarking the performance of + Orbix, ORBeline, ACE SOCK_SAP, and C sockets. These results are + available at URL http://www.cs.wustl.edu/~schmidt/COOTS-95.ps.Z + + * libsrc/Service_Configurator/Makefile: Added new commands to the + Service Configurator Makefile so that all automatically + generated flex and yacc symbols (i.e., the "yy" stuff) is + renamed "ace_yy". The purpose is to avoid conflicts with other + uses of flex/yacc lexers/parsers with ACE. Thanks to Steve + Ritter (ritter@titan.com) for this suggestion and code. + + * libsrc/IPC_SAP/TLI: Changed the TLI files so they are + conditionally compiled only if the platform supports TLI... + + * libsrc/Connection: Changed the inlining strategy of Connector, + Acceptor, and Svc_Handler so that very short methods are always + inlined, but anything larger is never inlined... + +Sun Jul 9 14:07:02 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * include/ace/testconfig.h: Changed all occurrences of DEFAULT_* + to ACE_DEFAULT_ to prevent namespace collision. + + * libsrc/Connection/Connector: Massively improved the Connector + class so that its connect() method supports the following + behavior (tv == "timeout value" and ur == "use Reactor"): + + Parameters | Description + | + tv | ur | + -----|----------|------------------------------- + | | + NULL | yes | infinite timeout (using Reactor) + | | + time | yes | try asynch transaction for + | | the specified time (using Reactor) + | | + 0,0 | yes | poll; try, if EWOULDBLOCK, + | | then return immediately + | | (using Reactor) + | | + NULL | no | block forever (don't use Reactor) + | | + time | no | do a blocking transaction + | | for the specified time + | | (don't use Reactor) + | | + 0,0 | no | poll; but do not initiate a + | | nonblocking transaction + | | (don't use Reactor) + + * libsrc/IPC_SAP/SOCK_SAP/SOCK_Connector: Changed the behavior of + the SOCK_Connector::connect() method so that it uses Time_Values + rather than a simple flag that indicates whether or not to use + non-blocking connectors. The new scheme is an improvement since + it allows greater control over synchronous and asynchronous + timeouts for connection establishment. This behavior parallels + that of SOCK_Acceptor, as well! If this works well then I'll + update the TLI_Connector and SPIPE_Connector to match this + interface. + + * libsrc: Continued to improve ACE's use of the global name space + by prefixing all "helper" classes with "ACE_" + + * Updated SPIPE_Acceptor so that it would have the same basic + interface as the SOCK_Acceptor and TLI_Acceptor. + + * libsrc/IPC_SAP: Consolidated the handle_timed_wait() methods + used by the TLI, socket, and STREAM pipe wrappers so that they + share the new ACE::handle_timed_accept() method, which is in + libsrc/Misc. + + * libsrc/Misc: Modified the structure of Misc.[Ch]. Originally, + this file contained a bunch of stand-alone C functions with the + prefix "ace_" to keep them from conflicting with user's code. + I've modified things now so that all the miscellaneous functions + are now static methods in class ACE. This provides better scope + control... + + * libsrc/Log_Msg/Log_Msg: Replaced the use of a Mutex in class + Log_Msg with a Recursive_Lock. This is necessary to + handle signals correctly... + + * libsrc/Reactor/Reactor: Modified the behavior of + Reactor::notify() so that writers will block if the pipe is + full. This solves some nasty flow-control problems. + + * libsrc/Reactor/Handle_Set: changed all uses of fd_set to + ACE_FD_SET_TYPE * so that HP_UX would work correctly... + + * include/ace/config-hpux.h: Removed the ACE_HAS_XLI flag until I + get a better idea which HP systems this is installed on. + + * libsrc/Threads/Thread: Added a new static method called + spawn_n() that spawns "n" threads all running the same function. + +Sat Jul 8 14:14:34 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Service_Configurator: Made some miscellaneous changes to + "const" methods and parameters in order to handle the new + Reactor changes (C++ can be such a pain about this + sometimes...). + + * libsrc/Threads: Added "yield" and "sigsetmask" methods to class + Thread. How did I manage to omit these before?! + + * libsrc/Reactor: Updated the Reactor to use the new Token class + described below. This greatly simplies the structure of the + multi-thread support in the Reactor code. In addition, it + should improve performance because it cuts the number of context + switches compared with the old scheme. Many thanks to + Karl-Heinz and Detlef for encouraging me to redo the Reactor + implementation. + + * libsrc/Threads: Added a new class called Token that provides a + flexible and efficient recursive mutex scheme. Thanks to + Karl-Heinz Dorn (kdorn@erlh.siemens.de) and Detlef Becker + (beckerd@erlh.siemens.de) for sharing their original code for this. + +Thu Jul 6 10:37:45 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor/Event_Handler_T: Conditionally compiled this so + that it will only compile if the compiler supports template + typedefs (e.g., G++ doesn't seem to like this...). + + * Started to make changes in ACE to deal with the new ANSI C++ + semantics in the scope of variables defined within for loops. + Thanks to Aniruddha Gokhale (gokhale@cs.wustl.edu) for noticing + this in G++ 2.7... + +Wed Jul 5 21:50:39 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Connection/Svc_Handler: Fixed the behavior of the + Svc_Handler class so that it can be configured with a Reactor + other than Service_Config::reactor, just like the Acceptor and + Connector. Thanks to Karl-Heinz Dorn (kdorn@erlh.siemens.de) + for suggesting this! + +Tue Jul 4 00:21:31 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Added some new changes for Linux courtesy of Charles Rennolet + (clr@thurse.mn.org). + + * libsrc/Reactor/Reactor.C (bit_ops): Fixed a dumb error in + bit_ops that was caused by checking "else if (Reactor::SET)" + rather than "else if (ops == Reactor::SET)". Thanks to Mark + Patton (mark_patton@tx72.mot.com) for finding this bug and + reporting it along with the fix. + + * include/ace/sysincludes.h: Added new fixes for M_SYNC and + ENOTSUP on SunOS 4. + + * libsrc/Reactor: Added new support for integrating X and the + Reactor. These files are called XtReactor.* and XReactor.*. + Thanks to Eric Vaughan (evaughan@arinc.com) for providing this + stuff... + +Mon Jul 3 19:44:07 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Added support for SunOS 5.5 on i86 PC. Thanks to Bin Mu + (mubin@wfg.com) for the config files and fixes. + + * libsrc/Misc/Profile_Timer: Added new support for versions of + UNIX that don't support prusage_t. The new version of + Profile_Timer will use gettimeofday() and getrusage() of + prusage_t and /procfs isn't available... This code hasn't been + tested yet (since I don't have SunOS 4.x) so I don't know if it + works. + + * Hopefully fixed the SunOS4 prototype for gettimeofday(). Thanks + to Andrew McGowan (ajm@se09.wg2.waii.com) for the suggested fix. + + * include/makeinclude/platform_hpux.GNU (CC): Added new support + for building ACE and shared libraries on HP/UX. Thanks to Jam + Hamidi (jh1@osi.com) for this code. + + * libsrc/Reactor/Handle_Set: Fixed Handle_Set_Iterator::operator++ + to check for index to be greater or equal than NUM_WORDS instead + of just equal. This is better for sanity, although it may not be + needed. Thanks to Carlos Garcia Braschi (cgarcia@caramba.tid.es) + for suggesting this fix. + +Wed Jun 14 11:16:40 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP/TLI_Acceptor: modified TLI_Acceptor so that it's + public constructor/open() and accept() methods are more similar + to the SOCK_Acceptor. In particular, added support for + "SO_REUSEADDR" in TLI_Acceptor and time values for accept(). + Thanks to John P. Hearn (jph@ccrl.nj.nec.com), TLI_SAP now does + the right thing for socket options. + + * libsrc/IPC_SAP: Fixed up the SOCK_Acceptor and TLI_Acceptor in + order to add better support for "timed accepts." The new scheme + uses Time_Values, which is more consistent with other parts of + ACE. In addition, the Time_Value was moved from the + constructor/open() to the accept() method, which allows more + fine grained control over this behavior. Thanks to Irfan + (ip1@cs.wustl.edu) for suggesting this. + + * libsrc/IPC_SAP: Cleaned up the SOCK_Acceptor::open and + TLI_Acceptor::open routine. In addition to being more compact + and robust, this routine now also let's open() determine which + local port to bind to (if you pass in Addr::sap_any as the + local_addr). Thanks to Irfan (ip1@cs.wustl.edu) for suggesting + this. + +Tue Jun 13 16:09:13 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor/Timer_Queue: Fixed an odd problem with the + Timer_Queue on Solaris. Apparently the select() call will + return slightly earlier than the timeout dictates due to lack of + granularity with the system clock. This was causing problems + where the Reactor wasn't correctly dispatching the + handle_timeout() method of Event_Handlers. The fix was to add a + 10 Millisec "fudge factor" when calling the + Timer_Queue::expire() method. Please let me know if this causes + any problems. Thanks to Giang Hoang Nguyen + (yang@titan.com) to noticing this problem. + + * libsrc/Connection/Acceptor: Enhanced the Acceptor class so that + it is possible to accept a new SVC_HANDLER synchronously, rather + than always driving this acceptance out of the Reactor's event + loop. Thanks to Irfan (ip1@cs.wustl.edu) for suggesting this. + + * libsrc/IPC_SAP/Addr: Changed all occurrences of ace_sap_any to + Addr::sap_any (i.e., sap_any is now a static data member in + class Addr). This is an improvement since it helps to limit the + scope of what would otherwise be global variables... + +Wed Jun 7 17:26:31 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * apps/Logger/Reactor_Logger/Client_Acceptor.i (handle_input): + Fixed a braino that omitted an important block of code! Thanks + to Ken Konecki (kenk@wfg.com) for finding this. + +Fri Jun 2 13:59:07 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP/Addr/INET_Addr.i (set): Removed the special case + for INADDR_ANY. This should just fall right out... + +Thu Jun 1 19:45:21 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP/SOCK_SAP/SOCK_Connector: Added support to + SOCK_Connector so that it is possible to bind the local TCP port + number prior to establishing the connection. Also fixed the + TLI_Connector to be consistent with this approach. Thanks to + Mark Patton (mark_patton@tx72.mot.com) for this idea. + + * Fixed a problem with Mem_Map that was caused by the fact that + some versions of Unix (e.g., SunOS 4.x) don't support MS_SYNC... + Thanks to Andy McGowan (mcgowan@wg2.waii.com) for noticing this. + + * Fixed a very stupid bug in ./libsrc/Synch.h that accidentally + omitted this->lock_.acquire() from the Guard class constructor. + Thanks to Bin Mu (mubin@wfg.com) for noticing this! + +Fri May 26 13:20:38 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Connection/Acceptor: Added a new method called + make_svc_handler() that generalizes the dynamic creation of a + SVC_HANDLER by the Acceptor's Template Method handle_input(). + This scheme is completely backwardly compatible with the + original approach, but now allows transparent extension too! + + * libsrc/Connection/Acceptor: cleaned up the Template Method logic + in Acceptor::handle_input. No longer do we set the listener + socket into non-blocking mode and then rely on a -1 with + EWOULDBLOCK to indicate there are no more connections to + establish. This was causing problems for singleton Svc_Handlers + since the Acceptor was setting their peer_stream_ to -1... The + new approach should complete solve this problem. + +Mon May 22 15:10:27 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released version 3.2.3 so that Bill Sears can test the new + #include "ace/" features. + + * Modified all the ACE source, tests, and apps so that all + #includes of its headers are refixed by ace/, e.g.: + + #include + + There are two reasons for have the include files be of + this form: + + First, you can tell at a glance by looking at the caller where + the library is coming from. + + Secondly, you can build an include tree of the form: + + /include/lib1 + /include/lib2 + /include/lib3 + /include/ace + + which then links to WRAPPER_ROOT. Now, all you have to do + when you build a make file is point to the include root, and + put links in the include root. This is especially helpful + if there are multiple versions. + + This means just one less thing that has to be modified in the + Makefile. Thanks to Bill Sears (wsears@world.std.com) for + recommending this change. + +Sat May 20 17:12:35 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * config-irix5.3-sgic++.h: Added new configuration support for SGI + IRIX5.3 courtesy of Stuart Powell (stuartp@ot.com.au). + +Sat May 13 20:44:06 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Generalized the SOCK_Connector::complete method so that it takes + a Time_Value timeout. This allows applications to wait upto a + certain limit before giving up on a non-blocking connection. + Updated the tests in ./tests/IPC_SAP/SOCK_SAP/CPP-inclient.C to + illustrate how this is used. + + * Added some interesting new tests to ./tests/Mem_Map that can be + used to benchmark the performance of various strategies (e.g., + stdio, read/write, mmap, etc.) for copying files. + +Fri May 12 19:09:10 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Mem_Map/Mem_Map: Added two new overloaded methods called + sync() that are wrappers around the msync(3c) system call. Also + added a new unmap() method that gives access to the full + behavior of munmap(3c). + +Wed May 10 14:16:16 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Tried yet another fix for the gettimeofday() botch that both + Centerline and SunOS 5.4 screw up in different ways. Thanks to + Medhi Tabatabai (Mehdi.Tabatabai@ed.nce.sita.int) for the latest + fixes. + +Tue May 9 19:05:58 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor/Handle_Set.C: Fixed some "off-by-one" errors that + were occurring in the Handle_Set::sync() and set_max() methods. + Thanks to Nigel Hooke (n.hooke@trl.oz.au) for finding and fixing + these. + +Mon May 8 02:01:54 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor/Reactor.C: Moved the Null_Callback class from + being nested within the Reactor class to outside the Reactor + class. This fixes a problem with the SIG compiler. + + * Released version 3.2.2. + + * libsrc/Reactor/Signal.C: Made the Signal_Handler class + thread-safe as well as signal-safe. + + * libsrc/Reactor/Reactor.C: Modified the new Reactor + implementation slightly to handle signals correctly. + + * libsrc/Threads/Synch.h: Added a new conversion operator to + Recursive_Lock that returns the underlying LOCK in case we need + it for something (e.g., to initialize a Condition object). + +Sun May 7 04:17:46 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor/Reactor.C: Finished what I hope will be the last + set of changes to make the Reactor robust in multi-threaded + programs in situations where separate threads are used to + register and remove handlers. The final solution is elegant in + that it does not significantly penalize the performance of + programs that do not use separate threads to register and remove + handlers. Moreover, if you compile without the ACE_MT_SAFE flag + the Reactor will not include additional state information + related to the multi-threaded implementation. + + * libsrc/Threads/Synch.h: Subclassed the Guard class to make a new + class Try_Guard that uses tryacquire() to obtain a LOCK. + +Fri May 5 18:43:50 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released version 3.2.1 + +Thu May 4 19:43:01 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP/TLI_SAP/TLI_Connector.C (connect): Fixed a + problem whereby a t_bind() was being done twice. Since I didn't + write this code I don't know if my fix will work generically on + all platforms supporting TLI. Please let me know if there are + any problems. + +Tue May 2 17:21:53 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor: Added a new notification feature that allows + multiple threads of control to enqueue Event_Handler * to the + main Reactor thread via the pipe used to wake up the main + Reactor thread. The Reactor will call the handle_exception() + method on Event_Handler with a HANDLE == -1 to notify the + handler. This feature is very useful if you need to have + certain operations (such as handler termination) performed in + the main thread. + +Tue Apr 25 00:34:18 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor: Fixed a stupid pair of typos in the Reactor that + failed to cast arguments to the pipe to char *. + + * libsrc/Connection: Fixed a portability problem with the + Connector: we can't use RW_Mutex for synchronization since not + all platforms support threads. The quick fix is to use + Null_Mutex, but a better long term approach is on the way! + + * Released version 3.2. + + * Added richer support for the TLI_Connector to make it work + better with protocols other than TCP/IP. Thanks to Mats + Sundvall (sundvall@perrier.embnet.se) for these enhancements. + +Mon Apr 24 02:26:04 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Changed the SOCK_Dgram_Brdcast class name to SOCK_Dgram_Bcast + and the SOCK_Mcast to SOCK_Dgram_Mcast to be more consistent. + + * Massively improved the Reactor's support for multi-threading. + There was actually a major problem in previous versions of ACE + that used poll() as the underlying event demultiplexor. Poll() + produced incorrect results when the Reactor::handle_events() + method was run in one thread, but another thread came along and + registered or removed an Event_Handler. The new version fixes + this problem so that the Reactor will now work correctly in + multi-threaded programs. + + One consequence of this change is that sysincludes.h and the + SunOS 5.x configuration files have been changed so that poll() + is no longer used as the default demultiplexor. The reason is + that poll() doesn't work as efficiently when used in + multi-threaded programs (ugh). See the Reactor code for + examples of how this all works now. Basically, the trick is to + use the select()-style implementation for most of the code, and + transform to poll()-style implementation only when necessary. + +Sat Apr 22 03:35:51 1995 Douglas C. Schmidt (schmidt@lambada.cs.wustl.edu) + + * libsrc/ASX/Message_Queue: Added a new method to the + Message_Queue class called unblock(). This method allows one + thread to release all other threads that are waiting for + messages to be enqueued or dequeued on a Message_Queue. + Modified the return value of methods like enqueue_head() and + dequeue_head() so that if a thread unblocks() then these methods + return -1 with errno == ESHUTDOWN. Also changed the name of + some of the internal methods so that they would be more + consistent. + + * libsrc/Connection/Connector: Fixed a stupid bug caused by + failing to have a destructor for Connector. Thus, there are + cases where unconnected Svc_Handlers are left around in the + handler_map_. This causes problems for dynamic linking in + conjunction with the Reactor, so now the destructor iterates + through all the unconnected Svc_Handlers and removes them from + the Reactor. + +Fri Apr 21 15:28:46 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor/Signal: Changed Sig_Set::addset() and + Sig_Set::delset() to the more appropriately named sig_add() and + sig_del(). Also added '_' in the Sig_Set method names to be + more consistent... + + * Removed the ./libsrc/IPC_SAP/SOCK_SAP/misc.[hC] file and merged + the one function in that file (ace_bind_port) into + ./libsrc/Misc/Misc.[hC]. + + * Added a bunch of fixes from various people to make ACE compile + better on SGI, SunOS 4, and HP/UX. Thanks for all the fixes! + + * libsrc/IPC_SAP/Addr: Changed sap_any to ace_sap_any to avoid + problems with the namespace. + + * Added a new portability flag that only compiles the SOCK_Mcast.* + stuff if the platform supports multicast! + + * ./libsrc/Shared_Malloc: Fixed some portability bugs with + Memory_Pool.C and added new support for SunOS 4.x running SunC++ + 4.x. Thanks to Steve Warwick (swarwick@arinc.com) for this + strategic help. + +Wed Apr 19 09:05:43 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Fixed up the ./libsrc/CORBA_Handler so that it will correctly + compile on platforms that don't have Orbix... + + * libsrc/Misc: added a new "Simple String" class called SString. + This is not really meant to be used by end-user applications. + It is used by certain portions of ACE that need to have + operator== and operator!= defined on a string (e.g., the + Token_Server and the Orbix Event_Comm components that use the + Map_Manager). + +Tue Apr 18 00:09:31 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/ASX: Fixed a stupid bug in Task::activate() that didn't + spawn a thread if the Thread_Manager was NULL... + +Sat Apr 15 19:39:30 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor: Added a new class to the Reactor called + Event_Handler_T.[hi]. This class makes it easy to integrate + existing classes into the Reactor framework without requiring + them to inherit from Event_Handler directly. This technique is + a superset of the DEF_TIE approach used by IONA in Orbix as one + of the ways to combine an existing class (that doesn't know + anything about CORBA) with a CORBA interface. Thanks to Greg + Lavender + (g.lavender@isode.com) for the suggestion. + +Fri Apr 14 14:41:49 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Run catman on the ./man directory so that it now has a windex + file. This facilitates "man -k". + +Thu Apr 13 23:39:22 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor: Made the Reactor be a stand-alone component that + does not require any other ACE libraries. + + * Added two new methods to the Reactor so that you can now + register or remove a set of HANDLEs in a single call. Thanks to + Bill Sears + (wsears@world.std.com) for this suggestion. Basically, now you + can register or deregister a set of n HANDLEs with one operation + (rather than doing n register_handler () or n remove_handler + ()). + + * include/sysincludes.h: Changed the name of the macro MT to + ACE_MT and DB to ACE_DB to avoid polluting the namespace. + +Wed Apr 12 11:14:46 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor/Reactor.C (close): Added code to close down the + pipe handles when the Reactor is shut down. Thanks to Mark + Patton (mark_patton@tx72.mot.com) for this info. + +Fri Apr 7 18:33:30 1995 Douglas C. Schmidt (schmidt@siesta.cs.wustl.edu) + + * Added a new method to CORBA_Handler so that handlers don't need + to subclass from CORBA_Handler, but rather can call the + CORBA_Handler::register_service() method (which is static). + Thanks to Chris Tarr (ctarr@objectspace.co) for this suggestion. + +Mon Apr 3 13:09:45 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Added a new static method to Service_Config.[hC] called + end_event_loop(). This can be used to stop the run_event_loop() + method of the Service_Config. In addition, all the methods in + Service_Config were changed to be static to emphasize the fact + that the Service Configurator is a singleton... + + * include/Trace.h (ACE_TRACE): Changed the macro T to ACE_TRACE. + This will prevent namespace pollution. + + * Added support for the Orbix CORBA implementation. If you don't + have Orbix, you'll need to remove this flag from the + config-sunos5-sunc++.4.x.h file if you are compiling on SunOS + 5.x. + +Sun Apr 2 01:12:19 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Added new support for C++ wrappers around the IP multicasting. + There are three new files in ./libsrc/IPC_SAP/SOCK_SAP called + SOCK_Mcast.[hiC] and a new test directory in + ./tests/Reactor/multicast and ./tests/Reactor/ntalker to + illustrate how to use this stuff. Thanks to Tim Harrison + (harrison@cs.wustl.edu) for this code. + +Sat Apr 1 18:48:40 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Added support to the libsrc/Shared_Malloc/Memory_Pool.[hC] class + for System V shared memory, as well as for mmap(2) and sbrk(2) + memory. Please note that this has not been extensively tested + yet, so use with caution... + +Thu Mar 30 21:50:00 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Misc/Atomic_Op: Added the postfix versions of the ++ and + -- operators. This stops the Sun CC compiler from griping about + the "anachronistic" usage when using a++ rather than ++a. + Thanks to Bruce Worden for the + suggestion. + +Wed Mar 29 22:26:37 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor/Handle_Set: Fixed a weird problem where I was + using NOFILE as the max number of descriptors rather than + FD_SETSIZE. I don't know why I was doing this. + + * Also fixed up a problem with Handle_Set that was causing the + iterator to go nuts when it got a strange initial value of + fd_set in Handle_Set. Orbix triggers this kind of nonsense in + some cases... + +Tue Mar 28 21:01:36 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/Reactor/Reactor.C: swapped the order of dispatching so + that handle_exception methods are dispatched before handle_input + methods to improve response time for exceptions (e.g., OOB + data). Thanks to Detlef Becker + (beckerd@erlh.siemens.de) for suggesting this. + + * Fixed a bug in ./ASX/Stream.i that caused problems when a Module + was popped off a Stream. Thanks to Paul Stephenson for noticing + this and sending me the fix. + + * Changed the Reactor::dispatch methods so that they dispatch the + timers *before* dispatching the I/O-based event handlers. This + is helpful for systems that are time-delay sensitive. + + * libsrc/Reactor/Time_Value: Added new += and -= operators to + Time_Value. Thanks to Alex V. Maclinovsky + (garyh@teleng1.tait.co.nz) for this suggestion. + +Thu Mar 23 15:38:23 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP/Addr/SPIPE_Addr.i (set): Fixed a problem that the + HP/UX compiler had with complex arithmetic expressions. + + * libsrc/Service_Configurator: fixed up the Service_Configurator + source code so that it will compile correctly on HP/UX + platforms. + +Tue Mar 21 00:28:25 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * libsrc/IPC_SAP/SOCK_SAP/LSOCK_Connector.h: Fixed an amazingly + stupid bug with LSOCK_Connector, where I was passing in a + default argument of PF_INET instead of PF_UNIX... Arrgh! + +Mon Mar 20 20:24:29 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Fixed up the $WRAPPER_ROOT/include/makeinclude/ directory to + define a new set of platform-specific configuration files. This + should greatly improve the portability of ACE to different + OS/compiler platforms. + + * Added a bunch of changes to allow ACE to build with Lucid C++ on + SunOs 4.x. This should also fix some other problems we've been + having with SunOS 4.x. Thanks to Lee Baker (baker@ctis.af.mil) + for these changes. + +Sun Mar 19 00:34:30 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Added manual pages for all of the ./libsrc libraries. These + manual pages are all generated automagically from the libsrc + header files. + +Sat Mar 18 10:48:46 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Finally broke down and fixed the Makefile scheme so that there + is just one shared library (libACE.so) and one archive library + (libACE.a). This should massively simplify the application + development process, though it may require a bit of fixing of + Makefiles to remove all the -lReactor -lIPC_SAP stuff that was + in there before. + + * libsrc/IPC_SAP/TLI_SAP/: Fixed a stupid bug that was causing + core dumps since the TLI option pointers weren't initialized to + 0 in the TLI::TLI constructor. Thanks to Ed Brown for noticing + this (eebrown@netcom.com). + +Wed Mar 15 00:08:19 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Added some new fixes to get ACE to run on OSF1 and Linux. + +Tue Mar 14 13:36:31 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Added several changes to the source code and config-hpux.h + configuration file based on comments from Alex Ranous + (ranous@nsa.hp.com). In particular, changed ACE_HAS_NO_FDSET to + ACE_SELECT_USES_LONG. + +Mon Mar 13 09:23:58 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Improved the Makefile scheme so that the use of PTDIRS is no + longer required. The trick was to link the appropriate template + *.C files into the WRAPPER_ROOT/include directory. This enables + the compiler to find them in one single place. + +Sun Mar 12 22:35:50 1995 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Added a new mechanism to clean up the insane number of -D's in + the Makefile. This new mechanism requires a bit more work at + installation time, but should greatly reduce the effort during + normal software development + (once ACE is installed...). See the INSTALL file + for more details. + +Fri Mar 10 17:29:02 1995 Douglas Schmidt + + * Fixed a stupid bug in Map_Manager.i which wasn't correctly + setting default values for fields in one of the Map_Manager + constructors. + +Fri Mar 10 08:54:42 1995 Doug Schmidt + + * /libsrc/Connection/Acceptor.i: Fixed a potential memory leak in + handle_input(). + +Thu Mar 9 11:59:54 1995 Doug Schmidt + + * Changed the Map_Manager::find() method to use class Read_Guard + so that multiple finds may proceed in parallel on a multiple + threaded application. Likewise, changed the implementation of + bind() and unbind() to use class Write_Guard so that destructive + operations will be serialized correctly. One consequence of + this is that RW_Mutex must be used instead of Mutex... + + * Added a new overloaded Map_Manager::unbind() method with an + INT_ID parameter. This parameter that passes back a reference + to the internal id being unbound. This allows the caller to + clean up any dynamic memory associated with the INT_ID. + +Tue Mar 7 13:32:17 1995 Doug Schmidt + + * Changed a bunch more things to get ACE to compile with + Centerline C++. This should also make ACE more portable to + other cfront-based compilers. + + * Had to change the ASX source in ACE to work around a stupid + problem with templates in cfront-based C++ compilers. + Fortunately, it was possible to mask most of the problems using + the C++ preprocessor. + + * There seem to be some problems with cfront-based compilers (such + as centerline). They don't like the new SYNCH::MUTEX usage in + the Message_Queue. + + * Removed several unused local variables in the INET_Addr::set() + method. + +Wed Mar 1 00:35:11 1995 Douglas C. Schmidt (schmidt@tango) + + * Added a major performance boost on high-speed networks. It + turns out that send(3) and revc(3) are slower than write(2) and + read(2) (since the latter are system calls, and the former are + library calls. Therefore, I added new overloaded methods to + SOCK_IO so that write(2) and read(2) are available to the user! + +Tue Feb 28 10:13:09 1995 Douglas C. Schmidt (schmidt@tango) + + * libsrc/Reactor/Reactor.C: Fixed the implementation of the + Reactor::open and Reactor::Reactor constructor so that it is now + possible to resize the size of the Reactor *after* the + constructor has run (by calling open()) *without* having to shut + down the Reactor first. + + * Modified the Reactor::attach() method so that it will ADD the + new bits to the bitmask rather than SET them. Thanks to Mark + Patton for recommending this + (mark_patton@tx72.mot.com). + +Sat Feb 25 15:08:04 1995 Douglas C. Schmidt (schmidt@tango) + + * Released version 3.0.5. + +Fri Feb 24 17:57:01 1995 Douglas C. Schmidt (schmidt@tango) + + * Used the OSE class2man scripts to generate UNIX manual pages for + IPC_SAP, Thread, Connection, and Reactor. Other manual pages + will be forthcoming... + + * libsrc/IPC_SAP/Addr/INET_Addr.i: Fixed a bug in one of the + INET_Addr::set() methods that caused a segmentation fault if + host_name was NULL. In addition, greatly cleaned up the code so + that all the "set" methods share a common basis of code. + +Tue Feb 21 19:32:28 1995 Douglas C. Schmidt (schmidt@tango) + + * Updated the entire release to use the new SYNCH template + interface for Task, Module, Stream, and Message_Queue. This is + *much* cleaner, though it reveals some bugs with the Sun C++ + templates facility. + +Mon Feb 20 22:46:14 1995 Douglas C. Schmidt (schmidt@tango) + + * Changed the SPIPE_SAP, SOCK_SAP, and TLI_SAP *Connector class + methods from open() to connect(). This is a more accurate name + and it also fits in nicely with the Acceptor::accept() method. + + * Started integrating new versions of various header files that + include hooks to automatically generate documentation. + +Tue Feb 14 20:52:13 1995 Douglas C. Schmidt (schmidt@tango) + + * Changed the order in which the Reactor dispatches descriptors. + Originally, it dispatched the "read" descriptors *before* the + "write" descriptors. Now, it dispatches the "write" descriptors + first. This was necessary to handle weird behavior of sockets + over TCP/IP when data is piggy-backed with the final ACK on a + non-blocking connection. + +Mon Feb 13 15:49:21 1995 Douglas C. Schmidt (schmidt@tango) + + * Changed the name of Event_Handler::get_fd() to + Event_Handler::get_handle() to be more consistent with other + usage in ACE. + +Sat Feb 4 22:47:34 1995 Douglas C. Schmidt (schmidt@tango) + + * libsrc/Service_Configurator/Service_Object: changed the + destructor to be virtual (thanks to Steffen Winther Sorensen + for noticing this). + +Sat Jan 28 16:29:49 1995 Douglas C. Schmidt (schmidt@tango) + + * Changed the name of class Map_Manager's Search_Structure struct + to Map_Entry. This is more specific to what that data structure + really does. + + * Began adding support for Linux, courtesy of sts@dad.stibo.dk. + +Sun Jan 22 23:15:38 1995 Douglas C. Schmidt (schmidt@tango) + + * Changed the name of the ./libsrc/Connector-Acceptor directory to + ./libsrc/Connection. Also changed the name of libConn_Acc.so to + libConnection.so to be more consistent. + +Sat Jan 21 13:59:18 1995 Douglas C. Schmidt (schmidt@tango) + + * libsrc/IPC_SAP: Fixed the *Acceptor classes for SOCK_SAP and + SPIPE_SAP so they behave just like FIFO_SAP and contain a method + called remove(). This method closes the underlying descriptor + and also unlinks the local address from the file system. + + * libsrc/ASX/Message_Queue.i (copy): Fixed this code so that it + correctly stores starting at the wr_ptr rather than the rd_ptr. + Thanks to Chris Cleeland + (chris@milo.st-louis.mo.us) for pointing this out + to me. + +Wed Jan 11 13:07:19 1995 Douglas C. Schmidt (schmidt@tango) + + * Changed all uses of class Thr_Manager to class Thread_Manager + and class Thr_Cntl to Thread_Control. This is more readable and + is now consistent with the documentation... + +Tue Jan 10 13:49:31 1995 Douglas C. Schmidt (schmidt@tango) + + * Modified the makefile scheme so that only the *.so files are + built by default. If you want to build both *.a and *.so files, + uncomment out the lines described in + $WRAPPER_ROOT/include/makeinclude/rules.lib.GNU. Note that this + will require you to run make on the ./libsrc directories twice + in order to properly build and install both the *.a and *.so + libraries. + +Mon Jan 9 22:57:29 1995 Douglas C. Schmidt (schmidt@tango) + + * libsrc/Reactor/Signal.h: Changed the name of the Signal_Block + class to the Signal_Guard class to be more consistent with the + Guard class in Synch.h. + +Sat Jan 7 19:49:46 1995 Douglas C. Schmidt (schmidt@tango) + + * tests/ASX/Event_Server/Event_Server: Revised the Event Server + test example to use the Acceptor pattern components. + +Fri Jan 6 23:38:21 1995 Douglas C. Schmidt (schmidt@tango) + + * Added a new method to class Task that turns a task into an + active object (i.e., associates a thread of control with the + task). This is useful since it replaces all the places in + application code that original said "this->thr_mgr_.spawn + (THR_FUNC + (&this->svc_run))", etc... + +Thu Jan 5 21:05:15 1995 Douglas C. Schmidt (schmidt@tango) + + * libsrc/ASX: Changed the capitalization of class STREAM to class + Stream. This seems more reasonable since I don't see any + particular reason to shout about Streams! + + * libsrc/ASX/Task: Changed name of method qreply() to reply() to + reflect the fact that the name of the class is no longer Queue! + + * libsrc/ASX: Made both Task and Message_Queue into parameterized + types. This greatly improves the ability to parameterized + synchronization into an application. + + * Changed all occurrences of timestruc_t to use Time_Value + instead. This helps to improve portability and reduce the + "impedence mismatch" caused by mixing both C and C++ types in + the ACE interfaces. Note that one drawback of this is that we + lose nano-second timing accuracy. However, I don't know of any + real OS platforms that support that degree of precision anyway! + + * libsrc/Reactor: Moved the static "zero" data member from the + Timer_Queue class to the Time_Value class. Also added a new + static data member called "zerop," which is a pointer to "zero". + + * libsrc/Threads/Synch: Changed the interface of class Condition + so that it no longer has both wait() and a timedwait() methods. + Since C++ has default values, these two methods were redundant. + Now, there is only a single method called wait(). By default, + it's argument is 0, which defaults to the original wait() + semantics. If the argument is non-zero then the timewait + semantics apply. + + * libsrc/Threads/Synch: Added a new class called Null_Condition. + This is similar to the Null_Mutex class in the sense that it has + the same interface as class Condition, but it's methods are all + no-ops + (however, wait() and signal() both set errno = ETIME + before returning...). This class is useful for + parameterizing synchronization into an application. + diff --git a/ChangeLog-96a b/ChangeLog-96a new file mode 100644 index 00000000000..8b25e02595f --- /dev/null +++ b/ChangeLog-96a @@ -0,0 +1,3888 @@ +Sun Jun 30 15:28:43 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/OS.i (cond_timedwait): Fixed the implementation of the + ACE_OS::cond_timedwait() wrapper such that if the + caller-specified timeout elapses without the condition variable + being signaled that errno is always set to ETIME. This fixes + some inconsistencies that occurred with POSIX pthreads and Win32 + threads. Thanks to Ross Dargahi for pointing + this out. + + * ace/SOCK.cpp: Changed SOCK::close() to use the new + ACE_OS::closesocket() call. This should fix some weird bugs + that have been lurking in the code for some time now! + + * ace/OS: Added a new method to ACE_OS called closesocket(). This + handles the differences between Win32 and UNIX in their + treatment of sockets (e.g., NT requires the use of + closesocket(), whereas UNIX requires the use of close(). Thanks + to Irfan, Prashant, and Tim for figuring this one out! + +Sat Jun 29 21:23:04 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/SPIPE_Acceptor.cpp (create_new_instance): Added the flag + (FILE_FLAG_OVERLAPPED) in call to CreateNamedPipe. + +Fri Jun 28 01:31:24 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Svc_Handler.cpp (open): Fixed a small typo that caused a + compile error if the DEBUGGING macro was enabled. Thanks to + Irfan for finding this. + +Wed Jun 26 03:19:27 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Synch_T.cpp (ts_get): The tss object allocated off the heap + should be released if setspecific fails. Thanks to John Lu + for reporting this. + + * ace/CORBA_Handler.cpp (handle_input): changed ACE_OS::send and + ACE_OS::recv to ACE::send and ACE::recv respectively in + CORBA_Handler.cpp. Thanks to Irfan for pointing this out. + + * ace/Service_Config: slightly modified the Service_Config.[h,cpp] + in order to make it possible to create an ACE_Service_Config + with an external ACE_Reactor as a parameter. On creation I was + handling this partly correct (i.e., not creating a new reactor). + However, there was no flag for remembering this for a later + deletion. Thus, on deletion I was doing a delete on the Reactor + regardless of who created it. This is now fixed. Thanks to + Karlheinz for pointing this out. + + * examples/ASX/CCM_App/CCM_App.cpp: Changed all uses of init (int, + char **) to init (int, char *[]) to work around a "feature" with + MSVC++ 4.x... Thanks to Karlheinz for pointing this out. + + * ace/OS.h: Added a new typedef of TCHAR to be compatible with + Win32 UNICODE type names... + + * ace/{Mem_Map,DEV_Addr,SPIPE_Addr,FILE_Addr}: Added UNICODE + support for Win32 to all interfaces that require filenames. + + * ace/{SPIPE_Stream,SOCK_IO,FILE_IO,DEV_IO}: Added a new pair of + send()/recv() methods that take ACE_OVERLAPPED pointers in order + to make it possible to integrate seamlessly with Win32 + overlapped I/O. Naturally, these methods are simply + "callthroughs" to the ACE_OS versions... + + * ace/OS: Added a new pair of send()/recv() methods that take + ACE_OVERLAPPED pointers in order to make it possible to + integrate seamlessly with Win32 overlapped I/O. + + * ace/SPIPE_Acceptor: Factored out common code in the Win32 + implementation of ACE SPIPES (which uses Win32 Named Pipes, of + course ;-)). + + * ace/SPIPE_Acceptor.h: Removed a vestige of the past -- + ACE_SPIPE_LISTENER_H should be ACE_SPIPE_ACCEPTOR_H... + +Wed Jun 19 19:35:12 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/SPIPE_{Acceptor,Connector}: Modified SPIPE_Acceptor and + SPIPE_Connector to implement Named Pipes on NT. The public + interface remains the same. + +Sun Jun 16 00:45:41 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Service_Config: Provided public accessor methods for the + following data memebers of the ACE_Service_Config: + + reconfig_occurred_ + end_event_loop_ + + Thanks to Steve Warwick for suggesting this. + + * ace/Synch*: Added UNICODE support for the ACE synchronization + classes (e.g., ACE_Mutex, ACE_RW_Mutex, ACE_Semaphore, etc.). + + * ace/OS: Added UNICODE support for the ACE_OS::dl_open() + function, as well as the ACE_OS synchronization functions. + + * ace/CORBA_Handler: Added Seth's changes for Orbix 2.0. + +Sat Jun 1 13:30:55 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Memory_Pool.cpp (remap): Fixed a bug in + ACE_MMAP_Memory_Pool::remap (). The test for whether or not the + addr falls within the range had a '!' (not) missing, that is, it + was failing when it should be succeeding and vice versa. + +Sun Jun 9 00:01:44 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released version 4.0.24 for testing. + + * ace: Changed all uses of ACE_Guard m (lock_) to ACE_GUARD + (LOCK, lock_), which is a macro that is defined as follows: + + ACE_Guard ace_mon (LOCK); \ + if (m.locked () == 0) return; + + The reason we need this is (1) detect locking failures, rather + than have things fail silently and (2) to automatically detect + deadlock in the Reactor. In addition, I also added + ACE_GUARD_RETURN, which is similar to ACE_GUARD, except that it + returns a "failure" status when the lock is not acquired. + Thanks to Karlheinz for suggesting this. + + * ace/Log_Msg: Added the new thr_state() accessors to Log_Msg. + + * ace/Thread_Manager.cpp: factored out some common code by having + the public interfaces (like resume() and suspend()) utilize the + protected interfaces (like resume_thr() and suspend_thr()). + + * ace/Thread_Manager.cpp: Added sanity checks for suspend(), + resume(), cancel(), etc. so that we don't blow up if someone + tries to perform an operation on an invalid thread id. + + * ace/Thread_Manager: Added a suite of new methods for + (1) cooperatively "canceling" threads and (2) testing if threads + are cancelled (also added similar checks to test if threads are + suspended or resumed). The cooperative cancellation mechanism + is based on a design fleshed out with Detlef and Karlheinz. + It's essentially a compromise between the powerful mechanisms + available via POSIX pthreads vs. the totally lame mechanisms + available in Win32. + + Here's how it all works: + + 1. Added several new methods to ACE_Thread_Manager: + + cancel(thr_id); -- cancels thr_id + cancel_all(); -- cancels all the threads in a Thread_Manager + cancel_grp(grp_id); -- cancels a group of threads in a Thread_Manager + testcancel(thr_id); -- returns "true" if thr_id has been cancelled + + 2. Updated ACE_Log_Msg to maintain the current state of a thread + in thread-specific-storage (TSS). Actually, it's more clever + than that since I really keep a *pointer* to the state of a + thread in TSS. This pointer actually points *back* to the + ACE_Thread_State field in the ACE_Thread_Manager! I use it + as a cache as follows: + + ACE_Thread_Manager::testcancel (thread_t t_id) + { + ACE_MT (ACE_Thread_Mutex_Guard m (this->lock_)); + + // Try to get the cached value out of TSS to avoid lookup. + ACE_Thread_State *thr_state = ACE_LOG_MSG->thr_state (); + + if (thr_state == 0) + { // We need to init the cache. + int i = this->find (t_id); + if (i == -1) return -1; + // Update the TSS cache. + ACE_LOG_MSG->thr_state (thr_state = &this->thr_table_[i].thr_state_); + } + return *thr_state == ACE_THR_CANCELLED; + } + + Note that this allows me to avoid searching the + Thread_Manager on every Thread_Manager::cancel() access + except the first one! + + 3. I've updated the examples/Threads/test_thread_manager.cpp + test file to exercise the new cooperative thread cancellation + scheme. It basically spawns a bunch of threads that go into + their own event loops doing + + if (thr_mgr ()->testcancel (ACE_Thread::self ()) != 0) + break; + + every so often. Naturally, the main thread cancels them by saying + + thr_mgr ()->cancel_grp (grp_id); + + when it wants to inform them to shut down. + + * ace/Thread_Manager: Moved the Thread_State enum from the + ACE_Thread_Descriptor class to OS.h and renamed it to be + ACE_Thread_State. This will make it easier to integrate the + state of a thread in thread-specific storage... + +Sat Jun 8 13:35:17 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/OS.i (sema_post): revised the implementation of the POSIX + Pthreads semaphore implementation just a bit in order to make it + slightly more efficient (it now releases the mutex before + signaling the condition variable). + + * ace/OS.i and config-aix.4.1.h: added a fix that separates the + decision about whether optlen is a pointer from the decision of + the type of optlen. This fixes a problem on AIX. Thanks to Bob + Olson for this fix. + + * ace/Proactor.h: Fixed a small glitch that was causing some + compilers to break due to the fact that they can't grok fully + qualified destructor syntax in the class definition. Thanks to + Alfred Keller for reporting this. + + * ace/OS.h: Added some Win32 macros (e.g., GENERIC_READ) to the + UNIX side of the house in order to compile the Proactor on Win32 + and UNIX. + +Fri Jun 7 19:36:27 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Added a new Bourne shell script called ACE-install.sh that will + automatically download and install on UNIX machines. Thanks to + Ajit Sagar for contributing this. + +Thu Jun 6 00:37:02 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released version 4.0.23 for testing. + + * ace/Local_Tokens: Updated the *.cpp and *.i files to remove + warnings and generally improve the conformance to the ACE coding + guidelines. + + * examples: Moved the Proactor directory into the Reactor + directory since the Proactor and Reactor are really two + implementations of the same basic pattern. + + * ace/Memory_Pool.cpp: Fixed an inconsistency caused by not + updating __INLINE__ to __ACE_INLINE__. Thanks to Neil Cohen for + finding this. + + * ace: Added support for the Florida State PTHREADS package. + Thanks to Gary Salsbery and + Eric Beser for helping with this. + + * ace: Added support for the m88k OS. Thanks to Gary Salsbery + and Eric Beser + for helping with this. + + * ace/OS.h: Added a default value of NULL to the sigwait() OS + wrapper method to simplify the usecase in certain cases. + + * ace/Memory_Pool.cpp (commit_backing_store): Fixed what is + hopefully the last typo related to the ACE_DEFAULT_BASE_ADDR + macro. Thanks to Neil B. Cohen for reporting + this. + +Thu Jun 6 15:31:40 1996 Tim H. Harrison (harrison@lambada.cs.wustl.edu) + + * ace/CORBA_Handler.h: This version of the CORBA_Handler works + with Orbix 2.0. Most of the changes involve the use of C++ + Exception Handling (the removal of IT_X), and the location of + some CORBA system exception classes. + + * ace/Event_Handler.h: Added handle_*_complete methods for the + Proactor. The Proactor now takes Event_Handlers and calls back + the **_complete methods when overlapped I/O operations have + completed. + + * ace/Service_Config.h: Added static accessors for the Proactor to + the Service_Config object. Similar to the Reactor accessors, + applications can now use the Service_Config object as the global + access point to the Proactor event demultiplexor. + +Wed Jun 5 22:40:28 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/OS.i (t_free): Added a check to avoid deleting a NULL ptr. + This was causing problems for the TLI_Acceptor. Thanks to Ajit + Sagar for reporting this. + + * ace/Makefile: Changed things back so that both static and + dynamic libs are built by default... Thanks to Brad Brown + for pointing this out... + +Sat Jun 1 13:49:51 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released version 4.0.22 for testing. + + * Added Tim Harrison's latest tests for Proactor. + +Sat Jun 1 13:30:55 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Memory_Pool.cpp (remap): Fixed a bug in + ACE_MMAP_Memory_Pool::remap (). The test for whether or not the + addr falls within the range had a '!' (not) missing, that is, it + was failing when it should be succeeding and vice versa. + +Fri May 31 16:31:13 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Rereleased version 4.0.21 for testing. + + * Copied over new versions of the Proactor -- there was a small + problem with the UNIX version that caused it not to compile... + +Fri May 31 00:03:41 1996 Tim H. Harrison (harrison@lambada.cs.wustl.edu) + + * examples/Proactor/test_proactor.cpp: Added a test program for + the Proactor. Check examples/Proactor/README for more details + on this test example. + + * ace/Proactor.cpp: Added first pass at the Proactor for win32. + The Proactor is a Reactor-like abstraction that uses + asynchronous I/O, rather than synchronous I/O. On Windows NT we + implement the Proactor using overlapped I/O. We'll soon be + porting the Proactor to Solaris using POSIX 4.x aio_* API for + real-time programming. + + Unfortunately, the Proactor has not yet been integrated with + Windows NT WaitForMultipleObjects since it appears that I/O + Completion ports are not "waitable" objects on Windows NT. Does + anyone know if this has been fixed in release 4.0? + +Thu May 30 05:51:23 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Synch.i: Reordered the definitions of several methods in + Synch.i to avoid warnings from G++. Thanks to Marco Sommerau + for noticing + this. + + * ace/Log_Msg.cpp: There was a problem having to do with the order + in which static objects by G++. In particular, G++ was calling + the constructor of the lock_ mutex in Log_Msg.cpp *after* it was + being used for the first time. The right solution is to make + lock_ be a pointer and allocate it once in the instance() + method. Thanks to Marco Sommerau + for finding this + problem. + + * ace/TLI_Acceptor.cpp (close): Make sure to only close down the + TLI_Request_Queue if queue_ is non-NULL! Thanks to Ajit Sagar + for spotting this. + + * ace: Changed all the enums in the various SysV wrappers from + things like CREATE and OPEN to ACE_CREATE and ACE_OPEN to avoid + name clashes with other systems. In addition, also changed + NONBLOCK to ACE_NOWAIT to avoid clashes with the existing + ACE_NONBLOCK macro! Thanks to Steve Warwick + for suggesting this. + + * ChangeLog: Changed all usages of the INLINE macro to ACE_INLINE. + This avoids name clashes with other systems. Thanks to + Chris Eich for + suggesting this. + +Mon May 27 13:03:58 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Map_Manager.cpp (trybind): The function trybind() doesn't + return a value as it should. A return was missing from the last + line of the function. Thanks to Stuart Powell + for finding this problem. + + * ace/Acceptor.cpp (dump): The debug print referred to + "scheduling_strategy_" which doesn't exist in the relevant + class. Replacing it with "concurrency_strategy_" fixes the + problem. Thanks to Stuart Powell for + finding this problem. + + * ace/Mem_Map.i: Make sure to close down the file mapping + correctly when we upmap the view! + + * ace/OS.h: Changed the default shared memory address from 16 M to + 64 M in order to work around problems with AIX. + + * ace/Memory_Pool: Moved and renamed the enums in + ACE_Shared_Memory_Pool so that they'd be in OS.h. This makes it + easier to remember to change them if they are incorrect. Thanks + to Lionel Mommeja for suggesting this. + + * ace/Stream.cpp: Removed #if defined (ACE_HAS_THREADS) + + * ace/OS.cpp (svc_run): Added a Win32 try/except block to + Spawn_Args::svc_run so that we catch all Win32 structured + exceptions in order to make sure that we clean up correctly when + the thread exits. + +Sun May 26 11:37:08 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Local_Name_Space.cpp: Used the new Win32 exception + integration in order to ensure that the Name Server will + transparently work correctly when the backing store is extended + by other processes on the same machine. + + * ace/Memory_Pool.cpp: Revised the ACE_MMAP_Memory_Pool to export + the mechanism for extending the virtual memory mapping. This + can now be called by other programs (e.g., in order to integrate + with Win32 Structure Exception Handling). + + * ace/Memory_Pool.cpp: Changed the use of ACE_OS::lseek() to + ACE_OS::filesize() in order to determine the current offset when + we're remapping the address space. + +Wed May 22 13:08:44 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/OS.h (ACE_DEFAULT_TIME_SERVER_STR): Added a new entry for + ACE_DEFAULT_TIME_SERVER_STR. + + * ace/Malloc_T.cpp (advance): Fixed two small bugs. In + ACE_Malloc::try_bind(), if we have a match we need to set + pointer to node->pointer_ and not node->name_. + Ina ACE_Malloc_Iterator::advance(), the continue in the for loop + should be for strcmp != 0 instead of == 0. + +Sun May 19 12:03:11 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released version 4.0.20 for testing. + + * ace/Service_Record.cpp (remove): Fixed a very mysterious bug + that was caused by deleteing an object and then trying to access + it's next_ pointer. This worked on UNIX, but fortunately the + MSVC++ compiler does special things to deleted memory and the + bug was revealed! At long last, MSVC++ does something right + ;-). + + * ace/Module.cpp: Revised the code a bit to use the ACE_SET_BITS + and ACE_CLR_BITS macros to improve readability. + + * ace/SV_Semaphore_Complex.cpp (open): Fixed a race condition + where we weren't correctly checking for EIDRM. Thanks to + Michael Fortinsky for reporting this. + +Sat May 18 10:49:04 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace: Added a new ace.mak and ace.mdp file for Win32. + + * ace/Service_Record.cpp: Rewrote some code to work around a bug + with MSVC++. This bug was causing problems since the + ACE_Shared_Object methods were getting called, rather than the + Test_Task methods used in the examples/ASX/CCM_App.cpp file. + Thanks to Tom Leith for pointing out this problem! + + * ace/OS.h: Added a new #define for ACE_DEFAULT_SVC_CONF to deal + with differences between NT and UNIX pathnames. + + * ace/Time_Value.h: Moved the definition of the INLINE macro from + OS.h to Time_Value.h so that it will be in scope for + Time_Value.i. Thanks to Neil Cohen for reporting this. + + * examples/Reactor/Misc/signal_tester.cpp: There was a typo in + signal_test.cpp. It had mean to use handle_input() rather than + handle_output() to exercise the asynchronous signal handling + capabilities. This is fixed now. + + * apps/Synch-Benchmarks/Benchmark.cpp (thr_id): Added a new #if + define (ACE_HAS_DCETHREADS) to make this work on AIX. Thanks to + Greg Wilson for reporting this. + + * ace/Local_Name_Space: Moved ACE_NS_String and ACE_NS_Internal + from the *.cpp file to the *.h file to work around a "feature" + of the AIX C++ compiler. Thanks to Greg Wilson + for reporting this. + + * ace/Reactor.h (ACE_Handler_Repository): Changed the type of + cur_size_ from size_t to ssize_t to avoid type mismatches. + + * ace/Name_Request_Reply.cpp (decode): Fixed some inconsistencies + between signed and unsigned loop counters... + + * ace/OS.h: Changed the typedef of pid_t on Win32 from + DWORD to long to be consistent with UNIX. + +Thu May 16 18:49:14 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released version 4.0.19 for testing. + + * build/SunOS5.4/ace/ACE.cpp (ldfind): Fixed a bug in ldfind() + that caused a segfault if we didn't resolve the filename in the + LD_SEARCH_PATH. + + * ace/Reactor and Timer_Queue: Changed the interface of cancel() + to include a const void **arg. If arg is non-NULL then it will + be set to point to the ``magic cookie'' argument passed in when + the Event_Handler was registered. This makes it possible to + free up the memory and avoid memory leaks. + + * ace/Service_Record: Removed the #ifdefs that checked if + ACE_HAS_THREADS because we ought to be able to build all of this + stuff now that we've got the ACE_OS wrappers. + + * ace/Svc_Conf.y: Removed the #ifdefs that checked if + ACE_HAS_THREADS because we ought to be able to build all of this + stuff now that we've got the ACE_OS wrappers. + + * ace/OS.h (ACE_DEFAULT_BACKING_STORE): Made a different + ACE_DEFAULT_BACKING_STORE for NT and for UNIX to handle the + differences in directory separator characters... + +Wed May 15 18:45:48 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * examples/ASX/CCM_App/CCM_App.cpp: Fixed up the test application + so that it should support dynamic linking on Win32. Thanks to + Tom Leith for reporting this. + + * ace: Added the ACE_Export macro to class ACE and the various + "helper" classes related to ACE_Malloc in order to have this + work properly when use with ACE_Malloc outside of the ACE DLL. + + * ace/Svc_Conf.l: Added support for '\' and ':' in the regular + expression for an ACE pathname in order to support Win32 + filenames (e.g., "C:\foobar\"). Thanks to Tom Leith + for reporting this. + + * ace/Malloc_T.cpp (ACE_Allocator_Adapter): Moved the constructor + from the *.i file to the *.cpp file and added a new constructor + that takes both a pool_name *and* a lock_name. This is + necessary because the ACE Malloc now has this API, as well. + + * examples/Threads/test_barrier.cpp (main): Fixed a bug that was + caused by the main() thread exiting before all the other worker + threads had finished "waiting" on their Barrier. The fix is to + use ACE_Thread_Manager to control the thread exits... + +Mon May 13 00:03:09 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * examples/Connection/non_blocking/CPP-acceptor.cpp: Modified the + implementation of the Svc_Handler::open() method so that it will + truly behave as an iterative server (as advertised...). + Currently, it behaves as a half-iterative server (i.e., the + Oneshot_Acceptor is iterative, but the Svc_Handler is + "concurrently"), which is causing problems because we're wiping + out the values of Svc_Handler each time through the main event + loop. Thanks to Gerolf Wendland for noticing this problem. + + * ace/Log_Msg: Added an alternative logging mechanism that makes + it possible to integrate variable argument lists from other + logging mechanisms into the ACE mechanism. Thanks to Chris + Lahey for proposing this. + + * ace/Synch.h: Moved ACE_Process_Mutex so that it appears *after* + ACE_Mutex (since it depends on ACE_Mutex). Thanks to Dieter + Quehl for finding this. + + * Released version 4.0.18 for testing. + + * ace/Name_Space.cpp: Added the ACE_BUILD_DLL macro at the + beginning of this file so that it will build as a DLL on NT + correctly. + + * ace/Name_Space.cpp: Added a default constructor for + ACE_Name_Binding so that it will compile when used as a template + argument for ACE_Unbounded_Set. + +Sun May 12 14:23:44 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Map_Manager: Totally reworked the Map Manager so that it can + be more flexible with respect to where the allocator comes from. + This is necessary for certain parts of ACE (e.g., + Local_Name_Space) that must be very careful about which + allocator is used to manage memory. + + * ace/Synch: Moved ACE_Process_Mutex and ACE_RW_Process_Mutex + *outside* of the ACE_HAS_THREADS #ifdef since these are now + always defined on all platforms (because the Process_Mutex stuff + uses SV Semaphores, which are portable even if we don't have + threads!). + + * ace/Naming_Context.cpp (parse_args): Removed an unnecessary call + to strdup(). This was detected by Purify! + +Sun May 12 14:26:20 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Local_Name_Space.cpp (shared_bind): Fixed a small bug. In + computing type_len in shared_bind(), we needed to add 1 to + account for the NUL character. + + * ace/Local_Name_Space.cpp: (list_types): Fixed some potential + memory leaks. In list_types() as well as list_type_entries() + calling pattern.char_rep() was allocating memory which was never + getting deleted. Similarly, in list_names() and list_values, + call to char_rep was also allocating memory that was not getting + deleted. + +Sat May 11 16:19:51 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Log_Msg.cpp (local_host): added a static member to + ACE_Log_Msg that maintains the local host name. Now, instead of + always displaying "", we can insert the actual local + name into the object and then it will be automatically printed + when VERBOSE mode is enabled. Thanks to Chris Lahey for + suggesting this. + + * ace/Local_Name_Space.cpp: Used the new ACE_Name_Binding class to + simplify the implementation of all the list_* methods in + ACE_Local_Name_Space. + + * ace/Name_Space.cpp: Made a number of changes to the + ACE_Name_Binding class in order to make it work more efficiently + and concisely (e.g., reduce the amount of copying and eliminate + the need for converting the type field back and forth to/from + ACE_WStrings). + + * examples/Service_Configurator/IPC-tests/server/Handle_L_Dgram.cpp: + Fixed a typo where #if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + was *before* the #include of the header file that defines this + macro! Thanks to Nigel for pointing this out, as well. + + * ace: Added a number of fixes to make ACE compile on SCO UNIX + 3.2.4 using gcc 2.7.2. Thanks to Nigel Lowe for + helping with this. + + * netsvcs/lib/Name_Handler.cpp: operation_ needs to be declared as + just LIST_OP and not ACE_Name_Handler::LIST_OP. For some strange + reason NT complains otherwise. Thanks to Prashant for finding + this. + +Fri May 10 01:09:17 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace: Added new versions of ace.mak and ace.mdp to fix a couple + of minor typos. + + * ace/Malloc_T.cpp (ACE_Malloc): Added a new constructor that + takes both the pool_name and the lock_name explicitly. This is + more flexible. Thanks to Ramesh Nagabushnam + for suggesting this. + + * ace/Malloc_T: Modified the constructor of ACE_Malloc so that by + default the name of the memory pool (which is also used as the + name of the lock...) is ACE_DEFAULT_MUTEX. + + * Released version 4.0.17 for testing. + + * ace/Connector.cpp (create_AST): Must reset errno = EWOULDBLOCK + to avoid making caller's think that something else has gone + awry... Thanks to Steve Warwick for chasing + this down! + + * ace/ACE.cpp (handle_timed_complete): If you issue a non-blocking + connect on a socket, you will have back a failure with errno = + EINPROGRESS. Then, if for some reason, the connection could not + be established, the select (which you have to issue to know + about the completion of connection) will return you the fd set + both in the read mask and in the write mask (infact select + returns 2 in this case). The behaviour above affects the method + ACE::handle_time_complete, so I changed the last part of the + above method, this way: + + if (n <= 0) + { + ... + ... + } + else if (rd_handles.is_set(h)) + { + char dummy; + // The following recv() won't block provided that the + // ACE_NONBLOCK flag has not been turned off . + + if (ACE::recv (h, &dummy, 1, MSG_PEEK) <= 0) + return ACE_INVALID_HANDLE; + } + + // 1. The HANDLE is ready for writing or 2. recv() returned that + // there are data to be read thus the connection was successfully + // established. + return h; + + That is, I reversed the sense of the tests so that the + rd_handles() is checked first for failure along with the recv(). + Thanks to Antonio Tortorici for + suggesting this. + + * examples/Threads/test_thread_manager.cpp (main): Changed argv[1] + to argv[2]. Thanks to Andres Kruse for finding + this problem. + + * examples/Connection/non-blocking: Fixed some nasty bugs that + caused the non-blocking connector and acceptor test programs to + crash and burn. Thanks to Steve Warwick and Gerolf Wendland for + finding this problem. + + * ace/SV_Semaphore_Simple.cpp (open): Check for + ACE_INVALID_SEM_KEY and return -1 in this case. + + * ace/Synch.h: Removed the default value of 0 for the name of the + ACE_Process_Mutex and the ACE_RW_Process_Mutex and replaced it + with a new macro called ACE_DEFAULT_MUTEX. Using 0 didn't make + any sense on either NT or UNIX because process-wide Mutexes + should be named! + + * ace/SV_Semaphore_Simple.cpp (name_2_key): Added a check for name + == 0 and bail out of that's the case rather than crash! + + * ace/Reactor.cpp (wait_for_multiple_events): In the Reactor's + wait_for_multiple_events method, the do {} while () around the + select/poll system call is trying to wait until some "good" + event occurs, with handle_error() taking care of unexpected + problems. In the case of a bad file descriptor, however, + handle_error() returns 0. This was exiting the loop because the + loop exit condition was: + + do { /* ... */ } while (nfound == -1 && this->handle_error () > 0); + + which eventually causes ACE_Service_Config::run_event_loop() to + exit. Since the offending file descriptor is handled by + handle_error(), the loop should continue. Therefore, I've + changed the while to read: + + while (nfound == -1 && this->handle_error () >= 0); + + Thanks to Eric C. Newton for providing this fix. + + * ace/INET_Addr.cpp (string_to_addr): Changed the order of the + parameters so that the form is now "ip-address:port". This + should (finally) be consistent for both string_to_addr() and + addr_to_string()... + + * ace/Log_Msg: Changed the char * parameter of the log() method to + const char *. Thanks to Chris for suggesting this! + + * ace/Synch_T.cpp: Moved the #if defined (ACE_HAS_THREADS) down to + the right part of the file... Thanks to Alex Karev + for finding this. + + * ace/Malloc.h: Added a very important #else... Thanks to Alex + Karev for finding this. + + * ace/Signal.i (ACE_Sig_Guard): Changed the sense of the #ifdef + tests in the ACE_Sig_Guard constructor and destructor from #if + !defined (ACE_MT_SAFE) to #if 0 // !defined (ACE_MT_SAFE) in + order to get the right semantics for signals (which should be + blocked "process wide"). + + * ace/Synch_T.h: put the frigging copy constructor in the public + section of ACE_Atomic_Op because it was causing trouble for + NT... + +Mon May 6 00:11:37 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released version 4.0.16 for testing. + + * ace/Log_Msg.cpp: Was defining ACE_Recursive_Thread_Mutex in the + wrong place (i.e., outside of the #if defined (ACE_MT_SAFE). + This was screwing up HP/UX. Thanks to Neil Cohen for pointing + this out! + + * Incorported new versions of ace.mdp and ace.mak for Win32. + +Sun May 5 16:18:43 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * netsvcs/lib/Server_Logging_Handler.cpp (handle_input): Fixed a + bug whereby handle_input() was returning the number of bytes + read by handle_logging_record() rather than 0 or -1. This was + causing problems for the logger since it was hanging in read()! + + * ace/Synch_T.cpp: Fixed some minor problems with the use of const + in ACE_Atomic_Op that was causing warnings. + +Sat May 4 16:31:46 1996 Douglas C. Schmidt (schmidt@mambo.cs.wustl.edu) + + * ace/SOCK_Dgram_Bcast: Reimplemented most of the ACE socket + broadcast mechanism to (1) clean up the code and have it use + other parts of ACE and (2) make it work for Windows NT. Thanks + to Steve Weismuller for the basic + ideas here. + + * ace/INET_Addr: Added a new method to set the port number without + changing the host address. This is useful in the broadcast + class. + + * ace/Log_Record.cpp (print): Changed the hack of replacing the + newline with a call to flush() instead. This seems like a + better fix. Thanks to Alex for suggesting it. + + * ace/Log_Msg.cpp (log): Moved the order of the print operations + so that the ostream one goes last. This avoids a nasty problem + due to the fact that it replaces the newline (if any). Thanks + to Alex for pointing this out too! + + * ace/Log_Msg.cpp (log): Don't auto-increment bp at the end of + the log() method, instead just terminate it: + + *bp = '\0'; // Terminate bp. + + This makes the length computation correct... Thanks to the + ever-vigilent Alexandre Karev for + reporting this. + + * examples/Shared_Malloc/test_malloc.cpp: Fixed a bug where a void + * that was really an int was being cast incorrectly. Thanks to + Raj for pointing this out. + +Sat May 4 12:51:25 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Reactor.cpp (find): Modified the ACE_Handler_Repository so + that it doesn't crash when it isn't initialized properly. + Thanks to Darrin for pointing this out. + + * ace/Synch_T.cpp (wait): Changed the call wait(ACE_Time_Value *) + to wait(const ACE_Time_Value *) since wait() will not change the + time value object. + + * ace/Thread_Manager.cpp (wait): Changed the call + wait(ACE_Time_Value *) to wait(const ACE_Time_Value *) since + wait() will not change the time value object. Thanks to Chris + Lahey for suggesting this. + + * ace/Synch.h: Added a (const char * = 0) argument to + ACE_Null_Mutex so that it would work correctly with + ACE_Thread_Mutex and ACE_Process_Mutex... + +Fri May 3 17:26:07 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * netsvcs/lib/Name_Handler.cpp (lists_entries): Used '_' with + name/value/type in ACE_Name_Binding to be consistent with the + notation. + +Fri May 3 02:24:19 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Synch: Updated ACE_Process_Mutex to use SV_Semaphore_Complex + as the UNIX implementation. This seems like the only portable + and robust way to get the same semantics on UNIX and on NT! + + * ace/Malloc_T: It turned out there was a subtle bug with + ACE_Malloc on NT when used with the ACE_Process_Mutex + concurrency policy. On NT, we were storing the *HANDLE* of a + mutex in shared memory. Naturally, this didn't make any sense + since each HANDLE is relative to only one process!!! (duh ;-)). + This worked fine on UNIX because mutex_t's created with + USYNC_PROC mode can be stored in shared memory and accessed + directly... + + We fixed this by changing ACE_Malloc so that the + LOCK is allocated in non-shared memory. We then + fixed ACE_Process_Mutex so that on UNIX it is + implemented with SV_Semaphore_Complex. This is + (a) portable and (b) it gives the right semantics. + + As a result, we were able to totally eliminate the storage of + the lock in shared memory. Therefore, it doesn't matter of the + host crashes anymore! In addition, we were able to totally + remove the ugly "init_finished" lock that was previously stored + in shared memory by ACE_MMAP_Memory_Pool. This is *much* + cleaner!! + + Thanks to Karlheinz et al for pointing this problem out in the + first place! + + * ace: Removed a stray file called Svc_Conf_tokens.h. This was + causing problems on Win32 due to name clashes... Thanks to Adam + Miller for pointing this out. + + * ace/SString.cpp (strstr): there were some for (size_t j; ...) {} + if (j == x) constructs in the code that have as of recently + become non-standard. Thanks to Darrin + for reporting this. + +Tue Apr 30 00:18:46 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Thread.i (self): Commented out the ACE_Trace call in the + ACE_Thread::self() methods to avoid infinite recursion problems + on Win32. + + * ace/Token.cpp (ACE_Token): Commented out the ACE_Trace call in + the constructor of ACE_Token to avoid infinite recursion + problems on Win32. + + * ace/Log_Msg.cpp (instance): Moved the definition of the static + variable keylock_ into the static instance() method in order to + avoid "order of initialization" problems on Win32. Thanks + to Tim for figuring this out! + +Sun Apr 28 17:07:58 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * netsvcs: Rearranged and renamed the subdirectories so that they + are now called ./netsvcs/{lib,clients,servers}. In addition, + moved the Logger, Naming, and Tokens examples from ./examples + into the ./netsvcs/clients directory in order to make the + relationships more clear. + +Sat Apr 27 14:23:43 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Name_Space.cpp (operator ==): Created a new file + Name_Space.cpp and moved the definitions for + ACE_Name_Binding::operator== and ~ACE_Name_Space in it. Also + modified code to use '_' at the end of name/value/type in + ACE_Name_Binding. + +Sat Apr 27 16:00:03 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/INET_Addr.i (get_host_addr): There was an error where + sprintf(s,"%d:%s" ...) should have been %s:%d. Thanks to + Raj for pointing this out. + +Mon Apr 22 01:24:45 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Dump_T.h: #included "ace/Dump.h" so that this file will + compile on HP/UX. Thanks to Neil Cohen for reporting this + problem. + + * Released version 4.0.15 for testing. + + * ace/Synch_T: Added the appropriate "const" qualifiers to certain + operators in ACE_Atomic_Op. + +Sun Apr 21 12:54:18 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace: Fixed a problem that Dieter was having with the Name Server + when toggling between Naming_Contexts. Basically, what I've + done is + + 1. Moved the unmap() call into the ACE_Mem_Map::close() method + (this ensures that the region is correctly unmapped when the + Mem_Map is deleted). + + 2. I've removed the call to this->allocator_->remove () within + ~ACE_Local_Name_Space. This ensures that we don't remove the + backing store file. + + * ace/Mem_Map.cpp: Modified the ACE_Mem_Map::remove method to call + ACE_Mem_Map::close() in order to share code. + + * ace/Mem_Map.cpp: Modified the ACE_Mem_Map::close() method so + that it unmaps the mapped region before closing down the backing + store. This prevents "dangling mapping." + + * ace/Local_Name_Space.cpp (ACE_Local_Name_Space): Initialized all + the pointers to NULL. + + * ace/Synch_T.cpp (ACE_Atomic_Op): Enhanced the Atomic_Op + implementation by adding an assignment operator and disallowing + the copy constructor (forcing objects of ACE_Atomic_Op to be + passed by reference). + + * examples/Naming/Client/Client_Test: Reorganized the code for + Client_Test so that it will run correctly as a Win32 netsvc + (e.g., added the ACE_Svc_Export macro). + +Sun Apr 21 20:23:40 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Naming_Context.cpp (close): Added a new method to + Naming_Context called close() that deletes the instance of + name_space_. + + * ace/Local_Name_Space.cpp (ACE_Local_Name_Space): Added stuff to + the destructor of Local_Name_Space so that it calls remove on + the allocator_ to ensure we unmap the file. Also, we delete the + allocator_. + + * examples/Naming/Client/Client_Test.cpp (set_proc_local): Changed + set_proc_local (), set_node_local() and set_host() so that + before we change name space, we do a close() on + Naming_Context. The close ensures that we unmap the file as well + as delete the instance of the name space. + +Sat Apr 20 12:39:20 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace: Removed the Name_Options.* files and merged the + ACE_Name_Options class into Naming_Context.*. This simplifies + some order of include problems... + + * ace/Naming_Context.cpp (init): Switched the code so that rather + than always opening with ACE_Naming_Context::PROC_LOCAL, we use + ACE_Name_Options::context(), which can be overridden by using + the new -c command-line option (e.g., -c NODE_LOCAL). Thanks to + Dieter for suggesting this. + + * ace/OS.i: Modified the Win32 implementation of all the + ACE_OS::flock_*lock() methods so that they'd have the same + behavior as the UNIX ones with respect to a length of 0 meaning + "lock the entire length of the file." This works, of course, by + having each method check if len == 0, and if so, calling + GetFileSize() to set the size of the file. + + * ace/Synch.h: Changed the default len value for all the + File_Lock::*acquire* methods to 1 rather than 0 to work around a + problem with Win32. Thanks to Detlef for reporting this. + + * ace/ACE.cpp (ldfind): Added a strdup() of the LD_SEARCH_PATH + returned by getenv() so that we don't overwrite the environment + variable by using strtok(). Thanks very much to Prashant for + figuring this out! + +Thu Apr 18 22:13:43 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * examples/Naming/Client/Client_Test.cpp (list_value_entries): + Added check in list_name_entries and list_value_entries to see + if type actually exists before trying to print it out. + +Wed Apr 17 16:40:42 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released version 4.0.14 for testing. + + * Added Tim Harrison's new instructions for building and using ACE + as a DLL and SLL on Win32. + + * ace/Svc_Conf.h: Due to the new changes to the yacc code, I had + to move the definition of YYSTYPE into the Svc_Conf.h file + rather than have it in the Svc_Conf.y file. This solves a + variety of multiple-inclusion problems... + + * ace: Modified all the yacc token symbols so that they will be + prefixed with ACE_. This avoids namespace pollution problems. + + * Added the ACE_STATIC_SVC* macro support to a number of files so + that the static versions of all the ACE services will be + registered with the ACE Service Repository correctly. Thanks to + Jesper for pointing this out! + + * ace/OS.h: the first occurence of + + typedef thread_t tid_t; + + in the OS.h file should read + + typedef pthread_t tid_t; + + Thanks to Jan Rychter for reporting this. + + * ace/Read_Buffer.cpp: Fixed rec_read() so that it will fail + correctly when new fails! + +Wed Apr 17 19:05:42 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * netsvcs/lib/Name_Handler.cpp (type_request): Here is a brief + description of the changes made to ACE_Name_Handler to simplify + the dispatch method and make it more elegant: + + 1) I created a table called op_table_. It contains pointers to + member functions of ACE_Name_Handler. This table can be + indexed using the msg_type. However, I went one step further + to have all the list methods be grouped under two + methods. That is, requests for list_names, list_values, and + list_types are handled by one method called lists() and + similarly, requests for list_name_entries, + list_value_entries, and list_type_entries are handled by + another method called lists_entries(). A MASK is used to have + the op_table_ index to the same method for these requests. + + 2) I also created another table called list_table_. This is + primarily used by lists() to keep track of a couple of things: + + pointers to member functions of Name_Handler that + handle the actual request. + + pointers to member functions of Name_Handler that act + as factories to create the appropriate request to + send back. + + description of the message type. + + A different MASK is used to index into the list_table_ to + invoke the appropriate method or get the appropriate description. + + 3) Within the method lists_entries(), I once again make use of + the pointers to member functions technique. This time, + however, I use pointers to member functions of Naming_Context + which I assign in the switch statement. + +Tue Apr 16 13:03:49 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released version 4.0.13 for testing. + + * ace/INET_Addr.i: moved the get_port_number routine up to the top + of the file so it gets defined before it is used. Linux did not + like it where it was... Thanks to Neil Cohen for reporting + this. + + * ace: Split the Dump.* files into Dump_T.* files. This is + necessary to support the template policies of various C++ + compilers. + + * ace/Malloc_T.cpp (dump): Fixed an erroneous use of -> since + guard_ is a non-pointer... Thanks to Neil Cohen for reporting + this. + + * ace/Log_Record.cpp (print): Finally figured out how to do + extensible ostream logging so that it will seamlessly work with + ACE_Log_Msg. This required one change to ACE_Log_Record, + however. In Log_Record.cpp: + + In ACE_Log_Record::print(char *, int, ostream, size_t len), added + + char *t = this->msg_data_[len - 1]; + + if (t == '\n') + *t = '\0'; + + s << this->msg_data_ << endl; + + This is required because the virtual function overflow() in + streambuf does not get called until endl is called to flush the + buffer. Note that (at least on AIX), '\n' is treated separately + from endl and will not cause the overflow() function to be + called. Thanks to Chris Lahey for this idea. + + * ace/OS: Added a new wrapper for strrchr(). + + * ace/Token_Collection.cpp (renew): Added a cast of + (const char *) to token_name so that the conversion operator + will get called correctly. Thanks to Gonzalo Diethelm + for reporting this. + +Tue Apr 16 13:29:32 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Name_Request_Reply.cpp (decode): Fixed a small bug in encode() + and decode() of ACE_Name_Request. When doing ntohs and htons, we + only ought to do it for the name and value part of data. type + needed to be left alone since it is not a short. + +Mon Apr 15 02:31:00 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * include/makeinclude/platform_hpux_orbix.GNU: Added + David.L.Sames.1@gsfc.nasa.gov (David Sames) config*.h file and + platform_*.GNU file for HP/UX 9.x using Orbix. + + * ace/OS.i: Fixed all uses of pthread_cleanup_{pop,push} so that + they will work correctly if (1) the OS implements the as macros + and (2) if these macros must obey strict nesting rules... + Thanks to Reginald S. Perry for pointing out + how to do this effectively. + + * ace/Thread_Manager.h: Fixed a typo where the typedef + + typedef (ACE_Thread_Manager::*THR_FUNC)(int, int); + + was lacking a return value. Thanks to Reginald S. Perry + for reporting this. + + * netsvcs/bin/main.cpp (main): Fixed the main program so that it + passes the options correctly for the statically linked service + invocations. Thanks to Jesper for reporting this. + + * examples/Naming/Client/Client_Test: Updated the client test + program so that it will work on Window NT, where it's not valid + to select() on non-socket HANDLEs (ugh). Thanks to Jesper for + pointing this out... + + * Released version 4.0.11 for testing. + +Mon Apr 15 00:20:02 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Local_Name_Space.cpp (strstr): Fixed ACE_NS_String::strstr + to function properly. It was assuming that length of the pattern + as well as the string was in units of ACE_USHORT16 when in + reality the length is number of bytes. + + * ace/Local_Name_Space.cpp (value_): Modified ACE_NS_Internal so + that instead of taking an ACE_NS_String for type, it now take a + char*. It therefore keeps type around as a char*. This should + help solve some problems we were encountering with byte ordering + when sending data between NT machines and Sun. + + * netsvcs/lib/Name_Handler.cpp: Cleaned up lists_entries by making + use of pointer to member functions. A single call to the + appropriate list method takes care of everything. + +Sun Apr 14 16:21:32 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/INET_Addr.i (addr_to_string): Swapped the order that the + hostname and port number are printed to make this consistent + with the way that ACE_INET_Addr::string_to_addr works. Thanks + to Ashish Singhai for pointing + this out. + + * ace/TLI_Acceptor: Changed the methods to take an ACE_Addr rather + than an ACE_INET_Addr. This allows other address families (such + as DECnet) to be used with the TLI wrappers. Thanks to Ajit + Sagar for suggesting this. + + * ace/Local_Name_Space.cpp (list_types): Removed the use of + regular expression matching for the name and value types of the + name server and replaced these with substring matching instead. + This is necessary since we're working with wide characters here, + and it doesn't make any sense to perform regular expressions on + these puppies... + + * ace/Local_Name_Space.cpp: Added a new strstr() method on all the + ACE_NS_String class so that we can compare substrings for wide + character types. + + * ace/SString: Added a new strstr() method on all the + ACE_[WSC]String classes so that we can compare substrings, + even for wide character types! + + * apps/gperf: Incorporated the GNU gperf program from the FSF. + We're going to make some improvements to this for a subsequent + paper. + +Sun Apr 14 15:30:05 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Name_Request_Reply.h: Changed the enum values for the + Constants such as BIND, REBIND, etc. The new values allow us to + do bitwise operations using MASK to be able to dispatch the same + method for all the list operations. For use case of this, please + see Name_Handler::dispatch(). + + * netsvcs/lib/Name_Handler.cpp (dispatch): Completely changed + dispatch() so that now it uses a table of pointer to member + functions to call the appropriate method when a request + arrives. In addition, requests for LIST_NAMES, LIST_VALUES, and + LIST_ENTRIES are now handled by one method called lists() in which + I factored out a lot of common code. Similarly, requests for + LIST_NAME_ENTRIES, LIST_VALUE_ENTRIES, and LIST_TYPE_ENTRIES are + handled by lists_entries(). This has really cleaned up the code. + +Sat Apr 13 15:26:51 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Name_Request_Reply.cpp: Made changes so that all + byte-ordering computations take place in encode and decode + methods of ACE_Name_Request_Reply and ACE_Name_Reply + only. Previously some of these computations were taking place in + Get/Set methods such as name_len() which was highly error prone. + (init): Added new methods called init() to both ACE_Name_Request + and ACE_Name_Reply that initialize length to size of transfer_. This + is needed since the length gets set only once in the constructor + and after that each call to encode() switches the byte ordering + causing problems. + +Sat Apr 13 11:44:16 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released version 4.0.10 for testing. + + * ace: Removed the ACE_HAS_THREAD_T macro from various places. + This was unnecessary given the new scheme for dealing with + threading. + + * ace/config-linux-pthread.h: Fixed a typo that was preventing + compilation from working. Thanks to Jan Rychter + for finding this. + +Fri Apr 12 13:17:47 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * apps/Gateway/Gateway: The gateway application appears to + be working again! + + * ace/OS.cpp (thr_create): Based on conversations with Chris + Lahey, modified the pthreads ACE_OS::thr_create implementation + so that it doesn't try to assign the hthread_t thr_handle since + this is meaningless in pthreads... + + * apps/Gateway/Gateway/Gateway.cpp: Fixed a typo that was causing + the system to go into an infinite loop when the config file was + empty! + + * apps/Gateway/Gateway/Gateway.cpp: I was forgetting to set the + line_number to 0 before calling read_entry()... + + * ace/Parse_Node.cpp: Fixed a dumb error that arose because I + forgot that you can't call dlerror() twice and get the same + result (it returns NULL the second time). As usual, RTFM. + + * ace: Removed ACE_HAS_TLI from all the SunOS 4.x config*.h files + and platform_*.GNU files. There are just too many bugs with TLI + on SunOS 4.x to support it by default... + + * examples: Made some minor fixes to make the examples all compile + with GCC. + + * apps/Gateway/Gateway/Gateway: Reimplemented the Gateway + application as to be an ACE network service. This should make + life much easier on platforms with broken C++ templates... + + * apps/Gateway/Gateway: Revised the Config_Parser.* files so that + templates would be split from the non-templates. This avoids + bugs with some C++ compilers... + + * ChangeLog: added the ACE_TEMPLATES_REQUIRE_SPECIALIZATION flag + to the config-linux-pthreads.h file. Thanks to + Jean-Francois.Ripouteau@netsurf.org for reporting this, and also + for archiving the ACE mailing list. + +Thu Apr 11 01:37:25 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released version 4.0.9 for testing. + + * ace: regenerated all the manual pages and html pages. + + * Built ACE successfully on SGI IRIX 5.3 using GNU G++ 2.7.2. + + * ace/Thread_Manager: renamed the descriptor() accessor methods to + hthread_descriptor() and thread_descriptor() to avoid + ambiguities due to the fact that hthread_t and thread_t can now + be the same type. + + * ace/Thread_Manager: revised the hthread_t so that it is always + large enough to hold valid thread ids. + + * ace: Moved the config-osf1.h file to be named config-osf1-3.2.h + in anticipation of OSF/1 4.0... + + * ace: Changed all occurrences of wchar_t to ACE_USHORT16, which + is a more portable way of representing wchar_t's so that we can + pass them across the network... Unfortunately, wchar_t tends to + be different sizes on different machines, so we can't use the + binary form!!! + + * ace: Added many, many small changes to get ACE to compile on + OSF/1 3.2D using DEC C++ 5.3. Thanks to Tom Marrs + <0002104588@mcimail.com> for slogging through all of this stuff! + + * ace/Thread_Manager.h: Fixed a stupid oversight where I forgot to + add a -1 to the trailing argument of spawn*. Thanks to Neil + Cohen for spotting this. + + * ace: Added a new ACE config file for AIX 3.2.5 courtesy of Bob + Olson . In addition, I changed the name of the + config-aix.h file to be config-aix-4.1.x.h and called the new + file config-aix-3.2.5.h. + + * apps/Synch-Benchmarks/Benchmark.cpp: Added template + specializations for ACE_TSS and ACE_Atomic_Op. Thanks to Matt + Stevens for pointing out the need for this. + + * ace/CORBA_Handler: Added a number of fixes to get the ACE + CORBA_Handler to compile on Win32 with Orbix 2.0. Thanks to + Rich Ryan for these fixes. + + * ace/OS.cpp (thr_create): Fixed a small bug in the pthreads + thr_create() code by dereferencing p_thr before casting it + to hthread_t and assigning it to *thr_handle. + + * ace/OS.i: Backed out the previous changes of pthread_cleanup*. + It turns out that on SunOS 5.5 these macros force a certain + style of programming this is hard to integrate with the existing + implementations of other ACE wrapper methods. Fortunately, none + of this affects existing ACE code since we just use the default + solaris threads API in this case... + + * ace/OS.i: Modified the order of #ifdefs in various ACE_OS::thr_* + methods to take advantage of the pthreads features on Solaris + 2.5. + + * ace: Removed the last few typos that prevented ACE from building + on SunOS 4.x with G++... + + * ace/Thread_Manager: Changed spawn() and spawn_n() so that + they optionally take a group parameter and automatically add + this to an existing thread group. That way we don't need to + spawn the thread(s) and then reassign them after the fact. + The new API automatically assigns the thread(s) to the group + you specify. Thanks to Chris Lahey for this idea. + + * ace: Fully integrated POSIX pthreads into the ACE build for + Solaris 2.5. + + * netsvcs/lib/Server_Logging_Handler.cpp: Rearranged the Server + Logging files so that things will compile and link correctly + using stock GNU G++. + + * ace/Log_Msg.cpp (ACE_Log_Msg): Forgot to initialize the ostream + * to 0. This was causing problems for Win32... + + * ace: *Finally* got the static and dynamic ACE libraries to + compile on SunOS 4.x using stock G++! + + * ace/Synch_T.h: Added a new macro called ACE_SYNCH that will + be ACE_NULL_SYNCH if !ACE_HAS_THREADS and ACE_MT_SYNCH if + ACE_HAS_THREADS. + + * ace/Service_Record.cpp: Changed this to use ACE_SYNCH. This + will fix template problems with G++ on SunOS 4.x. + + * build/SunOS5.5/ace/OS.i (sema_wait): Changed all uses of + ::pthread_cleanup_{push,pop} to pthread_cleanup_{push,pop} since + these are implemented as macros on Solaris.... + +Thu Apr 11 19:43:33 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * examples/Naming/Dump_Restore/Dump_Restore.cpp (init): Modified + Dump_Restore in order to work correctly without having + Name_Options around as a Singleton. + + * examples/Naming/Client/Client_Test.cpp (set_host): Modified + Client_Test in order to work correctly without having + Name_Options around as a Singleton. It simply uses the accessor + provided by Naming_Context to get to Name_Options. + + * ace/Name_Options.cpp: Changed Name_Options so that it is no + longer a Singleton. As a result, now there is an instance of + Name_Options per Naming_Context. Note that for an application to + change Name_Options, it can use the accessor function provided + in Naming_Context. As a consequence of all these changes, we can + now have multiple Naming_Contexts per application. + +Wed Apr 10 20:19:50 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/OS.h: Incorporated a mapping for Solaris 2.5 pthreads so + that it fits in nicely with the earlier ACE pthreads support. + From now on, the pthreads API will be the default threading + scheme for ACE on Solaris 2.5... + + * ace: Added the file name to every *.cpp and *.i file in ACE. + This makes it easier to figure out what's what when looking at + the source code. Thanks to Chris Lahey for suggesting this. + + * ace/CORBA_Handler.cpp (ACE_CORBA_Handler): Added bodies for + the copy constructor and assignment operator of ACE_CORBA_Handler + (which are private) since some compilers generate link errors + for these! Thanks to Rich Ryan for + pointing this out. + + * ace/Synch_T.cpp (ts_get): at line 270 (within + ACE_TSS::ts_get (void) const) there was a keycreate() call + that did not have an instance pointer pass in with it. The + symptom has been that if the last active task has been finished + all active tasks being created afterwards won't get the close() + hook invoked. I've fixed this in order to solve a mysterious + bug with ACE_TSS. Thanks to the ever-vigilant Detlef for + reporting this bug and fix. + +Wed Apr 10 01:56:52 1996 Douglas C. Schmidt (schmidt@mambo.cs.wustl.edu) + + * ace: Added the ACE_TEMPLATES_REQUIRE_SPECIALIZATION to + config-sunos5.5-g++.h file. This should allow ACE to build + correctly. Thanks to Adam Miller for pointing this out. + + * ace: Installed SunOS 5.5, so now we can finally test pthreads! + + * ace/OS: Modified the implementation of mutex_t for Win32 so that + it automatically selects the CRITICAL_SECTION or the HANDLE form + of Mutex depending on whether the type argument is USYNC_THREAD + or USYNC_PROCESS, respectively. This now means that all the + existing ACE code that used ACE_Condition will + continue to work correctly on Win32 and UNIX! + +Tue Apr 9 23:04:30 1996 Douglas C. Schmidt (schmidt@mambo.cs.wustl.edu) + + * ace/Synch: Somehow, the definitions for ACE_Thread_Semaphore and + ACE_Process_Semaphore were MIA. I've added the implementations. + Thanks to Bruce Worden for + noticing this... + +Tue Apr 9 02:16:02 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Service_Config.cpp: reordered the #includes in this file so + that it works correctly on Win32. Thanks to Rich Ryan + for help with this. + + * ace/Auto_Ptr.cpp (remove): added the implementations of the + auto_ptr::remove() and auto_array_ptr::remove() static methods. + Thanks to Chris Lahey for noticing their absence... + + * ace/Auto_Ptr: Added the #pragma implementation ("Auto_Ptr.cpp") + statement if defined ACE_TEMPLATES_REQUIRE_PRAGMA to work on + AIX. Thanks to Chris Lahey for this. + + * ace/Makefile: Moved Auto_Ptr from FILES to TEMPLATE_FILES to + work on AIX. Thanks to Chris Lahey for pointing this out. + + * Modified a bunch of the apps and example Makefiles so that + things will build better using G++. + + * ace/Name_Options.cpp (parse_args): Made the "database" name the + same as the process name by default... + + * ace/Reactor.h: Changed the type of current_ in + ACE_Handler_Repository_Iterator from size_t to ssize_t so that + this can handle negative numbers. Thanks to Mark Zusman + for reporting this. + +Mon Apr 8 23:33:15 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * netsvcs/lib/Name_Handler.cpp (recv_request): Fixed a small + bug. In recv_request() ntohl was being called again on length + which was causing problems since the length was already in host + byte order. The ACE Name Server should now be working on NT. + +Mon Apr 8 02:14:30 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace: Fixed a number of minor problems that caused duplicate + symbols when linking ACE with G++ (no-repo) on SunOS 5.x and + SunOS 4.x. Thanks to Andy Gokhale for help with this. + + * ace: Added Jan Rychter very nice contribution + of pthreads and DCE threads to ACE. This should make life + easier for Linux users and users of other pthreads packages. + + * ace/Service_Config.cpp (process_directives): Changed the code to + use an auto_ptr to make sure that we always release the + ace_obstack memory, regardless of how we exit. + + * ace/OS.i (strerror): Changed sys_errlist to _sys_errlist to work + around bugs with SunOS 4.x. This will undoubted break some + other twisted UNIX system. + + * ace/Local_Tokens.cpp (acquire): Added a return 0 at the very + end... Thanks to Chris Lahey for reporting this (yet + again... ;-)). + + * ace/Parse_Node: Made a bunch of small changes to deal with the + fact that there's no dlerror() equivalent on NT... + + * ace/Task.h: The static function instance() should return + ACE_Task_Exit* (or ), not + ACE_Task_Exit *. Thanks to Chris Lahey for spotting this. + + * ace/Thread_Manager.cpp: added an argument to the exit() method + that allows applications to exit without calling thr_exit. This + would allow the method to be called from within a pthread + cancellation cleanup routine, without calling thr_exit a 2nd + time. Thanks to Chris Lahey for suggesting this. + + * ace/Log_Record.cpp (operator <<): Changed the verbose option so + that it is an attribute, this will allow the ostream to print + verbose information if necessary. Thanks to Chris Lahey for + suggesting this change. + + * ace/config-win32-msvc*.h: Added the + ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES flag since it appears + that this causes problem with some versions of MSVC++ 4.0... + + * Released version 4.0.6 for testing. + + * netsvcs/lib/Server_Logging_Handler.h: #included the + Svc_Handler.h file, that absence of which was causing problems + for HP/UX. Thanks to Richard Orr + for reporting this. + + * Made a few minor changes to the source to make sure that it + compiles correctly on SunOS 5.x with G++. + + * ace/Thread_Manager.h: Added the insert() method for the non-MT + version of Thread_Manager. Thanks to Alexandre Karev + for reporting this. + + * ace/Task: Renamed the static double-check lock_ to + ace_task_lock_ to avoid a name conflict with the existing + this->lock_ instance in each class. Thanks to Prashant for + tracking this down... + +Sun Apr 7 14:40:05 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * examples/Service_Configurator/IPC-tests/server/Handle_Thr_Stream.cpp: + Rolled back a change that replaced #defines with typedefs. It + turned out the #defines were there for a reason... Thanks Neil + B. Cohen for pointing this out... + + * ace/OS.h: Added a new check to deal with the fact that many + versions of Pthreads don't support tid_t (which seems to be an + AIXism...). + +Thu Apr 4 01:19:19 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Officially released version 4.0.5... + + * ace/OS.h (ACE_TSS_TYPE): Somehow the ACE_TSS_TYPE macros ended + up *before* the inclusion of Time_Value.h, which meant that + these macros weren't being expanded properly. This may help + explain odd behavior with ACE TSS. + + * ace/Thread_Manager.cpp (insert): Added a new method that allows + us to insert a thread into an ACE_Thread_Control after it's been + constructed. + + * ace/Message_Block: Fixed a typo in the init() method. Thanks to + Ross Dargahi for noticing this. + + * ChangeLog: Finally got all of ACE built on SunOS 5.x and SunOS + 4.x using only the stock GNU GCC compiler (i.e., no template + repository...). This should make it easier to port to other + versions of G++. + + * ace/Task: Modified the ACE_Task and ACE_Task_Exit implemenation + so that it only uses 1 TSS key per ACE_Task template + instantation, rather than 1 TSS key per ACE_Task instance. This + works around horrible limitations with Win32... + + * ace/Thread_Manager: Added new methods to set and get the + Thread_Manager used in a Thread_Control. + + * ace/Pipe.cpp (open): Fixed a bug in where ACE_Pipe::open did not + set this->handles_, thus a garbage handle gets registered. + Inserted the following two lines at line 53 of Pipe.cpp: + + this->handles_[0] = reader.get_handle (); + this->handles_[1] = writer.get_handle (); + + Thanks to Kirk Sinnard for this fix. + + * ace/OS.h: Added a couple of fixes for the SCO port. Thanks + again to Matt Newhook + + * ace/OS.cpp: Integrated Detlef's clever scheme for freeing up + thread-specific storage correctly on Win32... + + * ace/Task.cpp (ACE_Task): Made sure to initialize the + next_-pointer of ACE_TASK and Message_Queue point to NULL. + This fixes a problem on NT. Thanks to Karlheinz for + noticing this... + + * include/makeinclude/rules.lib.GNU (VLIB): Fixed up the ACE + makefiles so that we can now build on SunOS 4.x correctly + without using the template repositories... + + * ace/Service_Config.cpp: Added a bunch of template + specializations so that GNU G++ can be used to compile ACE on + SunOS 4.x *without* requiring the template repository hacks... + Thanks to Mark Zusman for helping with this. + +Wed Apr 3 00:55:12 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * examples/Reactor/Misc/test_reactors.cpp: Added a new torture + test of the ACE_Reactor and ACE_Task. Thanks to Detlef for + contributing this... + + * netsvcs/bin/Makefile: Removed a stray -lACE_svcs from the + Makefile. Thanks to Matt Stevens for reporting this. + + * ace/Synch.cpp: Fixed two mistakes related to keeping INLINE on + the get_thread_id() and get_nesting_level() when I moved them + into the *.cpp file... Thanks to Matt Stevens for finding this. + + * ace/Reactor.cpp (owner): modified owner() so that it returns + the original owner when setting a new owner. This makes it + possible to write code like this: + + thread_t t; + + reactor->owner (ACE_Thread::self (), &t); + reactor->handle_events (); + reactor->owner (t); + + * ace/SOCK_Connector.cpp (connect): Added an additional check for + errno == EWOULDBLOCK for non-blocking connects due to screwy + semantics of Win32 non-blocking sockets... + + * netsvcs/lib/Client_Logging_Handler: Fixed a very obscure bug + that arose due to the way that UNIX select() interacts with + SVR4 MSG_BAND data. It turns out that you must use the + ACE_Event_Handler::EXCEPT_MASK to get this to work properly + (gag). This stuff is much easier with SVR4 poll(). + +Tue Apr 2 13:57:05 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/OS.i: Fixed an error compiling the new Log_Msg.cpp because + when it inlined OS.i, there were references to + ACE_OS::thread_mutex_*() before the functions were declared + inline. The references were assumed to be external, and then + when the linkage was actually declared as inline, the compiler + choked. To fix this, in OS.i, all the thread_mutex_* calls + where moved above the first reference, which was in + ACE_OS::cond_broadcast(). Also moved the mutex*() calls since + they are referenced by the thread_mutex calls. So the order is + mutex*(), then thread_mutex*(), and then cond*(). Thanks to + Chris Lahey for reporting this. + + * netsvcs/lib/Client_Logging_Handler.cpp: Added missing return + values in some of the methods. Thanks to Tim Harrison for + spotting this... + + * ace/Map_Manager.cpp (shared_unbind): It was possible that INT_ID + could be assigned a value from a previously unbound map entry. + The shared_unbind matches the ext_id, but does not see if the + entry had previously been unbound. This causes a problem if the + INT_ID type is a pointer type, and the user of the map deletes + objects as a result of the unbind returning a 0. The correct + solution is to include a test for is_free in the shared_unbind + before checking the equality of the ext_id. Thanks to Phil + Mesnier for reporting this. + + * ace/Reactor.cpp (next): Fixed a bug that prevented the + iterator's next() method from detecting the end of the + iteration. Thanks to Mark Zusman + for reporting this. + + * ace/Reactor.cpp (advance): Fixed a bug that prevented the + iterator from advancing. Thanks to Mark Zusman + for reporting this. + + * ace/Log_Msg.cpp (open): Added a check for logger_key being NULL, + in which case we log to STDERR rather than segfault... + + * netsvcs/lib/Server_Logging_Handler.h: Fixed a typo in + the declaration of + + ACE_SVC_FACTORY_DECLARE (ACE_Server_Logging_Acceptor) + + Thanks to Neil Cohen for finding this. + +Mon Apr 1 00:17:21 1996 Douglas C. Schmidt (schmidt@mambo.cs.wustl.edu) + + * ace/Time_Value.i: Fixed two stupid bugs in the Time_Value + relational operators. Thanks to Mathew Newhook + for pointing this out. + + * ace/OS.h: Added an extern "C" block around the netdb, net/if.h, + netinet/in.h, arpa/inet.h to work around problems with SCO. + Thanks to Mathew Newhook for this. + + * ace/Reactor: Merged the ACE_Pipe into the Reactor + implementation. This cleans up some nasty OS-specific code in a + clean way. + + * ace/CORBA_Handler.cpp (ACE_MT_CORBA_Handler): Fixed some typos + that arose during the transition to the ACE_Pipe. + + * ace/Pipe: Added a new open() method that doesn't return the + handles, it just stashes them away for safe keeping. This is + useful for places like the Reactor. + + * ace/Local_Name_Space.h: Added ACE_Export to the front of + ACE_NS_String. Thanks to Detlef for suggesting this. + + * From now on, I'll be numbering each new release of ACE with a + different minor number. However, the latest version of ACE will + also always be available at + + http://www.cs.wustl.edu/~schmidt/ACE.tar.gz + + This is useful if you just want to get the latest one without + having to bother with keeping track of minor numbers. For + instance, that way you can still keep that reference in my + bookmark list and you don't have to remodify it with every + release. Thanks to the ever-vigilant Chris Lahey for suggesting + this. + + * ace: added new a ACE project file (ace.mdp) and Makefile + (ace.mak) to create ACE as a DLL on Win32. This should greatly + simplify the Win32 build process... + + * INSTALL: Added new INSTALL file explaining how to build for + Win32. + + * ace/Thread_Manager.cpp: Fixed a horrible bug with Win32. On + reasonable systems ACE_Thread::exit() should not return. + However, due to horrible semantics with Win32 thread-specific + storage this call can return (don't ask...). Therefore, we need + to reacquire the mutex so that we don't get burned when the + Guard automatically releases it when this method returns. Thanks + to Tim for helping me figure this out. + + * ace: Fixed some problems with errno in Remote_Tokens and + Local_Tokens. + + * ace/Reactor.cpp: Fixed an annoying preponderance of useless + ACE_MT_SAFE #ifdefs in the Reactor implementation. Thanks to + Gerolf Wendland for pointing this + out! + +Sun Mar 31 13:09:27 1996 Douglas C. Schmidt (schmidt@mambo.cs.wustl.edu) + + * ace/OS: Changed the implementation of cond_t and rwlock_t for + Win32 to use thread_mutex_t (i.e., CRITICAL_SECTIONS) rather + than mutex_t (i.e., Win32 Mutexes). This should improve + performance without sacrificing generality (of which there is + none at the moment since we don't have process-wide condition + variables or readers/writer locks on Win32 anyway.. + + * ace/Thread_Manager.cpp (remove_thr): Fixed bugs in the + ACE_Thread_Manager class. The wait() member grabbed the + Thread_Mutex lock_, then (if the current_count is not zero) + grabs the Condition lock zero_cond_. Doing so, however + implicitly released lock_, which meant that another thread could + get into wait(), and wait on zero_cond_. zero_cond_ was only + signaled from ACE_Thread_Manager::remove_thr() when the + current_count_ is zero, but it signaled with + ACE_Condition_Thread_Mutex::signal(), which only releases one + thread that is waiting on the Mutex. Thus, any other threads + waiting on zero_cond_ would never be resumed. The fix was to + use ACE_Condition_Thread_Mutex::broadcast() rather than + ACE_Condition_Thread_Mutex::signal() in + ACE_Thread_Manager::remove_thr(). This fix is only reliable + since remove_thr() is called only when ACE_Thread_Manager::lock_ + is held by the calling thread. Thank to Bruce Worden + for reporting problem and + suggesting this fix. + + * ace/Token: Modified this class so that it only works with + ACE_Thread_Mutex (which is more precise than what was going on + before...). + + * ace/Synch.h: Modified ACE_RW_Process_Mutex so that on Win32 it + uses ACE_Process_Mutex until we've got a working + RW_Process_Mutex for Win32... + + * ace/Synch: Removed the ACE_Process_Barrier until we get a + working implementation... + + * ace/Synch: Changed the ACE_Barrier so that it only tries to work + within a single process. + + * ace: Changed all uses of ACE_Condition_Mutex to + ACE_Condition_Thread_Mutex to reflect what's really going on + here... + + * Changed all uses of ACE_Mutex to ACE_Thread_Mutex throughout + ACE. This is *much* more meaningful and makes it possible to do + some great optimizations on Win32! + + * ace: Changed all uses of ACE_Mutex_Guard to + ACE_Thread_Mutex_Guard. This is a more accurate name for how + this is used in ACE. + + * netsvcs/lib/Client_Logging_Server: Reengineered the ACE + Client_Logging service so that fits into the ACE network service + format. This version is particularly interesting since it + illustrates a "Connector-driven" service. In contrast, all the + other ACE network services are "Acceptor-driven" services. + + * netsvcs: Merged the implementation of all the ACE network + services into a single ./netsvcs/lib directory. Each of these + is now a fully dynamically linkable service. Created a single + main.cpp program in the ./netsvcs/bin directory. This main + illustrates how to dynamically link an or all of the ACE network + services to form complete applications. Thanks to Prashant for + help with this. + + * ace/OS.cpp: Changed readv() and writev() so that they will once + again compile for Win32. Note, however, that if you try to + readv() and writev() on the same descriptor you will lose since + they are not atomic! However, this stuff is stuff useful if + you're *not* reading/writing to a common descriptor... + + * ace/Synch_T.cpp: Removed the ACE_Null_Condition<> template. + This didn't really make any sense... + + * ace/OS: Changed the test of lock_.get_nesting_level() in + ACE_TSS_Cleanup::exit () to account for the fact that a + ACE_Recursive_Thread_Mutex now starts out with a nesting level + of 1 when it is first acquired. + + * ace/Synch_T: Removed the implementation of ACE_Recursive_Lock. + It just doesn't generalize correctly to other types of + synchronization mechanisms... + + * ace/Synch: Reimplemented ACE_Recursive_Thread_Mutex using Dave + Butenhof's strategy. This fixes some + latent race conditions in the original implementation. + + * ace: Changed the name of ACE_Recursive_Mutex to + ACE_Recursive_Thread_Mutex since the current implementation + really only works for Thread_Mutexes or Thread_RW_Mutexes... + + * ace: Removed the "Assert.h" file and moved its functionality + into Log_Msg.h. This is more consistent with the rest of the + error reporting and logging in ACE and also avoids some nasty + circular include problems. + + * ace/Local_Tokens.cpp: Changed the use of ACE_RETURN so that it + passes in errno. + + * ace/Log_Msg: Changed the arguments to the ACE_RETURN macro so + that errno can be returned explicitly. + +Sun Mar 31 15:52:58 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Local_Name_Space.cpp (create_manager): Added three new + methods -- list_name_entries, list_name_values, and + list_name_types. They work similar to list_names, list_values, + and list_types (respectively) except they return the entire + tuple associated with a name binding. + +Sat Mar 30 16:46:32 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/SPIPE_Stream.i (send_handle): There was a typo -- the + parameter shouldn't be "const ACE_HANDLE handle", it should + just be ACE_HANDLE handle. + +Sat Mar 30 16:09:25 1996 Douglas C. Schmidt (schmidt@mambo.cs.wustl.edu) + + * INSTALL: Added new Win32 installation instructions to build + ACE as a DLL. + +Sat Mar 30 14:42:02 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Carefully tested ACE on SGI and SunOS 5.x using G++ and CC. + Everything seems to work now... Released version 4.0.2. + + * ace/Acceptor.cpp (ACE_Strategy_Acceptor): Added default + initializations of NULL for service_name_ and + service_description_ in the ACE_Strategy_Acceptor's default + constructor. + + * ace: Fixed a slew of warnings for HP/UX. Thanks to John Morey + for reporting these. + + * ace/FILE.h (ACE_FILE_Info): Changed the type of field size_ from + size_t to off_t to avoid warnings from C++ compilers... + + * ace/OS.cpp (ftruncate): Added a new function for platforms like + SCO that lack ftruncate(). Thanks to Matthew Newhook + for contributing this. + +Sat Mar 30 12:41:16 1996 Douglas C. Schmidt + + * ace: Removed the ACE_svcs library for the time being and merged + everything back into libACE. There were two reasons for this + change: + + 1. There is a subtle dependency between the ACE_Reactor and the + ACE_Local_Tokens* stuff when deadlock detection is enabled. + This was causing problems. + + 2. This was driving GNU G++ nuts because of the need to + do the "prelink." + + Sooo, for the time being, there's just one ACE library. If + anyone wants to take the time to split everything up so that it + works for all different platforms and send me the fixes I'll be + glad to include this in ACE. + + * ace/Thread.i: Made the ACE_Thread::thr_self() methods call + down to the ACE_OS::thr_self() methods for the case where + the platform doesn't support threads. This means that we + only have to set the default thread id in one place... + +Sat Mar 30 11:53:31 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * bin/class2info.awk: Modified the handleClass() AWK function so + that it can correctly deal with the new ACE_Export and + ACE_Svc_Export tags needed to build ACE DLLs... Here's the + trick: + + sub( "^[\t ]*class[\t ]+(ACE_[.]*Export[\t ]+)?", "", $0 ) + + completely intuitive, eh? ;-) + + * apps/Gateway: Reimplemented the Gateway prototype so that it + uses the new Reactor cancel_wakeup() and schedule_wakeup() + methods instead of mask_ops(). + + * ace/Reactor: Added new high-level "scheduling" + operations called schedule_wakeup() and cancel_wakeup(). These + methods utilize the lower-level Reactor mask_ops() methods to + schedule and cancel Event_Handlers for subsequent dispatching by + the Reactor. I added these new interfaces because they are more + intuitive than calling mask_ops(), which is a non-descriptive + name unless you understand the Reactor implementation... + + * ace/config-irix5.*.h: It turns out that on IRIX 5.x the + bi-directional SVR4 pipe semantics are *disabled* by default. + Therefore, I've changed the config-irix4.*.h files to comment + out ACE_HAS_STREAM_PIPES. + +Fri Mar 29 08:25:33 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/ACE.cpp (ldfind): Changed the character given to strtok() to + account for the differences in UNIX and Win32 described in the + follow bullet. + + * ace/OS.h: UNIX and Win32 use different characters to separate + pathnames in their runtime LD search path (':' and ';' + respectively). Therefore, I've added new macros to ACE OS to + account for this stuff portably. + + * ace/OS.i: Changed the behavior of the ACE_OS::thr_self() methods + so that they always return 1 if ACE_HAS_THREADS is *not* + enabled. This makes application code work correctly across + threaded and non-threaded platforms. + + * ace/OS.i: Changed the return value of the Win32 arm of the + ACE_OS::dlopen() and ACE_OS::dlsym() functions so that they are + now identical to the way that UNIX behaves. + + * ace/Svc_Conf.y: added a #define for ACE_BUILD_DLL to make Win32 + happy... + + * ace/Synch.i: Fixed a number of bugs in the ACE_Mutex and + ACE_Thread_Mutex tryacquire_read() and tryacquire_write() + methods. I was calling mutex_lock() rather than + mutex_trylock()! Thanks to Prashant for finding this. + + * ace/OS.cpp (exit): Fixed a bug caused by the fact that the test + for the nesting level of the recursive mutex should have been + for > 0 rather than > 1. Thanks to Kirk Sinnard + <1764@mn.lawson.lawson.com> for tracking this down! + + * ace/Log_Msg: Enhanced ACE_Log_Msg so that it automatically + caches the process id. This makes it more robust even if users + don't call open()! + + * examples/Connection/non_blocking/CPP-connector.cpp Fixed a bunch + of typos that caused templates to fail on HP/UX. Thanks to Neil + Cohen for spotting this. + + * ace/Shared_Memory_SV: Change all uses of "int id" to "key_t id" + to reflect the new use of key_t in the Memory_Pool. + + * ace/Memory_Pool.cpp (ACE_MMAP_Memory_Pool): Fixed a potential + but in the construction of an MMAP memory pool. Because NT uses + strings rather than integers to name its semaphores we were + passing in junk to the NT Process_Mutex initializer. Arrgh! I + fixed this problem by typedef'ing key_t to be char * on Win32 + and then updating the ACE_DEFAULT_SEM_KEY to be + "C:\\temp\ace.sem" rather than 1234.... Also added a new macro + called ACE_INVALID_SEM_KEY, which is NULL on NT and -1 on UNIX. + + * ace/Log_Msg.cpp (instance): Fixed a typo for HP/UX and + other non-threaded platforms! + + * ace/Synch_T.cpp (ACE_TSS_Guard): Added another small fix + to ACE_TSS_Guard to make sure we free up the key when we + go away. + +Thu Mar 28 15:28:44 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/OS.h: changed the names of macros ACE_DYNAMIC_SVC* to new + names that reflect their new, more general nature now that we've + got the ACE_Static_Svcs stuff... + + * ace/Service_Config.cpp (load_defaults): Added a very nice + mechanism that generalizes the configuration of statically + linked services. This makes it possible to insert statically + linked services into a program without changing any of the + existing ACE_Service_Config code. These static services can + then be enabled via the svc.conf file using the "static" + directive. Thanks to Matthew Newhook for + suggesting this and for doing the bulk of the implementation. + + * ace: Commented out the ACE_TRACE calls in ACE_Unbounded_Set, + ACE_OS, and all the ACE synchronization wrappers to work around + some horrible dependencies with Win32 and thread-specific + storage... The moral here is that you have to be careful what + you trace because circualar dependencies abound... My new + policy is that low-level routines are not automatically traced + because they can cause infinite recursion. + + * ace/Synch_T.cpp: Fixed a nasty bug with ACE_TSS_Guard. This was + causing programs that uses ACE_TSS_Guard to segfault... Thanks + to Kirk Sinnard for reporting this. + + * ace/Synch: Added "lock()" methods to all the ACE synchronization + wrappers to return the underlying C level object... This is + necessary at some points in ACE. + + * ace/Synch: Fixed a horrible bug in ACE_Recursive_Mutex and + ACE_Recursive_Lock that was causing instant deadlock because the + non-recursive Solaris/Pthread mutex was being acquired too + eagerly... + +Thu Mar 28 12:14:57 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Map_Manager.cpp (rebind): Added a new method called resize() + which increases the size of the map. Both open() and + shared_bind() make use of this method to dynamically increase + the size of the map. + + * ace/Local_Name_Space.cpp (shared_bind): Modified shared_bind() + in accordance to the changes to Map_Manager. shared_bind() no + longer has to check if the map runs out of room since + Map_Manager dynamically grows the map. + + * ace/Map_Manager.cpp (shared_bind): Changed shared_bind() so that + when the map reaches max_size_, we grow the map by DEFAULT_SIZE + by making a call to open(). + +Wed Mar 27 20:00:47 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Local_Name_Space.cpp (shared_bind): Fixed a bug which was + allocating memory for a name binding which would fail on a bind + since there already existed a binding. This was causing the + mapped-file to grow even when binds would fail. + +Tue Mar 26 13:49:24 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/INET_Addr.i (addr_to_string): Moved the order of + get_host_addr() so that it comes before addr_to_string(). + Thanks to Neil Cohen for finding this. + + * ace/Synch: Added a new implementation of ACE_Thread_Mutex that + takes advantage of the new ACE_OS::thread_mutex_* mechanisms. + + * ace/OS: Added a new set of ACE_OS::thread_mutex_* mechanisms + that map efficiently to either Win32 CRITICAL_SECTIONs or UNIX + mutex_t's with type set to USYNC_THREAD. This allows ACE to + take advantage of the lightweight Win32 synchronization + mechanisms. When Windows NT 4.0 comes out, we'll at last have a + perfect mapping since WinNT 4.0 supports + TryEnterCriticalSection! + +Tue Mar 26 17:35:31 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Map_Manager.cpp: Added two new methods -- total_size() and + current_size() which return the max_size and current_size of the + map respectively. + +Mon Mar 25 20:22:25 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Service_Config.cpp (initialize): Updated the use of ACE_ARGV + to use the new method names. + + * ace/ARGV.cpp (ACE_ARGV): Changed the name of the two main + methods of ACE_ARGC from count() and operator&() to argc() and + argv(). This seems much more consistent with UNIX and C/C++ + naming conventions. + + * ace/ARGV.cpp (ACE_ARGV): Added environment variable substitution + to the ACE_ARGV class using the new ACE::strenvdup() method. + This is transparently available to the ACE Service Configurator + now, which enables the svc.conf file to include things like + this: + + dynamic Name_Service Service_Object * + name_svc.so:make_Name_Service() "-p $PORT -h $HOST" + + * ace/ACE: Added a new function called strenvdup() that returns a + dynamically allocated duplicate of its argument, + substituting the environment variable if str[0] == '$'. + + * ace/Naming_Context: Modified this class so that it now inherits + from ACE_Service_Config. This enables application programmers + to dynamically link instances of ACE_Naming_Context into their + applications via the svc.conf file. + + * ace/OS.i (access): Added a new wrapper for the access() method. + + * ace/Local_Name_Space.cpp: Fixed an error in each list_xxx + methods. If there's an error in the for-loop we must still call + ACE_OS::free() to release resources. Thanks to the + ever-vigilant Karlheinz Dorn for spotting this. + + * ace/Strategies: added virtual methods with name dump() to + ACE_Scheduling_Strategy, ACE_Schedule_All_Reactive_Strategy, and + ACE_Schedule_All_Threaded_Strategy. These methods are + referenced in ACE_Strategy_Acceptor::dump() method + (Acceptor.cpp). Thanks to Alexandre Karev for reporting this. + + * include/makeinclude: Added a number of changes to allow ACE to + build shared libraries correctly on AIX. Thanks to Chris Lahey + for these fixes. + + * ace/Makefile: added tempinc to the list of directories to delete + for "clean". Also, between the call to the two sub make files, + added a $(RM) -rf tempinc. Since we make both libs from the + same directory, we need to delete the tempinc directory to be + sure we don't get the templates generated for libACE included in + libACE_svcs. + + * ace/OS.i: Improved the mapping between ACE Win32 GetLastError() + values and POSIX-like errnos. This is now centralized in the + ACE_FAIL_RETURN macro. + + * examples/Threads/test_thread_specific.cpp: Added many new tests + to exercise the ACE thread-specific storage mechanisms on Win32 + and UNIX. + +Mon Mar 25 4:00:01 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Name_Options.cpp (parse_args): Added a new data variable + called database_ that keeps the name of the name server + database. Also added accessor methods for this. + + * ace/Local_Name_Space.cpp (create_manager): Changed + create_manager() to use ACE_Name_Options::instance ()->database + () instead of ACE_Name_Options::instance ()->process_name(). + + * ace/ACE.cpp (ldopen): Added a new method called ldopen that + finds a file either using absolute path or using + LD_LIBRARY_PATH. If the file is found, it opens the file and + returns a pointer to the file. + + * ace/Parse_Node.cpp: used the new ACE::ldfind() method to locate + the shared object file. This makes it possible to put + "relative" names into svc.conf files and then allow ACE to + locate the appropriate shared object DLL. + + * ace/ACE: added new methods called ldopen() and ldfind() that + find the file either using absolute path or using + LD_LIBRARY_PATH. If found, ldopen() opens the file and returns + a pointer to the file. + +Sun Mar 24 10:41:12 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Compiled ACE successfully on Windows '95. + + * ace/OS: Totally redid the ACE thread-specific storage cleanup + mechanism in OS.cpp to avoid bugs with the previous + implementation. + + * ace/Synch_T: Modified ACE_TSS_Guard so that it will call + ACE_OS::thr_keyfree () when it's finished. This should help to + eliminate the unbounded use of thread-specific storage slots + within a thread. + + * ace/Thread: added a new method keyfree() that calls down to the + ACE_OS::thr_keyfree (). + + * ace/Thread_Manager.cpp: Modified the semantics of + ACE_Thread_Manager::exit () so that it "always" calls + ACE_Thread::exit () even if the user hasn't registered this + thread with the thread manager. This avoids some subtle + problems that arise typically when I forget to put an + ACE_Thread_Control around the main() function. + + * examples/Threads/test_thread_specific.cpp: Added new tests to + ensure that the Win32 TSS cleanup logic is working correctly! + + * ace/Log_Msg: Moved the definition of the ACE_FIFO_Send_Msg queue + from the Log_Msg.h file to the Log_Msg.cpp file. The MSVC++ + compiler was having problems with this when building a DLL. + Besides, this needs to be replaced with Sockets for Win32 + anyway... + + * ace/OS.cpp: Put a safe guard in the readv() and writev() + emulations so that they return ACE_NOTSUP_RETURN if + ACE_HAS_THREADS is enabled. This is necessary because the + readv() and writev() emulations are *not* atomic if multiple + threads are used. If someone can provide an atomic + implementation I'll enhance the code to remove the existing + restrictions. + + * ace/OS: Created a new macro called ACE_SYSCALL_FAILED, which is + mapped to 0xFFFFFFFF on Win32 and -1 on UNIX. + + * ace/Synch and Synch_T: cleaned up the implementation of the + Recursive_Lock and Recursive_Mutex to use the ACE_Guard classes. + This simplifies the code. + +Sat Mar 23 16:53:14 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace: Updated all ACE classes to use the new ACE_Export macro. + This will enable them to transparently be used to create a Win32 + DLL. Also added ACE_BUILD_DLL to all the *.cpp files. + + * tests/CPP-inserver.cpp (main): Modified CPP-inclient.cpp and + CPP-inserver.cpp to use non-blocking I/O. In particular, + CPP-inserver times out on select and then checks to see if any + connections have arrived. Both applications are also working on + NT. + +Sat Mar 23 15:02:47 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Local_Tokens.cpp (proxy_): Modified the print statement for + local tokens to account for the fact that thread ids can be + unsigned on some platforms. + + * ace/Log_Msg.cpp (log): Modified the output format of the %t + directive to ACE_Log_Msg::log() so that it prints values in + unsigned form rather than signed form. This fixes a bug with + Win32 on Windows '95. + + * ace/ACE: Added two new methods ACE::read_n() and ACE::write_n(). + These are now necessary since Win32 distinguishes between + operations on SOCKETs and operations on other forms of HANDLEs. + + * ace/ACE: Changed all uses of ACE::set_fl() and ACE::clr_fl() to + ACE::set_flags() and ACE::clr_flags(). + + * ace/ACE: Changed the name of ACE function handle_timed_connect() + to handle_timed_open() since this is reall what it does... + +Fri Mar 22 00:11:19 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Stack: Added a "Node of last resort" to the + ACE_Unbounded_Stack. This ensures we are graceful in the face + of memory failures. + + * ace/OS.i (sleep): Fixed a bug with the Win32 ACE_OS::sleep + mapping. This should have had an "ACE_OSCALL_RETURN" in it... + + * ace/ACE.h: Had forgotten to put "static" in front of "basename". + Thanks to Neil Cohen for reporting this... + + * ace/Name_Options.cpp (process_name): Changed char * to const + char * to avoid compile error. Thanks to Neil Cohen for this... + + * ace/IPC_SAP: Implemented the enable()/disable() methods to work + with non-blocking I/O for SOCKETs on Windows NT. + + * ace/OS.i: Modified ioctl() to support the ioctlsocket() call on + Windows NT. + + * ace/Log_Msg.cpp (log): Fixed a bug that was caused by not + NUL-terminating the logging string properly when a %a is given. + Thanks to Tim Harrison for finding this. + + * ace/OS: Added a new overloaded "ACE_OS::sleep" method that takes + an ACE_Time_Value rather than a u_int. This is much more useful + for fine-grained timers than the horrible UNIX sleep() call. + + * ace/OS.h: #included "sys\timeb.h" in the Win32 version of ACE. + +Thu Mar 21 22:18:50 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * apps: Fixed all incorrect usages of ACE_HANDLE = -1 to use + ACE_HANDLE = ACE_INVALID_HANDLE in order to work with Win32... + + * ace/OS.i (gettimeofday): Replaced the existing implementation of + gettimeofday with a new version that is shorter, more efficient, + and most importantly, correct... Thanks to Todd Montgomery. and + Mike Flinn for this stuff. + + * ace/ACE: added a new method called basename() that returns the + filename portion of a pathname. + +Thu Mar 21 21:51:48 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/OS.h (ACE_DEFAULT_GLOBALNAME): Added some new #defines for + NT: ACE_DEFAULT_NAMESPACE_DIR, ACE_DEFAULT_LOCALNAME, and + ACE_DEFAULT_GLOBALNAME. + + * ace/Local_Name_Space.cpp (ACE_Local_Name_Space): Fixed a subtle + bug. Instead of doing a new char [xxx], I was doing a new char + (xxx). Also, added some #if defined (ACE_WIN32) to support + special cases for NT (for example determining the context file + name). + +Wed Mar 20 02:03:39 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Log_Msg.cpp (log): If we're writing to stdout or to an + iostream make sure the lock is help to avoid race conditions and + scrambled output. + +Tue Mar 19 00:12:25 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Thread_Manager.h: Added new default values to spawn() and + spawn_n(). + + * ace/OS.i (sigaction): Added support for signals to the ACE NT + mapping. + + * ace/ACE: Added 4 new methods to class ACE: send(), send(), + recv(), recv(). These calls mask some differences between UNIX + and Win32 IPC mechanisms. Then, reimplemented the Reactor's + notification mechanism to use this. + + * ace/OS.i (ACE_OSCALL_RETURN): fixed zillions of warnings on + HP/UX by making a small change to line 151 of the OS.i file. + Thanks to Neil Cohen for reporting this. + + * ace/Reactor.cpp: Rewrote the Reactor::notify() mechanism to + avoid using readv() and writev(). These work fine on UNIX, but + don't work correctly on Windows NT due to race conditions. + Basically, we need to reimplement this stuff on Win32 to avoid + the problem. + + * ace/OS.h: Added SIGQUIT, SIG_BLOCK, SIG_UNBLOCK, and SIG_SETMASK + definitions to NT. + + * ace/Time_Value: added a new set() method to be consistent with + the ACE_Time_Value (long, long) constructor. + + * ace/Service_Config.cpp (open): Fixed a bug where the + ACE_Service_Repository and ACE_Reactor weren't being initialized + correctly if the ACE_Service_Config::ACE_Service_Config (const + char *) method was called. + + * ace/Service_Config.cpp: Changed the constructor for + Service_Config so that it doesn't barf if the svc.conf file + isn't found. + +Mon Mar 18 00:34:45 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Reactor.h: Hid the inclusion of the Local_Tokens.h file in + the Reactor so that by default there will be no dependency + between libACE and libACE_svcs. This should prevent compilation + problems on some platforms. + + * bin: Included the html-windex shell script from Vincent Pommier + . + + * man: Included a shell script to automatically generate an + acewindex.html file. This file is useful just after running + man2html. Thanks to Vincent Pommier + for contributing this. + + * man/html: I've just used the man2html programs to generate the + html documentation from the man3 directory. It seems to work + pretty well. + + * ace/Assert.h: Added a forward declaration for class ACE_Log_Msg + to fix problems NuMega preprocessing. Thanks to Mike Flinn + for finding this. + + * ace: Implemented about 1/3rd of the "dump" methods for the + various ACE classes. + + * ace/Acceptor.cpp (info): Fixed a bug -- should use PR_AD rather + than ACE_INET_Addr since this is used for SPIPEs as well... + + * ace/Synch_T.cpp (ACE_TSS): If ACE_Thread::keycreate () fails + then we do an fprintf() and return at the moment. It doesn't do + any good to do an ACE_Log_Msg operation since those all require + thread-specific storage and this will just cause a recursive + problem... + + * ace/OS.cpp: Removed a memory leak in ACE_OS::thr_destory_tss() + that was caused by forgetting to delete each ACE_TSS_Key_Info + object when we no longer needed it. Thanks to Mike Flinn + for finding this. + + * ace/OS.cpp: Added a new method to class ACE_OS called + thr_keyfree(). This enables us to free up a thread-specific + storage key on Win32 (it isn't implemented on the UNIX + platforms). + + * ace/ACE.cpp (timestamp): In order to get ACE_OS::timestamp to + work on Win32, the wMonth, wDay, wYear structure members were + added to the sprintf statement. Thanks to Mike Flinn + for this fix. + + * examples: Changed all uses of ACE::send_n (1, ...) to + ACE_OS::write (ACE_STDOUT, ...) to avoid problems with NT's + hacked support for sockets and HANDLEs. Thanks to Bernd Hofner + for noticing this. + +Sun Mar 17 00:43:14 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/CORBA_Handler.cpp (handle_input): Fixed the CORBA_Handler to + use send()/recv() rather than read()/write(). + + * ace/Process_Manager: put the hooks in for the forthcoming ACE + Process Manager, which will provide a service similar to the + ACE_Thread_Manager, except that it will work for processes, not + threads. + + * netsvcs: all the ACE network services appear to be working + again... + + * man: Completely regenerated all the manual pages to reflect all + the most recent changes. + + * ace/OS.h: Created a new macro called ACE_DEFAULT_REACTOR_SIZE. + This is useful for two reasons (1) it centralizes this value in + one place in ACE and (2) removes a horrible circular dependency + between the Service_Config.h and Reactor.h... + + * ace/Strategies: Added new strategies to handle "scheduling" of + Svc_Handlers launched by a Strategy_Acceptor. In this context, + scheduling refers to "suspending" and "resuming" Svc_Handlers. + There are several alternative strategies ranging from (1) + suspending/resuming a single handler, (2) suspending/resuming + all the handlers in a Reactor, and (3) suspending/resuming all + handlers controlled by a Thread_Manager. This very powerful + feature makes it simple to write ACE_Network_Services that can + control all their handlers in one fell swoop... + + * ace/Task: Added new accessors/mutators to get/set the + Thread_Manager and the Message_Queue associated with a Task. + This makes life easier and more abstract in subclasses and + elsewhere. + + * ace/Reactor: added an iterator to the ACE_Handler_Repository. + This makes it possible to implement the suspend_handlers() and + resume_handlers() very efficiently on both UNIX and Windows NT. + + * ace/Reactor: Added two new methods called suspend_handlers() and + resume_handlers(). These methods suspend and resume all the + active Event_Handlers in the Reactor in one fell swoop. + + * ace/Reactor.i (suspend_handler): Fixed a bug in the Reactor + where we were not factoring out the code for suspend_handler() + appropriately with respect to locking. + + * netsvcs/Logging/Server_Daemon/Thr_Logging_Handler: Enhanced the + threaded logging service so that all active threads can be + automatically suspended and resumed via the ACE_Service_Config + svc.conf file. + + * netsvcs/Logging/Server_Daemon/Logging_Handler.cpp: Rewrote the + ACE Logging service to use the new ACE_Strategy_Acceptor + implementation. This greatly reduced duplicate code. There's + almost nothing left in this directory save the actual service + itself! + + * netsvcs/Tokens: Rewrote the ACE Token service to use the new + ACE_Strategy_Acceptor implementation. This greatly reduced + duplicate code. There's almost nothing left in this directory + save the actual service itself! + + * netsvcs/Naming: Rewrote the ACE Naming service to use the new + ACE_Strategy_Acceptor implementation. This greatly reduced + duplicate code. There's almost nothing left in this directory + save the actual service itself! + +Sat Mar 16 20:02:08 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * netsvcs: Created a new subdirectory off of $WRAPPER_ROOT and put + all the ACE network services (e.g., Time, Logging, Naming, and + Tokens) into that directory. These services all instantiate the + new ACE_Strategy_Acceptor implementation, which greatly + simplifies their behavior and code. + + * ace/Acceptor: Made some enhancements to the + ACE_Strategy_Acceptor in order to make it more suitable for use + as a generic "Service" launcher. This class now defines common + behavior for all the ACE network services (e.g., Time, Logging, + Naming, and Tokens). + + * apps/Token_Server: Made the main Token_Server application be + dynamically linked if there's a valid svc.conf file. + + * apps/Name_Server/Name_Server: Made the Server_Test a + "well-behaved" service. Previously, it block in a private event + loop within Name_Server::run(), which was called by + Server_Test::init() when the service was linked dynamically. + This obviously doesn't work correctly since it means that we + can't dynamically link any other services after this one! The + new version is "event-loop" friendly since it uses the main + Service_Config::run_event_loop() method. + + * ACE-categories: Added a new emacs "outline" file that + illustrates how the filenames in $WRAPPER_ROOT/ace cluster into + class categories. Thanks to Chris Eich + and Alex V. Maclinovsky + for helping create this. + + * ace: Split ACE into two libraries: libACE and libACE_svcs. + libACE contains the "core" ACE components. libACE_svcs contains + the client-side layered services (e.g., naming service, token + service, etc.). There are two reasons for doing this: + + 1. It reduces the size of ACE for many common usecases (i.e., + most people aren't using the naming service or the token + service). Any future layered services in ACE will be placed + into the libACE_svcs library rather than libACE. + + 2. It works around annoying compiler bugs with lame compilers + like HP/UX C++. Now, if those compiles can't compile the + token service (which is very template intensive) it won't + affect the core ACE library components. This improves the + portability of ACE. + + * Added -lACE_svcs to the ./apps/{Token_Server,Name_Server} and + ./examples/{Tokens,Naming} Makefiles to account for the new + libraries. Note that no source code changes are required... + +Fri Mar 15 00:03:48 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * apps/Name_Server/server/Name_Handler.cpp (recv_request): Fixed + the same problem as occurred in Token_Handler (these both come + from the same source...). + + * apps/Token_Server/Token_Handler.cpp (recv_request): There was a + subtle bug in the Token_Handler that stems from my old code. + The line + + n = this->peer_.recv ((void *) (((char *) &this->token_request_) + + sizeof (ACE_UINT32)), + length); + + This should actually be: + + n = this->peer_.recv ((void *) (((char *) &this->token_request_) + + sizeof (ACE_UINT32)), + length - sizeof (ACE_UINT32)); + + since length was read already. The old way tried to read 4 + bytes too much. Thanks to Jesper for noticing this. + + * ace/Connector.cpp (connect_svc_handler): Modified the connector + so that it automatically calls the close () method of the + Svc_Handler when the connection fails abortively. This makes + the semantics the same for synchronous and asynchronous + connection invocation modes. Thanks to Irfan for insisting on + this! + + * apps/Token_Server/Token_Acceptor.cpp (handle_input): Changed + return type from int to ACE_HANDLE for NT compatibility. Thanks + to Jesper for this insight. + + * ace/OS.h: The defines for ACE_LACKS_MODE_MASKS (OS.h) were only defined + when !ACE_WIN32. This has been fixed. Thanks to Irfan for + spotting this too. + + * ace/OS.i (mmap): made a small change to ACE_OS::mmap to fix NT + portability problem (new variable added:nt_flags). Thanks to + Irfan for spotting this. + + * ace/Local_Tokens.h: Added #include "ace/Map_Manager.h" after + line 41 in Local_Tokens.h to allow ACE to compile correctly with + the horrid HP/UX compiler. Thanks to Neil Cohen for figuring + this out (what a trooper!). + + * ace/Local_Tokens.cpp (ACE_TPQ_Entry *): Replace + + return ACE_TSS::operator ACE_TPQ_Entry *(); + + with + + return (ACE_TPQ_Entry *) (*((ACE_TSS *) this)); + + to work around problems with MSVC++ 4.0 when the browse option + is enabled. Thanks to Kirk Sinnard <1764@mn.lawson.lawson.com> + for this fix. + + * ace/config-sunx86-sunc++-4.x.h: Swapped the lines + + // Compiler/platform supports SVR4 signal typedef. + //#define ACE_HAS_SVR4_SIGNAL_T + #define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + + to + + // Compiler/platform supports SVR4 signal typedef. + #define ACE_HAS_SVR4_SIGNAL_T + //#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + + to avoid an error using ProWorks C++ 4.0.1 (w/ patches) which + blow up in the Signal.x stuff with a prototyping error. Thanks + to John P. Hearn for this recommendation. + + * ace/Shared_Memory.h: The conditional compilation wrapper was out + of date, so I renamed it. Thanks to Alex V Maclinovsky + for reporting this. + +Thu Mar 14 23:18:59 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Thread.h: There was a bug in the ACE_Thread class. I + attempted to make the class uninstantiable by making the + constructor private. However, the statement was: + + private: + Thread (void); + + which is not the definition of the ctor! The code compiled + since it thinks Thread is a member function. As a result, you + could instantiate a object of ACE_Thread class, but no longer... + Also added this to the !defined (ACE_HAS_THREADS) arm of the + conditional compilation. Thank to Sandeep Joshi + for noticing this. + + * ace/Log_Record.i (decode): Fixed a stupid typo where htonl + (this->length_) should have been htohl (this->length_)... + Thanks to Audun Tornquist for + noticing this. + +Tue Mar 12 14:51:39 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Name_Request_Reply.cpp (decode): Added ntohl and htonl calls + wherever data was being exchanged. + +Sat Mar 9 17:49:51 1996 Tim H. Harrison (harrison@lambada.cs.wustl.edu) + + * ace/OS.i (cond_wait): Updated the Win32 implementation to + correspond precisely with the UNIX semantics where the mutex is + always reacquired even when errors occur. + +Mon Mar 4 23:03:37 1996 Tim H. Harrison (harrison@lambada.cs.wustl.edu) + + * INSTALL: updated the win32 to describe building test + applications. + +Mon Mar 4 16:17:05 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Local_Name_Space.cpp (resolve): Fixed a small bug. The type + field in resolve was copying extraneous stuff (because of being + kept around as a wchar_t). So I added a new method to the class + ACE_NS_String called len() which simply returns len_. Using this + I can now do a strncpy of len bytes for type (instead of a + simple strcpy) and then null-terminate the string to remove the + garbage. + +Thu Feb 29 23:41:04 1996 Tim H. Harrison (harrison@lambada.cs.wustl.edu) + + * ace/Token_Request_Reply.cpp: Fixed a byte-order bug which was + showing up on intel platforms. + + * ace/Remote_Tokens.cpp: Fixed a race condition in + ACE_TSS_Connection which was munging mt token server clients. + + * examples/Tokens/mutex/*: The Token Server example applications + now use ACE_Thread_Manager, which should make them portable to + Win32. + + * apps/Token_Server/Token_Server.cpp: The Token Server is now a + Service_Object which can be dynamically linked. + + * ace/OS.i: Win32 ACE_OS:: signal methods now return 0 instead of + -1. So, calls to signal code succeed, but do nothing useful. + +Thu Feb 29 20:38:32 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * apps/Logger/Server_Daemon/Server_Logger.cpp + (handle_logging_record): There was a typo where + ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES was incorrectly spelled. + This caused problems on HP/UX. Thanks to Neil Cohen for + finding this. + +Wed Feb 28 11:41:49 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Mem_Map.cpp: Fixed a nasty bug with Win32 memory mapping... + It turns out we need to be very careful when remapping a + previously mapped region if the MapViewOfFile we're trying to + establish *grows* beyond what was originally mapped with + CreateFileMapping(). The new scheme seems to work correctly + with both UNIX and Win32. + + * ace/OS.h: apparently when using MFC library functions it + is not possible to include windows.h. Instead, users + must include AFX.h. Therefore, I've modified OS.h to + include the following: + + #if !defined (__AFX_H__) + #include + #endif /* __AFX_H__ */ + + Thanks to Patty Genualdi (genualdp@agcs.com) for pointing this + out. + + * ace/Memory_Pool.cpp: Modified init_acquire() so that it calls + ACE_Mem_Map::open() rather than ACE_Mem_Map::map() the first + time. This ensures that the file is mapped correctly. + + * ace/Mem_Map: Added a new method called open() that creates/opens + a file without actually mapping it. + + * ace/SOCK_Dgram_Mcast.cpp (make_multicast_address): Added + new support for Windows NT. + + * ace/Memory_Pool: reimplemented ACE_MMAP_Memory_Pool so that uses + ACE_Mem_Map. This ensures that we can leverage all the work + that went into making ACE_Mem_Map work on Win32. + + * ace/Memory_Pool.cpp (map_file): Modified the code so that we + always unmap the file before trying to remap it. This avoids + problems with Win32... + + * ace/Mem_Map: Modified the implementation of ACE_Mem_Map so that + it takes advantage of the improved features in ACE_OS::mmap. + Also added new a method that returns the memory-mapped addr more + easily. + + * ace/OS: Modified the ACE_OS::mmap() method so that it is more + efficient for remapping files on Win32. + + * ace/OS.h: renamed the type QWORD to ACE_QWORD to avoid namespace + pollution. Thanks to Patty Genualdi (genualdp@agcs.com) for + pointing this out. + + * ace/OS.h: Changed the value of the SIGPIPE emulation for Win32 + to match the UNIX value in order to avoid problems. Thanks to + Jesper for noticing this. + + * apps/Token_Server: Fixed misuse of int for ACE_HANDLE in various + places. Thanks to Jesper for noticing this. + + * Renamed the ./tests directory to ./examples to make way for the + new ACE regression tests. These tests will go into the new + ./tests directory. + + * ace/Mem_Map.cpp: Added a destructor and a close() method that + closes down the file HANDLE if we allocated it. This is useful + to prevent descriptor leaks. Thanks to Irfan for suggesting + this. + + * ace: Made a number of changes to remove unreferenced parameters + from ACE methods. This eliminates zillions of warning from the + HP/UX compiler. Thanks to Neil Cohen for reporting this. + + * ace/Local_Name_Space.cpp (resolve): revised some code to work + around bugs with the HP/UX compiler... Thanks to Neil Cohen for + this workaround. + +Tue Feb 27 21:06:09 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/OS.i: The Win32 CreateFile does not handle the return you + would expect when the file exists. You would expect EEXISTS (17 + in UNIX) but the GetLastError is set to 80 + (ERROR_FILE_EXISTS). Therefore, I changed ACE_OS::open to map + ERROR_FILE_EXISTS onto EEXIST. This is only a partial solution, + however. There must be a better way to handle this! + + * ace/Mem_Map.cpp (ACE_Mem_Map): Fixed a bug with one of the + ACE_Mem_Map destructors that was causing problems due to the + fact that base_addr_ wasn't being initialized to 0. Thanks to + Karlheinz for noticing this. + + * ace/Signal.i: signals on AIX cannot use sigprocmask() in any + multithreaded programs. Instead, the call + ACE_OS::thr_sigsetmask() should be used since it is used to + update the thread signal mask. This comes up only in the + Sig_Guard constructor and destructor. Therefore, I #ifdef the + call under the ACE_MT_SAFE macro, using sigprocmask() in the + #else case. Thanks to Chris Lahey for reporting this. + + * tests: removed all uses of ACE_OS::join (0, ....) in ACE and + replaced them with ACE_Thread_Manager::wait() calls. This + ensures that the ACE code is portable to Win32 and POSIX + pthreads! + + * ace/Dynamic_Service.cpp: Added a #include of + "ace/Service_Config.h" to work around problems with HP/UX. + Thanks to John Morey for reporting this. + +Sun Feb 25 12:10:38 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * apps/Token_Server: changed the name token_server.cpp to main.cpp + to avoid a name clash on Win32... + + * man/man3: updated all the ACE manual pages to reflect the + most recent changes. + + * ace/OS.i: Implemented the cond_timedwait() method correctly in + ACE_OS. This method should now do the right thing with respect + to blocking, polling, and timewaits for Win32. + + * ace/OS.i: Modified the Win32 implementation of all the + socket-related wrappers in ACE_OS. The new implementation very + cleverly sets errno to the result of WSAGetLastError() if a + socket-related call fails. Since all of the WinSock errors are + mapped into their equivalent UNIX errno values this enables + socket applications to work portably for UNIX and Win32. + + * ace/Malloc_T.cpp (ACE_Malloc): Improved error reporting for + cases where the Memory_Pool::init_acquire() fails (e.g., if the + backing store was already created by another user and we don't + have permission to access it...). + + * ace/Task: modified Task.h so that it is no longer necessary to + write #include "ace/Synch_T.h" in order to use ACE_MT_SYNCH, + etc. + + * ace/SOCK.cpp (DllMain): Added a clever "Schwartz counter" to + make sure that the WinSock library is correctly initialized, + even if we're not using ACE as a DLL!!! + + * tests/Mem_Map/file-reverse: got the file reverse test program + working. The ACE_Mem_Map class should now be ported to Win32... + + * ace/OS.i (open): Changed how the O_CREAT flag was handled + to give it UNIX semantics... + +Sat Feb 24 12:55:27 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/UPIPE_Stream.cpp (recv): Fixed a signed/unsigned mismatch. + There should be no more mismatches in ACE... + + * ace/Name_Proxy.cpp (recv_reply): Fixed a signed/unsigned + mismatch. + + * ace/Message_Block.cpp (copy): Fixed a signed/unsigned mismatch. + + * ace/INET_Addr.cpp (get_host_name): Changed the type of the + hostnamelen parameter from int to size_t to be more "abstract." + This will also prevent a warning from the MSVC++ compiler. + + * apps/Logger/Client_Daemon/Client_Logger.i: Fixed a braino with + network byteoder that was causing Client_Logger::send() to fail + on INTEL boxes. Thanks to Bryon G. Rigg + for finding this. + +Fri Feb 23 01:59:34 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/OS.i: Enhanced mmap() to give the same semantics as UNIX + mmap() by using MapViewOfFileEx(). Also greatly improved the + UNIX emulation capabilities so that mmap() now has the same API + for UNIX and Win32. + + * ace/Time_Value: Added functions to constructor and conversion + from/to Win32 FILETIME. This enables us to reuse those 100ns + conversions in ACE_Profile_Timer. + + * ace/Time_Value: Fixed a problem with these: + + // True if tv1 < tv2. + + INLINE int + operator < (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2) + { + ACE_TRACE ("operator <"); + return tv2 > tv1; + } + + This should be "tv2 >= tv1". Same problem was fixed with + operator <=. + + * ace/Profile_Timer.i, fixed the following: + + this->end_time_ = ACE_OS::gettimeofday (); + this->last_time_ = this->end_time_; + this->last_usage_ = this->end_usage_; + ACE_OS::getrusage (RUSAGE_SELF, &this->end_usage_); + + This will overwrite end_time before it is saved to + last_time... + + * tests/Threads: Added Jesper's test for readers/writers locks. + The test adds a number of reader and writer threads. When + active, writers modify a shared variable and verify that only + one writer and no readers are active. When active, readers + check that no writers are active and that the shared data is + never changed. The test passes for different ratios of + readers/writers, and debug output shows that several readers are + allowed simultaneously. Or, in other words, we have an + indication that it should work. + + * ace/OS.i: Added Win32 implementations of getpid(), fork(), + lseek(), dup(), cond_timedwait (), getrusage () + + * ace/OS.i: Modified all the ACE_OS::str* routines so that they no + longer do an ACE_OSCALL_RETURN. This can lead to weird bugs... + Thanks to Jesper for noticing this. + + * ace/config-sunos4-sun4.1.4.h: Added a new config file that + should work with SunOS 4.x... Also added support for SunOS + 4.1.4. Thanks to Mick Adams (eeimas@eei.ericsson.se) for help + with this. + +Thu Feb 22 18:58:36 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * tests/Naming/Client/Name_Service.h (ACE_Service_Object): + Modified test application to make use of ACE_Dynamic_Service. + + * ace/Dynamic_Service.h: Added a new class called Dynamic_Service + which provides a general interface to add and retrieve arbitrary + things into the ACE service repository. + + * apps/Name_Server/README: Rearranged files so that Name_Server + and Name_Handler are now contained in the server directory under + apps and are no longer under /ace. Also, the Dump_Restore + directory has been moved under /tests/Naming. + +Thu Feb 22 01:56:46 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/INET_Addr.cpp (set): Fixed a byteorder bug in ACE_INET_Addr + that was causing problems when ACE was used on Win32 running on + Intel platforms... + + * ace/Mem_Map.cpp (map_it): Fixed ACE_Mem_Map so that it will work + correctly on Win32. + + * ace/SOCK_Stream.i: Changed the implementation of the Win32 + versions of send() and recv() so that they will never use the + read() and write() calls. This works around limitations with + Win32, which can't do a ReadFile() or WriteFile() + *synchronously* with a SOCKET. + + * Changed all occurrences of read (0, ...) to read (ACE_STDIN, + ...) and all occurrences of write (1, ...) to write + (ACE_STDOUT, ...) in order to be compatible across UNIX and + Win32. + + * tests/ASX/Event_Server: Fixed up all the socket I/O calls so + that they use the WinSock send()/recv() methods rather than + ReadFile and WriteFile... + + * ace/OS.i: Updated open() to correctly emulated UNIX open() + semantics on Win32. + + * ace/OS.cpp (thr_exit): Added support to the NT port so that + thr_exit() doesn't endup doing multiple deletions of the same + object. Thanks to Karlheinz for this fix. + + * ace/OS.h: Moved the location of ACE_MAXCLIENTIDLEN so that + MAXHOSTNAMELEN would be correctly visible for NT. + + * ace/Reactor.cpp: Added a temporary fix for the fact that + writev() and readv() don't work correctly yet on NT. The + solution is to replace write() with two writes() and readv() + with two reads() for the Reactor's notification scheme. A + better solution should be forthcoming. + + * ace/Reactor.cpp: Made sure to initialize the timer_queue_ to 0 + in the constructors so that the Reactor's destructor can avoid + crashing horribly if the constructor fails. Thanks to Karlheinz + for pointing out the need for this. + + * ace/SOCK.cpp: Added support for WSAStartup for using WinSock + within the ACE_SOCK class. + +Wed Feb 21 21:05:55 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/ACE.cpp (bind_port): Made a quick fix to work around the + fact that NT doesn't set errno... + + * ace/OS.i (mmap): Fixed a bug in mmap for the NT port. It should + return MAP_FAILED on error rather than 0 to be equivalent to the + UNIX version. Thanks to Irfan for spotting this. + +Mon Feb 19 00:31:42 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Typed_SV_Message.i (ACE_Typed_SV_Message): Modified the + constructor calls so that length_ and max_size_ are correctly + set when created. Thanks to Alexandre Karev + for reporting this. + + * ace/SV_Message_Queue.i (remove): fixed bug in + ACE_SV_Message_Queue::remove method where `internal_id_' member + was modified *BEFORE* it was used the last time in + ACE_SV_Message_Queue::control. Thanks to Alexandre Karev + for reporting this. + + * ace/Typed_SV_Message.i (length): Fixed a minor typo that caused + a bigger bug ;-). Thanks to Alexandre Karev + for reporting this. + + * ace/OS.h: Added new macros that allow programs to portably + access stdin, stdout, and stderr HANDLEs on Win32 and UNIX as + follows: + + #if defined (ACE_WIN32) + #define ACE_STDIN GetStdHandle (STD_INPUT_HANDLE) + #define ACE_STDOUT GetStdHandle (STD_OUTPUT_HANDLE) + #define ACE_STDERR GetStdHandle (STD_ERROR_HANDLE) + #else + #define ACE_STDIN 0 + #define ACE_STDOUT 1 + #define ACE_STDERR 2 + #endif /* ACE_WIN32 */ + + * ace/INET_Addr.i: modified the return value of get_port_number so + that it returns the value in host byte order. This has actually + been a latent bug in ACE for years, but it only surfaced + recently after porting to NT on the Intel instruction set (which + is "little-endian"). + + * tests/ASX/Event_Server: Merged in the latest changes to the + Event_Server tests, which enable it to compile on Windows NT. + Now, I just need to get it working on NT... + + * Updated all of ACE to use the new ACE_ASSERT rather than assert. + + * ace/Assert.h: Added a new file and a new macro called + ACE_ASSERT. This uses the ACE_Log_Msg Singleton to provide a + more consistent means to do assertions. Thanks to Alexandre + Karev for suggesting this. + + * ace/Log_Msg.cpp (log): added for method ACE_Log_Msg::log lines + to skip the `sprintf' part for %N - file name and %l - line + number format specifiers. Thanks to Alexandre Karev + for reporting this. + + * Remote_Name_Space: Removed an initalizer to ACE_WString that was + driving the HP/UX compiler nuts. + +Sun Feb 18 18:11:22 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Synch.h (ACE_Null_Condition_Mutex): Added a missing body to + the wait() method. Thanks to Byron Riggs for noticing this. + +Sat Feb 17 19:10:06 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * tests/Naming/README (client): Added description for new + features, including support for list_values and list_types. Also + added a small description about test programs using DLL. + + * ace/Name_Request_Reply.cpp (decode): Fixed a small bug in + ACE_Name_Request::decode. type_ was not null terminated causing + some garbage to be returned. + +Thu Feb 15 14:57:06 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Remote_Name_Space.cpp: Changed names of some parameters to + comply with ACE syntax. + +Wed Feb 14 13:36:31 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Local_Name_Space.cpp (resolve): Type support has been added + to Name_Server. A new class called ACE_NS_Internal was created to + keep value and type information. + +Fri Feb 9 17:12:00 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * "Officially" released ACE 4.0 + + * ace/OS.i (sema_post): Fixed a bug in the NT port. + + #elif defined (ACE_HAS_WTHREADS) + return ::ReleaseSemaphore (*s, 1, 0); + #endif /* ACE_HAS_STHREADS */ + + This returns 1 for success, and disturbs cond_broadcast... + This was replaced by: + + #elif defined (ACE_HAS_WTHREADS) + return ::ReleaseSemaphore (*s, 1, 0) ? 0 : -1; + #endif /* ACE_HAS_STHREADS */ + + Thanks to Jesper S. M|ller (stophph@diku.dk) for this. + + * ace/OS.i (cond_init): Fixed a bug in the NT condition synch + code, as the initial count of the semaphore was 1. This gives an + inconsistent condition: The first waiter went straight through... + Change in ACE_OS::cond_init: + + if (ACE_OS::sema_init (&cv->sema_, 0, type, name, arg) != 0) + return -1; + + Thanks to Jesper S. M|ller (stophph@diku.dk) for this. + + * ace/Singleton.cpp: Fixed a stupid bug that was caused by failure + to #include "ace/Synch_T.h"... Thanks to Neil Cohen and Byron + Riggs for giving me insights on what the problem was. ACE now + compiles on HP/UX. + +Fri Feb 9 11:07:04 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * tests/Naming/server/Server_Test.cpp (init): Modified server + tests to dynamically link Naming Services. Both client and + server tests now make use of the ACE dynamic linking mechanisms. + + * ace/Local_Name_Space.cpp: Added list_values() to Name + Server. The functionality is very similar to list_names (returns + list of values that match a pattern). + + * tests/Naming/client/Client_Test.cpp (bind): Replaced all uses of + cerr and cout with ACE_ERROR, ACE_ERROR_RETURN, and ACE_DEBUG. + Split the file Client_Test.cpp into two files -- Client_Test.cpp + and Name_Service.cpp (similarly .h file) each containing the + corresponding class. Modified svc.conf to work with the changes. + +Thu Feb 8 02:05:26 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Log_Msg.cpp (log): Enhanced the Log_Msg class so that it + supports "nested" calls via %r. If SILENT mode enabled, nested + outputs will enclosed in {..} brackets in thread-specific + storage. Thanks to Alexandre Karev for + suggesting this. + + * ace/Synch: Added a new class called ACE_Null_Condition_Mutex. + This is necessary to fix bugs with stupid compilers... Thanks + to Zusman Mark for reporting this. + + * tests/Naming/client: made a first pass implementation of a + client application that dynamically links in a Naming_Context + based on information provided by the svc.conf file. + + * ace/Name_Options: Fixed yet more problems with dynamic memory + management. The old version didn't make a copy of the strings + it was passed and this caused major problems. + + * ace: Fixed a whole slew of problems with the ACE Name Server + stuff that arose from inconsistent use of const char * vs. char + *... + +Wed Feb 7 00:58:45 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/CORBA_Handler.cpp (ACE_MT_CORBA_Handler): Added new + enhancements to ACE_MT_CORBA_Handler to make it work correctly + with Windows NT. Thanks to Irfan for making these changes. + + * ace/Connector.cpp (fini): Make another workaround for bugs with + MSVC++ 2.0... + + * ace/SPIPE_Connector.cpp (connect): Added a call to ACE_CLR_BITS + (flags, O_CREAT) to make darn sure that the O_CREAT flag is not + set. Thanks to Chris Cleeland for suggesting this. + +Tue Feb 6 01:40:29 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/OS.h: added a new prototype to OS.h that should help with + portability to nasty platforms with broken rand_r() definitions. + Thanks to Aurelio Nocerino + for suggesting this. + + * Local_Tokens: Changed all uses of enumerals MAXTOKENNAMELEN and + MAXCLIENTIDLEN to symbol #defines ACE_MAXTOKENNAMELEN and + ACE_MAXCLIENTIDLEN. This works around bugs with HP/UX. + Thanks to Neil Cohen for reporting this problem. + + * ChangeLog: split the ChangeLog files into 4 separate files -- + one for '96, '95, '94', and '93. Hard to believe I've been + working on this stuff for so long! + + * ace/OS: Fixed the use of ::memset to replace sizeof buffer with + sizeof (ACE_SERVENT_DATA) and sizeof (ACE_HOSTENT_DATA). This + fixes bugs that surfaced on AIX. Thanks to Chris Lahey for + finding these. + + * ace/SPIPE_Addr.cpp (ACE_SPIPE_Addr): Fixed a bug in + SPIPE_Addr::SPIPE_Addr(const SPIPE_Addr&). What happens is that + when the size is calculated it does not take into account the + required zero byte at the end of the rendezvous_ member. Thanks + to Chris Cleeland for reporting this. + + * ace/Local_Tokens: Had to move all ACE_Token_Proxy methods from + Local_Tokens.i to Local_Tokens.cpp and remove INLINE - otherwise + gcc reported them as undefined methods during linkage stage. + Thanks to Zusman Mark for + reporting this. + + * ace: Changed ACE_Name_Request_Reply::LAST to + ACE_Name_Request_Reply::MAX_ENUM to avoid problems with name + conflicts on OSF/1. Thanks to Eshel Liran + for suggesting this. + + * ace/Synch_T: Fix all definitions of ACE_Atomic_Ops so that they + compile correctly on platforms that lack threads! Thanks to + Alexandre Karev for noticing this. + + * include/makeinclude: Added a new config file from Bryon G. Rigg + , which should allow ACE to build on + Linux. + + * ace/Remote_Tokens.cpp: Moved ACE_TSS_Connection to + Remote_Tokens.h to avoid problems with AIX. Thanks to the + ever-vigilant Chris Lahey for reporting this. + +Mon Feb 5 23:34:42 1996 Tim H. Harrison (harrison@lambada.cs.wustl.edu) + + * Added CORBA_Ref.h which contains the new class ACE_CORBA_Ref. + This class provides a nice wrapper for making the use of Orbix + object references more transparent. This is done by automating + the release and duplicate calls. + +Mon Feb 5 15:43:17 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace: added Prashant's latest changes to the Name_Handler*, + Naming_Context*, and Remote_Name_Space*. These changes make it + possible to retrieve lists of values based on a pattern, which + can be a regular expression. + + * Moved the apps/Name_Server/Client-Server tests into tests/Naming + and most of the apps/Token_Server/* tests into tests/Tokens to + conform to Karlheinz's testing style. + + * ace: Modified a number of files in ACE to make it compile + correctly with MSVC++ 2.0. + +Sun Feb 4 23:58:43 1996 Douglas C. Schmidt (schmidt@mambo.cs.wustl.edu) + + * ace/Reactor: Generalized ACE_Null_Callback to work correctly + with Windows NT (which lacks pipes). The new design uses the + ACE socket wrappers for NT. It requires very few changes to the + code to handle NT now! Also changed the name to + ACE_Notification_Handler, which is more descriptive. + +Sun Feb 4 14:47:50 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Remote_Tokens.cpp: Reworked ACE_Singleton to avoid + portability problems on compilers like GCC. + +Thu Feb 1 12:47:46 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Remote_Tokens.cpp: Generalized the parameters passed into + ACE_Singleton so they would compile on HP/UX and other platforms + that lack threads. Thanks to Neil Cohen for noticing the + problem. + +Wed Jan 31 22:49:13 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace: Modified a number of minor things in ACE to get it to + compile successfully with Windows NT MSVC++ 4.0. Updated the + INSTALL file to explain this process better... + +Tue Jan 30 01:12:07 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/CORBA_Handler.cpp: changed things so that no diagonistic + messages are printed. + + * Regenerated all the ACE manual pages to bring them up to date + with the recent changes. + + * ace/Malloc.h: Modified the ACE_Malloc header file so that it + works correctly when ACE_MALLOC_STATS is enabled. Thanks to + Alexandre Karev for reporting this. + + * ace/OS.cpp (mutex_lock_cleanup): removed the leading & before + p_lock. Thanks to Chris Lahey for noticing this. + + * ace: Added the new ACE_Singleton class. This class uses the + Adapter pattern to turn ordinary classes into Singletons + optimized with the Double-Check pattern. + + * Added Tim's latest Token Server changes (which include support + for local and remote mutexes and readers/writer locks) and + Prashant's latest Name Server changes (which allows the contents + of a Name Server to be dumped and restored to/from an ASCII + file). + +Mon Jan 29 02:22:23 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Handle_Set: Changed MAX_SIZE and WORD_SIZE to MAXSIZE and + WORDSIZE to avoid name collisions with HP/UX. Thanks to Byron + Rigg for suggesting this. + + * ace/Time_Value.h: Added a new config symbol ACE_HAS_SVR4_TIME to + differentiate between UNIX platforms that support "POSIX_TIME" + (i.e., timespec_t) and those that support "SVR4_TIME" (i.e., + timestruc_t). This is necessary to work around HP/UX... Thanks + to Byron Rigg for suggesting + this. + + * ace/config-hpux-10.x.h: config-hpux.h has now been renamed to + config-hpux-10.x.h and config-hpux-9.x.h. Thanks to Byron Rigg + for suggesting this. + + * ace/Synch_T: Added a new method called ts_get() and made both + the operator-> and operator TYPE * call this. I hope this will + fix a bug with HP/UX reported by Neil Cohen... + + * ace/OS.i (dlclose): Added Win32 support for dlclose(). Thanks + to Todd L. Montgomery for pointing the way + here... + + * ace: Split off the old class ACE_Dynamically_Allocated, renamed + it ACE_Dynamic, put it in a separate file called Dynamic.*. + This is necessary to solve nasty multiple definition problems + with compilers that require the source of template. + + * ace/Synch_T: moved + + template TYPE * + ACE_TSS::make_TSS_TYPE (void) const + { + return new TYPE; + } + + out from condition compilation block + + #if (defined (ACE_HAS_THREADS) && defined(ACE_HAS_THREAD_SPECIFIC_STORAGE)) + + in file Synch_T.cpp. This class member called in many other + places regardless ACE_HAS_THREADS and + ACE_HAS_THREAD_SPECIFIC_STORAGE defined or not... + + * ace/Name_Handler.cpp: Changed the use of the "inherited" typedef + to fully expand to ACE_Svc_Handler. This is necessary to workaround bugs with AIX. + Thanks to Chris Lahey for reporting this. + + * tests and apps: Fixed an odd problem that only surfaced recently + with GNU G++. Apparently, it doesn't like function-style casts + of the form ACE_SignalHandler (foo), but will accept + (ACE_SignalHandler) foo. Since both approaches are equally good + for what I'm doing, I've updated all the code in ACE to be more + portable. + +Sun Jan 28 12:24:58 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * tests/Shared_Malloc/test_malloc.cpp (spawn): when forming + argv[] for execv, moved + + argv[ ... ] = Options::instance ()->debug () ? "-d" : ""; + + to the end of the vector just before terminator. This will + allow to pass rest of arguments to exec if -d switch not + specified. Thanks to Alexandre Karev + for reporting this. + + * tests/Shared_Malloc/Malloc.cpp: To avoid conflict with + ACE_DEFAULT_SEM_KEY in OS.h changed SEMA_KEY value in + tests/Shared_Malloc/Malloc.cpp to ACE_DEFAULT_SEM_KEY + 1. + Thanks to Alexandre Karev for reporting + this. + + * ace/SV_Semaphore_Complex.i: Changed all arguments in calls like + + this->acquire( n+2 ) + and + this->tryacquire( n+2 ) + to + this->acquire( n ) + and + this->tryacquire( n ) + . + Since the semaphore number is incremented by 2 in + SV_Semaphore_Complex::acquire + and + SV_Semaphore_Complex::tryacquire + + when SV_Semaphore_Simple::(acquire/tryacquire) is called. + Thanks to Alexandre Karev for pointing + this out. + +Sat Jan 27 16:14:27 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Read_Buffer: Added a new component that efficiently reads in + an artibrarily large buffer from a file up to an including a + termination character. Also performs search/replace on single + occurrences a character in the buffer using the priniciples of + Integrated Layer Processing. + +Fri Jan 26 12:01:06 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Thread_Manager: Made a small change to workaround the use of + a struct type for thread_t and hthread_t in HP/UX. Thanks to + Bryon Rigg for noticing this. + +Thu Jan 25 19:54:01 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Svc_Handler: Added some minor changes to account for + limitations with GNU G++. I think the new implementation will + be portable across all C++ platforms. + + * ace/SV_Semaphore_*: Widened the interface of SV_Semaphore* + classes to include a flags parameter. This can be used to pass + in SEM_UNDO, which is important in many applications. Thanks to + Andrew Gilbert for suggesting this. + + * ace/Synch_T.cpp: We are forced to "cast away const" inside of of + the ACE_TSS const methods in order to make the ACE_Guard work. + The right thing to do would be to make the lock "mutable" but + that's hopelessly non-portable. + +Thu Jan 25 14:34:12 1996 Douglas C. Schmidt (schmidt@merengue.cs.wustl.edu) + + * ace/Log_Msg: Fixed a minor bug in ACE_Log_Msg that kept + resetting the restart and iostream value no matter what we'd set + it to before. Thanks to Prashant for finding this. + + * bin: Fixed up the Makefile process for the clone program. Now + it builds without having to depend on ACE. Thanks to Brad Brown + (bbrown@rdxsunhost.aud.alcatel.com) for suggesting this. + + * ace/Synch: Modified ACE_Condition*.remove so that cond_destroy() + is called in a loop if the condition variable is BUSY. This + avoids a condition where a condition is signaled and because of + some timing problem, the thread that is to be signaled has + called the cond_wait routine after the signal call. Since the + condition signal is not queued in any way, deadlock occurs + unless this loop is used. Thanks to Chris Lahey for pointing + this out. + + * ace/CORBA_Handler: Made all the methods in ACE_CORBA_Handler + private to make sure that users don't inherit from this class! + Instead, the ACE_MT_CORBA_HAndler and ACE_ST_CORBA_Handler + should be used as Singletons. + + * ace/CORBA_Handler: Added new support for Orbix on Windows + NT. This requires clever use of macros in order to handle + inherent differences between generated code. + + * ace/Svc_Handler: Added a clever idiom that transparently checks + if we were allocated dynamically. This information is used by + the method to decide if we need to delete ... + The idiom is based on a paper by Michael van Rooyen + (mrooyen@cellnet.co.uk) that appeared in the April '96 issue of + the C++ Report. We've spruced it up to work correctly in + multi-threaded programs by using our ACE_TSS class. + + * ace/config-win32-msvc4.0.h (ACE_LACKS_RECVMSG): Fixed a typo + in the MSVC++ config files. + +Thu Jan 25 02:59:22 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Finally got the frigging library built on SGI. This was a chore + due to compiler bugs, but at least it's another datapoint for + successful cross-platform building... + +Wed Jan 24 00:10:29 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Time_Value.cpp (operator-=): Changed operator += and + operator -= to use const ACE_Time_Value & rather than + ACE_Time_Value &. Thanks to Alex V Maclinvosky for noticing + this. In addition, also changed *all* ACE_Time_Value parameters + to be const ACE_Time_Value &. This should reduce the number of + excess constructors called... + + * ace/OS: Added Chris Lahey's latest changes that introduce POSIX + pthread cancellation cleanup handlers. Also added an herror() + function that is comparable to perror(). + + * ace/OS: (thr_join): Added a new version of thr_join() which + works for Windows NT. Windows NT requires a HANDLE, which is + fundamentally incompatible with other things... + + * ace/Thread_Manager: added two new methods that return the + ACE_Thread_Descriptor corresponding to either a thr_id or a + thr_handle. + + * ace/Thread_Manager: Made the spawn() interface compatible with + the other spawn() interfaces in ACE_OS and ACE_Thread by adding + the hthread_t type. + + * ace/Log_Msg.cpp (log): Fixed things up so that we can now print + out the thread id for all versions of threads! + + * ace/OS: Added a new overloaded version of ACE_OS::thr_self() + that returns the "kernel" thread id. This is necessary on + systems like NT and AIX, which separate kernel thread ids from + user thread ids. Thanks to Chris Lahey for suggesting this. + +Tue Jan 23 01:17:23 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/OS.i (sigwait): Changed the parameter of sigwait() from + const sigset * to sigset *. Thanks to Neil Cohen for chasing + this down on SunOS 5.5.... + + * ace/Malloc_T.cpp: Fixed a typo in bind() whereby + the test if (duplicates == 0 || this->shared_find (name) != 0) + should be if (duplicates == 0 && this->shared_find (name) != 0). + Thanks to the ever vigilant Alexandre Karev + for reporting this. + + * tests: Fixed all test programs that previously used the "execl" + family of system calls to use the "execv" family instead. + + * ace/OS: Added support for the "execv" family of exec() system + calls. Unlike the "execl" family, these calls are easy to + support since they don't require variadic arguments. I've added + the hooks for the "execl" family, as well, but haven't actually + implemented them yet. + + * ace/Memory_Pool.cpp (ACE_Shared_Memory_Pool): Fixed a bug that + was tickled when pool_name == 0. Thanks to Alexandre Karev + for reporting this. + + * ace/OS.h: removed FD_SETSIZE from the ACE_WIN32 stuff since this + is defined in winsock.h. + + * ace/OS.cpp (ACE_Spawn_Args): Added "f" to the parameter list. + + * ace/CORBA_Handler: Added a new macro called CORBA_T that masks + the incompatibilities between the version of Orbix on NT and on + Solaris. + + * ace/OS.h: Added support for compilers (like NT) that don't + support "mode masks" (these are used to give symbolic names for + file creation modes passed to open() and creat(). + + * ace/SString.cpp: Added Tim's new copy constructor code for + SString.cpp. This doesn't appear to be strictly necessary , but + it is more explicit and therefore it useful. + + * ace/Map_Manager.cpp: Fixed a bug in Map_Manager that was failing + to call the placement new operator for every element in the map + that was dynamically created by the allocator(). + + * ace/Synch_T: Added Tim's new ACE_TSS implementation. This + version is more flexible than the old one. + +Mon Jan 22 00:03:24 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Time_Value.h: changed a few minor things to get this + compiling again on NT. Thanks to Irfan for helping with this. + + * ace/Synch_Options: Changed all the "accessor" methods to be + const member functions at the request of Irfan. I just know + this is going to cause const cancer... ;-) + + * ace/Acceptor and Connector: Changed all parameters that take + ACE_Synch_Options & to take const ACE_Synch_Options & at the + request of Irfan. + + * ace/OS.i (uname): Added rudimentary support for the uname() + function for Windows NT. If anyone has suggestions on how to + fill in all these fields portably please let me know! + + * ace/Connector.h: Changed a stray -1 to ACE_INVALID_HANDLE. + Thanks to Irfan for noticing this. + + * ace/Profile_Timer.h: Added the keyword "public" to handle one + arm of the conditional compilation that is only exercised on + NT... Thanks to Irfan for noticing this. + + * ace/OS.i (mutex_init): Removed the call to + pthread_mutexattr_setkind_np() it isn't in the final POSIX + standard. + + * ace/Reactor.cpp (unbind): Removed the ACE_MAX3 template function + from OS.h and inlined its only use in the Reactor. This was + causing problems with some C++ compilers. Thanks to Mark Zusman + for reporting this. + + * ace/OS.i: Fixed a number of omitted return results in + gettimeofday() and ctime_r() that were masked by the + ACE_OSCALL_RETURN macros. Thanks to Mark Zusman + for reporting these. + + * ace/config-linux.h: Added new symbolic constants to handle the + fact that Linux seems to lack recvmsg(), sendmsg(), msync(), and + madvise(). Thanks to Neil Cohen for noticing this. + + * include/makeinclude: Fixed all the *-orbix.GNU files to use + $(ORBIX_ROOT)/lib rather than $(ORBIX_ROOT)/ace. Thanks to + Pramod Kumar Singh for reporting + this. + + * ace/config*.h: Changed all typos of the form ACE_HAS_SVSV_IPC to + ACE_HAS_SYSV_IPC. Thanks to Alexandre Karev + for reporting this! + + * ace/OS: Changed the order of parameters passed to thr_create() + to be consistent with all the spawn() and spawn_n() usages in + ACE. Thanks to Chris Lahey for pointing this out. + +Sun Jan 21 15:06:15 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace: Added a new "priority" parameter to the spawn() and + spawn_n() methods in ACE_Thread and ACE_Thread_Manager. This + allows us to pass the priority on down to thr_create(). Thanks + to Chris Lahey for pointing this out. Note that this change + required reordering the parameters so that the stack and + stack_size parameters now come last for these methods. Since + those are not likely to change much this is a good place to put + them (i.e., at the end). + + * ace/Thread.i (spawn_n): Added a new overloaded spawn_n() method + that accepts an array of thread_t's to be filled in. This is + useful if you want to know the thread IDs of any threads + created. + + * Changed ACE_OS::signal() to ACE_Sig_Action across all of ACE to + be portable to pthreads implementations. Thanks to Chris Lahey + for pointing this out. + + * ace/OS: Added a new set of OS C++ wrappers for POSIX pthread + cancellation routines. Thanks to Chris Lahey for these. + + * ace/Thread: Added a new set of ACE C++ wrappers for POSIX + pthread cancellation routines. Thanks to Chris Lahey for + these. + + * ace/Map_Manager: Revised the Map_Manager::bind method. This has + now been split into bind() and rebind() methods. The bind() + method is very simple -- if you try to bind() to something that + already exists you fail. The rebind() method allows you to + atomically update existing values in a map. It also gives you + back the existing values so that you can delete them if + necessary. The Local_Name_Space::bind() and rebind() methods + have been updated to use this new interface. + + * ace/Malloc_T.cpp (find): Fixed a typo -- find() should have set + its pointer parameter to node->pointer_, rather than + node->name_! This bug was revealed during testing of the ACE + Name Server. + + * ace/Local_Name_Space.cpp: Fixed bugs with computation of the + size of ACE_NS_Strings -- they needed to count the wchar_t's + correctly, along with several other minor fixes. These were + revealed during testing of the ACE Name Server. + + * ace/SString.cpp: Fixed several bugs that prevented the + assignment operators from working correctly. These were + revealed during testing of the ACE Name Server. + +Sat Jan 20 08:33:54 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Local_Name_Space.cpp (shared_bind): The args to to the + NS_String constructors were not in the correct order: + + wchar_t *value_rep = (wchar_t *) (ptr); + wchar_t *name_rep = (wchar_t *) (ptr + name_len); + ACE_NS_String ext_id (name.fast_rep (), name_rep, name_len); + ACE_NS_String int_id (value.fast_rep (), value_rep, value_len); + + They should be: + + ACE_NS_String ext_id (name_rep, name.fast_rep (), name_len); + ACE_NS_String int_id (value_rep, value.fast_rep (), value_len); + + Thanks to Irfan for noticing this. + + * ace/OS.h: defined the following in ACE_OS: + + #define MS_ASYNC 0 + #define MS_SYNC 0 + #define MS_INVALIDATE 0 + + under NT so that calls to mmap will port transparently. Thanks + to Irfan for suggesting this. + +Thu Jan 18 16:25:16 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace: Added a new symbol that indicates if the platform supports + the new BSD sin_len field of inet_addr. + + * ace/OS: added new support for AIX gethostbyaddr_r(), + gethostbyname_r(), and getservbyname_r(). This fixes some + problems caused by improper choice of buffer size. Also changed + the INET_Addr.cpp file to use these new changes. Thanks to + Chris Lahey for recommending these changes. + +Wed Jan 17 01:10:48 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/OS.i (printf): the ACE_OS::printf() function did not work. + Needed to call vprintf() internally, not printf. Thanks to + Chris Lahey for pointing this out. + + * Released version 4.0. + + * include/makeinclude: added the -lgen library to all the + platform_sunos5.*.GNU files. + + * ace/Memory_Pool.cpp: removed the INLINE macros in Memory_Pool.cpp. + Thanks to Alexandre Karev (karev@vxcern.cern.ch) for noticing + this! + + * ace/Malloc_T.cpp: moved the comment "Ce n'est pas une catst" + outside of the macro ACE_NEW_RETURN. The prepocessor truncates + the macro expansion when it encounters the comment. Thanks to + Greg Baker for pointing + this out. + + * ace/Reactor.cpp (close): added "return 0" at the end of the + close member function. The function is prototyped to return an + int and the compiler expects a return outside of the if clause. + Thanks to Greg Baker for + pointing this out. + + * ace/Stack.cpp (free_all_nodes): Removed a spurious ACE_OS that + was stuck on the front of ::delete. Thanks to Greg Baker + for pointing this out. + + * ace/OS.i: Added extern "C" to the prototype for syscall in OS.i. + Without it, you get unresolved symbols at link time. Thanks to + Greg Baker for pointing + this out. + + * ace/Message_Queue.cpp: Changed the return values for + enqueue_head(), enqueue_tail(), dequeue_head(), and + peek_dequeue_head() to return the number of messages that are + still on the queue. This helps some algorithms perform better + and avoid blocking unnecessarily. Thanks to Alex V Maclinvosky + for suggesting this... + + * ace/Synch_T.cpp (ACE_Condition): Fixed a bug in + ~ACE_Recursive_Lock and ~ACE_Recursive_Mutex that was causing + the destructor to be called twice (once implicitly and once + explicitly). Thanks to Chris Lahey for pointing this out. + +Mon Jan 15 12:44:29 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace: Created a new config symbol called ACE_HAS_ALLOCA_H. This + is required to differentiate between AIX and other versions of + UNIX. Thanks to Chris Lahey for pointing this out. + + * ace: moved config-hpux.h to config-hpux-9.x.h in anticipation of + the changes required to handle HP/UX 10.0! + +Sun Jan 14 23:38:23 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/OS.h (ACE_MAX3): Fixed the definition of ACE_MAX3 (it needed + a return value of template type T). Thanks to Mark Zusman + for noticing this. + + * ace: Added a new section to all the template files called + ACE_TEMPLATES_REQUIRE_SPECIALIZATION to deal with the screwy GNU + G++ semantics that are required if you *don't* have the template + repository patches. Thanks to Mark Zusman + for this. + +Fri Jan 12 00:47:57 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Time_Value.h: #included to the Time_Value.h + class so that it would be the first file included. This fixes a + problem with AIX. Thanks to Chris Lahey for reporting this and + suggesting the fix. + + * ace: Fixed a braino with the #ifdefs in SPIPE_Stream and + SPIPE_Acceptor. These were checking for ACE_WIN32 rather than + ACE_HAS_STREAM_PIPES. Naturally, that failed on versions of + UNIX (e.g., Linux) that lack STREAM pipes! Thanks to Neil Cohen + for taking time out of fighting blizzards to report this! + + * ace/Svc_Handler: Added a new method for handle_timeout, which + shuts things down by default. Thanks to Irfan for suggesting + this. + + * Fixed a minor problem caused when Tim added the Double-Check + pattern to ACE_ODB... + +Thu Jan 11 01:48:02 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Integrated AIX fixes from Chris Lahey . + These should allow ACE to build correctly using the AIX compiler + and it's screwy template mechanisms! + + * ace: Fixed some minor bugs that caused problems when compiling + with G++. + +Wed Jan 10 00:17:05 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Trace.cpp: Fixed a typo that was causing problems when using + ACE_TRACE (we were ending up with recursive tracing in the + ACE_Trace class!). Thanks to Detlef for noticing this. + + * ace/ACE.cpp: Moved methods from ACE.i to ACE.cpp and removed the + INLINE macro to deal with order of include problems with GNU + G++. + +Tue Jan 9 19:00:41 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Task.i (flush): Added a check to make sure that msg_queue_ + != 0 before trying to close() the queue. This solves a problem + if the queue has already been closed. Thanks to Alex V + Maclinvosky for reporting this... + + * tests/ASX/Event_Server/Event_Server: Fixed minor bugs in + Supplier_Router.cpp and Consumer_Router.cpp -- I was checking + for this->getq (mb) > 0 rather than this->getq (mb) >= 0. + Thanks to Alex V Maclinvosky for + noticing this... + + * ace/Synch_T.h: Commented out the ACE_ALLOC_HOOK stuff. This is + causing order-of-include problems on HP/UX. Also moved the + ACE_Null_Condition::wait() method to Synch_T.i to avoid the same + problem. Thanks to Greg Baker + for pointing this out. + +Sun Jan 7 18:57:49 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Makefile: Added the Dump file to ACE. Thanks to Tim for + fixing this up to make it ready for prime time. + + * Thanks to Craig Rodrigues for sending + me a new version of psnup that *finally* fixes the nasty + problems with "4-up" printing of postscript! This makes it much + easier to distribute ACE documentation... + +Sun Jan 7 18:31:07 1996 Tim H. Harrison (harrison@merengue.cs.wustl.edu) + + * ace: Used the "Double-Check" pattern to eliminate potential race + conditions when using Singletons in multi-threaded programs. + Classes affected included ACE_[MS]T_CORBA_Handler, Name_Options, + Trace, and ACE_ODB. + +Fri Jan 5 00:03:29 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/OS.i: Added the following to OS.i: + + #if defined (ACE_LACKS_SYSCALL) + int syscall (int, ACE_HANDLE, struct rusage *); + #endif /* ACE_LACKS_SYSCALL */ + + This should fix some problems with HP/UX. Thanks to Walt Akers + (akers@cebaf.gov) for pointing out the problem. + + * ace/Handle_Set: Fixed the Handle_Set conversion operator so that + it returns fd_set * rather than ACE_FD_SET_TYPE *. Thanks to + Walt Akers (akers@cebaf.gov) for pointing out the problem. + + * ace/Time_Value.h: I think I've fixed the problem with the order + of #includes with respect to POSIX and SVR4 time. The trick was + to put this test in ace/Time_Value.h and then to make sure that + the ace/config.h file was included at this point! Also changed + the symbol from ACE_HAS_POSIX_TIMERS to ACE_HAS_POSIX_TIME to be + more accurate. + +Thu Jan 4 23:16:59 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/OS.i (gettimeofday): Changed the implementation of + gettimeofday() to use the ::_ftime call rather than the more + complex ::GetSystemTime(), ::SystemTimeToFileTime() duo. + +Thu Jan 4 9:32:38 1996 Chris Lahey (clahey@ix.netcom.com) + + * ace/config-aix.h: added #define ACE_TEMPLATES_REQUIRE_SOURCE + to make ACE work with AIX C++ compiler. + + * include/makeinclude/platform_aix.GNU: + + Added -qtempinc to the CPPFLAGS + Removed the PIC= definition completely + + * ace/Task.h: ACE_Task::svc() should not be declared as a pure + virtual, removed = 0. + + * ace/Map_Manager.cpp: in trybind() member function, the line + int_id = ss.int_id_; + should be: + int_id = search_structure[index].int_id_; + +Thu Jan 4 01:23:38 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Map_Manager.cpp: Fixed a braino in Map_Manager -- didn't + need the parameter to shared_bind(). Thanks to Tim for + finding this! + + * ace/Log_Msg.cpp (instance): Tim Harrison did a noble service to + humanity by fixing a potential race condition in the instance() + Singleton of ACE_Log_Msg. + +Wed Jan 3 00:49:57 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace: Made some minor changes to fix portability problems with + SGI. Fortunately, this should also fix some other problems with + HP/UX another other non-thread platforms. + + * ace/ACE.cpp (format_hexdump): Added Todd Montgomery's amazing + "format_hexdump" method to class ACE. + +Tue Jan 2 20:47:57 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/SV_Semaphore*: updated the interface of the _Simple and + _Complex System V semaphore wrappers to include the _read() and + _write() forms of acquire() and tryacquire(). Note that I've + implemented these as calls to acquire() and tryacquire(), so + they don't add any extra behavior. This is needed for interface + conformance with other forms of ACE synchronization mechanisms. + + * ace/Time_Value.h: Changed the header to #include + in order to work around nasty "order of include" problems. + + * tests: Created a new directory called Win32. This contains test + programs that This directory contains test programs that have + been compiled and tested successfully under Windows NT. As we + get further along, we'll move this stuff into the general ACE + $WRAPPER_ROOT/tests directory (since of course all ACE programs + will run without any problems under Win32, right? ;-)). See + the ./tests/Win32/README file for instructions on how to build + these tests. + + * ace/Reactor.h: Moved the ACE_Handler_Repository out of the + ACE_MT_SAFE section of the code. This was a "typo." Thanks to + Walt Akers for reporting this. + +Mon Jan 1 01:18:12 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/ACE.i: Moved the recv_n() and send_n() methods from ACE.cpp + into ACE.i and set things so that if __INLINE__ is set then + we'll inline those too! + + * ace: Irfan and I got the first major part of the Win32 to work + finally! We made two socket programs (client and server) that + talked to each other and to UNIX. Things are really starting to + take shape! diff --git a/ChangeLog-96b b/ChangeLog-96b new file mode 100644 index 00000000000..f5111699d98 --- /dev/null +++ b/ChangeLog-96b @@ -0,0 +1,2760 @@ +Sat Oct 19 12:33:56 1996 David L. Levine + + * added ACE threads mappings to VxWorks 5.2 tasks in OS.*. + NOTE: this is _untested_ at this point, but only affects + VxWorks code + + * changed name of first argument of ACE_OS::sigprocmask() and + ACE_OS::thr_sigsetmask() from "signum" to "how" to better + represent what it really is. + +Wed Oct 16 01:59:40 1996 Douglas C. Schmidt + + * ace/Log_Record.cpp (print): added Luca's suggestion for checking + if host_name == 0 for the ostream version of print(), as well. + + * Released version of ACE 4.0.32 for testing. + + * ace/Synch.h: Added many small fixes for HP/UX 10.x. Thanks to + Alan Stewart for providing these. + + * ace/OS.h: Added many new ACE_LACKS* and ACE_HAS* macros to + support the MVS port. Thanks to Chuck Gehr + for these. + +Tue Oct 15 11:56:59 1996 Douglas C. Schmidt + + * ace/OS.h: in a continuing effort to protect the ACE namespace, + I've changed ace/OS.h around lines 127-137 so that "SYNCH" and + "SYNCH_MUTEX", etc. are prefixed with "ACE_". Thanks to Alan + Stewart for suggesting this. + + * ace/Local_Tokens.h: Removed an unnecessary parameter name + that was unused. Thanks to Stuart Powell + for reporting this. + +Tue Oct 15 17:03:37 1996 Tim H. Harrison + + * ace/ReactorEx.cpp (handle_events): Fixed a bug in handle_events + so that the correct handlers get called when multiple handles + become signaled simultaneously. Thanks to Ari Erev + for pointing out this bug. I also took + this opportunity to fix a bug when handlers are removed during + handle_events. + + * examples/Reactor/ReactorEx/test_remove_handler.cpp: Added a new + application that tests how the ReactorEx services simultaneous + events and removes handlers. This example also illustrates the + use of the new ACE_Events wrapper. Check + examples/Reactor/ReactorEx/README for more details. + +Mon Oct 14 11:43:18 1996 Douglas C. Schmidt + + * tests: Added a new version of run_tests.sh, which was + contributed by Michael Rueger . + + * examples/Logger/simple-server/Logging_Handler.cpp (handle_input) + and examples/Logger/Acceptor-server/server_loggerd.cpp + (handle_input): Changed from stderr to cerr to work around bugs + with the C run-time libraries on Win32. Thanks to Tilo Christ + for suggesting this. + +Mon Oct 14 11:09:42 1996 Prashant Jain + + * ace/Local_Name_Space_T.cpp (remap): Added processor specific + stuff to remap(). The code was taken from the book "Win32 + Network Programming" by Ralph Davis (p.18) and takes care of + cases specific to the 80x86 processor. The code ensures that the + registers are set properly when we continue execution after an + exception. + +Sun Oct 13 21:18:38 1996 Douglas C. Schmidt + + * ace/Log_Record.cpp (print): Added a test to make sure that the + value returned from ctime_r != 0 (e.g., if time_stamp_ == -1) in + order to avoid crashes. + + * examples/Logger/client/logging_app.cpp (main): Moved the + construction of the ACE_Log_Record log_record object into the + loop so that it will be recreated each time through. If this + isn't done, then we'll be continually "encoding" values into + network byte order that have already been encoded and screwing + things up on little-endian machines (such as Intel). Thanks to + Irfan and Tilo Christ for pointing + me in the right direction on this. + + * ace/Log_Record.cpp: Changed the default constructor so that it + gives default initializations to the data members. + + * examples/Logger/Acceptor-server/server_loggerd.cpp (handle_input): + Fixed a couple of typos where + + Logging_Handler::handle_input (int) + + should be: + + Logging_Handler::handle_input (ACE_HANDLE) + + and + + size_t len; + + should be: + + ssize_t len; + + Thanks to Irfan for finding these. + +Sat Oct 12 08:48:23 1996 Douglas C. Schmidt + + * Released a beta version of ACE 4.0.32 for testing. + + * ace/Log_Record.cpp: rewrote the code a bit to try and avoid + problems on NT when host_name == 0. + + * ace/Log_Record.cpp: Changed the use of ACE_OS::ctime() to + ACE_OS::ctime_r() to avoid problems that might arise when + ACE_Log_Record::print() is called from multiple threads. + + * ace/Log_Record.cpp: Commented out calls to ACE_TRACE to avoid + weird problems with circular dependencies. Thanks to Luca + Priorelli for suggesting this. + + * build/SunOS5.5/examples/Makefile: Added the Logger directory to + the list of targets that are build automatically by Make. + +Fri Oct 11 17:13:03 1996 Douglas C. Schmidt + + * ace: Fixed lots of small warnings revealed when using the + Greenhills compiler on VxWorks. Thanks to David Levine for + this. + + * ace/Pipe.h: In Pipe.h, the return value of ACE_Pipe::close() + isn't explicitly declared, so some compilers gag. Thanks to + David Levine for this. + +Thu Oct 10 12:05:55 1996 Douglas C. Schmidt + + * ace/Thread.cpp: Correctly wrapped the methods in the *.cpp file + so that they are ignored if threads *aren't* supported. + + * ace/Service_Repository.cpp (remove): Added the ACE_MT in front + of all the ACE_GUARD* macros that utilize ACE_Thread* locks in + order to ensure that ACE compiles correctly on all non-MT + platforms. + + * examples/Shared_Malloc/Malloc.cpp: Removed the special purpose + class for PROCESS_MUTEX since ACE_Process_Mutex will now work + for non-MT platforms. + + * examples/Misc/test_dump.cpp: Changed all occurrences of + + cerr << "string " << this << endl; + + to + + cerr << "string " << (u_long) this << endl; + + to work around problems with IRIX 5.3. Thanks to Tilo Christ + for reporting this. + + * ace/config-linux.h: Added a // in front of a stray comment line. + Thanks to Neil Cohen for pointing this out. + + * ace/config-hpux-10.x-g++.h: Added a new config file for HP/UX + 10.x which should fix some problems with templates by using the + G++ compiler. Thanks to for + contributing this. + +Wed Oct 9 14:34:19 1996 Douglas C. Schmidt + + * ace/OS: Changed the logic of socket initialization, which has + been moved out of ACE_SOCK and into ACE_OS. This makes it + possible to program more fully at the ACE_OS API (if such a + crazy thing is really necessary ;-)). + + * examples/IPC_SAP/SOCK_SAP/C-in{client,server}.cpp: Fixed up the + client and server apps so they will work on NT + (i.e., replaced the use of int with ACE_HANDLE). Thanks to Joe + DeAngelis for suggesting this. + + * ace/Synch.h: Now that we've got support for POSIX semaphores on + Solaris, then we'll use them (when they are supported...) as the + implementation of ACE_Process_Semaphore rather than using the + slower ACE_SV_Semaphore_Complex stuff... + + * ace/OS.{h,i}: Added David Levine's support for named POSIX + semaphores. If ACE_HAS_POSIX_SEM is defined, then ACE_Semaphore + will construct a named POSIX semaphore if passed a non-null + name, or an unamed POSIX semaphore if passed a null name. This + is a great addition because POSIX semaphores are more powerful + and useful than the Solaris UI semaphores. Unfortunately, + Solaris 2.5 doesn't support them (yet). + +Tue Oct 8 16:00:00 1996 Irfan Pyarali + + * ace/OS: Integrated Irfan's encapsulation/emulation for Win32 + Events at the ACE_OS level. A new structure ACE_event_t was + created to support Events on non-WIN32 platforms. On WIN32 + platforms ACE_event_t is just a HANDLE. On non-WIN32 platforms, + ACE_event_t uses a combination of mutexes, condition variables, + and counters to emulate Events. Both auto-reset and manual-reset + events are supported. + + * ace/Synch: Integrated Irfan's encapsulation/emulation for Win32 + Events at the C++ wrappers level. There are three wrappers that + were created: ACE_Event, ACE_Auto_Event, and ACE_Manual_Event. + ACE_Event is a wrapper for the ACE_event_t structure. It + provides functionality for signal, wait, pulse, and reset on an + event. ACE_Event supports both auto-reset and manual-reset + events. However, specializations of ACE_Event were created + (ACE_Manual_Event and ACE_Auto_Event) to make it easier to use + Events. + + * examples/Threads/test_manual_event.cpp: A test for manual-reset + events. The test involves the creation and use of a barrier + which uses an ACE_Manual_Event. + + * examples/Threads/test_auto_event.cpp: A test for auto-reset + events. The test involves the use of an ACE_Auto_Event for + signaling threads. + +Tue Oct 8 15:45:01 1996 Douglas C. Schmidt + + * ace/DEV.cpp (ACE_DEV): Removed a stray call to + ACE_IO_SAP::dump(). Thanks to Brad Flood + for this fix. + + * ace/OS.i: Added ACE_HAS_CHARPTR_SOCKOPT for VxWorks. Thanks to + David Levine for this. + + * ace/Dump.cpp (instance): Added an ACE_MT() macro around the + ACE_GUARD_RETURN macro so that this will compile correctly on + non-threaded platforms. Thanks to David Levine for this. + + * ace/OS.h: the declaration of ACE_OS::msgctl needs "struct + msqid_ds" instead of just "msqid_ds" to compile with the + Greenhills C++ compiler. Thanks to David Levine for this... + + * ace/Local_Name_Space_T.h: Added #include "ace/Local_Name_Space.h" + to avoid a problem during template generation. Thanks to + Chris Lahey for this fix. + + * ace/OS.i (getprotobynumber_r): Added a pair of fixes from Chris + Lahey to get the ACE wrappers for the getprotoby*_r() methods to + compile on AIX. + + * examples/Threads: Added two new examples (test_auto_event.cpp + and test_manual_event.cpp) that exercise the new ACE_Event + mechanisms. + + * ace/Synch: Integrated Irfan's encapsulation/emulation for Win32 + Events at the C++ wrappers level. + + * ace/OS: Integrated Irfan's encapsulation/emulation for Win32 + Events at the ACE_OS level. + +Fri Oct 4 08:32:47 1996 Douglas C. Schmidt + + * ace/OS.i: Added David Levine's new ACE_OS::mktemp() implementation. + +Wed Oct 2 13:26:20 1996 Douglas C. Schmidt + + * ace/SV_Message_Queue.i: Changed the casts of (msgbuf *) to + (void *). + + * ace/OS.i: Added David Levine's implementation of inet_addr() for + VxWorks. + + * ace/OS.i: Continued to merge together various parts of Win32 and + UNIX to reduce redundancies. + +Tue Oct 1 15:03:42 1996 Douglas C. Schmidt + + * ace/OS.i: Added Chuck Gehr's new changes to ACE_OS::mutex_init() + and ACE_OS::cond_init() to handle the MVS Pthreads madness. + + * ace/OS.i: Added zillions of #ifdefs for VXWORKS. It's amazing + these guys call themselves POSIX compliant -- lots of stuff is + missing. Thanks to David Levine for doing this! + + * ace/OS.cpp: Added David Levine's implementation of mktemp() + for platforms that don't support it. + + * ace/OS.h: Added a bunch of minor changes for VXWORKS. In + addition, started to factor out common #ifdefs to make the code + easier to maintain. + + * ace/OS.h: Added a new macro for ACE_LACKS_UTSNAME, and factored + this out for both VxWorks and Win32. + + * ace/Time_Value.h: Added support for 2 VXWORKSisms: (1) we need + to #include sys/times.h rather than the standard UNIX sys/time.h + and (2) we need to change const timeval & to const struct + timeval & to keep the Greenhills compiler happy. Thanks to + David Levine for this. + + * ace/INET_Addr.cpp: Added support for the insane VXWORKS + hostGetByName() function. Yikes! Thanks to David Levine for + this. + + * ace/Memory_Pool.cpp: Added a new #define called ACE_LACKS_SBRK + and ACE_LACKS_SYSV_SHMEM, which is enabled on Win32 and VxWorks. + Thanks to David Levine for reporting this. + + * ace/OS.h: Added new macros that #define ETIME for platforms like + VxWorks that don't support it, but do support ETIMEDOUT. + + * ace/OS.h: Added placeholder #defines for USYNC_PROCESS and + USYNC_THREAD when !defined (ACE_HAS_THREADS). Thanks to Neil + Cohen for reporting this. + +Tue Oct 1 00:42:35 1996 Douglas C. Schmidt + + * ace/Message_Block.cpp (size): Member base_ of ACE_Message_Block + was being set to the new memory pointer before the old contents + are saved in method size. So the line + + this->base_ = buf; + + was moved to a place some lines below. Thanks to Marco Sommerau + for detecting this. + + * ace/Message_Queue.cpp: Changed the implementation of the + enqueue_i() method so that FIFO order is maintained when + messages of the same priority are inserted consecutively. + Thanks to Jay Denkberg for + suggesting this. + +Mon Sep 30 22:59:38 1996 Douglas C. Schmidt + + * ace/OS.i (thr_yield): Added a new macro ACE_HAS_YIELD_VOID_PTR + to make pthread_yield work on MVS. Thanks to Chuck Gehr + for this fix. + + * ace/OS: Added a new macro called ACE_HAS_TIMEZONE_GETTIMEOFDAY + that handles problems on MVS. Thanks to Chuck Gehr + for this fix. + +Mon Sep 30 13:45:10 1996 Tim H. Harrison + + * ace/Local_Tokens.h: Updated some documentation in all the Token + files. + +Mon Sep 30 18:01:12 1996 Prashant Jain + + * netsvcs/lib/: Renamed files Logger.{h,cpp} to + Logging_Strategy.{h,cpp} to avoid confusion with Server_Logging + and Client_Logging stuff. In addition, I modified the affected + files, including Makefile, README, and the config files in the + tests directory. + +Sun Sep 29 12:47:37 1996 Douglas C. Schmidt + + * ace/OS.h: Added Chuck Gehr fixes for + MVS to enable signals to work correctly. + + * ace/Time_Value.h: Added an extern "C" { } block around #include + to solve a problem with Linux. Thanks to Padhu + Ramalingam for reporting this. + + * netsvcs/lib/Server_Logging_Handler.cpp: Changed the + initialization of a static template object from ::request_count_ + (0L) to ::request_count_ = 0L. Thanks to Gonzalo Diethelm + for reporting this. + + * ace/Remote_Tokens.h: Moved the inclusion of "Singleton.h" from + Remote_Tokens.cpp to Remote_Tokens.h. This should avoid + template instantiation problems on some platforms (e.g., Irix + 6.2). + + * ace/config-irix6.2-sgic++.h: Changed ACE_HAS_SIGINFO to + ACE_HAS_SIGINFO_T and added ACE_HAS_UCONTEXT_T. Thanks to + Gonzalo Diethelm for reporting this. + + * ace/Token_Invariants.h: The ctor/dtor were private and the + compiler would not allow a template of the class to be created. + I switched them to public, but I wish there was a better way... + Thanks to Gonzalo Diethelm for reporting + this. + + * ace/Synch_T.h: #include'd "ace/Event_Handler.h". Thanks to + Gonzalo Diethelm for reporting this. + + * ace/Synch.h: The parameter name gives warnings when + instantiating templates. Thanks to Gonzalo Diethelm + for reporting this. + + * ace/Process: Changed the definition of the get_pid() method to + getpid() to avoid a conflict with Irix. Thanks to Gonzalo + Diethelm for reporting this. + + * ace/Log_Msg.cpp (log): Added another #elif !defined (ACE_WIN32) + to handle logging for OS platforms that (1) aren't Win32 and (2) + are versions of UNIX that don't support STREAM pipes. Thanks to + Gonzalo Diethelm for reporting this. + + * ace/Acceptor.cpp (handle_signal): Erased the signum parameter + name to avoid a nasty warning about arguments not used when + instantiating templates. Thanks to Gonzalo Diethelm + for reporting this. + + * ace/OS.h: Added the ACE_Export symbol to the definition of + ACE_Str_Buf. This makes it compile and link on NT. Thanks to + Prashant for noticing this (our favorite Win32ism...). + + * ace/Thread.h (ACE_Thread): Removed a default argument for one of + the ACE_Thread::join() wrappers so this won't be ambiguous with + the other join() wrapper. + + * ace/OS: Added a new wrapper for strtok_r(). + +Sun Sep 29 16:12:01 1996 Prashant Jain + + * netsvcs/lib/: Renamed the project file for Win32 from lib.mdp to + netsvcs.mdp. Also the original project file did not include some + files such as Naming_Handler.cpp and Server_Logging_Handler.cpp + and I fixed that. Finally removed two files System_Time.{h,cpp} + which are already present in ace/. + +Sat Sep 28 16:34:56 1996 Douglas C. Schmidt + + * ace/OS: Added a new overloaded select() method that takes a + const ACE_Time_Value &. This is useful for situations where you + are passing in ACE_Time_Value::zero. + +Fri Sep 27 16:20:46 1996 Douglas C. Schmidt + + * ace/ACE: Added a fix for the fact that VxWork's write() call + doesn't take a const char *. + + * ace: Started adding support for VxWorks and GreenHills compiler, + e.g., added the config-vxwork-ghs-1.8.h file. Thanks to David + Levine for getting this rolling! + +Thu Sep 26 00:15:46 1996 Douglas C. Schmidt + + * ace/Timer_Queue: Changed the public interface methods to be + virtual in order to make it possible to override them in + subclasses. This makes it feasible to implement different types + of Timers. + + * ace/OS: Added a wrapper for the strspn() string call. Thanks to + Irfan for noticing this omission. + + * ace/Synch_T.cpp (wait): Changed the line: + + return ACE_OS::cond_wait (&this->cond_, this->mutex_); + + to + + return ACE_OS::cond_wait (&this->cond_, &this->mutex_.lock_); + + Thanks to Dieter Quehl + for noticing this. + + * ace/config-sunos5.4-g++.h: Removed the #define for + ACE_HAS_BROKEN_RANDR and replaced the ACE_HAS_SVR4_SIGNAL_T with + ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES since it looks like the + latest gcc release (2.7.2) fixes this in their own header files. + +Sat Sep 21 10:45:43 1996 Douglas C. Schmidt + + * ace/OS.h: Added a new #define called ACE_HAS_BROKEN_MSG_H to the + config-osf1-3.2.h file and used it in OS.h to work around + problems with prototypes on that platform. + +Fri Sep 20 00:15:29 1996 Douglas C. Schmidt + + * Released version 4.0.31 for testing. + + * ace/Pipe.cpp: Initialize handles_ to ACE_INVALID_HANDLE in + default constructor. Thanks to Tim Harrison for pointing this + out. + + * ace: Copied in new versions of ace.{mak,mdp} for Win32. + + * ace: Added TTY_IO.cpp to the Makefile. + + * ace/config-win32-msvc[24].0.h: Updated the config file so that + it *doesn't* #define ACE_HAS_STRBUF_T since this type clearly + isn't available on Win32! + + * ace: Modified all of OS.i and config-*.h files so that they + would be consisten with respect to handling the size_t and int + differences in socket implementations. Thanks to Chuck Gehr + for helping with this for AIX. + + * ace/ACE.h (ACE): Added a new method called max_handles() that + returns the maximum number of open handles currently supported + by the process. + + * examples/Reactor/Misc/signal_tester.cpp: Revised the test to + utilize the new idioms for programming with signals. + + * ace/OS.h: added a new #define called ACE_DEV_NULL that defaults + to "/dev/null" on UNIX and "nul" on NT. Thanks to David Trumble + for reporting this fix. + + * ace/Log_Msg.cpp: Added some checks to make sure that we don't + try to strdup() if we are passed a NULL pointer. Thanks to Luca + for suggesting this. + + * ace/OS: Move ACE_Str_Buf into OS.{h,i} and remove the Str_Buf.h + file. + + * Makefile: Added the "performance-tests" directory to the list of + directories we build when making ACE. + + * ace: Moved the definition of strbuf from Str_Buf.h into OS.h. + Thanks to Irfan for recommending this. + + * ace/Makefile: Added some additional sed magic on the + Svc_Conf_y.cpp file in order to remove the very last warnings + from MSVC++! + +Thu Sep 19 00:00:17 1996 Douglas C. Schmidt + + * ace/Service_Config.cpp (open): Only initialize the logger to use + STDERR if the user hasn't already set the ACE_Log_Msg::flags(). + Thanks to Tom Leith for suggesting this. + + * ace/OS: Removed all traces of the ACE_HAS_INT_SOCKNAME and + ACE_HAS_LENPTR_SOCKOPT since Chris Lahey's new fixes for AIX + obviate the need for these. + + * ace/OS.i: Only #include if the platform has RPC! + Thanks to Chuck Gehr for suggesting + this. + + * ace: Removed all uses of ACE_HAS_SETOWN and replaced them with + explicit tests for F_SETOWN and FASYNC. This is more portable. + Thanks to Chuck Gehr for suggesting + this. + + * ace/OS: Added a new #define called ACE_HAS_SIZET_SOCKET_LEN to + handle platforms where the length parameter of bind(), + connect(), accept(), etc. uses size_t rather than int. This + helps to get ACE working on MVS. Thanks to Chuck Gehr + for suggesting this. + + * ace/OS: Added Chris Lahey's fixes that make the + getprotoby{name,number}_r() functions work for AIX. + + * ace: Changed the ACE_HAS_STRUCT_HOSTENT_DATA to + ACE_HAS_STRUCT_NETDB_DATA because we use a single symbol to + refer to all of the odd netdb.h stuff that AIX has... + + * ace: Changed all uses of: + + iovec *iovp = (iovec *) alloca (total_tuples * sizeof *iovp); + + to + + iovec *iovp = (iovec *) alloca (total_tuples * sizeof (iovec)); + + to keep the AIX compiler from complaining (falsely) about using + iovp before it is initialized. Thanks to Chris Lahey for + reporting this. + + * ace/OS.h: Added Chris Lahey's changes that handle AIX's + _XOPEN_EXTENDED_SOURCE features without polluting all the socket + implementations! + + * ace/Thread.cpp (spawn_n): Removed an unreferenced local variable + so that the Win32 compiler doesn't complain. + + * ace/OS.h: Added the definition for strbuf{} for NT. + + * ace: Removed the msg_hack.h file since it had OSF and DEC + copyright info in it. Replaced this with Antonio Tortorici's + clever use of _KERNEL and the + new ACE_LACKS_SYSV_MSQ_PROTOS. + + * ace/INET_Addr.h: Updated the documentation to indicate more + clearly the use of getservbyname(). + + * ace/OS.cpp (thr_create): Added basic hooks to support the use of + AfxBeginThread on Win32. This is necessary to allow ACE to work + seemlessly with MFC applications. Added an THR_USE_AFX flag + that can be "or'd" in with the other thread flags in calls to + ACE_OS::thr_create(). If this flag is enabled *and* if we are + compiling with ACE_HAS_MFC enabled, then AfxBeginThread() is + called rather than _beginthreadex(). + + * ace/INET_Addr.h (set): Fixed a typo in the documentation for + set() (the order of "host:port" was backwards...). Thanks to + Brad Flood for reporting this. + +Wed Sep 18 00:36:01 1996 Douglas C. Schmidt + + * ace/SOCK_IO.cpp: Added a new recv() method that allows a client + to read from a socket without having to provide a buffer to + read. This method determines how much data is in the socket, + allocates a buffer of this size, reads in the data, and returns + the number of bytes read. The caller is responsible for + deleting the memory. Thanks to Luca Priorelli + for suggesting this. + + * ace/OS.h: Added a special #ifdef for IRIX 6.2 threads so that + THR_BOUND and THR_SCOPE_SYSTEM are different. Thanks to Gonzalo + Diethelm for reporting this. + + * ace/Message_Block.i (msg_class): Added a new "class" of messages + to ACE_Message_Block: MB_USER. This is useful for writing + extensible applications a la Microslush Windows MSG stuff... + +Tue Sep 17 16:38:44 1996 Douglas C. Schmidt + + * ace/Message_Block: Changed the signature of the + ACE_Message_Block constructors (and init()) so that they take + const char * rather than char *. In addition, changed the + definition of one of the constructors (and init()) so that it + takes a size field in addition to the buffer. + + * ace/Message_Block.cpp (size): Fixed a bug in the + ACE_Message_Block::size() method -- we were failing to deal with + allocators and ownership correctly during a resize. Thanks to + Amos Shapira for reporting + this. + + * ace/Naming_Context.cpp: Removed the source of yet another + warning about "inconsistent dll linkage. dllexport assumed." + + * ace/Mem_Map.cpp (map_it): Added a cast to size_t (file_len) + because by this time we know that file_len >= 0. This avoids + yet another warning on WinNT! + + * ace/Reactor.h: Fixed the remaining warnings about + "signed/unsigned mismatch" in Win32 by changing the type of + cur_size_ from size_t to ssize_t. + + * ace/Log_Msg.cpp: Modified the code so that on NT we use + ACE_SPIPE_Msg rather than ACE_FIFO_Send_Msg. Thanks to Luca + Priorelli for suggesting this. + + * ace/OS.i: Implemented the and put[p]msg() wrappers by being + smart about allocating and copying data. + + * ace/TTY_IO.cpp (control): There was one too many end parentheses + on line 192 of TTY_IO.cpp. Thanks to Dave Trumble + for reporting this fix. + + * ace/Log_Msg.cpp (local_host): Fixed the use of program_name_ and + local_host_ so that they strdup() the values passed by the + users, rather than copying pointers. This avoids problems if + the user doesn't pass in static memory. Thanks to Luca + Priorelli for reporting this. Somehow + this change got lost and I've reapplied it... + + * ace/Log_Record.cpp (round_up): Added an extra + 1 to the length + since otherwise the final '\0' gets lots if len is a multiple of + 8. Thanks to Luca Priorelli for reporting + this. Somehow this change got lost and I've reapplied it. + + * ace/Memory_Pool.h: removed #if defined (ACE_HAS_SIGINFO_T) logic + from both handle_signal() definitions (ACE_Shared_Memory_Pool + and ACE_MMAP_Memory_Pool). Thanks to Chris Lahey for fixing + this. + + * ace/OS.h: Moved the define of SA_RESTART below the #include for + signal.h. Otherwise SA_RESTART will always be defined by OS.h, + since SA_RESTART is defined on AIX in signal.h. Thanks to Chris + Lahey for fixing this. + + * ace/OS.h: Added some new #pragmas to suppress harmless warnings + for the MSVC++ compiler. + +Tue Sep 17 13:20:53 1996 Prashant Jain + + * ace/Local_Name_Space_T.cpp: Modified ACE_Local_Name_Space:: + create_manager () so that all three naming scopes use the + database variable defined in Name Options. This allows us to + specify different names for databases for all three naming + contexts. However, it is imporant to note that this can lead to + potential problems where, for example, a process may use the + same name for PROC_LOCAL database as an already existing + NET_LOCAL database. + +Mon Sep 16 01:31:21 1996 Douglas C. Schmidt + + * examples/Logger/simple-server/Logging_Handler: get_handle(), + handle_input(), and handle_close() want the right types + (ACE_HANDLE instead of int). Thanks to Luca Priorelli + for reporting these. + + * examples/Logger/simple-server/Logging_Acceptor.cpp: Fixed a typo + (Log_Mskg.h should be Log_Msg.h of course...). In addition, + changed the use of -1 to ACE_INVALID_HANDLE. Thanks to Luca + Priorelli for reporting these. + + + * ace: Changed all uses of ACE_HAS_ACE_INLINED_OSCALLS to + ACE_HAS_INLINED_OSCALLS. This was a vestiage of a global + replace gone amok. Thanks to Alan Stweart for + reporting this! + + * ace/Log_Msg.cpp (open): Added a check for the OSTREAM flag in + the ACE logger. Thanks to Rick Orr + for noticing this. + + * Released version 4.0.30 for testing. + + * netsvcs/clients/Naming/Dump_Restore/Dump_Restore.cpp + (Dump_Restore): Deleted an extra "return 0;" within a + constructor (duh...). + + * examples/Threads/test_process_{semaphore,mutex}.cpp (main): + Fixed some annoying G++ compiler bug related problems. We need + to use old-style C casts to prevent ambiguous parsing. + + * examples/ASX/Event_Server/Transceiver/transceiver: Rewrote this + example to illustrate how to use the ACE_Connector and + ACE_Svc_Handler. + + * examples/ASX/Event_Server/Transceiver/transceiver: Finally clued + in and realized that it is just not suitable to implement the + event server transceiver with separate threads for input and + output. It is simply to non-portable to get these shut down + gracefully. I think John Ousterhout was right -- threads are + evil! + + * examples/ASX/Event_Server: Merged the Consumer/Supplier + directories into a single Transceiver directory to reflect the + fact that the Consumer and Supplier were completely symmetrical! + + * ace/Module.cpp (close): Don't delete the Tasks in a Module if + there are still threads running in them. Otherwise we'll end up + with a big mess. + +Mon Sep 16 15:50:45 1996 Prashant Jain + + * performance-tests/Misc/test_naming.cpp: Added a new test to the + performance-tests directory called test_naming which simply does + performance testing on Naming Service. The test runs both the + SYNC and the NO-SYNC version of Naming Service. + +Mon Sep 16 15:22:52 1996 Tim H. Harrison + + * ace/Proactor.cpp (initiate): Added a check for + ERROR_NETNAME_DELETED after ReadFile/WriteFile. Now the + initiating handler is immediately dispatched for EOF *and* + closed connections. Thanks to Luca Priorelli + for suggesting this change. + +Sun Sep 15 00:55:59 1996 Douglas C. Schmidt + + * Fixed all uses of ACE_Service_Config::end_event_loop() and + ACE_Service_Config::run_event_loop() to be + ACE_Service_Config::end_reactor_event_loop() and + ACE_Service_Config::run_reactor_event_loop() since we now have + to consider the other event loops (e.g., Proactor and ReactorEx) + and it doesn't seem right to relegate those to 2nd class status. + + * ace: Finally got fed up with all the #ifdefs required to deal + with extended signals and just changed the + ACE_Event_Handler::handle_signal() method to always use the + extended signal interface. Fortunately, we can use default + values to hid this from callers (though you may need to change + your class definitions if you were assuming the + handle_signal(int) interface. + + * ace/Memory_Pool.h: Changed all the methods of the various + Memory_Pool classes to be virtual so that subclasses can + selectively override them. This shouldn't affect performance + since all existing use cases work directly with the "derived" + classes themselves, so there shouldn't be any overhead since the + compiler can use direct calls rather than virtual function + calls. + + * ace/OS.cpp (thr_create): Changed the call to CreateThread() to + _beginthreadex() and the call to ExitThread() to _endthreadex() + for Win32 in order to make ACE threads work correctly with + Win32. Thanks to James Mansion for + recommending this. + + * ace/ACE: Added two new static functions: read_adapter() and + register_stdin_handler(). These are useful when writing code + that must demultiplexing ACE_STDIN on both Win32 and UNIX. This + works around Win32 limitations that don't allow us to select() + on non-sockets (such as ACE_STDIN). + + * examples/ASX/CCM_App/SC_Server.cpp: Updated this + test so that it should now work correctly on Win32, where it + isn't possible to select() on STDIN... + + * ace/Synch_T: Added a new class to ACE called "ACE_Test_and_Set." + As this name implies, this class implements an atomic ``test and + set'' abstraction. This has all sorts of useful implications, + particularly because it is a template that can be paramaterized + by the type of LOCK (e.g., ACE_Null_Mutex, ACE_Thread_Mutex, + etc.) and the type of TYPE (e.g., int, double, sig_atomic_t, + etc.). In addition, because this "is-a" ACE_Event_Handler it + instances can be registered with the Reactor and used to shut + down event hoops gracefully upon receipt of certain signals + (e.g., SIGINT). In fact, I've redone many of the example + applications (e.g., ./examples/Logger/server/server_loggerd.cpp) + to illustrate how this works. + +Sun Sep 15 20:40:17 1996 Tim H. Harrison + + * ace/ReactorEx.cpp (notify): I've redesigned this code. + Previously, ReactorEx was explicitly managing a handle that it + kept in handles_[0]. handles_[0] was used to implement + ReactorEx::notify, which allowed other threads to wake up the + thread waiting in ReactorEx::handle_events. Now ReactorEx has + an Event_Handler (ReactorEx_Notify) that is registered in the + constructor of ReactorEx. This allows us to treat events from + handles_[0] just like every other event (i.e. by dispatching to + handles_[0]->handle_signal). One of the results of this change + is that code in remove_handler() is simplified a bit. + +Sun Sep 15 17:56:52 1996 Prashant Jain + + * ace/Naming_Context.cpp: Added a new flag to the constructor and + open() method of ACE_Naming_Context that allows us to specify + which Memory_Pool to use when creating ACE_Local_Name_Space + (that is choose between ACE_MMap_Memory_Pool and + ACE_Lite_MMap_Memory_Pool). + + * ace/Memory_Pool.cpp: Added a new class called + ACE_Lite_MMap_Memory_Pool which subclasses ACE_MMap_Memory_Pool + and overrides the sync method so that it is a no-op. + + * ace/Local_Name_Space.cpp: Made some siginificant changes in + ACE_Local_Name_Space. Here is what the problem was: + ACE_Name_Space_Map (which is an ACE_Map_Manager) used an + ACE_RW_Process_Mutex for synchronization. However, since the Map + was kept in shared memory and was shared by all the processes, + it got instantiated only by the first process which came + along. Therefore, only the first process got around to creating + and initializing the lock. + + In fixing the problem, we made some other changes to + ACE_Local_Name_Space and ACE_Name_Space_Map. Both classes are + now template classes. ACE_Local_Name_Space needs to be + parameterized with a Memory_Pool (thus giving us a hook to + implement the NO-SYNC option) as well as a LOCK. + ACE_Name_Space_Map needs to be parameterized by an ALLOCATOR + which is created by ACE_Local_Name_Space. Note that the reason + we need to parameterize ACE_Name_Space_Map is so that we can + pass an ACE_Allocator_Adapter (which subclasses from + ACE_Allocator) with every method. It is not possible to pass an + ACE_Allocator since the ::remap() method relies on an + allocator() method defined on the ALLOCATOR that is passed in + (and ACE_Allocator does not define an allocator() method). + + The purpose of the class ACE_Name_Space_Map still remains the + same. It IS_A Map_Manager and provides the hook to set the + allocator to the process specific one. However, none of its + methods acquire any locks. For that reason, the Map_Manager is + parameterized with the Null_Mutex. All synchronization takes + place inside ACE_Local_Name_Space. ACE_Naming_Context + instantiates ACE_Local_Name_Space (depending upon the scope) and + by default parameterizes it with ACE_MMap_Memory_Pool and + ACE_RW_Process_Mutex. + + Also made some more fixes to ACE_Local_Name_Space. In + create_manager(), after we create the allocator, we now check to + see if the backing store was created successfully and if not, we + return -1. + +Sat Sep 14 00:00:31 1996 Douglas C. Schmidt + + * examples/Logger: Renamed the original server directory to + "simple-server" and added a new directory called + "Acceptor-server" which implements the Logger using the + ACE_Acceptor. Note that almost all of the implementation code + disappears! + + * ace/Local_Name_Server_T.cpp: Removed the name_server_map_ array + and replaced it with the ACE_NAME_SERVER_MAP #define, which is + now contained in OS.h. + + * ace/Malloc.h: Added "virtual ... = 0" to the bind() and + trybind() methods of the ACE_Allocator since they should be pure + virtual functions... + + * ace/Synch{_T}: Separated out the wait (ACE_Time_Value *) and + wait (void) methods in order to optimize the call sequence for + the common case when there is no timeout. + + * ace/Synch: Added a new wait(ACE_Thread_Mutex &) method to + ACE_Condition_Thread_Mutex so that we are consistent with the + templated ACE_Condition_Mutex. + + * include/makeinclude: Changed uses of -pic to -PIC because ACE is + now creating more than 2082 symbols. It's probably time to + split up the library... + + * ace/DEV_IO: Moved the ACE_DEV_Addr instance from ACE_DEV_IO into + ACE_DEV so that it will be available for the ACE_DEV_Connector. + This fixes a bug that prevented us from using the ACE_Connector + in conjunction with the ACE_DEV_* classes. Thanks to Karlheinz + for clarifying what had to occur. + +Fri Sep 13 00:16:32 1996 Douglas C. Schmidt + + * ace/OS.h: Changed the order of #includes so that + comes before . This fixes some bugs with the + Siemens SVR4 C++. Thanks to Antonio Tortorici + for this fix + + * ace/ACE.cpp (handle_timed_complete): Added yet another weird + hack to deal with the insanity that is TLI... + + * ace/Synch.cpp: Replaced all uses of ACE_Thread_Mutex_Guard with + ACE_GUARD macros in order to avoid problems when mutexes fail. + + * ace/OS.h: Changed the definition of the ACE_*GUARD macros so + that they are always enabled, even when we turn off ACE_MT_SAFE. + This avoids a nasty semantic problem for components that use + ACE_Process_Mutex. Thanks to Avraham Nash + for reporting this problem. + + * ace/OS: Removed ACE_OS::fork_exec() since its functionality has + been subsumed by ACE_Process. + + * ace/Thread_Manager: Added a new thread_descriptor_i() method + that *doesn't* grab the lock in order to avoid deadlocks. + + * include/makeinclude/platform_sunos5_sunc++.GNU (CXX): had to add + the -pta option so that we achieve template closure in ACE. + + * include/makeinclude: Added -lthread to the + platform_sunos5_sunc++.GNU file. I don't know how this slipped + through the cracks! + + * ace/{DEV_IO,FILE_IO,SOCK_IO,SPIPE_Stream}: Fixed a braino with + alloca where I was failing to multiply by sizeof (iovec). Isn't + C great? ... Thanks to Chuck Gehr for + reporting this. + + * ace/SOCK_Dgram_Mcast.cpp: Added two changes to the ACE multicast + code in order to get it to work on Win32. The first change is + to put the IP_ADD_MEMBERSHIP setsockopt() call *after* the + bind() (in shared_open()). The second is to convert the + ACE_INET_Addr::get_ip_address() from host byte order into + network byte order. Thanks to Todd L. Montgomery + and Steve Weismuller + for helping with this. + + * examples/Threads/test_barrier2.cpp: Incorporated Karlheinz's + new ACE_Barrier test program. + + * ace/Synch.h: Added Karlheinz's ACE_Null_Barrier class. + +Fri Sep 13 00:30:50 1996 Tim H. Harrison + + * tests/{Tokens_Test,Time_Service_Test}.cpp: Updated tests to use + ACE_Process instead of ACE_OS::fork_exec. + + * ace/Process.cpp: Added a new ACE_Process abstraction that is a + Portable encapsulation for creating new processes. It allows + assignment of STDIN, STDOUT, and STDERR of the new process. On + UNIX, ACE_Process uses fork and exec. On Win32, it uses + CreateProcess. Since we can set the standard handles, we can + mimic UNIX pipes on Win32 by building chains of processes. This + class should be used instead ACE_OS::fork_exec. + + * examples/OS/Process/process.cpp (main): Added new example + application to show how to use ACE_Process. + +Thu Sep 12 00:55:25 1996 Douglas C. Schmidt + + * ace/DEV_IO: Added methods get_local_addr() and get_remote_addr() + so that ACE_Connector will work correctly. Thanks to Brad Flood + for reporting this. + + * ace/Thread_Manager.cpp (thr_self): Added a fix to solve the + problem that Win32 GetCurrentThread() returns a pseudo-handle + rather than a real handle. Now, we just look things up using + the thread id rather than the thread handle. Thanks to Luca + Priorelli" for clarifying this. + + * ace/Proactor.cpp (initiate): Fixed an incorrect set of return + values -- they were reversed. Thanks to Brad Flood + for reporting this. + + * ace/OS.i (thr_cmp): Added a check for + !defined(ACE_HAS_SETKIND_NP) to avoid a problem with OSF/1. + Thanks to Martin Schoeckle for + reporting this. + + * examples/IPC_SAP/DEV_SAP: Updated these examples to use the new + ACE_TTY_IO classes. + + * ace: Moved the TTY_IO code from the + examples/IPC_SAP/DEV_SAP/{reader,writer} directories into the + files TTY_IO.{h,cpp} in the main part of ACE and integrated Brad + Flood's changes for Win32. + + * ace/DEV_IO.i: Changed the mapping of send_n() and recv_n() + methods to use write_n() and read_n() respectively so they will + work on NT. Thanks to Brad Flood for + reporting this. + + * ace/Thread_Manager.h: Implemented a non-synchronized version of + the lookup function for the . This version + assumes that the lock is help. We need this to avoid + intra-class method deadlock on systems (such as Solaris) that + lack recursive mutexes. + + * ace/Log_Msg.cpp (ACE_Log_Msg): made sure to initialize + ACE_Log_Msg::thr_handle_ to 0. I'm not sure how this got + changed... Thanks to Luca Priorelli for + reporting this. + + * examples/Reactor/ReactorEx/test_reactorEx.cpp + (register_thread_exit_hook): Changed hthread_t to ACE_hthread_t. + Thanks to Luca Priorelli for reporting + this. + + * apps/Gateway/Gateway/Channel.h: Due to inconsistencies between + the semantics of sockets and TLI with respect to establishing + non-blocking connections it's not a good idea to use TLI in + conjunction with select(). Therefore, I've #if 0'd out the use + of TLI in the Gateway application. + +Wed Sep 11 00:25:38 1996 Douglas C. Schmidt + + * ace/ACE.cpp (handle_timed_complete): Fixed a typo that was + failing to set n = ACE::recv(...). In addition, rethought how + we figure out if a connection completes for the nth time... + + * ace/TLI.cpp (open): Modified the implementation of open() so + that if oflag == 0 it is given an initial value of O_RDWR. + Otherwise we'll get a "badflags" t_errno. + + * ace/Connector.h (connect): Modified connect() so that the + default value of the flags parameter is O_RDWR. This is + necessary to make TLI_Connector::connect() work correctly by + default. + + * examples/Logger: Updated the example logger client and server to + illustrate more clearly how things like the Singleton Reactor + and the ACE_Reactor timer mechanism work. Thanks to Joe + DeAngelis for suggesting this. + + * ace/Pipe: Added a new constructor that makes it possible to + initialize the from the and handles. + Thanks to Stevan Warwick (sjw@aesthetic.com) for suggesting + this. + + * config-irix5.3-sgic++.h: Added #define for ACE_NEEDS_SYSTIME_H. + Thanks to Stevan Warwick (sjw@aesthetic.com) for reporting this. + + * examples/Logger/server/Client_Acceptor: Fixed some stray + mis-uses of int that should have been ACE_HANDLE. Thanks to + Luca Priorelli" for reporting this. + + * ace/{ACE,Log_Msg}.cpp: Added fixes for hexdump(). Thanks to + Luca Priorelli" for supplying these. + + * ace/Reactor.cpp (ACE_Reactor): Fixed a typo: "this->max_handlep1 + ()" should be "this->handler_rep_.max_handlep1 ()". Thanks to + Scott Shupe for reporting this. + + * apps/Orbix-Examples/Event_Comm: Added a bunch of changes to make + this application compile with Orbix 2.0. Thanks to Mike + O'Malley for the fixes. + + * ace/OS.cpp (thr_create): Added yet another fix for the IRIX 6.2 + pthreads implementation. Thanks to Gonzalo Diethelm + for reporting this. + + * ace/config-irix6.2-sgic++.h: Changed ACE_HAS_IRIX53_GETTIMEOFDAY + to ACE_HAS_IRIX_GETTIMEOFDAY because this also seems to be the + case for IRIX 6.2... Thanks to Gonzalo Diethelm + for reporting this. + + * ace/TLI_{Connector,Acceptor}.cpp: Added tests against NULL + pointers to avoid segmentation faults when the TLI + implementation doesn't allocate memory for the udata and opt + fields of netbuf structures. + + * ace/Mem_Map.i (ACE_Mem_Map): Added an accessor so that callers + can get the name of the filename that is being used as the + backing store. Thanks to the James Mansion + for recommending this. + +Tue Sep 10 00:26:52 1996 Douglas C. Schmidt + + * ace/OS.cpp (thr_create): Modified the thr_create() + implementation for Win32 so that if the caller doesn't care + about this value we can avoid a HANDLE leak. Thanks to the + James Mansion for recommending this. + + * ace/Thread.cpp (ACE_Thread): Moved both definitions of spawn_n() + into the Thread.cpp since they have loops and don't benefit from + being inlined. + + * ace/Svc_Handler.h: Moved operator delete() into the public part + of the class in order to make various compilers happy... + + * ace/OS.i (ACE_OS): Fixed the #define that selects the (union + wait *) alternative of wait(). This original was protected by + ACE_LACKS_POSIX_PROTO, but it should be ACE_HAS_UNION_WAIT. + + * performance-tests: Created a new directory that will contain all + of the ACE performance tests. Move the Synch-Benchmarks and the + TTCP tests from ./apps into here, and also moved the + test_mutex.cpp and test_singleton.cpp files from + ./examples/{Threads,Misc}, respectively. Thanks to Tim Harrison + for this suggestion. + + * ace/OS.i (ACE_OS): in WIN32 closesocket() returns 0 if call is + OK, so I changed the return value to be the other way around. + Thanks to Luca Priorelli for reporting + this. + + * ace: Changed the ACE_NO_POSIX_PROTO #define to something more + meaningful: ACE_LACKS_POSIX_PROTO. Thanks to Jonathan Biggar + for suggesting this. + + * ace/config-sunos4-g++.h: Added the #define ACE_NEEDS_SYSTIME_H. + Thanks to Alexandre Karev for reporting + this. + + * ace/OS: Fixed a bunch of pthreads portability problems that + showed up on OSF/1 4.0. Also added support for asctime_r() and + ctime_r() for OSF/1 4.0. Thanks to Dave Trumble + for reporting these fixes. + + * ace/Synch_T.cpp (ACE_TSS_Read_Guard): Removed a stray "new" that + was causing problems for the ACE_NEW macro. Thanks to Dave + Trumble for reporting this. + + * ace/Local_Tokens.h: Fixed a broken use of "friend", which was + missing the keyword "class." Thanks to Dave Trumble + for reporting this. + + * ace/config-osf1-4.0.h: Included Dave Trumble's + config file for OSF/1 4.0. + + * include/makeinclude/platform_osf1_4.0.GNU: Included Dave + Trumble's platform macros file for + OSF/1 4.0. Also renamed platform_osf1.GNU to + platform_osf1_3.2.GNU to deal with the new version. + + * ace/Proactor: There wasn't a way to destroy an + ACE_Overlapped_File object without closing the ACE_HANDLE + attached to it. Therefore, I added a flag that keeps track of + whether we have to delete this or not. Thanks to Amos Shapira + for suggesting this. + + * examples/Threads/test_future[12].cpp: Updated the tests to use + the new call() semantics in order to shut down the Scheduler's + event loop gracefully. + + * ace/Method_Object.cpp: Added a return value to the call() + routine. This can be used to indicate to the caller that it is + necessary to shut down the event loop. + +Mon Sep 9 02:07:08 1996 Douglas C. Schmidt + + * ace/Service_Config.cpp (ACE_Service_Config): #ifdef's out the + registration of signal handling to control reconfiguration on + Win32 since it doesn't really handle signals very well. Thanks + to John Morey for bringing this to my + attention. + + * ace/CORBA_Handler: Replaced CORBA_[123] with ACE_CORBA_[123]. + + * examples/CORBA: Updated the test programs to work portably + across different versions of Orbix. + + * ace/OS: Added a new wrapper for the getcwd() call. + + * examples/Threads/test_recursive_mutex.cpp: Added the use of + ACE_Guard<> to illustrate how these work with the + ACE_Recursive_Thread_Mutex. Thanks to Gonzalo Diethelm + for motivating me to do this. + + * examples/Threads/test_process_{mutex,semaphore}: Added two new + tests to illustrate how the ACE_Process_Mutex and + ACE_Process_Semaphore work, respectively. + + * ace/Synch: Replaced the implementation of ACE_Process_Semaphore + to use SV_Semaphore_Complex on UNIX platforms in order to get + the same semantics for Win32 and for UNIX. Thanks to the James + Mansion for recommending this. + + * ace/OS.h: Added some parens around the ACE BIT* macros so that + the precedence levels would be dealt with correctly and we don't + get any nasty surprises... + + * ace/{Synch_T,Synch}: Modified the implementation of all the + *acquire()/release() methods so they keep track of whether they + own the mutex. Thus, if a code path needs to give up the mutex + within the lifetime of the mutex, and it calls mutex_.release(), + then the destructor will not call it again. Thanks to the James + Mansion for recommending this. + + * ace/{Synch_T,Synch}: Changed the name of the field result_ to + owner_ for the ACE_Thread_Muetx_Guard and ACE_Guard. This is + more representative of the true purpose of this field. + + * ace/Synch: Updated ACE_Thread_Mutex_Guard so that it has the + same interface and semantics of ACE_Guard. Thanks to the + ever-vigilant James Mansion for + noticing this. + + * examples/Log_Msg/test_log_msg.cpp (main): Added a test of the + new ACE_Log_Msg::priority_mask() functionality. + + * ace/Log_Msg.cpp: Added a new method called priority_mask(), + which updates the new thread-specific priority_mask_ data member + with the new mask and returns the old mask. This is useful for + applications written using ACE_Log_Msg. Often, these have log() + calls with low priority such as LM_DEBUG that don't need to be + printed, but for which the logging code should not be removed. + The priority_mask() scheme makes it possible to selective enable + printing of certain priorities. Thanks to Rochi Febo Dommarco + for suggesting this. + + * netsvcs/clients/Logger/indirect_logging.cpp (main): Modified the + test program so that it randomly selects logging priorities that + are powers of two. + + * ace/Log_Priority.h: Renumbered the LM_* logging flags so that + they are all powers of two. This makes it easy to implement a + scheme for selectively printing only certain logging values. + +Sun Sep 8 10:46:40 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Proactor.cpp: Fixed up the error handling in ACE_Proactor so + that it returns an error both in case of "bad errors," as well + as when ACE_WIN32 isn't defined. Thanks to Amos Shapira + for reporting this. + +Sun Sep 8 14:11:08 1996 Tim H. Harrison + + * examples/Reactor/Proactor/README: Updated the test_proactor.cpp + and README files to clarify the relationship between the + Proactor and ReactorEx. This example uses the Proactor as the + main event loop (not the Reactor or ReactorEx). Thus, this + application can only do overlapped I/O and timers + asynchronously. To be able to react to other Win32 events, see + the ACE_ReactorEx and the examples/Reactor/ReactorEx/ test. + Thanks to Amos Shapira for + pointing out the ambiguity. + +Sat Sep 7 14:09:21 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Task.cpp: Enhanced the activate() method so that the caller + can set the priority and the thread group id. Thanks to + Karlheinz for this suggestion. + + * ace/OS.h: Added default values of 0 for the trailing arguments + for the {mutex,sema,cond}_init() methods. + + * examples/Threads/test_mutex.cpp: Added a new test program that + illustrates the difference between implementations of thread + mutex wrappers that use inheritance and dynamic binding vs. the + ACE approach (which doesn't use inheritance and dynamic + binding). The results I got on my SPARCstation 20 model 712 is + included in the source file. Thanks to James Mansion + for motivating me to write this. + + * examples/Misc/test_singleton.cpp: Added a new test program that + illustrates the performance of using the Double-Checked Locking + pattern compared with the standard "Mutex::acquire()/release()" + approach. Thanks to Jim Coplien + for encouraging me to get these performance numbers. + +Tue Sep 3 00:38:47 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/XtReactor: Added minor fixes to XtReactor to fix complaints + about "bool" not being defined and the destructor + ~ACE_XtReactor() has already having a body. Thanks to Andres + Kruse for these fixes. + + * ace/Mem_Map.cpp: Make sure that this->length_ is initialized to + 0 in ACE_Mem_Map::map (). Thanks to James Mansion + for pointing this out. + + * ace/Thread.i (spawn_n): In ACE_Thread::spawn_n the sense of the + following check is wrong: + + for (i = 0; i < n; i++) + // Bail out if error occurs. + if (ACE_OS::thr_create (func, arg, flags, &t_id, 0, priority, + stack == 0 ? 0 : stack[i], + stack_size == 0 ? 0 : stack_size[i]) != 0) + thread_ids[i] = t_id; + else + break; + + The '!=' should be '=='. Thanks to James Mansion + for pointing this out. + + * include/makeinclude/rules.local.GNU (MAKEFILE): Changed the + $WRAPPER_ROOT/include/makeinclude/rules.local.GNU line that + says: + + sed -e "s:$(WRAPPER_ROOT);$$(WRAPPER_ROOT);g" \ + + so that the double dollar is now "\$$" (prefixed the first + dollar sign with a backslash). If not, my shell will try to + execute WRAPPER_ROOT for some reason. With "\$$" it works as it + should. Thanks to Marius Kjeldahl for + reporting this. + + * Released version 4.0.29 for testing. + + * ace/OS.i (thr_getspecific): Added a new case for OSF/1. Thanks + to Martin Schoeckle for + reporting this. + + * ace/Thread_Manager.cpp (spawn_i): Removed an invalid + initialization of ACE_hthread_t = 0, which doesn't work on all + pthreads platforms because pthreads uses a struct in some + implementations. Thanks to Martin Schoeckle + for reporting this. + + * man: Updated all the nroff and html documentation to conform to + the latest version of ACE. + + * netsvcs/lib/{Name_Handler,TS_Server_Handler}.cpp: Fixed + some mistakes in the ACE_TEMPLATES_REQUIRE_SPECIALIZATION + code so that all the services can be linked together without + multiply defined symbols. + + * netsvcs/lib/Name_Handler.cpp: Fixed a spot where we weren't + passing in an lvalue to send_request(). Why this wasn't showing + up earlier I don't know, but GCC caught it! + +Mon Sep 2 00:47:00 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Thread_Manager.cpp: Updated all comparisons of ACE_thread_t + and ACE_hthread_t so that they use the ACE_OS::thr_equal() and + ACE_OS::thr_cmp() methods, respectively. Thanks very much to + Martin Schoeckle for identify + the need for this. + + * ace/OS: Added a new method called thr_cmp() which compares two + ACE_hthread_t values for equality. Unfortunately, we can't just + compare these directly via == because on some platforms they are + implemented as structs. Right now, I'm assuming that if + ACE_HAS_TID_T is enabled that we can compare tid_t's using ==. + If this turns out to be incorrect (e.g., if tid_t's are also + implemented as structs, please let me know). + + * ace/Future: Changed the overloaded result() method to a pair of + get()/set() methods. + + * tests/test_config.h: Fixed a bug in the reset() routine. This + was originally deleting the global static ace_file_stream. + However, this was causing segmentation faults if destructors for + objects local to main() were trying to write to the output file. + Therefore, instead of deleting the ostream, we simply flush() + it! + + In addition, also renamed the various functions in test_config.h + to make sure they don't conflict with any other names by + prefixing them with ace_test_... + + * ace: Added many small fixes for IRIX 6.2. Thanks to Gonzalo + Diethelm for reporting all of these! + + * ace/OS: Added a wrapper for the UNIX syscon() system call. + + * ace/LSOCK.cpp (recv_handle): Rearranged the casts so that things + work correctly on platforms with odd definitions ot struct + iovec. Thanks to Gonzalo Diethelm for + reporting this. + + * ace/Task.cpp (ACE_Task_Exit): Rearranged the order in which we + shut down a Task via the Task_Exit hook so that we first + decrement the count of the threads in the task and *then* call + its close() hook. This guards against cases where the close() + hook does something crazy like "delete this". + + * ace/XtReactor.h: Changed #include "X11/Intrinsic.h" to #include + . Thanks to Gonzalo Diethelm + for suggesting this. + + * ace/Future.cpp (ACE_Future): Added some strategic "consts" to + the assignment operator and copy constructor for ACE_Future and + ACE_Future_Rep. + + * examples/Threads/test_task_three.cpp (main): Revised the test so + that it will shut itself down automatically when all the threads + have finished. + + * examples/Threads/test_task_two.cpp (main): Revised this test so + that it doesn't run forever, but only runs either 1000 times or + as many times as the user specifies on the command line. Thanks + to Gonzalo Diethelm for suggesting this. + + * ace/OS.i: Added an extra #else for thr_sigsetmask(), + thr_min_stack(), and thr_kill() for weirdo platforms that don't + conform to the other threading APIs... + +Sun Sep 1 20:15:28 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * examples/ASX/Message_Queue: Changed the use of read(0, ...) and + write(1, ...) to ACE_OS::read(ACE_STDIN, ...) and + ACE_OS::write(ACE_STDOUT, ...) in buffer_stream.cpp and + bounded_buffer.cpp. + + * ace/OS.i: Fixed the errno mapping of the cond_timedwait() + functions so that they set errno to ETIME rather than EBUSY when + timeouts occur. This is necessary to support Solaris and POSIX + pthreads semantics on Win32. + + * build/SunOS5.5/examples/ASX/Message_Queue/buffer_stream.cpp: + Modified the example somewhat so that it uses the Singleton + thr_mgr() method from ACE_Service_Config. + +Sun Sep 1 17:29:58 1996 Tim H. Harrison (harrison@lambada.cs.wustl.edu) + + * ace/ACE.cpp (map_errno): Added a new static method to the ACE + class. This method allows us to map troublesome win32 errno + values (e.g. WSAEWOULDBLOCK) to values that standard C strerr + function understands. Thank you Microsoft. + + * ace/Log_Msg.cpp (log): Added a call to ACE::map_errno to the %p + option. Now the ACE logger can begin to map Win32 error values + into meaningful strings. + + * netsvcs/lib/lib.mdp: Added a project file for the netsvcs + library. This builds a dll into ace/netsvcs.dll (not into the + netsvcs/lib directory). This reduces the number of paths needed + in %PATH%. + + * examples/Tokens: Renamed this directory netsvsc/clients/Tokens. + + * ace/ace.mdp: Removed wsock32.lib from the ace files listing. + The problem is that we can't assume where MSDEV is installed. I + added wsock32.lib and advapi32.lib to the + build/settings/link/library_modules line. + + * ace/config-win32-msvc4.0.h: Disabled the "C4355: 'this' : used + in base member initializer list" warning. Thanks to Amos + Shapira for figuring this out for us. Although "this" is + unneeded for win32, it is required for compilers on other + platforms (e.g., AIX). + + * ace/Message_Queue.cpp (dequeue_head_i): Andres Kruse pointed out + that we weren't doing head_->prev (0), when dequeuing! + +Tue Aug 27 21:00:25 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * include/makeinclude/platform_sunos5_sunc++_4.1.GNU (CXX): Added + Andres Kruse's changes for SunC+ 4.1. + + * ace: Fixed line # 12 of ace/config-sunos4-sun4.1.4.h, + which read: + + "#define ACE_HAS_SVSV_IPC" (ACE_HAS_ ess vee ess vee _IPC) + + to + + "#define ACE_HAS_SYSV_IPC" (ACE_HAS_ ess wye ess vee _IPC) + + Fix another problem: + + #define ACE_LACKS_THREAD_STACK_ADDR (OS.cpp) + + was inconsistently defined in: + + #define ACE_LACKS_THREAD_STACK_ADDRESS (config-aix-4.1.x.h) + + Thanks to Alan Stweart for reporting + this! + +Mon Aug 26 00:34:05 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Updated all of ACE such that the ACE_GUARD* macros now all take + the name of the ACE_*Guard* that they will use as the scoped + locking object. This is important for several reasons: + + 1. It make it more clear what is going on in the code, rather + than hiding behind the macros! + + 2. It is now possible to have multiple ACE_GUARD* macros in the + same scope by calling each scoped locking object a different + name. This is used in the Local_Tokens.cpp file. + + * ace/Synch.h (ACE_Null_Mutex_Guard): Added the locked() method so + that this signature will conform to the one expected of + ACE_Guard. + + * tests: Added a new file Test_Future.cpp, which tests the new ACE + Futures mechanism using Active Obejcts. Thanks to Andres Kruse + for contributing this test. + + * ace: Added three new files: Future.{h,cpp}, + Method_Object.{h,cpp}, and Activation_Queue.{h,cpp}, which + implement Polymorphic Futures. Thanks to Andres Kruse + for contributing these. + + * ace/Stream.cpp (dump): Replaced LM_INFO with LM_DEBUG. + +Sun Aug 25 21:57:57 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace: Rather than using operator new directly, most of ACE now + uses the ACE_NEW and ACE_NEW_RETURN macros. For instance, + rather than writing: + + if (token_manager_ == 0) + token_manager_ = new ACE_Token_Manager; + + we should write: + + if (token_manager_ == 0) + ACE_NEW_RETURN (token_manager_, ACE_Token_Manager, 0); + + The reason for this is that it makes it much easier to ensure + that all dynamic memory allocation errors are treated uniformly. + I've updated the entire ACE library code tonight to make this + usage consistent whenever possible. + +Sat Aug 24 11:51:38 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Time_Value.h: Simplified various things so that the nasty + macros necessary to build DLLs on Win32 will be simplier. In + addition, I will only #include for those platforms + that don't already do this in (i.e., if + ACE_NEEDS_SYSTIME_H is defined in config.h). Please let me know + if you run across any platforms like this. + + * ace/TLI_{Connector,Acceptor}: Added two additional parameters at + the end of the connect() and accept() methods, respectively, so + that the ACE TLI wrappers can be used with X.25. Thanks to Ajit + Sagar for suggesting this fix. + + * ace: Integrated Eric Newton's XtReactor into the Makefile. If + you want to include this into ACE, make sure to define + ACE_HAS_XT in the config.h file. + + * examples/Misc: Integrated the XtReactor tests. + + * ace/OS.i (getservbyname,gethostby*): Fixed a suble omission -- + any calls to socket function should be wrapped by the + ACE_SOCKCALL_RETURN macro in order to make the errnos work + correctly on Win32. + + * ace/OS: Added support for the getprotoby{name,number} wrappers. + Thanks to Joe DeAngelis for suggesting this. + + * ace/Connector.cpp: Fixed a subtle bug in the ACE_Connector. + The problem centered around the following line in + cleanup_AST(): + + if (this->handler_map_.find (handle, ast) == -1) + + This lookup always failed because the key, the handle of the + service handler, was always -1. The service handler's handle is + not set until a successful connection is made and connector + transfers ownership of the handle to the service handler. The + fix for this is to store the ACE_HANDLE in the ACE_Svc_Tuple + *separately* from the ACE_Svc_Handler. Thanks to Bill Gerecke + for being so persistent in tracking this + down. + + * ace/ARGV.cpp (ACE_ARGV): Added a nifty new constructor that + converts argv-style vectors of strings into a single string + (this is the reverse of what the original constructor does!). + + * ace/ACE: Added a new utility method called strecpy(), which + copies to , returning a pointer to the end of the copied + region (rather than the beginning, a la . + +Thu Aug 22 15:43:58 1996 + + * ace/OS.h: Changed the interface of ACE_OS::fork_exec (char + *const argv[]). (There is no longer a separate const char *path + parameter. Now, argv[0] must be the full path name to the + executable. + + * tests/Time_Service_Test.cpp: Updated the Time Service + one-button test to use the new ACE_OS::fork_exec. I didn't + event break it. + + * tests/Tokens_Test.cpp: Updated the Tokens one-button test to + use the new ACE_OS::fork_exec. It actually works now. + + * tests/test_config.h: Added some more #defines to help simplify + path differences between NT and UNIX. Perhaps these should be + moved into OS.h? + +Thu Aug 22 13:46:58 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Thread_Manager.cpp (ACE_Thread_Control): The status_ member + in ACE_Thread_Control() was not being initialized! This caused + Purify to complain loudly about invalid memory accesses. I have + added an initialiser to ACE_Thread_Control::ACE_Thread_Control + to set status_ to 0. Thanks to Ross Dargahi + for reporting this. + + * ChangeLog: The ACE configuration files "config-irix*.h" defined + 'ACE_HAS_SIGINFO' to indicate that IRIX supports SVR4 extended + signals. This should be 'ACE_HAS_SIGINFO_T' instead. Thanks to + Craig Johnston for reporting + this. + +Wed Aug 21 21:09:01 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Time_Value.h: Added an extra condition, #if defined + (ACE_BUILD_DLL) so that ACE_Svc_Export evaluates to + something. Previously, it was evaluating to nothing in some + files such as Naming_Context.cpp where we were doing #define + ACE_BUILD_DLL and not #define ACE_BUILD_SVC_DLL. + +Wed Aug 21 00:33:17 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/ACE.cpp (format_hexdump): Fixed a minor bug in + format_hexdump(). If the buffer to dump is a multiple of 16 it + prints an extra blank line. ALso fixed the code to use spaces + rather than tabs and put an extra space between the first 8 HEX + bytes and the second. Thanks to Luca Priorelli + for this code. + + * ace/Log_Msg.h (ACE_HEX_DUMP): Added a new logging macro: + + #define ACE_HEX_DUMP(X) \ + do { int __ace_error = errno; \ + ACE_Log_Msg *ace___ = ACE_Log_Msg::instance (); \ + ace___->set (__FILE__, __LINE__, 0, errno, ace___->restart (), + ace___->msg_ostream ()); \ ace___->log_hexdump X; \ + } while (0) + + which makes it possible to dump info in HEX. Thanks to Luca + Priorelli for suggesting this. + + * ace/config-win32-msvc4.0.h: Added + + #define _WINSOCKAPI_ + + To avoid multiple inclusions. Thanks to Luca Priorelli + for suggesting this. + + * ace/OS.h: enclosed the #define of WIN32_LEAN_AND_MEAN macro + definition between #ifndef ... #endif to avoid compiler + warnings. Thanks to Luca Priorelli for + suggesting this. + + * ace/SOCK.cpp (win32_fini): Fixed a potential problem in ACE + where any code of the form: + + ACE_DEBUG ((LM_DEBUG, "%d", GetLastError())); + + will reset errno a couple of times before GetLastError() gets + called. So the result is always 0. The fix is to say: + + int ret = GetLastError(); + ACE_DEBUG ((LM_DEBUG, "%d", ret)); + + Thanks to Luca Priorelli for noticing + this. + + * ace/Connector.cpp (create_AST): Was missing a return 0; if we + successfully register a cancellation id. Thanks to William + L. Gerecke for reporting this bug. + + * ace/Module.h: Added a non-existent friend class to get ACE + to stop complaining + + private: + friend class ACE_Shutup_GPlusPlus; // Turn off g++ warning + ~ACE_Module (void); + // *Must* use dynamic allocation. + + Thanks to Eric Newton for the suggestion. + + * ace/Svc_Conf.y (ace_create_service_type): Removed some stray + calls to ACE_ERROR that were left over from earlier + configurations of ACE. Thanks to Gonzalo Diethelm + for reporting this. + + * ace/Log_Msg.cpp (instance): Fixed the #ifdefs so that + ACE_MT_SAFE implies ACE_HAS_THREAD_SPECIFIC_STORAGE. Thanks to + Gonzalo Diethelm for reporting the need for + this. + +Tue Aug 20 13:09:55 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * INET_Addr.cpp, line 84: Irix's C++ is not able to determine + whether to use the set(u_short,ACE_UINT32,int) or the + set(u_short,const char [],int), since on Irix, INADDR_ANY is 0. + I cast the value so that the call would read set(port, + ACE_UINT32(INADDR_ANY)) and everything went fine. Thanks to + Gonzalo Diethelm for reporting this. + + * ace/Synch[_T]: Added a new wait() method that takes a first + parameter which is the mutex used to serialize access to the + condition. This is useful if you want to store the + ACE_Condition object in shared memory (in which case, the use of + a reference to mutex_t doesn't work!). Thanks to Mark Patton + for recommending this approach. + + * ace/Task.h: Added a forward template declaration for + ACE_Task_Exit so that it will compile on HP/UX. Thanks to Tim + Ottinger for pointing this out. + + * ace: changed line 19 of ace/Str_Buf.h from + + #include "OS.h" + + to: + + #include "ace/OS.h" + + Fixed similar problems with OS.h at line 1154 and Dump.h at line + 150. Thanks to Alan Stewart for reporting this. + +Tue Aug 20 20:18:49 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * tests/TSS_Test.cpp (main): Fixed a small typo. I was referencing + the wrong variable but didn't catch it since it was in the #if + !defined (ACE_HAS_THREADS) section. Fixed the typo and also + renamed the variable called big_count to iterations. Thanks to + Tim Ottinger for pointing this out. + +Mon Aug 19 19:25:50 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * {examples,apps,tests}: Removed the use of zerop from these + files, as well... + + * ace/{Acceptor.cpp,Name_Proxy.cpp,Token.i}: Removed the use of + zerop from these files, as well... + + * ace/Connector.cpp (connect_svc_handler): It looks like our good + friend ACE_Time_Value::zerop isn't getting initialized correctly + on Win32. Therefore, I've replaced it with a direct use of + &ACE_Time_Value::zero. + + * ace/Time_Value.cpp: Removed the static pointer variable "zerop" + since there was no guarantee it was getting intialized before it + is used! Instead of using ACE_Time_Value::zerop, use + &ACE_Time_Value::zero. Thanks to William L. Gerecke + for reporting this problem. + + * ace/OS: Added zillions of changes to make ACE compile with OSF/1 + and its DCE threads implementation. Thanks to Martin Schoeckle + for sending these. + + * ace/config-osf1-3.2.h: Updated this file with fixes for OSF/1 by + Martin Schoeckle . + + * ace/ACE.cpp (handle_timed_complete): Added new logic to + ACE::handle_timed_complete() so that it sets errno to + ECONNREFUSED if the connection is refused by the server. When + you issue an asynchronous connect request, to complete it, you + will use complete() with a timeout. However, complete can fail, + and then it will deallocate any resource, (i.e. close down the + socket handle), also for timeout expiration. So, a user + interested in retrying to complete a connection while the + timeout expires will not use complete(); but rather will use + handle_timed_complete(). In fact, using handle_timed_complete() + the user could detect the reason of a failure (by examining + errno) and decide how to proceed. In the old ACE version the + problem was that, if handle_timed_complete() failed because of + the recv() returning 0, errno remained unchanged and so its + value could be quite misleading with respect to the reasons of + the failure. Thanks to Antonio Tortorici + for this fix and the explanation + above. + + * ace/OS.h: Added support for Borland 5.0's uint64. Thanks to + Hani Yakan for suggesting the strategy to + accomplish this. + +Mon Aug 19 15:52:07 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * tests: Added new macros to the test_config.h file in order to + simplify the testing. + +Mon Aug 19 00:21:22 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Re-released version 4.0.28 for testing (will change the version + number after Tim gives me the new Token stuff). + + * {netsvcs/lib,tests/test_config.h}: Removed spurious dependencies + on fstream.h and iostream.h. Thanks to Alan Stewart + for reporting this. + +Sat Aug 17 17:25:49 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Reactor: Removed the use of "inline" in the Reactor.cpp + files because this was causing problems with some + compilers/linkers. Thanks to Gonzalo Diethelm + for recommending this. + + * examples/Misc/test_XtReactor1.cpp: Added a new test of the + XtReactor, courtesy of Eric Newton . + + * ace/config-hpux-10.x.h: According to Eugene K. Plaude + , HP-UX 10.01 supports user-level threads + based on the pthreads interface specified by POSIX in 1003.4a, + Draft 4 (which is basically DCE threads). Therefore, I've + enabled the ACE_HAS_DCETHREADS symbol in the config-hpux-10.x.h + configuration file. If this isn't correct, please let me know. + +Sat Aug 17 02:18:39 1996 Tim H. Harrison (harrison@lambada.cs.wustl.edu) + + * examples/Tokens/manual/README: Added a new Token example + application. The manual test gives users a text-based + interactive interface to local or remote tokens. This is + extremely useful for manually testing the token server and + setting up deadlock scenarios. See the README file for more + details. + + * examples/Tokens/deadlock/README: Updated the deadlock example + application to test the new deadlock detection algorithm for + readers/writer locks. I also added the use of Token Invariants + to ensure correctness of the mutexes and readers/writer locks. + See the README file for more details. + +Fri Aug 16 22:16:05 1996 Tim H. Harrison (harrison@lambada.cs.wustl.edu) + + * ace/Token_Manager.cpp: Updated all Token code to use + ACE_OS::last_error instead of errno. + +Fri Aug 16 00:03:24 1996 Douglas C. Schmidt + + * After a long hiatus, released version 4.0.28 for testing. + +Thu Aug 15 21:04:35 1996 Douglas C. Schmidt + + * man: Updated all the ACE manual pages and html pages to reflect + recent changes. + + * netsvcs/lib/Server_Logging_Handler.cpp: Fixed an omitted + "ACE_BUILD_SVC_DLL" that was causing linker errors on NT. + Thanks to Luca Priorelli for reporting + this. + + * examples/Log_Msg/test_log_msg.cpp: Added a test for the new + log_hexdump() function. + + * ace/Log_Msg.cpp (log_hexdump): Integrated the log_hexdump() code + into the ACE Log_Msg abstraction. Thanks to Luca Priorelli + for fixing this and for Todd Montgomery + for originally supplying the code. + + * ace/Signal.cpp (ACE_Sig_Handlers): Moved the #endif /* HPUX */ + down to the end of the file so that it works correctly on HPUX. + Thanks to Eric C. Newton for report this bug. + + + * ace/OS.i: Updated the behavior of thr_join() so that it will do + a ::CloseHandle after getting the exit status. Thanks to the + ever vigilant James Mansion + (mansionj@lonnds.ml.com) for noticing this. + + * examples: Finally added Tim and Prashant's examles/OS directory, + which contains a test that illustrates a "portable" means to + spawn processes on NT and UNIX. + + * ace/Malloc_T.cpp (next): Added an overloaded next() method that + returns the name that is bound to the pointer in the + Malloc_Iterator. This is useful in order to differentiate + entries in the pool based on their name. Thanks to Kim Gillies + for suggesting this. + + * ace: Changed all uses of thread_t, thread_key_t, mutex_t, + rwlock_t, sema_t, cond_t, etc. to ACE_* in order to avoid + polluting the name space. Also switched from using macros to + using typedefs whereever possible. Thanks to Gonzalo Diethelm + for recommending this. + + * ace/System_Time.cpp: Added template specializations for + templates used in the ACE_System_Time class. This should solve + some nasty undefined templates problems with GCC... Thanks to + Joseph DeAngelis for pointing out the + problem. + + * ace/Name_Space.cpp: Fixed the file Name_Space.cpp as follows: + + // Name_Space.cpp + #define ACE_BUILD_DLL + //#include "Name_Space.h" + #include "ace/Name_Space.h" + + Thanks to Eugene K. Plaude for fixing this! + + * ace/config-hpux-10.x.h: Added support for TLI since according to + Eugene K. Plaude this should work. If not, + please let me know. + +Wed Aug 14 21:29:46 1996 Douglas C. Schmidt + + * examples/Reactor/Logger: rearranged the Logger directory so it + would be more clear what the client and server programs did and + how to run them. + + * examples: Merged the contents of the SVR4 examples directory + into the IPC_SAP/SOCK_SAP directory so that we can remove the + SVR4 directory altogether (it wasn't contributing much...). + + * examples: Removed the vestigal Win32 tests since ACE now runs on + Win32 and we don't need a separate test directory. + + * netsvcs/client: Renamed the file remaining file in this + directory to logging_app.cpp since I moved the other file to the + examples/Reactor/Logger directory. + + * ace/Reactor.cpp (check_handles): If eh->get_handle() returns -1 + the select() code will index the [-1] element of an array. To + fix this, I've added a check of the value returned from + eh->get_handle(). Thanks to Eric C. Newton for + reporting this. + + * ace/OS.i (sema_wait): Fixed a subtle bug in the Pthreads + wrappers that surfaced on the SGI IRIX 6.2 port. There was some + code that looked like this: + + pthread_cleanup_push(); + int result = 0; + ... + pthread_cleanup_pop(); + return result; + + However, on Irix 6.2, the push introduces a new scope that is + closed by the pop, so result goes out of scope before returning. + Thanks to Gonzalo Diethelm for pointing this + out. + + * ace/OS.h: Changed the definition of pthread_mutex_t and + pthread_cond_t to mutex_t and cond_t to be consistent with other + usage in ACE. Thanks to Gonzalo Diethelm for + pointing this out. + +Wed Aug 14 01:25:47 1996 + + * ace/SPIPE_Acceptor.cpp: Added the PIPE_TYPE_MESSAGE | + PIPE_READMODE_MESSAGE flags to CreateNamedPipe pipe options so + that data is received in messages rather than as a stream. This + is consistent with the behavior of the SPIPE_Connector. When we + have time, we need to extend the interface so that stream pipes + are also supported, as well. + + * SPIPE_Acceptor.cpp: Made the ACE SPIPE in and out buffer sizes + 10 k. The previous size was just 512 bytes. This larger buffer + size helps decrease flow control. + +Tue Aug 13 23:21:46 1996 + + * examples/Connection/blocking: Updated the blocking SPIPE example + application to use a pool of threads in the proactor to handle + incoming client messages. The SPIPE-acceptor example + illustrates how named pipes are used on NT. Once the server + establishes a connection to a single client, it spawns a thread + pool to handle incoming requests via the proactor event + loop. That is, a separate thread from the pool is used to + process each message sent by a client. The size of the thread + pool can be specified by command-line arguments. This example + leverages the queueing performed by the NT kernel to trivially + implement a thread pool architecture. See + examples/Connection/blocking/README for more details. + + * Service_Config.h: Added a parameter (with a default + size of 0) to the proactor accessor method. This allows + applications to specify the size of the thread pool that can + block on Proactor::handle_events. + +Tue Aug 13 02:30:58 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Task: Added a new public interface called thr_count(). This + returns a count of the number of threads running within a Task. + If the value returned is 0, then the Task is a Passive Object. + If the value returns is > 0 the task is an Active Object, and + the value is a count of the number of threads running within the + object at this snapshot of time. + + * ace/OS: I implemented Karlheinz's suggested optimizations for + the ACE condition variable implementation under Win32. Here's + the deal... The original implementation used an internal_mutex + to ensure that access to the count of the number of waiters was + serialized between the waiter and signaler threads. The new + implementation is designed so that only the waiter threads + access the waiter count. Therefore, we can utilize the + external_mutex to serialize access to this, thus eliminating the + need for the internal_mutex. However, this means that code + *must* be written using the standard condition variable idiom, + i.e., + + int resources () + { + external_mutex.acquire (); + + // ... + + cond.signal (); + external_mutex.release (); + } + + Rather than like this: + + int resources () + { + external_mutex.acquire (); + + // ... + + external_mutex.release (); + cond.signal (); + } + + which is what some thread programming books recommend as an + optimization. However, you should be careful not to use this + form since it can lead to "lost wakeup" bugs caused by the fact + that the implementation of ACE_OS::cond_signal will test if the + waiter count > 0 *without holding any locks*!!! + + Fortunately, ensuring this shouldn't be a problem since most ACE + code uses the following idiom: + + int resources () + { + ACE_Guard mon (external_mutex); + + // ... + + cond.signal (); + // Destructor of mon releases external_mutex. + } + + Clearly, there are subtle tradeoffs between performance and + programmability here... + + * ace/Synch: Updated all of the ACE semaphore wrappers to take the + new "max" value as their final constructor argument. + + * ace/OS: Added a new default argument to the end of the + sema_init() method. This allows us to specify the maximum value + of the semaphore (this is only important on NT). Currently, it + is hard-coded to 0x7fffffff in uses. The new approach makes it + possible to set the max to a different value. Thanks to + Karlheinz for requesting this. + + * ace/Message_Queue.cpp: Added an implementation of the dump(). + Thanks Karlheinz. + + * ace/Synch.cpp: Added an implementation of the dump() method. + Thanks Karlheinz. + + * ace: Updated all usage of ACE_Thread_Mutex_Guard so that it now + uses the ACE_GUARD* macros correctly. Thanks to Chris Eich + for pointing out the + need for this. + + * examples/Threads: Added Karlheinz's new test_barrier2.cpp test + program that makes sure that the ACE_Message_Queues are working + correctly when accessed by multiple threads. + + * netsvcs/lib/Server_Logging_Handler.cpp (handle_logging_record): + Fixed an errant use of ACE_Guard, which wasn't properly checking + of the Guard acquired the lock. Thanks to Chris Eich + for pointing this out. + + * ace/OS.h (ACE_GUARD): Added default "ace_mon" implementations of + type ACE_Null_Mutex even in cases where there's no threading + defined so that code accessing ace_mon.release() and + ace_mon.acquire() will compile correctly. + + * apps/Gateway/Gateway/Channel.h: Fixed the code so + that we don't try to use TLI if the platform doesn't support it + (instead, we'll use sockets). Thanks to Marius Kjeldahl + for reporting this problem. + + * examples/ASX/Event_Server/{Supplier,Consumer}: Fixed the code so + that we don't try to use TLI if the platform doesn't support it + (instead, we'll use sockets). Thanks to Marius Kjeldahl + for reporting this problem. + +Mon Aug 12 14:50:47 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * examples/Misc: Added Eric Newton's test case for + his XtReactor integration. + + * ace: Included Eric Newton's code that integrates + ACE with the Xt event loop. This still needs a bit of work + (e.g., making it thread-safe and incorporating signal support), so + I haven't added it to the Makefile yet. If someone can take the + time to fix it up, I'll be happy to integrate it into ACE. + + * ace/Message_Queue.cpp (dequeue_head): Fixed the mother of all + bugs in the ACE_Message_Queue implementation... The problem was + that I was trying to be too clever by optimizing the number of + Condition::signal() calls by only calling signal() when the + queue changed state from empty to non-empty (or full to + non-full). It turns out that this optimization works fine for a + single producer/consumer case, but fails when there are multiple + consumers. The fix was just to call signal() every time. This + should be ok because the underlying Condition variable + implementation will perform the optimization in the correct + fashion. Thanks to the omniscient Karlheinz for detecting this + problem and reporting it. + +Sun Aug 11 15:52:07 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * tests: Made minor changes to test_config.h, SPIPE_Test.cpp, and + UPIPE_SAP_Test.cpp to accomodate the change made to SPIPE_Addr. + SPIPE_Addr now accepts a string of the form [host:]port and then + creates the rendezvous point. Originally, SPIPE_Addr would + assume that the string being passed in was the actual rendezvous + point. + +Sat Aug 10 18:41:21 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * netsvcs/lib/Logger.cpp (init): Added a new service to netsvcs + called ACE_Logger which allows us to control the output of all + the services. The ACE_Logger service can be invoked with + different flags (such as STDERR|OSTREAM) which in turn sets + ACE_Log_Msg to direct the output of all the services to the + appropriate stream(s). Note that if a service needs to stay + unaffected from ACE_Logger, it should be invoked before + ACE_Logger gets invoked. Also note that like other services in + netsvcs, ACE_Logger can also be dynamically linked in. + +Sat Aug 10 14:23:07 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Added Steve Huston's patches to get ACE + to compile on UnixWare 2.01. This mostly involved changes to + the internal types used by the socket wrappers. Thanks Steve! + +Fri Aug 9 01:34:19 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * examples/ASX/UPIPE_Event_Server/Options.cpp (print_results): + Added a typedef to avoid problems if a platform doesn't support + prusage_t. Thanks to Marius Kjeldahl for + reporting this. + + * include/makeinclude/platform_linux_pthread.GNU. The line that + say: + + LIBS = -lpthreads -lstdc++ + + was modified to say: + + LIBS += -lpthreads -lstdc++ + + Thanks to Marius Kjeldahl for reporting + this. + +Fri Aug 9 18:26:16 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Local_Name_Space.cpp (reset): Fixed a subtle (yet very + annoying bug). In switching contexts a test program would hang + after a certain number of switches. Having gone through the code + thoroughly and with the aid of Purify, the bug was narrowed down + to an extraneous delete taking place in + ACE_Name_Space::reset(). Essentially, we do not need to delete + ACE_Name_Space_Map::instance() which is actually the + SHARED_MALLOC since it gets deleted in the destructor of + ACE_Local_Name_Space. + +Thu Aug 8 17:55:20 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/SPIPE_Addr.cpp (set): Implemented + ACE_SPIPE_Addr::string_to_addr(). Modified ACE_SPIPE_Addr::set() + using code provided by Brad Flood to create the rendezvous + point. Note that originally ACE_SPIPE_Addr constructor and set() + would take the actual rendezvous point but now they rely on + being passed a string which is of the format "[host]:port" + (where host is optional). The rendezvous point is then created + by extracting from the string the hostname (if any) and also + using the port number as the unique pipe name. Note that this + approach works on both UNIX and Win32. + +Mon Aug 5 20:15:59 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/OS.i (last_error): Fixed a typo. In the set and get methods + last_error(), there should be a check for "if defined + (ACE_WIN32)" and not "if defined (ACE_HAS_WIN32)" + +Wed Aug 7 00:21:42 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Log_Msg.h: Replaced all uses of errno *following calls to + ACE_Log_Msg::instance()* so that we first cache errno in a local + variable called __ace_errno. We need to do this because + ACE_Log_Msg::instance() can reset errno == 0. Thanks to + Tim for pointing this out. + +Mon Aug 5 20:15:59 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/OS.i (last_error): Fixed a typo. In the set and get methods + last_error(), there should be a check for + "if defined (ACE_WIN32)" and not "if defined (ACE_HAS_WIN32)" + +Sat Aug 3 14:52:32 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * examples/Win32/win32_client.cpp: Changed ACE_GUARD_RETURN to + ACE_GUARD in the method Errno::flags since the return type is + void. + + * examples/Connection/non_blocking/CPP-connector.cpp: Made some + minor changes to get things compiling on Win32. The call to + handle_close now takes zero as the first argument (which is + never used). Also the arguments to ACE_SERVER_ADDRESS are now + swapped (hostname followed by port number) to be consistent with + the change made to the macro. Thanks to Brad Flood for + suggesting these changes. + + * examples/Connection/non_blocking/CPP-acceptor.cpp: Made minor + changes to some of the methods to make sure all control paths + return a value. Also changed the default port number to + ACE_DEFAULT_SERVER_PORT_STR to match what the connector tries to + connect to. Thanks to Brad Flood for + suggesting these changes. + + * ace/OS.h (ACE_SERVER_ADDRESS): Modified the macro + ACE_SERVER_ADDRESS so that it creates a string of a server + address with a "host:port" format. Previously the order was + reversed. Thanks to Brad Flood for suggesting this change. + +Sat Aug 3 00:07:26 1996 Douglas C. Schmidt (schmidt@lambada.cs.wustl.edu) + + * ace: Fixed problems with recursive tracing of ACE_TRACE by + commenting out certain constructors in IPC_SAP.cpp, + FIFO_Send_Msg.cpp, FIFO_Send.cpp, and FIFO.cpp. Thanks to + Karlheinz for finding and reporting these fixes. + +Fri Aug 2 22:19:05 1996 Douglas C. Schmidt (schmidt@lambada.cs.wustl.edu) + + * ace/ACE.cpp (format_hexdump): Fixed an infamous "off by one" bug + that was causing this to fail on Win32 (time to switch to Java? ;-)). + Thanks to lucapri@mbox.vol.it for finding this. + +Thu Aug 1 14:08:30 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/CORBA_Handler.cpp (activate_service): Fixed a typo caused by + an omitted ENDTRY. Thanks to Garrett Conaty + for noticing this. + +Mon Jul 29 10:03:16 1996 Douglas C. Schmidt (schmidt@lambada.cs.wustl.edu) + + * examples/Win32/win32_client.cpp: There was a typo in one of the + ACE_GUARD macros. Thanks to Tim Ottinger + for pointing this out. + +Mon Jul 22 12:41:22 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Local_Name_Space.cpp (reset): Added a new method + ACE_Name_Space_Map::reset() which deletes the instance of + ACE_Name_Space_Map. This forces instance() to create a new + instance using a new context file in the case of the context + having changed. I make use of this in + ACE_Local_Name_Space::create_manager(). + +Fri Jul 19 12:28:07 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/System_Time.cpp (get_master_system_time): Modified + ACE_System_Time::get_master_system_time() so that if an entry + for the time is not found in shared memory (indicating that no + Clerk is running), then we should just return the local time of + the host. + + * netsvcs/lib/TS_Clerk_Handler.cpp (update_time): Modified + ACE_TS_Clerk_Handler::update_time() so that if the Clerk is not + connected to any servers, is sets the delta time to zero + allowing clients to then use the local time of the host. + +Wed Jul 17 22:19:53 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/UPIPE_Connector.cpp (connect): Added an #ifdef around the + check of ACE_OS::isastream (handle) in + ACE_UPIPE_Connector::connect() since the call is not supported + on NT. + +Thu Jul 11 22:22:57 1996 Tim H. Harrison (harrison@lambada.cs.wustl.edu) + + * ace/OS.i (kill): Modified ACE_OS::kill so that it works on NT. + It takes a process ID, creates a handle for the associated + process, and calls TerminateProcess on the handle. This is + actually pretty dangerous according to the NT documentation. + Can majorly confuse DLLs. Does the same old thing on UNIX. + + * ace/OS.cpp (fork_exec): Added a fork_exec operation to ACE_OS. + This works on UNIX and NT. It combines the forking and exec'ing + into one call. This has to be combined since Win32 + CreateProcess only starts applications from scratch (unlike UNIX + fork). + + * examples/OS/test_os.cpp: Added a new example application to test + the new ACE_OS::fork_exec and ACE_OS::kill operations. + +Tue Jul 9 13:04:14 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Service_Manager.cpp (reconfigure_services): To improve + portability on Win32 and UNIX I replaced the use of a signal to + trigger reconfiguration to instead make a call to the new + ACE_service_Config::reconfig_occurred() method. This should + actually perform the same as the original approach, since all + the signal handler ever did was to set this flag! Thanks to + Karlheinz for pointing out the need for this. + + * ace/Service_Config.h: Added a new static public method called + reconfig_occurred(sig_atomic_t) to set if a reconfiguration + should take place the next time through the event loop. + +Mon Jul 8 14:20:01 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Time_Value.h: Added "ACE_Export" before all global operators + to allow them to be dll-exportable on NT. + +Mon Jul 8 13:12:05 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/{Message_Block,DEV_IO,SPIPE_Stream}.cpp: Fixed several more + cases of delete array that should have been delete [] array. + Thanks to Tom Leith for pointing out some of these. I can hear + the ghost of James Mansion coming closer... ;-) + + * INSTALL: Added tips on how to install ACE on a Win32 platform + that lacks a network card. + + * ChangeLog: Split ChangeLog-96 into two files (ChangeLog-96a and + ChangeLog-96b) since it was becoming quite large! Thanks to + Chris Lahey for pointing this out. + + * ace/Stream.cpp: Was missing a "return 0;" at the end of the + close() method. Thanks to Tom Leith for + finding this. + +Mon Jul 8 14:20:01 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Time_Value.h: Added "ACE_Export" before all global operators + to allow them to be exportable from Win32 DLLs. + +Sun Jul 7 10:34:48 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released version 4.0.27 for testing. + + * config-sunos5.5*.h: Removed all uses of ACE_HAS_SVR4_SIGNAL_T in + the config files since Solaris 2.5 has consistent signal and + sigaction types (at last!). + + * Installed and compiled ACE successfully with the new SunC++ 4.1 + compiler on Solaris 2.5. However, there seems to be major + problems with the interaction of the SunC++ exception handling + runtime system and the Solaris multi-threading mechanisms. This + is causing the ACE multi-threading tests to bomb with + segmentation faults inside of the _ex_unwind() library function. + If you read the /opt/SUNWspro_3.1/READMEs/c++ file you'll see + why this problem is occurring (apparently due to bugs in the + Solaris libC.so.5 C++ runtime library). + + There seem to be two fixes for this problem: + + 1. Add the following to *all* threads (including main): + + #include + + void *my_thread_entry_point (void *) { + set_terminate (abort); + set_unexpected (abort); + + // Do real work... + } + + This is the approach recommended by the README file in + SUNWspro_3.1. However, it is *clearly* a horrible hack and + very non-portable (therefore, I deem it worthy of Microsoft + ;-)). + + 2. Compile ACE (and applications?) with -noex in order to avoid + this bug. This is clearly not desirable either since it + precludes the use of exception handling with C++ and threads + on Solaris... + + Since ACE doesn't use exceptions internally on Solaris option 2 + seems like the best approach for the time being. When Sun gets + it act together and releases a bug-free library and C++ + software, I'll fix ACE accordingly. + + * tests: Integrated the latest of Prashant's "one-button" tests + into the main ACE release. These will run on both UNIX and + Win32 now. + + * ace/UPIPE_Stream.cpp (recv): Changed the semantics of the + ACE_UPIPE_Stream::recv (char *, size_t, ACE_Time_Value *) + method. Currently, the behavior is to block until *exactly* N + bytes are read. However, this is incorrect for 2 reasons: + + 1. It makes it hard to write a server that doesn't know + precisely how big the messages are from the client. In + particular, if the receiver doesn't know how big the buffer + messages are from the client it will block indefinitely! + + 2. It is redundant with respect to the + ACE_UPIPE_Stream::recv_n(), which also blocks until all N + bytes are received. + + Therefore, I've made the new UPIPE_Stream::recv() method block + only until it's received the first block of data that allows it + to fulfill its size request, or anything that is smaller than + that size. + + * ace/OS.cpp (thr_create): Since POSIX pthreads doesn't provide an + equivalent of THR_NEW_LWP in the pthreads_attr_* functions, I've + added an emulation that should work for Solaris. Basically, if + THR_NEW_LWP is set when ACE_OS::thr_create() is called, we use + the ACE_OS::thr_{get,set}concurrency methods to increase the + number of LWPs by one. + + * ace/Message_Block: Changed the default high water mark for an + ACE_Message_Queue from 4K to 16K. This is useful since it + allows applications to buffer more information before blocking. + + * ace/Log_Msg: Added a pair of operations that allow applications + to acquire and release the synchronization lock used internally + by the ACE_Log_Msg implementation. This allows applications to + hold the lock atomically over a number of calls to ACE_Log_Msg, + which is useful for composite operations like the following: + + // Make sure the following operations are run atomically! + ACE_LOG_MSG->acquire (); + + while (c != '!') + { + if (c_stream.recv (&c, 1) == -1) + ACE_DEBUG ((LM_DEBUG, + "(%t) buffer recv from supplier failed\n")); + else + ACE_DEBUG ((LM_DEBUG, "%c", c)); + } + + ACE_LOG_MSG->release (); + + * examples/IPC_SAP/UPIPE_SAP: Revised all of the UPIPE_Stream + tests to make them more consistent and correct with respect to + the new changes. + + * ace/Stream.cpp (link_i): There was a bug in the link_i() logic + because we weren't also linking the other stream back to our + stream. + + * ace/UPIPE_{Acceptor,Connector}: Modified both of these classes + so that they don't + + * ace/Stream.cpp (close): Modified close() so that it now detects + "double-closes" and ignores anything but the first one. + + * ace/UPIPE_Stream: Updated this class so that it no longer + inherits from ACE_Stream (previously ACE_UPIPE_Stream had + inherited from *both* ACE_Stream *and* ACE_SPIPE). There are + several reasons we shouldn't inherit from ACE_Stream: + + 1. There are operations on ACE_Stream that don't make any sense + on ACE_UPIPE_Stream (e.g., link(), unlink()). + + 2. ACE_Stream isn't really designed to be subclassed (e.g., + it doesn't have virtual methods). + + 3. Not inheriting makes the interface cleaner, e.g., we now use + send() and recv() methods consistently, rather than + send_msg()/put() and recv_msg()/get(). + + 4. The return values from the I/O methods are now more + consistent than they were before. + + * ace/Message_Block: The signature for the copy() method was + incorrect. It should have been copy (const char *, .....) + rather than copy (char *, ....). + + * examples/IPC_SAP/UPIPE_SAP: Together with Prashant, fixed up the + ACE_UPIPE_Stream tests so they more cleverly + (and correctly) utilize and illustrate various ACE concurrency + features. + +Sat Jul 6 18:28:55 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Stream.cpp: Fixed some obscure bugs with Stream::unlink() + and Stream::link(). These bugs were triggered by the + ACE_UPIPE_Stream tests. We need to make sure that we don't have + race conditions in the order in which ACE_UPIPE_Stream close() + down. Prashant and I fixed this problem by (1) adding a lock to + unlink() and link() and then creating unlink_i() and link_i() to + perform the work and (2) being more careful about trying to + unlink our side and the other side of a linked Stream. + + * ace/config-linux.h: According to Istvan Buki + , Linux now supports the + send_msg()/recv_msg() system calls, as well as UNIX domain + sockets. Therefore, I've updated the config-linux*.h file to + remove the existing restrictions. If this turns out not to be + the case, please let me know. + + * ace/LSOCK.cpp (recv_handle): Added a change to some casts to + make ACE compile with Linux. Thanks to Istvan Buki + for reporting this. + + * apps/Gateway/Gateway/File_Parser.cpp (readword): Removed + yet another use of: + + for (int x; foo(x); ) + { + } + + x = 10; + + Which is now a deprecated feature of C++. + + * include/makeinclude: added the -lw library to the GNU G++ + platform*.GNU file in order to pick up the wide-character string + functions. + +Fri Jul 5 18:11:44 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Re-released version 4.0.26 for testing. + + * ace/CORBA_Handler.cpp (activate_service): Revised the code to + use the Orbix macros for TRY/CATCH rather than try/catch. We + need this to make legacy code work! Thanks to Irfan for + pointing this out. + + * ace/Thread_Manager: Fixed a bunch of typos that grelims snuck + in. Thanks to Jack Erickson for reporting this. + + * examples/IPC_SAP/TLI_SAP/ftp-server.cpp: Fixed some typos that + were causing problems on AIX. Thanks to Greg Wilson + for reporting this. + + * examples/Reactor/Misc/test_time_value.cpp (operator<<): Added a + "const" in front of the ACE_Time_Value & in order to make things + work correctly on AIX. Thanks to Greg Wilson + for reporting this. + + * ace/SPIPE_Acceptor: Fixed some missing "returns" that had sprung + up in the #else arm of the SPIPE code. Thanks to Greg Wilson + for reporting this. + + * apps/Synch-Benchmarks/Benchmark: Fixed a typo that was causing + the application to fail to compile on AIX. Thanks to Greg + Wilson for reporting this. + + * Changed all uses of virtual int init (int, char **) to virtual + int init (int, char *[]) to workaround bugs with MSVC++... + + * ace/OS.h: for POSIX pthreads, changed the definition of the + THR_SCOPE_SYSTEM macro so that it has the same value as + THR_BOUND. If this isn't done, then things don't quite work + right when we implement the ACE_OS::thr_create() wrapper. + +Thu Jul 4 13:17:35 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Thread_Manager: Added a new method called thr_self() that + *does* return a real handle that can be used by + WaitForMultipleObjects, etc. Note that this new approach + cleverly caches this handle in TSS in order to cut down on + search time. Thanks to Jesper for pointing this technique out. + + * ace/OS.i (thr_self): After receiving comments from Jesper, undid + the earlier change today that was returning a duplicated handle + for ACE_OS::thr_self(). It turns out this is a bad idea because + the handle most typically doesn't get released, which leads to + handle leaks. + + * ace/Thread_Manager: Added a new private method called + check_state(). This method extends existing code to be smarter + about how we check to see what "state" (e.g., suspended, + cancelled, etc.) a thread is in. The original code + (which was a macro called ACE_CHECK_STATE) didn't behave + correctly if we asked about the state of a thread that was + different from ourselves! + + * ace/Thread: Modified the public interface to + ACE_Thread::spawn_n() so that it now takes a void *stack[] and + size_t stack_size[]. If stack != 0 it is assumed to be an array + of n pointers to the base of the stacks to use for the threads + being spawned. Likewise, if stack_size != 0 it is assumed to be + an array of n values indicating how big each of the + corresponding stacks are. This is useful since now we can spawn + a group of threads each of which has its own custom stack and/or + stack size. Thanks to Ashish Singhai + for pointing out the need for + this. + + * apps/Synch-Benchmarks: Updated the Synch benchmarks so that most + of them work again. The trick is *not* to use ACE_OS::sleep () + (which doesn't seem to be thread-friendly...) but instead to use + ACE_OS::select() as a timer. + + * man: updated the manual pages and html pages to reflect all the + recent changes. + + * ace/Malloc_T.cpp (open): Added a check to make sure that if + init_acquire() fails we don't let this go by undetected... + Thanks to Karlheinz for pointing out the need for this. + + * ace/OS.i (thr_getconcurrency): Fixed a subtle bug with the + ACE_OS::thr_getconcurrency() function. I was mistakenly using + ACE_ADAPT_RETVAL for the result of ::thr_getconcurrency(), which + is clearly wrong! + + * ace/Service_Record.cpp (remove): Fixed a typo that was causing + the removals of Modules in a dynamically configured Stream to go + into infinite loops. + + * ace/OS.i (thr_self): Modified the ACE_OS::thr_self (hthread_t &) + function so that it will return a *duplicate* of the current + thread's pseudo-handle returned by GetCurrentThread(). This + change is necessary because the pseudo-handle returned by + GetCurrentThread() is pretty useless (e.g., it can't be used by + any other thread to "wait" for this thread to exit). This new + behavior is used in the examples/Reactor/ReactorEx test program. + + * ace/Service_Config.cpp: I'd forgotten to assign the + delete_svc_rep_ flag when dynamically allocating the svc_rep_. + This is fixed now. + +Wed Jul 3 20:09:44 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Added a new subdirectory called $WRAPPER_ROOT/tests that + contains the first phase of the ACE regression tests. + + * ace/Reactor.cpp (check_handles): Fixed an earlier fix with the + ACE_Reactor::wait_for_multiple_events() method. The earlier fix + had changed the exit condition of do/while loop to be + + while (nfound == -1 && this->handle_error () >= 0); + + However, this was causing signal handling to break... + Therefore, the right fix is to keep the exit test as: + + while (nfound == -1 && this->handle_error () > 0); + + and instead fix handle_errors() so that it returns 1 if we're + able to fix a bad handle... Thanks to Prashant and Irfan for + tracking this down. + + * ace/OS: Finally broken down and added a new pair of ACE_OS + functions called "last_error()". These basically call + SetLastError/GetLastError on Win32 or they set/get errno on + UNIX. + + * ace/config-linux.h: Fixed an annoying problem with + struct msghdr in Linux by adding + + #define msg_accrights msg_control + #define msg_accrightslen msg_controllen + + to the config-linux*.h files. Thanks to Michael R"uger + for suggesting this. + + * ace/SOCK_IO.cpp (recv): Fixed a "bug" where + ACE_SOCK_IO::{send,recv} allocates with: + + iovec *iovp = new iovec[total_tuples]; + + But deletes with: + + delete iovp; + + Thanks to the ever vigilant James Mansion + (mansionj@lonnds.ml.com) for noticing this. + +Tue Jul 2 23:48:38 1996 Tim H. Harrison (harrison@lambada.cs.wustl.edu) + + * ace/Service_Config.h: Added ReactorEx to the singleton resources + that the Service_Configurator holds. This includes accessors, + destruction hooks, and event loop methods. + + * examples/Reactor/ReactorEx/README: There is a new example + application for the ReactorEx. Please check out + examples/Reactor/ReactorEx/README for details. + +Tue Jul 2 18:43:12 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * Released version 4.0.25 for testing. + + * examples/ASX/Message_Queue/priority_buffer.cpp: Added a new test + program that illustrates the use of the new Message_Queue + priority scheme. + + * ace/Message_Queue: Added new support for prioritized message + enqueueing into the ACE_Message_Queue. Now, when an application + uses ACE_Message_Queue::enqueue() the new Message_Block is + inserted into the queue according to its msg_priority(). When + dequeue_head() is used the item retrieved will then be the item + of "highest priority" (priorities range from 0 to MAX_LONG). + Note that the semantics of the existing enqueue methods, + enqueue_head() and enqueue_tail(), remain unchanged. + + * ace/Message_Block: Changed the type of the priority in a message + block to u_long rather than u_char. This gives us a much + greater range of priorities! + +Mon Jul 1 01:12:08 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * ace/Thread.h: Changed a couple of mistyped comments. Thanks + to the eagle eyes of Andres Kruse for noticing this. + + * ace/OS: added more comprehensive support for UNICODE to + both the Win32 and UNIX OS adaptation layer. This new + support automagically selects the appropriate implementation + (i.e., either char * or wchar_t *) for the string comparison + routines (which are used in places like ACE_Mem_Map). + + * ace/Service_Config: Split up the ACE_Service_Config::close() + method into two parts: close_svcs() and close_singletons(). + This makes it possible to remove svc.conf services without + destroying Singletons like the Proactor, Reactor, etc. Thanks + to Karlheinz for recommending this. + + * ace/Service_Config: Added flags for remembering who created the + Singleton Proactor, Allocator, Thread_Manager, and + Service_Repository (in addition to the Reactor, which I did last + week). If we created these Singletons, then we are responsible + for freeing them up. Thanks to Karlheinz for pointing out the + need for this. + +Mon Jul 1 16:26:27 1996 Prashant Jain (pjain@merengue.cs.wustl.edu) + + * ace/Connector.cpp: Added two new arguments to connect () namely, + "int flags" and "int perms". The Connector can now pass these + two arguments to its template arguments (e.g., SOCK_Connector, + SPIPE_Connector, etc.) when calling their connect() method. A + consequence of doing this was that we had to modify the + signature of the connect() method on some of the IPC_SAP classes + (e.g., TLI_Connector, SOCK_Connector, and LSOCK_Connector). + Note that these changes may break some existing code, + particularly with TLI_Connector (see below), so beware... + + * ace/TLI_Connector.cpp: Changed the order of the connect() + arguments to be more consistent with the rest of the IPC_SAP + classes used with the Connector. Please note that existing + examples which use TLI_Connector may need to be modified as a + result of this change. + + * ace/OS.i (open): Modified ACE_OS::open() to use the argument + perms to turn the flag FILE_FLAG_OVERLAPPED on and off for + Win32. + + * ace/Service_Config.cpp (end_proactor_event_loop): Added new + methods run_proactor_event_loop() and end_proactor_event_loop() + which call handle_events on the Proactor. + +Mon Jul 1 02:15:34 1996 Tim H. Harrison (harrison@lambada.cs.wustl.edu) + + * ace/Proactor.h: Made ACE_Proactor an ACE_Event_Handler so that + it can be registered with the ACE_ReactorEx. ACE_Proactor + associates the same global HANDLE with every overlapped I/O + operation. This global HANDLE can be registered with the + ACE_ReactorEx. Therefore, by using the + ACE_Proactor::handle_signal method as an adapter, we can now + dispatch overlapped I/O and other "waitable" objects from a one + ACE_ReactorEx running in a single thread of control. Thanks to + James Mansion for setting us on the + right path! + + * ace/ReactorEx.h: Added a ACE_ReactorEx to encapsulate Win32 + WaitForMultipleObjects(). The ACE_ReactorEx handle_events() + method calls ACE_Event_Handler::handle_signal when the + corresponding Win32 HANDLE becomes signaled. This gives us a + uniform abstraction for dispatching all "waitable" objects on + Win32, including events related to I/O completion ports and + events related to other forms of NT synchronization (such as + mutexes, semaphores, threads, etc.). + + * ace/Timer_Queue.h (calculate_timeout): Added a calculate_timeout + method to ACE_Timer_Queue. Also removed the same method from + ACE_Reactor. This is so Reactor, ReactorEx, and Proactor can + all reuse the calculations required by the Timer_Queue without + duplicating code. + diff --git a/FAQ b/FAQ new file mode 100644 index 00000000000..bab85562258 --- /dev/null +++ b/FAQ @@ -0,0 +1,1877 @@ +There are many changes and improvements in the new version of ACE. +The ChangeLog file contains complete details about all of them. + +I've tested ACE thoroughly on Solaris 2.3 and 2.4 with the SunC++ 4.x +compiler and Centerline 2.x. I've also tested it with the SunC++ 3.x +compiler on the SunOS 4.x platform. However, I've not been able to +test it on other platforms. If anyone has time to do that, and can +report the results back to me I'd appreciate that. + +Please let me know if you have any questions or comments. + + Doug + +---------------------------------------- + +1. SIGHUP + +> 1) Where the heck does the HUP signal get registered for the +> $WRAPPER_ROOT/tests/Service_Configurator/server stuff? I looked there and +> in $WRAPPER_ROOT/libsrc/Service_Configurator. No luck. I guess I am +> just blind from reading. + + Take a look in ./libsrc/Service_Configurator/Service_Config.h. +The constructor for Service_Config is where it happens: + + Service_Config (int ignore_defaults = 0, + size_t size = Service_Config::MAX_SERVICES, + int signum = SIGHUP); + +---------------------------------------- +2. Multi-threaded Signal_Handler support + +> It appears Signal_Handler is +> not setup for multi-threaded apps. How do you handle signals +> in different threads? Do I have to put in the hooks in my app or should +> it go in the Threads arena? + + Ah, good question... My design follows the approach espoused +by Sun. Basically, they suggest that you implement per-thread signal +handling atop of the basic UNIX signal handlers (or in the case of +ACE, the handle_signal() callbacks on Event_Handler subclasses) by +using the thread id returned by thr_self() to index into a search +structure containing the handlers. This should be pretty straight +forward to layer atop the existing ACE Signal_Handler mechanisms. +However, you might ask yourself whether you really want (1) separate +signal handler *functionality* in different threads or (2) different +threads that mask out certain signals. The latter might be easier to +implement and reason about! + +---------------------------------------- +3. Problems compiling ACE with G++ + +> I substituted -lg++ for -lC in macro_wrappers.GNU and ran make. +> +> Most stuff seemed to build. Continually got messages like the following: +> ld: /usr2/tss/jvm/ACE_wrappers/lib/libASX.a: warning: archive has no table of c +> ontents; add one using ranlib(1) +> ld: /usr2/tss/jvm/ACE_wrappers/lib/libThreads.a: warning: archive has no table +> of contents; add one using ranlib(1) +> ld: /usr2/tss/jvm/ACE_wrappers/lib/libSPIPE.a: warning: archive has no table of +> contents; add one using ranlib(1) +> ld: /usr2/tss/jvm/ACE_wrappers/lib/libASX.a: warning: archive has no table of c +> ontents; add one using ranlib(1) +> ld: /usr2/tss/jvm/ACE_wrappers/lib/libThreads.a: warning: archive has no table +> of contents; add one using ranlib(1) +> ld: /usr2/tss/jvm/ACE_wrappers/lib/libSPIPE.a: warning: archive has no table of +> contents; add one using ranlib(1) + +> no matter how many times I used ranlib or removed the libraries and re-compiled +> or whatever. Perhaps these are System V specific and will not work on 4.1.3? + + Yes, that's exactly right. If you look at the files, they all +contain ifdef's for features that aren't included in the +./include/makeinclude/wrapper_macros.GNU file. To make this more +obvious, I've enclosed the following message in the INSTALL file: + + * Sun OS 4.1.x + + Note that on SunOS 4.x you may get warnings from the + linker that "archive has no table of contents; add + one using ranlib(1)" for certain libraries (e.g., + libASX.a, libThreads.a, and libSPIPE.a). This + occurs since SunOS 4.x does not support these features. + +> never able to get .so -- assume these are shared libraries that gcc can not +> deal with. + + Yes, if you use the stock gcc/gas/gnu ld +compiler/assembler/linker, you won't get shared libraries to work. It +is possible to hack this by using the "collect" version of g++. +However, as usual, I strongly advise people to stay away from g++ if +you want to use shared libraries or templates. + +> got some linker errors as follows: +> +> g++ -g -DACE_NTRACE -DACE_HAS_MT_SAFE_SOCKETS -DACE_HAS_NO_T_ERRNO -DACE_HAS_ +> OLD_MALLOC -DACE_HAS_POLL -DACE_HAS_SEMUN -DACE_HAS_SETOWN -DACE_HAS_STRBUF_T - +> DACE_HAS_STREAMS -DACE_HAS_SVR4_DYNAMIC_LINKING -DACE_HAS_TIUSER_H -DACE_HAS_SY +> S_FILIO_H -DACE_PAGE_SIZE=4096 -DACE_HAS_ALLOCA -DACE_HAS_CPLUSPLUS_HEADERS -DA +> CE_HAS_SVR4_SIGNAL_T -DACE_HAS_STRERROR -DMALLOC_STATS -I/usr2/tss/jvm/ACE_wrap +> pers/include -I/usr2/tss/jvm/ACE_wrappers/libsrc/Shared_Malloc -o test_malloc +> .obj/test_malloc.o -L/usr2/tss/jvm/ACE_wrappers/lib -Bstatic -lSemaphores -lS +> hared_Malloc -lShared_Memory -lReactor -lThreads -lMem_Map -lLog_Msg -lFIFO -lI +> PC_SAP -lMisc -lnsl -lg++ +> ld: /usr2/tss/jvm/ACE_wrappers/lib/libThreads.a: warning: archive has no table +> of contents; add one using ranlib(1) +> ld: Undefined symbol +> _free__t6Malloc2Z18Shared_Memory_PoolZ13PROCESS_MUTEXPv +> _free__t6Malloc2Z17Local_Memory_PoolZ10Null_MutexPv +> _malloc__t6Malloc2Z18Shared_Memory_PoolZ13PROCESS_MUTEXUl +> _malloc__t6Malloc2Z17Local_Memory_PoolZ10Null_MutexUl +> _remove__t6Malloc2Z17Local_Memory_PoolZ10Null_Mutex +> ___t6Malloc2Z17Local_Memory_PoolZ10Null_Mutex +> _print_stats__t6Malloc2Z17Local_Memory_PoolZ10Null_Mutex +> _remove__t6Malloc2Z18Shared_Memory_PoolZ13PROCESS_MUTEX +> ___t6Malloc2Z18Shared_Memory_PoolZ13PROCESS_MUTEX +> _print_stats__t6Malloc2Z18Shared_Memory_PoolZ13PROCESS_MUTEX +> collect2: ld returned 2 exit status +> gcc: file path prefix `static' never used +> make[2]: *** [test_malloc] Error 1 +> make[2]: Leaving directory `/usr2/tss/jvm/ACE_wrappers/tests/Shared_Malloc' +> <======== End all: /usr2/tss/jvm/ACE_wrappers/tests/Shared_Malloc + + That looks like a problem that G++ has with templates. I +don't know of any reasonable solution to this problem using g++. + +> Finally decided there was enough stuff that it looked like I might have some +> thing so I tried to run some tests and could not find so much as one piece +> of documentation that might give me some clue about running tests. + +You should take a look at ./tests/Service_Configurator/server/README +file. That explains how to run the more complicated tests. As for +the other tests, it is pretty straight forward if you look at the +./tests/IPC_SAP/SOCK_SAP and ./tests/Reactor/* directory code to +figure out how to run the tests. I don't have a Q/A department, so +any documentation has to come from volunteers. + +---------------------------------------- +4. Is there any docs or man pages on the Log_Record class? + +There is a paper in the C++_wrappers_doc.tar.Z file on ics.uci.edu +called reactor2.ps that has some examples of using Log_Record. The +./apps/Logger directories show several examples using Log_Record. +Finally, the source code for Log_Record is pretty short (though it +clearly could be commented better ;-)). + +---------------------------------------- +5. Signal handling prototypes + +> According to the man page on sigaction on our system, that line +> should look something like the following: +> +> sa.sa_handler = SIG_DFL; + + The problem is that most versions of UNIX I've come across +don't have a correct prototype for this field of struct sigaction. +That's why I define two variants of signal handler typedefs: one that +is a typedef of the "correct version" (which I call SignalHandler) and +one of which is a typedef of the "incorrect version" (which I call +SignalHandlerV). You might check out the sysincludes.h file to see +how it is defining SignalHandlerV and make sure this matches what your +OS/Compiler defines in + +---------------------------------------- +6. Omitting shared libraries + +> Can anyone tell me a way to turn off the creation of the shared libraries +> in the ACE build. + +You can simply comment out the LIB target in the $WRAPPER_ROOT/ace/Makefile +or change the BUILD target from + +BUILD = $(VLIB) $(VSHLIB) $(SHLIBA) + +to + +BUILD = $(VSHLIB) $(SHLIBA) + +---------------------------------------- +7. DCE threading and signal handling + +>Reading the DCE docs leaves me confused as to how to make everyone +>work together in a happy hormonious whole. May basic need is to catch +>asynchronous signals so i can release some global resources before +>the process exits. + +You need to spawn a separate thread to handle signals. As part of +your init, do this: + pthread_create(&tid, thread_attr, signal_catcher, NULL); + pthread_detach(&tid); + +Where signal_catcher is like this: +static void * +signal_catcher(void *arg) +{ + static int catch_sigs[] = { + SIGHUP, SIGINT, SIGQUIT, SIGTERM, SIGCHLD + }; + sigset_t catch_these; + int i; + error_status_t st; + + for ( ; ; ) { + sigemptyset(&catch_these); + for (i = 0; i < sizeof catch_sigs / sizeof catch_sigs[0]; i++) + sigaddset(&catch_these, catch_sigs[i]); + i = sigwait(&catch_these); + /* Note continue below, to re-do the loop. */ + switch (i) { + default: + fprintf(stderr, "Caught signal %d. Exiting.\n", i); + CLEANUP_AND_EXIT(); + /* NOTREACHED */ +#if defined(SIGCHLD) + case SIGCHLD: + srvrexec__reap(); + continue; +#endif /* defined(SIGCHLD) */ + } + } + return NULL; +} +---------------------------------------- +8. + +> I have installed ACE2.15.5 on SunOS 4.1.3 with gcc2.6.0. I run the test program +> ---server_test. The static is OK, but error found when I commented out the first +> one and uncommented out the second one in the svc.conf file: +> +> #static Svc_Manager "-d -p 3912" +> dynamic Remote_Brdcast Service_Object * .shobj/Handle_Broadcast.so:remote_broad +> cast "-p 10001" +> +> The error goes like this: +> +> ----------- +> jupiter[12] %server_test -d +> starting up daemon server_test +> opening static service Svc_Manager +> did static on Svc_Manager, error = 0 +> signal signal 1 occurred +> beginning reconfiguration at Sat Feb 25 13:40:29 1995 +> Segmentation fault (core dumped) +> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +My guess is that the code generated by GCC on SunOS 4.x does not +correctly initialize static variables from shared libraries. The +SunC++ 4.0.x compiler does this correctly on Solaris 2.x (though I +believe that on SunOS 4.x it doesn't work without some extra coaxing). + +In general, I try to avoid using ACE's explicit dynamic linking +mechanisms on SunOS 4.x and GCC. You can write plenty of interesting +and useful code with ACE without using those features. Those tests +are mostly there to illustrate the "proof of concept." +---------------------------------------- +9. + +> a) I noticed the default constructor for the reactor does an open w/ defaults. +> Does this mean I need to close it if I wish to re-open it with different +> size and restart values? + + No. With the latest versions of ACE, you can now just call +open() with a new size and it will correctly resize the internal +tables to fit. + +> b) What is the usage difference between the normal FD_Set objects +> (rd/wr/ex_handle_mask_) and the ready FD_Set objects +> (rd/wr/ex_handle_mask_ready)? + + The normal FD_Sets (now called Handle_Set in ACE 3.0.5) holds +the "waitable" descriptors (these are the descriptors given to +select() or poll()). In contrast, the ready FD_Sets may be set by +Event_Handler subclasses (by called the set_ready() API) to indicate +to the Reactor that they want to be redispatched on the next go-round +*without* blocking. If you look at the Reactor code, you'll see that +the wait_for() method checks the ready sets first and doesn't block if +there are any bits set in those masks. This features makes it +possible for Event_Handlers to control subsequent dispatching policies +of the Reactor. + +> c) What does the positive return value do from an event handler callback: +> -1 detaches the event handler for that mask +> 0 does nothing - keeps the event handler registered for that mask +> >0 resets a bit in the current dispatching mask (I think) - does this mean +> this event will be called again before the current dispatch cycle is done? + +Almost... (it's tied in with my description of the ready sets above). +It means that once the Reactor finishes cycling through the set of +descriptors it got back from select() or poll(), it will redispatch +the ready set descriptors before sleeping. + +> Without direct access to the bit masks in X, I'm not sure I could emulate +> this activity - what do you think? + +I'm not sure. I'm not enough of an X guru. Maybe someone else on the +list knows the answer to this? + +> d) If I let X do the select blocking, will that have any affect on +> the Reactor performing signal handling? + + Yes, I think that will cause problems since the Reactor relies +on a "handshake" between its Signal_Handler component and its +handle_events loop to properly handle signals. + +> e) Is the Poll method preferred over Select if it is available - why? + +For systems that implement select() in terms of poll() (e.g., Solaris +2.x) then it may be somewhat faster. Otherwise, it doesn't really +matter since (1) they (should) do the same thing and (2) the end user +shouldn't notice any change in behavior. + +---------------------------------------- +10. + +> I would very much like to evaluate/use the ACE Toolkit, +> but am limited as to disk space on our system. +> What is the total disk space required for a compiled, +> usable toolkit? + +The source code itself is around 2 Meg, uncompressed. + +The compiled version of ACE is around 90 Meg compiled with the SunC++ +4.x compiler (naturally, this will differ with other compilers). +However, of this amount, about 40 meg are for the libraries, and +another 50 meg are for the test programs. Naturally, you don't need +to keep the test programs compiled. + +The postscript documentation is around 5 Meg, compressed. + +---------------------------------------- +11. + +> This is regarding the newer release of ACE and pertaining to the library +> archive file. My question is, if all the ".o" files are archived into one +> single "libACE.a", does it increase the size of the executable program? + +No. The use of a *.a file allows the linker to extract out only those +*.o files that are actually used by the program. + +> If it does, then does a large executable program mean possibility of it being +> slower? + + No. + +---------------------------------------- +12. + +> What happens if I have several reactors in a process (e.g. in different +> threads)? +> +> Programmer 1 decides to register at reactor 1 in his thread 1 a signal handler +> for SIGUSR. +> Programmer 2 decides to register at reactor 2 in his thread 2 a signal handler +> for SIGUSR. + + Naturally, the behavior of this all depends on the semantics +of the threads package... In Solaris 2.x, signal handlers are shared +by all threads. Moreover, the Reactor uses a static table to hold the +thread handlers. Thus, only one of the handler's would be registered +(i.e., whichever one was registered second). + +> Programmer 3 designs the process and decides to have thread 1 and thread 2 +> running in the same process and also makes use of a third party software library +> that internally has also registered a signal handler (not at the reactor) for +> SIGUSR. + + Now you've got big problems! This is an example of a +limitation with UNIX signal handlers... In general, it's a bad idea +to use signal handlers if you can avoid it. This is yet another +reason why. + +> When looking into Ace/ACE_wrappers/tests/Reactor/misc/signal_tester.C you +> have shown a way to do this by marking the dummy file_descriptor of the +> Sig_Handler object ready for reading asynchronously. The handle_input() +> routine of Sig_Handler object will then be dispatched synchronously. +> But what happens if I have several reactors. +> The asynchronously dispatched +> handle_signal() routine does not know via which reactor it has been registered +> so in which reactor to modify the dummy file_descriptor. +> Is your suggestion to have just one process global reactor in such a case? + + Yes, precisely. I would *strongly* recommend against using +several reactors within separate threads within the same process if +you are going to be having them handle signals. Can you use 1 +reactor and/or have one reactor handle signals within a process? + +> One thing we want to do is the priorization of Event_Handlers. I.e. in case +> of concurrent events the sequence in which the Event_Handler methods will be +> activated depends on their priority relative to each other. +> We have two choices: +> - complete priorization, which means a high priority Input Event_Handler may +> be activated prior to a lower prioritized Output Event_Handler (and doing +> so violating the 'hardcoded rule' that output must be done prior to input). +> - priorization only in categories, which means all Output Event_handler are +> ordered by their priority regardless of priorities for the category of Input +> Event_Handlers. The priority is fixed between the categories, i.e. first +> output then input then out-of-band. +> +> Right now I would think that we have to use the second choice if we want to +> use the feature of asynchronous output with automatical re-queueing. Am I right +> ? + + Hum, that's an interesting problem. It might be better to +subclass the Reactor to form a new class called Priority_Reactor. +This subclass would override the Reactor's dispatch method and +dispatch the event handlers in "priority" order. I've never done +that, but I don't think it would be all that difficult. + +---------------------------------------- +13. + +> Is the non CORBA version still aroung? I think I still need it from the +> follow error, or is something else? + +Aha, there are two ways to get around this problem: + +1. Set your ORBIX_ROOT environment variable to the location of the + Orbix release (e.g., /opt/Orbix). Naturally, this only works + if you've got Orbix installed on your machine. + +2. If you don't have Orbix, then to get rid of that problem all you + need to do is change the symbolic links on the + +./include/config.h +./include/makeinclude/platform_macros.GNU + +files to + +./include/config-sunos5-sunc++-4.x +./include/makeinclude/platform_sunos5_sunc++.GNU + +rather than the *-orbix* versions, which they point to by default. +And then recompile ACE. +---------------------------------------- +14. +> We are using your ACE software and ran into a problem which may or may not +> be related to the mutex locks. The question may have more to do with how +> mutex locks should be used. We had a class which was using your mutex +> lock wrapper. Each member function of the class acquired the lock before +> processing and released on exiting the function. Some member functions may +> call other member functions. The following is an example: +> +> class foo { +> +> void a() +> { +> MT( Mutex_Block m( this->lock_ )); +> +> if( cond ) +> b(); +> } +> +> void b() +> { +> MT( Mutex_Block m( this->lock_ )); +> +> if( cond ) +> a(); +> } +> +> }; +> +> Is this valid ? My assumtpion is that the mutex lock is recursive and +> the same thread can acquire the lock multiple times in different member +> functions. + + Ah, that's a great question since there are subtle and +pernicious problems lurking in the approach you are trying above. +Basically, Solaris mutex locks are *not* recursive (don't ask why...) +Thus, if you want to design an application like the one above you'll +need to use one or more of the following patterns: + +---------------------------------------- +A. Use recursive mutexes. Although these are not available in + Solaris directly they are supported in the later versions + of ACE. You might want to take a look at the latest + version (./gnu/ACE-3.1.9.tar.Z). It's got lots of new + support for threading and synchronization. In that case, + you simply do the following: + + class Foo + { + public: + void a() + { + MT( Guard > m( this->lock_ )); + b (); + } + + void b() + { + MT( Guard > m( this->lock_ )); + b_i (); + } + + }; + + The advantage with this is that it requires almost no + changes to existing code. The disadvantage is that + recursive locks are just slightly more expensive. + +B. Have two layers of methods (a) which are public and acquire + the Mutex and then call down to methods in layer (b), which + are private and do all the work. Methods in layer b assume + that the locks are held. This avoids the deadlock problem + caused by non-recursive mutexes. Here's what this approach + looks like (using the more recent ACE class names): + + class Foo + { + public: + void b() + { + MT( Guard m( this->lock_ )); + b_i (); + } + + void b_i() + { + if( cond ) + a_i(); + } + + void a_i() + { + if( cond ) + b_i(); + } + + void a() + { + MT( Guard m( this->lock_ )); + a_i (); + } + + }; + + The advantage here is that inline functions can basically + remove all performance overhead. The disadvantage is that + you need to maintain two sets of interfaces. + +C. Yet another approach is to release locks when calling + other methods, like this: + + class Foo + { + public: + void b() + { + MT( Guard m( this->lock_ )); + m.release (); + a (); + m.acquire (); + } + + void a() + { + MT( Guard m( this->lock_ )); + m.release (); + b (); + m.acquire (); + } + + }; + + The disadvantage with this, of course, is that you + greatly increase your locking overhead. In addition, + you need to be very careful about introducing race + conditions into the code. The primary reason for + using this approach is if you need to call back to + code that you don't have any control over (such as + OS I/O routines) and you don't want to hold the + lock for an indefinite period of time. +---------------------------------------- + + BTW, all three of these patterns are used in the ACE Reactor +class category. The Reactor has a number of fairly complex +concurrency control and callback issues it must deal with and I've +found it useful to use all three of these patterns jointly. + + I'd be interested to hear any comments on these approaches. + + Doug +---------------------------------------- +15. + +> I am working on Solaris 2.3 and trying to understand how to get around +> the problem of trying to open a Socket connection to a remote host that +> is "dead". Of course you get a nice long process block if the socket +> is in Blocking mode (TCP lets you know when you can continue - how polite). +> +> So how does a non-blocking connect work with respect to using +> the Reactor and a SOCK_Stream object to coordinate the opening +> of the connection? Do I wait on the OUTPUT event for the FD? +> How do I know if the connect worked or possibly timed-out? Is +> this a reliable approach (I read somewhere that this will only +> work if the STREAMS module is at the top of the protocol stack +> - MAN page I think)? + +An example of implementing this is in the Gateway sample application +in the new ACE. It's also encapsulated in the Connector<> pattern of +the Connection class category in ./libsrc/Connection. You may want to +take a look at those two things for concrete usage examples. + +However, the basics of getting non-blocking to work are: +- set socket to non-blocking +- initiate connect() request +- if connect() returned 0 you're connected +- if connect() returned -1 and errno is EWOULDBLOCK (or EAGAIN, depending +on where you are), then register an event handler for read and write events +on the socket +- any other errno value is fatal + +When an event is returned +- no matter which event you get back (read or write), you may have gotten +the event out of error. Thus, re-attempt the connect() and check to see if +errno is EISCONN (if it's not there's a problem!) +- if errno was EISCONN, the connection is ready to go, otherwise you must +handle an error condition + +If you want to "time out" after a certain period of time, consider +registering for a timer event with Reactor. If the timer goes off before +the connection succeeds, close down the appropriate socket. + +> Is using a separate thread to make the connection a better way to avoid +> the potentialy long block in the main thread during the connect call? + +You could do that, but it can all be accomplised in a single process using +the facilities available. +---------------------------------------- +16. + +> I was wondering, does the Reactor class have the ability to prioritize +> activity on the registered event handlers? + + The default strategy for the Reactor's dispatch routine +(Reactor::dispatch) does not prioritize dispatching other than to +dispatch callbacks in ascending order from 0 -> maxhandlep1. + +> We have a requirment to be able to process both real-time, as well as, stored +> telemetry and ERMs concurrently. Real-time needs to be processed at a higher +> priority than stored data. Our design is based on both real-time and stored +> data coming into our process via separate sockets. + + I can think of several ways to do this: + + 1. Use dup() or dup2() to organize your sockets such that the + higher priority sockets come first in the Handle_Sets that + the Reactor uses to dispatch sockets. This is pretty easy + if you don't want to muck with the Reactor code at all. + + 2. You could subclass Reactor::dispatch() and revise it so + that it dispatches according to some other criteria that + you define in order to ensure your prioritization of + sockets. + +BTW, I'm not sure what you mean by "real-time" but I assume that you +are aware that there is no true "real-time" scheduling for network I/O +in Solaris. However, if by "real-time" you mean "higher priority" +then either of the above strategies should work fine. +---------------------------------------- +17. + +> I compiled the new ACE 3.2.0 's apps/Gateway. The compiling went +> through without any errors. But I could not get it running, neither single +> threaded nor multi-threaded. The cc_config and rt_config files entries are given +> below. Also the machine configurations are given below. Does it need some more +> settings or some patch !!?? + + I believe you are seeing the effects of the dreaded Sun MP bug +with non-blocking connects. The easy work around for now is simply to +give the "-b" option to the Gateway::init() routine via the svc.conf +file: + +dynamic Gateway Service_Object *.shobj/Gateway.so:_alloc_gatewayd() active + "-b -d -c cc_config -f rt_config" + +If you check line 137 of the Gateway::parse_args() method you'll see +what this does. +---------------------------------------- +18. + +How to get ACE to work with GCC C++ templates. + +The first and foremost thing to do is to get the latest version of GCC +(2.7.2) and also get the template repository patches from + +ftp://ftp.cygnus.com/pub/g++/gcc-2.7.1-repo.gz + +This will get the ball rolling... + +Here is some more info on G++ templates courtesy of Medhi TABATABAI +: + +Where's the Template? +===================== + + C++ templates are the first language feature to require more +intelligence from the environment than one usually finds on a UNIX +system. Somehow the compiler and linker have to make sure that each +template instance occurs exactly once in the executable if it is +needed, and not at all otherwise. There are two basic approaches to +this problem, which I will refer to as the Borland model and the +Cfront model. + +Borland model + Borland C++ solved the template instantiation problem by adding + the code equivalent of common blocks to their linker; template + instances are emitted in each translation unit that uses them, and + they are collapsed together at run time. The advantage of this + model is that the linker only has to consider the object files + themselves; there is no external complexity to worry about. This + disadvantage is that compilation time is increased because the + template code is being compiled repeatedly. Code written for this + model tends to include definitions of all member templates in the + header file, since they must be seen to be compiled. + +Cfront model + The AT&T C++ translator, Cfront, solved the template instantiation + problem by creating the notion of a template repository, an + automatically maintained place where template instances are + stored. As individual object files are built, notes are placed in + the repository to record where templates and potential type + arguments were seen so that the subsequent instantiation step + knows where to find them. At link time, any needed instances are + generated and linked in. The advantages of this model are more + optimal compilation speed and the ability to use the system + linker; to implement the Borland model a compiler vendor also + needs to replace the linker. The disadvantages are vastly + increased complexity, and thus potential for error; theoretically, + this should be just as transparent, but in practice it has been + very difficult to build multiple programs in one directory and one + program in multiple directories using Cfront. Code written for + this model tends to separate definitions of non-inline member + templates into a separate file, which is magically found by the + link preprocessor when a template needs to be instantiated. + + Currently, g++ implements neither automatic model. The g++ team +hopes to have a repository working for 2.7.0. In the mean time, you +have three options for dealing with template instantiations: + + 1. Do nothing. Pretend g++ does implement automatic instantiation + management. Code written for the Borland model will work fine, but + each translation unit will contain instances of each of the + templates it uses. In a large program, this can lead to an + unacceptable amount of code duplication. + + 2. Add `#pragma interface' to all files containing template + definitions. For each of these files, add `#pragma implementation + "FILENAME"' to the top of some `.C' file which `#include's it. + Then compile everything with -fexternal-templates. The templates + will then only be expanded in the translation unit which + implements them (i.e. has a `#pragma implementation' line for the + file where they live); all other files will use external + references. If you're lucky, everything should work properly. If + you get undefined symbol errors, you need to make sure that each + template instance which is used in the program is used in the file + which implements that template. If you don't have any use for a + particular instance in that file, you can just instantiate it + explicitly, using the syntax from the latest C++ working paper: + + template class A; + template ostream& operator << (ostream&, const A&); + + This strategy will work with code written for either model. If + you are using code written for the Cfront model, the file + containing a class template and the file containing its member + templates should be implemented in the same translation unit. + + A slight variation on this approach is to use the flag + -falt-external-templates instead; this flag causes template + instances to be emitted in the translation unit that implements + the header where they are first instantiated, rather than the one + which implements the file where the templates are defined. This + header must be the same in all translation units, or things are + likely to break. + + *See Declarations and Definitions in One Header: C++ Interface, + for more discussion of these pragmas. + + 3. Explicitly instantiate all the template instances you use, and + compile with -fno-implicit-templates. This is probably your best + bet; it may require more knowledge of exactly which templates you + are using, but it's less mysterious than the previous approach, + and it doesn't require any `#pragma's or other g++-specific code. + You can scatter the instantiations throughout your program, you + can create one big file to do all the instantiations, or you can + create tiny files like + + #include "Foo.h" + #include "Foo.cc" + + template class Foo; + + for each instance you need, and create a template instantiation + library from those. I'm partial to the last, but your mileage may + vary. If you are using Cfront-model code, you can probably get + away with not using -fno-implicit-templates when compiling files + that don't `#include' the member template definitions. + +4. Placing a function that looks like this near the top of a .C file + that uses any inline template member functions permits proper inlining: + + // #ifdef __GNUG__ + // This function works around the g++ problem with inline template member + // calls not being inlined ONLY in the first block (in a compilation + // unit) from which they are called. + // This function is inline and is never called, so it does not produce + // any executable code. The "if" statements avoid compiler warnings about + // unused variables. + inline + void + gcc_inline_template_member_function_instantiator() + { + if ( (List *) 0 ); + } + // #endif // __GNUG__ + + other prerequisites: + -- All inline template member functions should be defined in + the template class header. Otherwise, g++ will not inline + nested inline template member function calls. + -- Template .h and .C files should NOT include iostream.h + (and therefore debugging.h). + This is because iostream.h indirectly includes other + GNU headers that have unprotected #pragma interface, + which is incompatible with -fno-implicit-templates and optimal + space savings. + -- inline virtual destructors will not be inlined, unless necessary, + if you want to save every last byte + -- be sure that -Winline is enabled + +---------------------------------------- +19. + +> 1. when are dynamically loaded objects removed from the Service_Config. + +The Service Configurator calls dlclose() when a "remove Service_Name" +directive is encountered in the svc.conf file (or programmatically +when the Service_Config::remove() method is invoked). Check out the +code in ./libsrc/Service_Config/Service_Repository.i and +./libsrc/Service_Config/Service_Config.i to see exactly what happens. + +> 2. In the Service Configurator, when an item is entered in the svc.conf +> how dow you know which items will be invoked as threads and +> which items are forked. I know that static items are executed +> internally. + + No! It's totally up to the subclass of Service_Object to +decide whetehr threading/forking/single-threading is used. Check out +the ./apps/Logger/Service_Configurator_Logger for examples of +single-threaded and multi-threaded configuration. +---------------------------------------- +20. + +> I have been reading the Service Configurator Logger. I was wondering about +> cleanup of new objects. In the handle_input method for the Acceptor a new +> svc_handler is allocated for each new input request and deleted in the +> handle_close. I was wondering how handle close was called when a client who +> has created a socket terminates the connection (i.e., when is handle_close +> called). + +handle_close() is automatically called by the Reactor when a +handle_input()/handle_output()/etc. method returns -1. This is the +"hook" that instructs the Reactor to call handle_**() and then remove +the Event_Handler object from its internal tables. + +---------------------------------------- +21. + +> How does the Logger know to remove the client socket and the svc_handler object. +> Does he recieve an exception. + + No. when the client terminates the underlying TCP/IP +implementation sends a RESET message to the logger host. This is +delivered to the logger process as a 0-sized read(). It then knows to +close down. + +> What I am worried about is a leak. Where by alot of clients connect and +> disconnect and the server does not cleanup correctly. Such as a core dump +> from the client where he cannot close correctly. + + That's handled by the underlying TCP (assuming it is +implemented correctly...). + +> What I am doing is attempting to convert the logger example into an alarm +> manager for remote nodes. In this application a node may be powered down +> there by terminating a Logger/Alarm server connection abnormally, this could +> leave the Logger with many dangling sockets and allocated svc_handler objects. + + If the TCP implementation doesn't handle this correctly then +the standard way of dealing with it is to have an Event_Handler use a +watchdog timer to periodically "poll" the client to make sure it is +still connected. BTW, PCs tend to have more problems with this than +UNIX boxes since when they are turned off the TCP implementation may +not be able to send a RESET... +---------------------------------------- +22. + +Using templates with Centerline. + +Centerline uses ptlink to process the C++ templates. ptlink expect the +template declarations and definitions (app.h and app.C) to reside in +the same directory. This works fine for the ACE hierarchy since +everything is a link to the appropriate src directory (include/*.[hi] +--> ../src/). When a users of the ACE distribution attempts to include +the ACE classes in an existing application hierarchy this problem will +arise if ptlink is used. + +The solution is to create a link to the declaration file from the +definition file directory and use the "-I" to point to the definition +directory. + +---------------------------------------- + +23. + +> When I try to compile $WRAPPER_ROOT/src/Message_Queue.C on a Solaris +> 5.3 system using SUNPro CC 4.0, the compiler aborts with a Signal 10 +> (Bus Error). Our copy of CC 4.0 is over a year old and I do not +> know if any patches or upgrades exist for it. If they do, then we +> have not applied them to our compiler. + + Several other people have run across this as well. It turns +out that there is a bug in the Sun 4.0.0 C++ compiler that will get a +bus error when -g is used. If you compilg Message_Queue.C *without* +-g then it works fine. The later versions of SunC++ don't have this +bug. I'd recommend that you upgrade as soon as possible. + +---------------------------------------- + +24. + +> I have added a dynamic service to the Service Configurator. This new service +> fails on the load because it uses application libraries that are not shared +> object libraries (i.e., objects in libApp.a). I am assuming from the error +> message that the problem is the mix match of shared and non-shared objects. + + Right, exactly. + +> I was wondering if there is an easy way to add static services to the +> Service Configurator. The example directory listing static service is +> very tightly coupled with the Service_Config object. Is there another +> way of adding static services. + + Sure, that's easy. The best way to do this is to use the +interfaces of the Service_Respository class to configure static +services into the Service_Config. A good example of how to do this is +in Service_Config.[Chi]: + +int +Service_Config::load_defaults (void) +{ + for (Static_Svc_Descriptor *sl = Service_Config::service_list_; sl->name_ != 0; sl++) + { + Service_Type *stp = ace_create_service_type (sl->name_, sl->type_, + (const void *) (*sl->alloc_)(), + sl->flags_); + if (stp == 0) + continue; + + const Service_Record *sr = new Service_Record (sl->name_, stp, 0, sl->active_); + + if (Service_Config::svc_rep->insert (sr) == -1) + return -1; + } + return 0; +} + +---------------------------------------- +25. + +> 8. Do you have examples of the SYNC/ASYNC pattern? + + Yes. Check out the following: + + 1. The latest version of ./apps/Gateway/Gateway has + an example of this when you compile with the USE_OUTPUT_MT + flag. In this case, the Reactor performs the "Async" + processing, which multiplexes all incoming messages from peers + arriving on Input_Channels. These messages are then queued + up at the appropriate Output_Channels. Each Output_Channel + runs in a separate thread, performing the "Sync" + processing. + + 2. Also, the latest version of the OOCP-tutorial4.ps.gz + file available from wuarchive.wustl.edu in the + directory /languages/c++/ACE/ACE-documentation shows + an example of using the Half-Sync/Half-Async pattern + to build an Image Server. I'm using this as an + example in my tutorials these days. + +---------------------------------------- +26. + +> We had a discussion about something we saw in the new ACE code. +> I thing there was a member function of a class that was doing a +> "delete this". Is this safe? + +In general it is safe as long as (1) the object has been allocated +dynamically off the heap and (2) you don't try to access the object +after it has been deleted. You'll note that I tend to use this idiom +in places where an object is registered with the Reactor, which must +then must ensure the object cleans itself up when handle_close() is +called. Note that to ensure (1) I try to declare the destructor +"private" or "protected" so that the object must be allocated off the +heap (some compilers have a problem with this, so I may not be as +consistent as I ought to...). + +---------------------------------------- +27. + +> 5. What is the correct way for building a modified ACE library? +> Changing in "libsrc" or in "include" directory? +> When I make a complete new directory, how can I get introduced +> the dependencies within my new makefile, can you give a short hint? + +Sure, no problem. For instance, here's what I did tonight when I +added the new Thread_Specific.[hiC] files to ACE: + + 1. Created three new files Thread_Specific.[hiC] in + ./libsrc/Threads. + + 2. cd'd to ../../include/ace and did a + + % ln -s ../../libsrc/Threads/Thread_Specific.[hi] . + + 3. cd'd to ../../src and did a + + % ln -s ../../libsrc/Threads/Thread_Specific.C . + + 4. then I did + + % make depend + + on the ./src directory, which updated the dependencies. + +---------------------------------------- +28. The following is from Neil B. Cohen (nbc@metsci.com), who is + writing about how to work around problems he's found with HP/UX. + +I've been trying to compile the latest beta (3.2.9) on an HP running +HPUX9.05 for the past week or so. I've had problems with templates up +and down the line. I finally discovered (after some discussions with +the HP support people) that they have made numerous changes to their +C++ compiler recently to fix problems with templates and +exceptions. If you are trying to compile ACE under HPUX with anything +less than version 3.70 of the HP compiler, you may have serious +problems (we were using v3.50 which came with the machine when we +bought it a few months ago). + +Also, unlike earlier ACE versions, I was forced to add the following +line to the rules.lib.GNU file to "close" the library - ie. force the +various template files to be instantiated and linked to the ACE +library itself. I don't know if this is necessary, or the only way to +make things work, but it seems to do the job for my system. + +in rules.lib.GNU... + +$(VLIB): $(VOBJS) + - CC -pts -pth -ptb -ptv -I$(WRAPPER_ROOT)/include $(VOBJS) + $(AR) $(ARFLAGS) $@ $? ./ptrepository/*.o + -$(RANLIB) $@ + -chmod a+r $@ + +I added the CC line, and added the "./ptrepository/*.o" to the $(AR) +cmd. Sun has an -xar option, I believe that does something similar to +this. Also - note that I'm not sure that the "-ptb" option is +necessary. I added that before we upgraded the compiler, so it may not +be needed now... + +---------------------------------------- +29. + +> I just ran my program with Purify, and it is telling me that there +> is at least one large (~4k) memory leak in +> ACE_Thread_Specific. This may or may not be serious, +> but it is probably worth looking into. + +Right, that's ok. This is data that's allocated on a "per-thread" +basis the first time a thread makes a call using the LM_ERROR or +LM_DEBUG macros. The data isn't freed-up until the thread exits. + +---------------------------------------- + +30. + +> In my trying to use the Reactor pattern for my application I +> noticed that I had to couple my eventHandler derived objects with a +> specific IPC_SAP mechanism. To use some of your own examples your +> Client_Stream object contains a TLI_Stream object to use in data +> transfer. My application calls for determining the communication +> mechanism at run time. To do this my eventHandler must be able to +> create the appropriate IPC_Stream object at run time and use its +> methods through a super class casting. The problem is that there is no +> super class with the virtual methods for send, recv, etc. To solve my +> problem I will create that super class and have the TLI ( as well as +> other wrapper objects) inherit from it instead of IPC_SAP. My question +> is I am suspicious of why ACE wasn't designed with that in mind? Is my +> application that unique ? or is there a better way to do this that I +> am not aware of ? Your help in this matter will be much appreciated. + +ACE was developed using static binding for IPC_SAP in order to +emphasize speed of execution over dynamic flexibility *in the core +infrastructure*. To do otherwise would have penalized the performance +of *all* applications in order to handle the relatively infrequent +case where you want to be able to swap mechanisms at run-time. + +Since it is straightforward to create an abstract class like the one +you describe above I decided to make this a "layered" service rather +than use this mechanism in the core of ACE. + +BTW, I would not modify TLI_SAP and SOCK_SAP to inherit from a new +class. Instead, I would use the Bridge and Adapter patterns from the +"Gang of Four" patterns catalog and do something like this: + +---------------------------------------- +// Abstract base class +class ACE_IPC_Stream +{ +public: + virtual ssize_t recv (void *buf, size_t bytes) = 0; + virtual ssize_t send (const void *buf, size_t bytes) = 0; + virtual ACE_HANDLE get_handle (void) const = 0; + // ... +}; +---------------------------------------- + +and then create new classes like + +---------------------------------------- +template +class ACE_IPC_Stream_T : public ACE_IPC_Stream +{ +public: + virtual ssize_t recv (void *buf, size_t bytes) + { + return this->ipc_.recv (buf, bytes); + } + + virtual ssize_t send (const void *buf, size_t bytes) + { + return this->ipc_.send (buf, bytes); + } + + virtual ACE_HANDLE get_handle (void) + { + return this->ipc_.get_handle (); + } + // ... + +private: + IPC ipc_; + // Target of delegation + // (e.g., ACE_SOCK_Stream or ACE_TLI_Stream). +} +---------------------------------------- + +Then you could write code that operated on ACE_SAP *'s to get a +generic interface, but that reused existing code like SOCK_SAP and +TLI_SAP, e.g., + +---------------------------------------- +class My_Event_Handler : public ACE_Event_Handler +{ +public: + My_Event_Handler (void) { + // Figure out which IPC mechanism to use somehow: + + if (use_tli) + this->my_ipc_ = new ACE_SAP_IPC; + else if (use_sockets) + this->my_ipc_ = new ACE_SAP_IPC; + else + ... + } + +private: + ACE_IPC_Stream *my_ipc_; +}; +---------------------------------------- + +There are obviously details left out here, but this is the general idea. + +---------------------------------------- +31. + +> I was trying to view your 'Writting example applications in CORBA' article +> /tutorial using ghostview but the .ps file seems to be corrupted ( I tried to +> ftp it more than once). Any help would be much appreciated. + +There are two solutions to this problem (which seems to be caused by a +weird interaction between ghostview and the "psnup" program I use to +generate the slides 4-up on a page): + + 1. If you want to print them or view them 1-up on a page you + can edit the postscript file and remove the first 551 + lines or so (which are generated by the psnup script). + This will cause the document to be printed 1-up rather than + 4-up. + + 2. You can try to print the 4-up file on a postscript printer. + Believe it or not, this typically works, even though ghostview + can't handle it! + +---------------------------------------- +32. + +> We would like to use the Reactor class as a static member on some of +> our classes (one per process) so that we can see and use the Reactor +> witnin each process on a global level. We are using it to set +> timers several levels down in our class trees and don't want to pass +> a pointer to it through all of our constructors. My question is: +> are there any static initialization dependencies that you know of +> when using the default "do nothing" constructor of the Reactor that +> could prevent use from using it as a static member variable? Thanks +> for any advice on this issue. + +The only problems you'll have are the typical ones about "order of +initialization" of statics in separate files. You'll also have to +live with the default size of the I/O handler table, which probably +isn't a problem since the max is something like 1024 or so. + +BTW, I solve this problem in ACE via the Service_Config::reactor, +which is a static *pointer* to a Reactor. If you really wanted to +make this work nicely, you could use the Singleton pattern from the +"Gang of Four" patterns catalog. That should solve your problem even +more elegantly! + +---------------------------------------- +33. +> I just got the ACE-3.3 version and am trying it on the HP-UX. +> I run into a small problem while cloning the directories that +> might be worth fixing. +> +> I made a directory called ACE_WRAPPERS/HP-UXA.09.05-g1, cd to it +> and run "make -f ../Makefile clone". when I look in src, I have: +> Acceptor.C@ -> ../libsrc/Connection/Acceptor.C +> +> However, ../libsrc does not exist. It is not one of the CLONE +> variables in ACE_WRAPPERS/Makefile. I don't think you'd want to +> clone libsrc too, since its files don't change. + +I think you can solve this problem as follows: + +% cd ACE_WRAPPERS +% setenv WRAPPER_ROOT $cwd +% cd HP-UXA.09.05-g1 +% make -f ../Makefile clone +% setenv WRAPPER_ROOT $cwd +% make + +That should build the links correctly since they'll point to the +absolute, rather than relative, pathnames! + +---------------------------------------- +34. + +> Our quality personal has asked me the following questions for which +> I think you are the right guy for answering that: + +> o How long is ACE used in industrial products? + +It was first used at Ericsson starting in the fall of 1992, so that +makes it about 3 years now. + +> o What are reference projects comparable to ours that use ACE? + +The ones I have directly worked with include: + +Motorola -- satellite communication control +Kodak Health Imaging Systems -- enterprise medical imaging +Siemens -- enterprise medical imaging +Ericsson/GE Mobile Communications -- telecommunication switch management +Bellcore -- ATM switch signal software + +In addition, there are probably about 100 or more other companies that +have used ACE in commercial products. The current mailing list has +about 300 people from about 230 different companies and universities. +If you'd like additional info, please let me know. + +> o How many persons have contributed on testing and writing error +> reports for ACE? + +Around 60 or so. All the contributors are listed by name and email +address at the end of the README file distributed with the ACE release. + +> o How many bug fixes have been made since ACE was public domain? + +All information related to bug fixes is available in the ChangeLog +file distributed with the ACE release (I could count these for you if +you need that level of detail). + +> o How many literature is there on ACE? + +All articles published about ACE are referenced in the BIBLIOGRAPHY +file in the top-level directory of ACE. + +---------------------------------------- + +35. + +> We are currently evaluating ACE for use on a new telecom switch. +> Many of us like ACE but are having trouble convincing some team +> members that wrappers are better than using the direct Unix +> system calls. + +> I have read your papers that came with ACE, but was wondering if there +> are other papers that address the benefits (or problems) of wrappers? + +This topic has been discussed in other places, most notably the book +by Erich Gamma and Richard Helm and Ralph Johnson and John Vlissides +called "Design Patterns: Elements of Reusable Object-Oriented +Software" (Addison-Wesley, 1994), where it is described in terms of +the "Adapter" pattern. + +Very briefly, there are several key reasons why you should *not* use +UNIX system calls directly (regardless of whether you use ACE or not). + +1. Portability -- + + Unless you plan to develop code on only 1 UNIX platform (and + you never plan to upgrade from that platform as it goes + through new releases of the OS) you'll run across many, many + non-portable features. It's beyond the scope of this + FAQ to name them all, but just take a look at ACE sometime + and you'll see all the #ifdefs I've had to add to deal with + non-compatible OSs and compilers. Most of these are centralized + in one place in ACE (in the ace/OS.*files), but it took a lot + of work to factor this out. By using wrappers, you can avoid + most of this problem in the bulk of your application code + and avoid revisiting all of these issues yourself. + + In addition, ACE is now ported to other platforms (e.g., + Windows NT and Windows 95). If you want to write code that + is portable across platforms, wrappers are a good way to + accomplish this. + +2. Ease of programming -- + + I'd go as far as to say that anyone who wants to program + applications using C-level APIs like sockets or TLI is not + serious about developing industrial strength, robust, and easy + to maintain software. Sockets and TLI are *incredibly* + error-prone and tedious to use, in addition to being + non-portable. I've got a paper that discusses this in detail + at URL http://www.cs.wustl.edu/~schmidt/COOTS-95.ps.Z + +3. Incorporation with higher-level patterns and programming methods -- + + Here's where the Adapter pattern stuff really pays + off. For example, by making all the UNIX network + programming interfaces and synchronization mechanisms + have the same API I can write very powerful higher-level + patterns (e.g., Connector and Acceptor) that generalize + over these mechanisms. For proof of this, take a look + at the ./tests/Connection/non_blocking directory + in the latest ACE-beta.tar.gz at wuarchive.wustl.edu + in the /languages/c++/ACE directory. It implements + the same exact program that can be parameterized + with sockets, TLI, and STREAM pipes *without* + modifying any application source code. It is + literally impossible to do this without wrappers. + +---------------------------------------- +36. + +> How can I use a kind of "Reactor" in such a way that a reading +> thread can notice the arrival of new data on several shared memory +> areas ? + +Ah, that is a tricky issue! The underlying problem is that UNIX is +inconsistent with respect to the ability to "wait" on different +sources of events. In this case, Windows NT is much more consistent +(but it has its own set of problems...). + +> Poll, Select and Reactor (so far I read) assume that file +> descriptors are present, which is not the case with shared memory. + +That's correct (though to be more precise, the Reactor can also deal +with signals, as I discuss below). + +> Is there a common and efficient way to deal with that kind of +> situation, or do I have to insert extra ipc mechanisms (based on +> descriptors) ? + +There are several solutions: + +1. Use the Reactor's signal handling capability (see the + ./tests/Reactor/misc/signal_tester.C for an example) + and have the process/thread that writes to shared + data send a signal to the reader process(es). The + disadvantage of this is that your code needs to + be signal-safe now... + +2. Use a combination of SPIPE_Streams and the Reactor + to implement a simple "notification protocol," e.g., + the receiver process has an Event_Handler with a + SPIPE_Stream in it that can be notified when the + sender process writes data to shared memory. + The disadvantage here is that there's an extra + trip through the kernel, though the overhead + is very small since you only need to send 1 byte. + +3. Use threads and either bypass the Reactor altogether + or integrate the threads with the Reactor using its + Reactor::notify() mechanism (see the + ./tests/Reactor/misc/notification.C file for an + example of how Reactor::notify() works). The + disadvantage of this approach is that it won't + work for platforms that lack threads. + +---------------------------------------- +37. + +> What do you think about wrapping communication methodologies in C++ streams? +> What I mean is having defining a stream and extractor/insertor functions +> which the underlying implementation reads/writes on comm mechanisms instead of +> files. I would think this to be a very general interface for all comms +> implementations. All user code would look the same, but the underlying stream +> implementations would be different. Whether the stream functionality would +> be defined by the stream itself (eg tcpstream) or with manipulators +> (eg commstream cs; cs << tcp;) is up for grabs in my mind. +> +> Anyhow, I was wondering your input... + +That technique has been used for a long time. In fact, there are +several freely available versions of iostreams that do this and +RogueWave also sells a new product (Net.h++) that does this. I think +this approach is fine for simple applications. + +However, it doesn't really work well if you need to write +sophisticated distributed applications that must use features like +non-blocking I/O, concurrency, or that must be highly robust against +the types of errors that occur in a distributed system. + +For these kinds of systems you either need some type of ORB, or you +need to write the apps with lower-level C++ wrappers like the ones +provided by ACE. + +---------------------------------------- + +38. + +> What is the difference between cont() and next() in an ACE_Message_Block? + +Ah, good question. cont() gives you a pointer to the next +Message_Block in a chain of Message_Block fragments that all belong to +the same logical message. In contrast, next() (and prev()) return +pointers to the next (and previous) Message_Block in the doubly linked +list of Message_Blocks on a Message_Queue. + +BTW, this is *exactly* the same structure as in System V Streams... + +> Which would I use if I wanted to add a header and a trailer, each stored in +> ACE_Message_Blocks of their own, to another ACE_Message_Block? + +You should use cont() for that. Does that make sense? +---------------------------------------- + +39. + +> I think that your site is cool, but it's being a terrible tease in +> that I really want to read the contents, but don't know anything +> about x-gzip formatting. I'm running Netscape 2.0 under MS Windows +> NT. + + x-gzip is a hook for the GNU "gzip" program, which should be +freely available for NT at prep.ai.mit.edu in the /pub/gnu directory. +Here's how our "Global Mailcap" entry for Netscape looks like (see the +"Helper Applications" menu under "preferences": + +---------------------------------------- +# For the format of this file, see +# ftp://wuarchive/doc/internet-drafts/draft-borenstein-mailcap-00.txt.Z + +audio/*; audiotool %s; test=test -n "$DISPLAY" && test -w /dev/audio +image/*; xv %s; test=test -n "$DISPLAY" +application/postscript; ghostview %s; test=test -n "$DISPLAY" +video/mpeg; mpeg_play %s; test=test -n "$DISPLAY" +video/*; xanim +Ae %s; test=test -n "$DISPLAY" +application/x-dvi; xdvi %s; test=test -n "$DISPLAY" +application/x-compress; uncompress %s; test=test -n "$DISPLAY" +application/x-gzip; gunzip %s; test=test -n "$DISPLAY" +application/x-zip; unzip %s; test=test -n "$DISPLAY" +---------------------------------------- + +BTW, if you can't get uncompress to work, please ftp to +wuarchive.wustl.edu and look in the directory +/languages/c++/ACE/ACE-documentation/. All the papers are there, as +well. + +---------------------------------------- + +40. + +> What I am doing is +> 1. Making an ACE_SOCK_Dgram and let it choose the next available port number. +> 2. Making a message that will be broadcasted to X number of servers. This +> message has a port number which the server will use to send its reply. +> 3. Broadcast the message to a fixed port number. +> 4. Wait for replies from the servers. +> +> +> It looks like I need "ACE::bind_port" to return the port number that +> it picked and "ACE_SOCK_Dgram::shared_open" will need it store the +> port number so I could call some function like +> ACE_SOCK_Dgram::get_port_number or it would need to return the port +> number instead of the handle(I could always call +> ACE_SOCK_Dgram::get_handle if I needed the handle). +> +> Is there I way to get the port number that I have missed? + +Sure, can't you just do this: + +// Defaults to all "zeros", so bind will pick port. +ACE_INET_Addr dg_addr; + +ACE_SOCK_Dgram dg; + +dg.open (dg_addr); + +dg.get_local_addr (dg_addr); + +dg_addr.get_port_number (); + +---------------------------------------- + +41. How can you rename a core file? + +new_disposition.sa_handler = &Handle_Coredump_Signal; +sigemptyset(&new_disposition.sa_mask); +sigaddset(&new_disposition.sa_mask,SIGCHLD); +new_disposition.sa_flags = 0; +sigaction(SIGSEGV,&new_disposition,&old_disposition); + +***************** + +void +Handle_Coredump_Signal(void) +{ + int status; + pid_t child; + char new_core_name[64]; + + if(0 == (child = fork())) + { + abort(); + } + else + { + if(-1 == waitpid(child,&status,NULL)) + { + exit(-1); + } + sprintf(new_core_name,"core_%d",getpid()); + rename("core",new_core_name); + exit(0); + } +} + +---------------------------------------- + +42. + +> I have seen 2 different inlining policies in ACE +> +> 1) The .i file is included unconditionally by both the .h and .C file +> and all functions in the .i file carry the "inline" keyword. + +Right. Those are for cases where I *always* want to inline those +methods. I do this mostly for very short wrapper methods (e.g., +read() or write()) that are likely to be on the "fast path" of an +application. + +> 2) The .i file is included by the .h file ONLY if __INLINE__ is defined +> for the compile. This causes the functions in the .i file to be +> compiled as inline functions (INLINE translates to inline in this case). +> If __INLINE__ is not defined, the .i file is only included by the .C +> file and the functions do NOT carry the "inline" keyword. + +I do this for cases where it's really not essential to have those +methods inline, but some users might want to compile ACE that was if +they want to eliminate all the wrapper function-call overhead. For +instance, I'll typically do this when I'm running benchmarks. + +---------------------------------------- + +43. Integrating ACE and CORBA + +> Our goal is to implement a CORBA-II compliant application. I am +> trying to conceptually visualize the applicability to ACE to this +> attempt (which we're pretty excited about), and I was hoping you'd +> offer any opinions / observations that you might have. + +We've successfully integrated ACE with several implementations of +CORBA (in particular Orbix 1.3 and 2.0) and used it in a number of +commercial applications. In these systems, we use ACE for a number of +tasks, including the following: + +1. Intra-application concurrency control, threading, and + synchronization via the ACE_Thread_Manager and Synch* classes. + +2. Dynamic linking of services via the ACE_Service_Config. + +3. Integration of event loops via the ACE_Reactor. + +4. Management of shared memory via ACE_Malloc. + +5. High-performance network I/O via the ACE_SOCK* wrappers. + +plus many more. + +You can find out more info about the ACE/CORBA integration and the +performance issues associated with it in the following paper: + +http://www.cs.wustl.edu/~schmidt/COOTS-96.ps.gz + +---------------------------------------- + +44. + +> Can the Reactor's event loop be called recursively? + +This is not advisable. The Reactor's dispatch() method is not +reentrant (though it is thread-safe) since it maintains state about +the active descriptors it is iterating over. Therefore, depending on +the descriptors you're selecting on, you could end up with spurious +handle_*() callbacks if you make nested calls to the +Reactor::handle_events() method. + +> For example, if I have a program that sets up some event handlers +> and then calls, in an infinite loop, ACE_Reactor::handle_events(). +> Can one of the event handlers call handle_events() again if it needs +> to block, while allowing other event handlers a chance to run? + +I'm not sure if this is really a good idea, even if the Reactor were +reentrant. In particular, what good does it do for one Event_Handler +to "block" by calling handle_events() again? The event the handler is +waiting for will likely be dispatched by the nested handle_events() +call! So when you returned back from the nested call to +handle_events() it will be tricky to know what state you were in and +how to proceed. + +Here's how I design my single-threaded systems that have to deal with +this: + + 1. I use a single event loop based on the Reactor, which acts + a cooperative multi-tasking scheduler/dispatcher. + + 2. I then program all Event_Handler's as non-blocking I/O + objects. This is straightforward to do for both input and + output using the ACE_Reactor::schedule_wakeup() and + ACE_Reactor::cancel_wakeup() methods (available with the + latest version of ACE). + + 3. Then, whenever an Event_Handler must block on I/O, it + queues up its state on an ACE_Message_Queue, calls + ACE_Reactor::schedule_wakeup(), and returns to the + main event loop so that other Event_Handlers can be + dispatched. When the I/O is ready, the Reactor will + call back to the appropriate handle_* method, which + can pick up the state it left in the Message_Queue and + continue. + +There are a number of places to find more information on this sort of +design: + + 1. $WRAPPER_ROOT/apps/Gateway/Gateway/Channel.cpp -- + This Gateway application example shows the C++ code. + + 2. http://www.cs.wustl.edu/~schmidt/TAPOS-95.ps.gz -- + This paper describes the underlying patterns. + + 3. http://www.cs.wustl.edu/~schmidt/OONP-tutorial4.ps.gz + -- This tutorial explains the source code and + the patterns. + +BTW, I'll be describing patterns for this type of design challenge in +my tutorial at USENIX COOTS in June. Please check out +http://www.cs.wustl.edu/~schmidt/COOTS-96.html for more info. + +---------------------------------------- + +45. + +> In one of my programs, a process needs to receive input from +> multiple input sources. One of the input sources is a file +> descriptor while another is a message queue. Is there a clean way to +> integrate this a message queue source into the Reactor class so that +> both inputs are handled uniformly? + +Do you have multiple threads on your platform? If not, then life will +be *very* tough and you'll basically have to use multiple processes to +do what you're trying to do. There is *no* portable way to combine +System V message queues and file descriptors on UNIX, unfortunately. + +If you do have threads, the easiest thing to do is to have a thread +reading the message queue and redirecting the messages into the +Reactor via its notify() method. + +Please take a look at the program called + +examples/Reactor/Misc/notification.cpp + +for an example. + +---------------------------------------- + +46. + +> I'm writing a program to find out the address for a socket. The +> idea is that we open an ACE_Acceptor (and will eventually perform +> accept() on it.) Before we can do that we need to find out the +> address of the ACE_Acceptor so that we can publish it (for others to +> be able to connect to it.) The trouble is that the call +> ACE_INET_Addr::get_host_name () prints "localhost" as the host name +> while I would like to principal host name to be printed instead. + +All ACE_INET_Addr::get_host_name() is doing is calling +ACE_OS::gethostbyaddr(), which in turn will call the socket +gethostbyaddr() function. I suspect that what you should do is +something like the following: + +ACE_Acceptor listener (ACE_Addr::sap_any); + +ACE_INET_Addr addr; + +listener.get_local_addr (addr); + +char *host = addr.get_host_name (); + +if (::strcmp (host, "localhost") == 0) +{ + char name[MAXHOSTNAMELEN]; + ACE_OS::hostname (name, sizeof name); + cerr << name << endl; +} +else + cerr << host << endl; + +---------------------------------------- + +47. + +> Could you please point me to stuff dealing with asynchronous cross +> platform socket calls. I want to use non blocking socket calls on +> both UNIX and NT. + +Sure, no problem. Take a look at the + +./examples/Connection/non_blocking/ + +directory. There are a number of examples there. In addition, there +are examples of non-blocking connections in + +./examples/IPC_SAP/SOCK_SAP/CPP-inclient.cpp + +The code that actually enables the non-blocking socket I/O is in +ace/IPC_SAP.cpp + +---------------------------------------- + +48. + +> Is ACE exception-safe? If I throw an exception out of event +> handler, will the Reactor code clean itself? + +Yes, that should be ok. In general, the two things to watch out for +with exceptions are: + + 1. Memory leaks -- There shouldn't be any memory leaks internally + to the Reactor since it doesn't allocate any memory when + dispatching event handlers. + + 2. Locks -- In the MT_SAFE version of ACE, the Reactor acquires + an internal lock before dispatching Event_Handler callbacks. + However, this lock is controlled by an ACE_Guard, whose + destructor will release the lock if exceptions are thrown + from an Event_Handler. + +---------------------------------------- + +49. + +> I am building a Shared memory manager object using MMAP and MALLOC +> basically as: +> +> typedef ACE_Malloc SHMALLOC; +> +> I noticed that the ACE_MMAP_Memory_Pool class provides for the users +> to specify a Semaphore key. However, once I use it via the +> ACE_Malloc<..>::ACE_Malloc(const char* poolname) constructor, I lose +> this option. + +Yes, that is correct. That design decision was made to keep a clean +interface that will work for all the various types of memory pools. + +> Is there any recommended way to specialize ACE classes to allow this +> key to be overridden? + +Yes indeed, you just create a new subclass (e.g., class +My_Memory_Pool) that inherits from ACE_MMAP_Memory_Pool and then you +pass in the appropriate key to the constructor of ACE_MMAP_Memory_Pool +in the constructor of My_Memory_Pool. Then you just say: + +typedef ACE_Malloc SHMALLOC; + +Please check out the file: + +examples/Shared_Malloc/Malloc.cpp + +which illustrates more or less how to do this. + +---------------------------------------- + +50. + +> What is the best way to turn on TRACE output in ACE. I commented +> out the #define ACE_NTRACE 1 in config.h and rebuilt ACE and the +> examples. + +The best way to do this is to say + +#define ACE_NTRACE 0 + +in config.h. + +> When I run the CPP-inserver example in examples/IPC_SAP/SOCK_SAP, I +> get some trace output but not everything I would expect to see. + +Can you please let me know what you'd expect to see that you're not +seeing? Some of the ACE_TRACE macros for the lower-level ACE methods +are commented out to avoid problems with infinite recursion (i.e., +tracing the ACE_Trace calls...). I haven't had a chance to go over +all of these indepth, but I know that it should be possible to turn +many of them back on. + +> It would be nice to have a runtime option for turning trace on and +> off. + +There already is. In fact, there are two ways to do it. +If you want to control tracing for the entire process, please check +out ACE_Trace::start_tracing() and ACE_Trace::stop_tracing(). + +If you want to control tracing on a per-thread basis please take a +look at the ACE_Log_Msg class. There are methods called +stop_tracing() and start_tracing() that do what you want. + +---------------------------------------- + +51. + +> I've been using an acceptor and a connector in one (OS-) process. +> What does happen, if a signal is sent to this process? Is the signal +> processed by every ACE_Event_Handler (or its descendants) that is +> around? The manual page simply states that handle signal is called +> as soon as a signal is triggered by the OS. + +How this signal is handled depends on several factors: + +1. Whether your using ACE_Sig_Handler or ACE_Sig_Handlers to register + the signal handlers. + +2. If you're using ACE_Sig_Handler, then the ACE_Event_Handler * that + you've most recently registered to handle the signal will + have it's handle_signal() method called back by the Reactor. + +3. If you're using ACE_Sig_Handlers, then all of the ACE_Event_Handler * + that you've register will be called back. + +For examples of how this works, please check out + +$WRAPPER_ROOT/examples/Reactor/Misc/test_signals.cpp + +This contains a long comment that explains precisely how everything +works! diff --git a/INSTALL b/INSTALL new file mode 100644 index 00000000000..3e285b5b7b3 --- /dev/null +++ b/INSTALL @@ -0,0 +1,440 @@ +INSTALLATION NOTES FOR THE ADAPTIVE COMMUNICATION ENVIRONMENT (ACE) + +-------------------------------------------------- +The file explains how ACE to build ACE on the various UNIX and Win32 +platforms that it has been ported to. Please make sure you read the +./FAQ before installing ACE! In addition, please consult the ChangeLog +file to see whether any recent changes to the release will affect your +code. +-------------------------------------------------- + +SUPPORTED PLATFORMS AND COMPILERS + +The ADAPTIVE Communication Environment has been ported and tested +extensively on the following platforms and compilers: + +* Win32 (Windows NT and Windows '95) + + . All of ACE has been ported to the Win32 API (which includes + Windows NT and Windows '95). The entire release now + compiles using the Microsoft Visual C++ 4.0 compiler (the + 2.0 compiler should also work, but I haven't tested it + recently). ACE can be built as both a static and dynamic + library, using the Win32 installation process described + below. + +* Sun OS 5.x/4.x (a.k.a. Solaris 2.x/1.x) using Sun CC 3.0.1, Sun C++ + 4.0.x, Centerline C++ 2.x, and GNU gcc 2.7.x. + + . All the source code and tests should build and run without + any problems on the Solaris and SunOS platforms using the + Sun C++ compilers. + +* Sun OS 4.1.x using Centerline C++ 2.x, Sun CC 3.x, and Lucid + Energize 3.2. + + . Note that shared libraries do not interact very well with + Centerline C++ or Sun C++ on SunOS 4.1.x. This is due to + odd behavior of the SunOS 4.1.x linker, which (1) does not + properly call constructors of global objects within shared + libraries and (2) does not call the init() and fini() + functions in shared libraries, even though the manual claims + that these functions are called! In particular, this means + that the tests in the directory + $(WRAPPER_ROOT)/tests/Service_Configurator/IPC-tests/server/ + will not work for statically linked services... + + Some versions of SunOS 4.1.x do not contain the + /usr/lib/libnsl.a library. This library seems to be + optional since System V Transport Layer Interface (TLI) + support is optional on SunOS 4.1.x (in contrast, it's the + "preferred" transport interface on Solaris). + + The best work-around for now is probably to either add a + dummy libnsl.a in /lib (which may not be feasible) or simply + comment out the line: + + LIBS += -lnsl + + in the $WRAPPER_ROOT/include/makeinclude/wrapper_macros.GNU + file. Naturally, any programs (e.g., the TLI_SAP tests) + that use the TLI wrappers aren't going to work! + + Note that on SunOS 4.x you may get warnings from the linker + that "archive has no table of contents; add one using + ranlib(1)" for certain libraries (e.g., libASX.a, + libThreads.a, and libSPIPE.a). This occurs since SunOS 4.x + does not support these features. + +* AIX + + . The ACE port to AIX assumes that the user has installed the + AIX patch containing the dl*() APIs. To use these APIs, IBM + has created a separate product (free to AIX licensees) + called shared library hookable symbols (or slhs/6000). If + you don't have this patch, the sv* commands for compiling + and linking will not be present on the system. + +* Linux and SCO 4.2 + + . ACE has been ported to Linux and SCO UNIX using the GNU G++ + 2.7.2 compiler. + +* SGI IRIX 5.x + + . ACE builds fine using the SGI C++ and GNU GCC compilers for + IRIX 5.x. I haven't tried this on IRIX 6.x, but I assume + that will work too. If anyone can get ACE working with + IRIX 6.x pthreads please let me know. + +* HP-UX 9.x and 10.x + + . The current HP/UX C++ compiler is incredibly lame and has + problems compiling ACE templates and achieving template + closure. I've heard that the next release is better... + In the meantime, you might try using GNU GCC or SunC++ + on HP/UX. + +* OSF/1 3.2 + + . The current OSF/1 5.1 C++ compiler is also rather poor and there + seems to be no way to build shared libraries with templates + on OSF/1. I've also heard that the new version of this + compiler (5.3) is better. Again, you might try GNU GCC. + +* UnixWare 2.01 + + . Steve Huston has ported ACE to work with UnixWare 2.01 and + its standard C++ compiler. + +* VxWorks + + . David Levine has ported ACE to VxWorks 5.2 using the + GreenHills 1.8.7 compiler. + +* MVS + + . Chuck Gehr has ported ACE to IBM MVS. + +---------------------------------------- + +COMPILING ACE WITH GNU C++ + +If you use the GNU GCC C++ compiler please note the following: + + . Earlier versions of GNU GCC may not compile certain + parts of ACE correctly due to compiler bugs. + Please upgrade to GCC 2.7.2 or greater. + + . Make sure to update your gcc "config.status" file - + this specifies whether your gcc install uses, for + example, Solaris's "/usr/ccs/bin" binary utils or + GNU binary utils. + +-------------------------------------------------- + +INSTALLATION PROCESS FOR UNIX + +The installation process for installing ACE on UNIX is relatively +simple (the installation process for Windows NT is different, please +see the section below). Here's what you need to do: + +1. Install GNU make 3.7 or greater on your system (available via + anonymous ftp from prep.ai.mit.edu in the pub/gnu directory). + +2. Add an environment variable called WRAPPER_ROOT that contains the + name of the root of the directory where you keep the ACE wrapper + source tree. For example, in my .login file I have the following + entry: + + % setenv WRAPPER_ROOT /home/cs/faculty/schmidt/ACE_wrappers + + The ACE recursive Makefile system needs this information. + +3. Edit the $WRAPPER_ROOT/ace/OS.h file to update things like default + hostname and port numbers you'd like the programs in the + $WRAPPER_ROOT/{apps,tests} directories to use by default. + +4. Set the $WRAPPER_ROOT/ace/config.h file to point to the appropriate + platform/compiler-specific header configurations (such as + config-sunos5-sunc++-4.x.h). This file contains the #defines that + are used throughout ACE to indicate which features your system + supports (see the $WRAPPER_ROOT/ace/OS.h file for many + examples of how the ACE build configuration is affected by these + macro settings). + + There are config files for most versions of UNIX. If there isn't a + version of this file that matches your platform/compiler, you'll + need to make one. Please send me email if you get it working so I + can add it to the master ACE release. + +5. Set the $WRAPPER_ROOT/include/makeinclude/platform_macros.GNU file + to point to the appropriate platform/compiler-specific Makefile + configurations (e.g., platform_sunos5_sunc++.GNU). This file + contains the compiler and Makefile directives that are + platform/compiler-specific + +6. Note that since ACE builds shared libraries, you'll need to set + LD_LIBRARY_PATH to whereever you put the binary version of the + libraries. For example, you probably want to do somethink like the + following + + % setenv LD_LIBRARY_PATH $WRAPPER_ROOT/ace:$LD_LIBRARY_PATH + +7. When all this is done, hopefully all you'll need to do is type: + + % make + + at the root of the ACE source tree. This will build the static and + shared object libraries and build the tests and the sample + applications. + +-------------------------------------------------- + +INSTALLATION PROCESS FOR WINDOWS NT STATIC AND DYNAMIC LIBRARIES. + +The installation process for NT is a bit different than UNIX. First, +I assume you're using MSVC++ 4.0(things are a little different for the +2.0 version...). + +0. SET UP THE ACE FILES. + + Create a directory accessible via Windows NT (e.g., C:\ACE) and + copy all of ACE into it. This directory will be $WRAPPER_ROOT in + the following discussion. Then copy either config-win32-msvc4.0.h + or config-win32-msvc2.0.h (depending on your compiler of course) to + config.h. Note that files like ChangeLog may do strange things on + NT since they are symbolic links (which aren't supported under NT). + + The easiest thing to do is just use the default ace.mpd and ace.mak + files distributed with the release. Open workspace ace.mpd to + build ACE as a DLL. This included project assumes that you have + set the "global" include path to include $WRAPPER_ROOT. This can + be done via the following MSDEV menu item: + + Tools/Options/Directories/Show_Directories_For:Include_Files. + + If you choose not to use the given project, then the following + bullets 1 through 6 explain how to build ACE with MSDEV. + +1. CREATE A PROJECT WORKSPACE. + + Start by making a new project. It should be rooted at + $WRAPPER_ROOT. We normally browse to $WRAPPER_ROOT, and select + "ace" as the project name. This will cause MSDEV to use the + $WRAPPER_ROOT/ace directory to store the project files. The actual + directory and project name are unimportant, but we'll assume you + named the project "ace." Select the dynamic link library option + and say "ok." By default, the config-win32*.h files are set up to + build DLLs. If you choose to build ACE as a static library you'll + need to unset ACE_HAS_DLL in the config-win32*.h file and select + the static link library option when creating a project workspace. + +2. INSERT FILES INTO PROJECT. + + Go into the Insert menu and select "Files into project". If you're + building a static library, select all the *.cpp files in + $WRAPPER_ROOT/ace into the project. If you're building a DLL, you + need to omit the files in ACE which contain template class + definitions. You can find out which files this is by looking at + the TEMPLATE_FILES target in the $WRAPPER_ROOT/ace/Makefile. + + Once you've selected the files and pressed "ok" it should take a + few seconds or so to for MSDEV to create the project. (Note that + in MSVC2.0 there isn't an Insert menu, so go into the Project Menu + and then "Files" and from there insert all the *.cpp files.) When + including the files on windows 95, it may ask you to select fewer + files than *.cpp. Just do A-M and N-Z or something similar. + +3. SET THE INCLUDE PATH. + + Go into Options section of the Tools menu. Add the $WRAPPER_ROOT + directory to the default directory search path. This is necessary + since all ACE #include files refer to themselves via ace/Foo.h. + Then add $WRAPPER_ROOT\ace to the default library search path. + This means that you can now use relative paths for linking apps + with ace.lib. You may skip this step if you have set + Tools/Options/Directories/Include_Files to include $WRAPPER_ROOT. + +4. SET UP THE LINKER. + + You might want to link with the wsock32.lib into the ACE project, + as well, so that you don't have to include it with every + applications link setup. Do this by including wsock32.lib in the + project through Insert/Files_into_project. + + When building a DLL: In order to allow standard C library functions + to share common variables across DLL and exe boundaries, we must + ensure that both DLL and exe are using the same libraries. Go to + Build/Settings/C++/Category:Code_Generation. Set Use run-time + library to "Multithreaded DLL" or "Debug Multithreaded DLL" + depending on whether you're building a release or a debug version + respectively. + + When building a static lib: Go to + Build/Settings/C++/Category:Code_Generation and set run-time + library to "Debug Multithreaded" (or just "Multithreaded"). + +5. BUILD. + + Go to the Build menu and select "Build ace.{lib,DLL}". The first + time this happens it will rebuild all the dependencies. This may + take a while (i.e., 3 to 15 minutes, depending on whether you use + Samba, PC-NFS, native NTFS, etc.). The whole process will seem to + generate lots of errors and warning about not finding many UNIX + header files, etc. Just ignore these errors/warnings. They are + due to the lame MSVC++ compiler that doesn't pay attention to the + #ifdefs when computing the dependencies. Eventually, this process + will stop and from you won't have to rebuild the dependencies then + on (thank God...). + + At this point, the compiler should be happily chugging away on your + files. + +6. USING ace.lib. + + When the compilation is done, you should have a static or dynamic + library called ace.lib. You can use this to link with test + applications (such as those in the $WRAPPER_ROOT/examples directory). + This process is described below. + +Making test applications for Windows NT. + +0. CREATE THE PROJECT. + + As before, make a new project for each application. We've been + using Console Applications. Insert the appropriate .cpp files into + the project. + +1. SET THE INCLUDE PATH. + + In Build/Settings/C++/Category:Preprocessor, add $WRAPPER_ROOT to + "Additional include directories". If you've set the + Tools/Options/Directories/Include_Files to include $WRAPPER_ROOT, + then you don't need to do this. + +2. SET UP THE LINKER. + + You'll also need to tell MSVC++ what libraries to link with. In + Build/Settings/Link, add "$WRAPPER_ROOT/ace/Debug/ace.lib" to the + Object/library modules. If you've set + Tools/Options/Directories/Library_Files to include + $WRAPPER_ROOT/ace, you can just add "ace.lib" to the Object/library + modules instead of the complete path. + + When using ACE as a DLL: Go to + Build/Settings/C++/Category:Code_Generation. Set Use run-time + library to "Multithreaded DLL" or "Debug Multithreaded DLL" + depending on whether you're building a release or a debug version + respectively. + + When using ACE as a static lib: Go to + Build/Settings/C++/Category:Code_Generation and set the run-time + library to "Debug Multithreaded" (or just "Multithreaded"). + + If you're using WinSock, you will also need to add wsock32.lib to + this line if you haven't inserted into the ACE project already. + +3. BUILD. + + You should now be able to build the .exe. + +4. BUILDING ACE ON A WIN32 MACHINE THAT LACKS A NETWORK CARD + +You may want to run ACE on a non-networked machine. To do so, you must +install TCP/IP and configure it to ignore the absence of a network +card. This is one method: + + 1. Run Control Panel + 2. Choose Network from Control Panel + 3. Add Adapter: MS Loopback Adapter + 4. Configure MS Loopback Adapter with 802.3 (default) + 5. Add Software: TCP/IP Protocol + 6. Configure TCP/IP Protocol with a valid IP address and subnet mask. + Leave everything else at the default settings. + 7. Add Software: Workstation + 8. Exit and Restart System + 9. Run Control Panel again + 10. Choose Services from Control Panel + 11. The following services are not necessary and may + be set to Disabled Startup: + Alerter + Computer Browser + Net logon + Messanger + 12. Choose Network from Control Panel + 13. Confirm the following setup. This is all you need to run Orbix: + Installed Software: + Computer Browser + MS Loopback Adapter Driver + TCP/IP Protocol + Workstation + Installed Adapter Cards: + MS Loopback Adapter + +-------------------------------------------------- + +CLONING THE SOURCE TREE + + I typically like to support multiple platform builds using the +same ACE source tree. This idiom is supported by ACE using the +$(WRAPPER_ROOT)/bin/clone.c program. To build clone, perform the +following steps: + + % cd $WRAPPER_ROOT/bin + % make + % mv clone ~/bin + % rehash + +Then create a ./build subdirectory someplace (e.g., under +$WRAPPER_ROOT), and then invoke the top-level Makefile with the +"clone" target, e.g.: + + % cd $WRAPPER_ROOT + % mkdir build-SunOS5 + % cd build-SunOS5 + % make -f ../Makefile clone + % setenv WRAPPER_ROOT $cwd + % make + +This will establish a complete tree of links. When you do a make in +this directory you will be producing object code that is not stored in +the same place as the original source tree. This way, you can easily +build another platform in a parallel tree structure. + + *** VERY IMPORTANT! *** + +If you use the "clone trick" discussed above, make sure that the +symbolic links are correctly in place before starting the build. In +particular, if you plan to clone the tree, it is preferable to do so +before you start a build procedure on the original tree. This is +because the build procedure create object directories (.obj and +.shobj) and the cloning procedure will clone these directories also. +You would end up with links pointing to object files of another +platform. If you clone the tree after you've done a build on the +original tree, make sure to remove all ".obj", ".shobj" and (any other +files or directories) in all subdirectories before starting the build +on your cloned tree. + +BUILDING CORBA VERSIONS OF ACE + +Note that if you are compiling with IONA's Orbix implementation of +CORBA or Visigenix's version of ORBeline, you'll also need to set +ORBIX_ROOT to point to the root of the Orbix source tree and +ORBELINE_ROOT to point to the root of the ORBeline source tree. Since +many platforms don't have these CORBA tools the default for ACE does +*not* incorporate them. Thus, if you are compiling with Orbix or +ORBeline, make sure that you set the symbolic links for +$WRAPPER_ROOT/include/makeinclude/platform_macros.GNU and +$WRAPPER_ROOT/ace/config.h to point to the the config* and platform* +files that have "-orbix" in them! + +-------------------------------------------------- + +As the ACE wrappers become more widely used I hope developers will +pass back patches and improvements for other OS platforms and +compilers. If you have a problem compiling the ACE wrappers on other +platforms please let me know of any general solutions that may solve +this problem for others. However, I am primarily concerned with +supporting cfront 3.x variants of C++ and beyond, rather than older +versions that do not support features such as templates. diff --git a/Makefile b/Makefile new file mode 100644 index 00000000000..cbc1bc469ab --- /dev/null +++ b/Makefile @@ -0,0 +1,80 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Top-level Makefile for the ACE toolkit libraries, tests, and applications +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +INFO = README \ + VERSION + +DIRS = ace \ + apps \ + examples \ + netsvcs \ + performance-tests \ + tests + +CLONE = Makefile \ + ace \ + apps \ + bin \ + examples \ + include \ + netsvcs \ + performance-tests \ + tests + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + +# For the following to work you need to compile the +# $(WRAPPER_ROOT)/bin/clone.cpp file and install it in your ~/bin +# directory (or some place similar). + +clone: + @for dir in $(CLONE) ;\ + do \ + (clone -s $(WRAPPER_ROOT)/$$dir $$dir) \ + done + +RELEASE_FILES = ACE_wrappers/ACE-categories \ + ACE_wrappers/ACE-install.sh \ + ACE_wrappers/BIBLIOGRAPHY \ + ACE_wrappers/ChangeLog \ + ACE_wrappers/ChangeLog-96b \ + ACE_wrappers/ChangeLog-96a \ + ACE_wrappers/ChangeLog-95 \ + ACE_wrappers/ChangeLog-94 \ + ACE_wrappers/ChangeLog-93 \ + ACE_wrappers/FAQ \ + ACE_wrappers/INSTALL \ + ACE_wrappers/Makefile \ + ACE_wrappers/README \ + ACE_wrappers/VERSION \ + ACE_wrappers/ace \ + ACE_wrappers/apps \ + ACE_wrappers/bin \ + ACE_wrappers/examples \ + ACE_wrappers/include \ + ACE_wrappers/man \ + ACE_wrappers/netsvcs \ + ACE_wrappers/rpc++ \ + ACE_wrappers/performance-tests \ + ACE_wrappers/tests + +cleanrelease: + (make realclean; cd ..; /bin/rm -r ACE.tar.gz; tar cvf ACE.tar $(RELEASE_FILES); gzip -9 ACE.tar; chmod a+r ACE.tar.gz) + +release: + (cd ..; /bin/rm -r ACE.tar.gz; tar cvf ACE.tar $(RELEASE_FILES); gzip -9 ACE.tar; chmod a+r ACE.tar.gz) diff --git a/README b/README new file mode 100644 index 00000000000..07759a47364 --- /dev/null +++ b/README @@ -0,0 +1,615 @@ +[An HTML version of this README file is available at the following URL + +http://www.cs.wustl.edu/~schmidt/ACE.html. + +All software and documentation is available via both anonymous ftp and +the World Wide Web.] + +THE ADAPTIVE COMMUNICATION ENVIRONMENT (ACE) + +An Object-Oriented Network Programming Toolkit + +OVERVIEW OF ACE + +The ADAPTIVE Communication Environment (ACE) is a freely available +object-oriented network programming toolkit targeted for developers of +high-performance concurrent network applications and services. ACE +encapsulates the following user-level UNIX and Win32 (Windows NT and +Windows '95) OS facilities via portable, type-secure, C++ interfaces: + + . IPC mechanisms + -- Internet- and UNIX-domain sockets, TLI, Named Pipes + (for UNIX and Win32) and STREAM pipes + + . Event multiplexing + -- select(), poll(), and Win32 WaitForMultipleObjects + and I/O completion ports + + . Multi-threading and synchronization + -- Solaris threads, POSIX Pthreads, and Win32 threads + + . Explicit dynamic linking + -- dlopen/dlsym on UNIX and LoadLibrary/GetProc on Win32 + + . Memory-mapped files and shared memory management + -- BSD mmap(), SYSV shared memory, and Win32 shared memory. + + . System V IPC + -- shared memory, semaphores, message queues + + . Sun RPC + -- GNU rpc++, written by Michael Lipp + +In addition, ACE contains a higher-level network programming framework +that integrates and enhances the lower-level C++ wrappers. This +framework supports the dynamic configuration of concurrent network +daemons composed of application services. This framework contains the +following class categories: + + . The Reactor + -- Supports both Reactive and Proactive I/O + + . The Service Configurator + -- Support dynamic configuration of objects + + . The ADAPTIVE Service Executive + -- A user-level implementation of System V STREAMS, + which supports modular integration of + hierarchically-related communicaion services. + + . Shared malloc + -- A component for managing dynamically allocation + shared and local memory + + . Concurrency services + -- e.g., various forms of higher-level concurrency control + and synchronization mechanisms + + . Network services + -- e.g., distributed lock service, distributed naming + service, distributed logging service, distributed + routing service, and distributed time service + + . CORBA integration + -- Integrates ACE with CORBA implementations + (such as single-threaded and multi-threaded Orbix) + +ACE is currently being used in many commercial products including the +Bellcore Q.port ATM signaling software product, the Ericsson EOS +family of telecom switch monitoring applications, the Motorola Iridium +global mobile communications system, and enterprise-wide electronic +medical imaging systems for Kodak Health Imaging Systems and Siemens +medical engineering. + +OBTAINING ACE + +The current ACE release is provided as a tar file that is slightly +larger than 1.5 Meg compressed using GNU gzip. ACE may be obtained +electronically from http://www.cs.wustl.edu/~schmidt/ACE-obtain.html. +This release contains contains the source code, test drivers, and +example applications for C++ wrapper libraries and the higher-level +ACE network programming framework developed as part of the ADAPTIVE +project at the University of California, Irvine and at Washington +University. + +ACE DIRECTORY STRUCTURE + +The following subdirectories are included in C++_wrappers.tar.gz file: + + . ace -- the source code and binaries for C++ components (note that + all of these are at the same "level" in order to work around + deficiencies with Windows NT...) + . ASX -- higher-level C++ network programming + framework based on System V STREAMs + . Collections -- stacks, sets, strings, etc. + . Concurrency -- wrappers for Solaris, POSIX, and Win32 threads + . Connection -- implementations of connection + establishment patterns + . CORBA -- C++ wrappers that make it easier to work with CORBA + . Debugging -- C++ assert macro, dump methods, method call tracing, etc. + . IPC_SAP -- C++ wrappers around UNIX communication mechanisms + . Addr -- wrappers for various network addressing formats + . DEV_SAP -- wrapper for UNIX device I/O + . FIFO_SAP -- wrapper for FIFOS (named pipes) + . FILE_SAP -- wrapper for UNIX FILE *s + . IO_SAP -- wrapper for low-level serial-line I/O + . SOCK_SAP -- wrapper for BSD sockets + . SPIPE_SAP -- wrapper for SVR4 STREAM pipes and connld + . TLI_SAP -- wrapper for SVR4 TLI + . . UPIPE_SAP -- inter-thread communication mechanism + . Log_Msg -- library API for local/remote logging + . Memory + . Mem_Map -- wrapper for BSD mmap() memory mapped files + . Shared_Malloc -- shared memory malloc/free classes + . Shared_Memory -- wrapper for SysV/BSD shared memory + . Misc -- miscellaneous C++ wrappers for the GNU getopt utility, + Obstacks, GoF-style patterns + . Name_Service -- client-side classes for distributed name service + . OS -- encapsulation of UNIX and Win32 OS APIs + . Reactor -- a framework for OO event demultiplexing and + event handler dispatching + . Service_Configurator -- a framework for dynamically + linking/unlinking services into/from applications + at run-time + . System V IPC + . SV_Message_Queues -- wrapper for SysV message queues + . SV_Semaphores -- wrapper for SysV semaphores + . SV_Shared_Memory -- wrapper for SysV shared memory + . Timers -- High resolution timers and profile timers + . Token_Service -- client-side classes for distributed locking + . apps -- Several example applications written using the ACE wrappers + . Gateway -- application-level gateway + . Orbix-Examples -- examples of how to integrate Orbix with ACE + . gperf -- a perfect hash function generator program written in C++ + . Synch-Benchmarks -- benchmarks for OS IPC and synchronization mechanisms + . bin -- utility programs for building this release, in + particular, a set of scripts for automatically + generating manual pages from C++ class headers. + . examples -- programs that illustrate how to use ACE components + . man -- manual pages for ACE in nroff and HTML format + generated automatically by OSE class2man + . netsvcs -- network services + . clients -- test programs that exercise the ACE network services + . lib -- network services implemented using the general ACE service + framework: + . Client Logger -- client-side for distributed logging service + . Server Logger -- server-side for distributed logging service + . Name Server -- a distributed name service + . Token Server -- a distributed token service + . Time Server -- a distributed time service + . servers -- dynamically linkable main programs that + configure the services + . rpc++ -- C++ interface to Sun RPC developed by Michael Lipp + (mnl@dtro.e-technik.th-darmstadt.de). This code + is distributed "as is" (under the GNU GPL) and is + not part of the ACE release that I maintain. + . tests -- a suite of automated regression tests to exercise ACE features + +ACE DOCUMENTATION AND TUTORIALS + +Many of the C++ wrappers and higher-level components have been +described in issues of the C++ Report, as well as in proceedings of +the following journals, conferences, and workshops: + + . 4th IEEE International Conference on Software Reuse in + Orlando, Florida, April 1996. + . The SIGS OOP conference in Munich, Germany, February, 1996 + . The OOPSLA '95 conference in Austin, TX, October 1995 + . The ECOOP '95 conference in Aarhus, Denmark, June 1995 + . The SIGS Object Expo conference in New York, NY, June, 1995 + . The 1st USENIX Conference on Object-Oriented Technologies + in Monterey, CA, June, 1995 + . The SIGS OOP conference in Munich, Germany, February, 1995 + . The Winter USENIX General Conference in January, 1995 + . 3rd SIGS C++ World conference in November, 1994 + . The 9th ACM OOPSLA Conference held in October, 1994 + . The 1st Conference on the Pattern Languages of Programs, + August, 1994 + . The 6th USENIX C++ Conference, April, 1994 + . The 2nd IEEE International Workshop on Configurable Distributed + Systems, March, 1994 + . The 11th and 12th Annual Sun Users Group Conference in + December, 1993 and June, 1994 + . The 2nd SIGS C++ World conference, October, 1993 + . IEE Distributed Systems Engineering Journal, December 1994. + +A collection of white papers and tutorial handouts are included with +the release. The documentation is stored in the ACE-documentation +directory on wuarchive.wustl.edu (approximately 4 meg compressed). + +This directory contains postscript versions of various papers that +describe different aspects of ACE. You might want to read SUG-94.ps +first, since it gives an overview of the toolkit. + +Document Published in or presented at +-------- ---------------------------- +Acceptor-Connector.ps "Acceptor and Connector: Design Patterns for + Actively and Passively Initializing Network + Services." Presented at the EuroPLoP + workshop held in conjunction with the ECOOP + '95 conference, August 1995 + +ACE-concurrency.ps "An OO Encapsulation of Lightweight OS + Concurrency Mechanisms in the ACE Toolkit." + Washington University technical report WUCS-95-31. + +ACT.ps "Asynchronous Completion Token" submitted to + the ``3rd Pattern Languages of Programs + conference,'' Allerton Park, Illinois, + September, 1996. + +Active-Objects.ps "Active Object: an Object Behavioral Pattern + for Concurrent Programming," the proceedings + of the Pattern Languages of Programs Conference, + September 1995 + +Atomic_Op-94.ps "Transparently Parameterizing Synchronization + into a Concurrent Distributed Application", + C++ Report, July/August 1994 + +C++-report-col1.ps C++ Report Object Interconnections Column 1 +C++-report-col2.ps C++ Report Object Interconnections Column 2 +C++-report-col3.ps C++ Report Object Interconnections Column 3 +C++-report-col4.ps C++ Report Object Interconnections Column 4 +C++-report-col5.ps C++ Report Object Interconnections Column 5 +C++-report-col6.ps C++ Report Object Interconnections Column 6 +C++-report-col7.ps C++ Report Object Interconnections Column 7 + +C++-USENIX-94.ps "ASX: an Object-Oriented Framework for + Developing Distributed Applications," 6th + USENIX C++ Conference, April 1994 + +C++-world-93.ps "An Object-Oriented Framework for Developing + Network Server Daemons", 2nd C++ World + conference, Dallas, Texas, October 1993 + +C++-wrappers.ps "Systems Programming with C++ Wrappers: + Encapsulating Interprocess Communication + Services with Object-Oriented Interfaces", C++ + Report, September/October 1992 + +CACM-95.ps "Experience Using Design Patterns to Develop + Reuseable Object-Oriented Communication + Software," Communications of the ACM, Special + Issue on Object-Oriented Experiences, Vol. 38, + No. 10, October, 1995. + +COOTS-95.ps "Object-Oriented Components for High-speed + Network Programming," 1st USENIX Conference on + Object-Oriented Technologies, April 1995. + +COOTS-96.ps "Design and Performance of an Object-Oriented + Framework for Electronic Medical Imaging," + 2nd USENIX Conference on Object-Oriented + Technologies, June 1996. + +Connector.ps "A Design Pattern for Actively Initializing Network + Services," C++ Report, January 1996 + +daemon-design-94.ps "A Domain Analysis of Network Daemon Design + Dimensions", C++ Report, March/April 1994 + +DC-Locking.ps Double-Checked Locking, submitted to the ``3rd + Pattern Languages of Programs conference,'' + Allerton Park, Illinois, September, 1996. + +ECOOP-95.ps "Experiences Using Design Patterns to Evolve + System Software Across Diverse OS Platforms," + ECOOP '95 conference, August 1995 + +External-Polymorphism.ps "External Polymorphism: an Object Structural + Pattern for Transparently Extending Concrete + Data Types," submitted to the ``3rd Pattern + Languages of Programs conference,'' + Allerton Park, Illinois, September, 1996. + +EuroPLoP.ps Acceptor and Connector, Design Patterns for + Initializing Communication Services, + 1st European Conference on Pattern Languages + of Programs, Kloster Irsee, July, 1996. + +IPC_SAP-92.ps "IPC_SAP: An Object-Oriented Interface to + Interprocess Communication Services" C++ + Report, November/December 1992 + +JPDC-96.ps "The Performance of Alternative Threading + Architectures for Parallel Communication + Subsystems", Submitted to the Journal + of Parallel and Distributed Computing. + +PLoP-94.ps "Reactor: An Object Behavioral Pattern for + Concurrent Event Demultiplexing and Event + Handler Dispatching," Pattern Languages of + Programs Conference, August 1994 + +PLoP-95.ps "Half-Sync/Half-Async: A Pattern for Efficient + and Well-structured Concurrent I/O Systems." + Pattern Languages of Programs Conference, + September 1995 + +Reactor1-93.ps "The Reactor: An Object-Oriented Interface for + Event-Driven UNIX I/O Multiplexing (Part 1 of + 2)" C++ Report, February 1993 + +Reactor2-93.ps "The Object-Oriented Design and Implementation + of the Reactor: A C++ Wrapper for UNIX I/O + Multiplexing (Part 2 of 2)" C++ Report, + September/October 1993 + +IWCDS.ps "The Service Configurator Framework: An + Extensible Architecture for Dynamically + Configuring Concurrent, Multi-Service Network + Daemons", 2nd IEEE International Workshop on + Configurable Distributed Systems, March 1994 + +Service-Configurator.ps "Service Configurator," submitted to the ``3rd + Pattern Languages of Programs conference,'' + Allerton Park, Illinois, September, 1996. + +SIGCOMM-95.ps "AITPM: a Strategy for Integrating IP + with ATM," SIGCOMM '95, August, 1995. + +SIGCOMM-96.ps "Measuring the Performance of Communication + Middleware on High-Speed Networks," SIGCOMM + '96, August, 1996. + +SUG-94.ps "The ADAPTIVE Communication Environment: + An Object-Oriented Network Programming Toolkit + for Developing Communication Software", + 11th and 12th Sun Users Group Conference, + December 1993 and June 1994 + +TAPOS-95.ps "A System of Reusable Design Patterns for + Communication Software," The + Journal of Theory and Practice of Object + Systems Special Issue on Patterns and Pattern + Languages + +TSS-pattern.ps "Thread-Specific Storage: A Pattern for + Reducing Locking Overhead in Concurrent + Programs," submitted to the ``3rd Pattern + Languages of Programs conference,'' + Allerton Park, Illinois, September, 1996. + +I update these papers periodically to reflect changes to the ACE +architecture. Therefore, you might want to check the date on the +files to make sure that you have read the most recent versions of +these papers. + +ACE TUTORIALS + +I update these papers periodically to reflect changes to the ACE +architecture. Therefore, you might want to check the date on the +files to make sure that you have read the most recent versions of +these papers. + +There may not be enough space on this ftp server to store the +following tutorial handouts: + +OOCP-tutorial4.ps SIGS Object Expo, June 1995. + SIGS OOP '95 conference, February, 1995; + USENIX Winter Conference, January 1995; + +OONP-tutorial4.ps ECOOP conference, August 1995 + USENIX Conference on Object-Oriented Technologies, + June 1995; + 3rd SIGS C++ World conference, November, 1994; + 9th ACM OOPSLA conference, October 1994; + 6th USENIX C++ Conference, April 1994; + 2nd SIGS C++ World conference, October 1993; + +CORBA4.ps "Measuring the Performance of Object-Oriented + Components for High-speed Network Programming," + Object Expo, June 1995; + USENIX Conference on Object-Oriented + Technologies, June 1995 + HP Labs, June 1995 + +corba4.ps "An Overview of CORBA" + Washington University Distributed Operating + Systems class + +These handouts are available via WWW at URL: + +http://www.cs.wustl.edu/~schmidt/ + +as at wuarchive.wustl.edu in the directory /languages/c++/ACE. + +BUILDING AND INSTALLING ACE + +Please refer to the INSTALL file for information on how to build and +test the ACE wrappers. The overall ACE release is very large (~1 +Meg). Therefore, I'm sorry, but I will be unable to distribute the +ACE wrappers via email. The BIBLIOGRAPHY file contains information on +where to obtain articles that describe the ACE wrappers and the +ADAPTIVE system in more detail. + +The current release has been tested extensively on Sun workstations +running Sun OS 4.1.x and Solaris 2.x (on both SPARC and Intel +platforms) using Sun C++ 4.x and GNU G++ 2.7.x. The release has also +been ported to SCO UNIX, HP-UX, SGI, OSF/1, AIX, Linux, Windows NT and +Windows '95. I expect that major portions of the release will port +easily to other platforms. If you can help port ACE to other +platforms I'd appreciate it. + +ACE MAILING LIST + +A mailing list is available for discussing bug fixes, enhancements, +and porting issues regarding ACE. Please send mail to me at the +ace-users-request@cs.wustl.edu if you'd like to join the mailing list. + +COPYRIGHT INFORMATION FOR ACE + +ACE is copyrighted Douglas C. Schmidt and his research group at +Washington University. You are free to do anything you like with the +ACE source code such as including it in commercial software, as long +as you include this copyright statement along with code built using +ACE. + +You are under no obligation to freely redistribute any of your source +code that is built using ACE (be aware that rpc++ is distributed under +the GNU GPL, which has a different copyright policy). Please note, +however, that you may not do anything to the ACE code that will +prevent it from being distributed freely (such as copyrighting it). +Naturally, neither I nor my research group is responsible for any +problems caused by using ACE. + +My goal is to see ACE continue to evolve and become a more +comprehensive, robust, and well-documented C++ class library that is +freely available to researchers and developers. If you have any +improvements, suggestions, and or comments, I'd like to hear about it. + + Thanks, + + Douglas C. Schmidt + schmidt@cs.wustl.edu + +ACKNOWLEDGEMENTS + +ACE has been deeply influenced and improved by the following members +of my research group at Washington University: + +Aniruddha Gokhale +Tim Harrison +Prashant Jain +Irfan Pyarali +David Levine + +I would also like to thank all the following people who have also +contributed to ACE over the years: + +Paul Stephenson +Olaf Kruger +Ed Brown +Lee Baker +Alex Ranous +Mark Patton +Steffen Winther Sorensen for +Chris Cleeland +Tim Harrison +Troy Warner +Stacy Mahlon +Charles Eads +Mark Frutig +Todd Hoff +George +Aniruddha Gokhale +Irfan Pyarali +Prashant Jain +Brad Needham +Leslee Xu +Alex V. Maclinovsky +Detlef Becker +Bruce Worden +Chris Tarr +Bill Sears +Greg Lavendar +Steve Warwick +Mats Sundvall +Andreas Ueltschi +Nigel Hooke +Medhi Tabatabai +Stuart Powell +Bin Mu +Andrew McGowan +Ken Konecki +John P. Hearn +Giang Hoang Nguyen +Carlos Garcia Braschi +Jam Hamidi +Eric Vaughan +Karl-Heinz Dorn +Steve Ritter +Chandra Venkatapathy +Matt Stevens +Bob Vistica +David Trumble +John Morey +George Reynolds +Hans Rohnert +Alex V Maclinvosky +Todd Blanchard +Rob Clairmont +Christian Millour +Neil Cohen +Dieter Quehl +Reginald S. Perry +James Morris +Mark Seaborn +Phil Brooks +E. Jason Scheck +Daniel Proulx +Bill Tang +John Huchinson +Jack Erickson +Byron Walton +Bill Lear +Mark Zusman +Aurelio Nocerino +Walt Akers +Greg Baker +Alexandre Karev +Pramod Kumar Singh +Bryon Rigg +Brad Brown +Patty Genualdi +Eshel Liran +Mick Adams +Chris Eich +Mike Flinn +Audun Tornquist +Sandeep Joshi +Kirk Sinnard <1764@mn.lawson.lawson.com> +Bernd Hofner +Craig Perras +Kirk Sinnard +Matthew Newhook +Gerolf Wendland +Phil Mesnier +Ross Dargahi +Richard Orr +Rich Ryan +Jan Rychter +Tom Marrs <0002104588@mcimail.com> +Bob Olson +Jean-Francois Ripouteau +Ajit Sagar +Ashish Singhai +David Sames +Gonzalo Diethelm +Raj +Darrin +Steve Weismuller +Eric C. Newton +Andres Kruse +Ramesh Nagabushnam +Antonio Tortorici +Nigel Lowe +Tom Leith +Greg Wilson +Michael Fortinsky +Marco Sommerau +Gary Salsbery +Eric Beser +Alfred Keller +John Lu +James Mansion +Jesper S. M|ller +Chris Lahey +Michael R"uger +Istvan Buki +Greg Wilson +Jack Erickson +Garrett Conaty +Brad Flood +Marius Kjeldahl +Steve Huston +Eugene K. Plaude +Joseph DeAngelis +Kim Gillies +Luca Priorelli +Alan Stewart +Hani Yakan +William L. Gerecke +Craig Johnston +Pierre-Yves Duval +Rochi Febo Dommarco +Jonathan Biggar +Scott Shupe +Chuck Gehr +Avraham Nash +Padhu Ramalingam +Jay Denkberg +Ayman Farahat +Tilo Christ +Ari Erev + +I would particularly like to thank Paul Stephenson, who worked with me +at Ericsson and is now at ObjectSpace. Paul devised the recursive +Makefile scheme that underlies this distribution and also spent +countless hours with me discussing object-oriented techniques for +developing distributed application frameworks. + +Finally, I'd also like to thank Todd L. Montgomery +, fellow heavy metal head, for fulfilling his +quest to get ACE to compile with GCC! diff --git a/VERSION b/VERSION new file mode 100644 index 00000000000..210dc048c68 --- /dev/null +++ b/VERSION @@ -0,0 +1,4 @@ +This is version 4.0.32 + +All known bugs are fixed. If you have any problems with ACE, please +send email to Douglas C. Schmidt (schmidt@cs.wustl.edu). diff --git a/ace/ACE.cpp b/ace/ACE.cpp new file mode 100644 index 00000000000..3ce0ec93ccc --- /dev/null +++ b/ace/ACE.cpp @@ -0,0 +1,738 @@ +// ACE.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/IPC_SAP.h" +#include "ace/Time_Value.h" +#include "ace/Handle_Set.h" +#include "ace/ACE.h" +#include "ace/Thread_Manager.h" +#include "ace/Reactor.h" + +int +ACE::register_stdin_handler (ACE_Event_Handler *eh, + ACE_Reactor *reactor, + ACE_Thread_Manager *thr_mgr, + int flags) +{ +#if defined (ACE_WIN32) + return thr_mgr->spawn (&ACE::read_adapter, eh, flags); +#else + return reactor->register_handler (ACE_STDIN, eh, ACE_Event_Handler::READ_MASK); +#endif /* ACE_WIN32 */ +} + +// Used to read from non-socket ACE_HANDLEs in our own thread to work +// around Win32 limitations that don't allow us to select() on +// non-sockets (such as ACE_STDIN). This is commonly used in +// situations where the Reactor is used to demultiplex read events on +// ACE_STDIN on UNIX. Note that must be a subclass of +// . If the method of this event +// handler returns we default to reading from +// ACE_STDIN. + +void * +ACE::read_adapter (void *t) +{ + ACE_Event_Handler *this_ptr = (ACE_Event_Handler *) t; + ACE_HANDLE handle = this_ptr->get_handle (); + + if (handle == ACE_INVALID_HANDLE) + handle = ACE_STDIN; + + while (this_ptr->handle_input (handle) != -1) + continue; + + this_ptr->handle_close (handle, ACE_Event_Handler::READ_MASK); + return 0; +} + +const char * +ACE::execname (const char *old_name) +{ +#if defined (ACE_HAS_WIN32) + if (ACE_OS::strstr (old_name, ".exe") == 0) + { + char *new_name; + + ACE_NEW_RETURN (new_name, char[ACE_OS::strlen (old_name) + + ACE_OS::strlen (".exe") + + 1], -1); + char *end = new_name; + end = ACE::strecpy (new_name, old_name); + // Concatenate the .exe suffix onto the end of the executable. + ACE_OS::strcpy (end, ".exe"); + return new_name; + } +#endif /* ACE_HAS_WIN32 */ + return old_name; +} + +u_long +ACE::hash_pjw (const char *str) +{ + u_long hash = 0; + + for (const char *temp = str; *temp != 0; temp++) + { + hash = (hash << 4) + (*temp * 13); + + u_long g = hash & 0xf0000000; + + if (g) + { + hash ^= (g >> 24); + hash ^= g; + } + } + + return hash; +} + +char * +ACE::strenvdup (const char *str) +{ + ACE_TRACE ("ACE::strenvdup"); + + char *temp; + + if (str[0] == '$' + && (temp = ACE_OS::getenv (&str[1])) != 0) + return ACE_OS::strdup (temp); + else + return ACE_OS::strdup (str); +} + +int +ACE::ldfind (const char *filename, + char *pathname, + size_t maxlen) +{ + ACE_TRACE ("ACE::ldfind"); + if (ACE_OS::strchr (filename, ACE_DIRECTORY_SEPARATOR_CHAR) != 0) + { + // Use absolute pathname. + ACE_OS::strncpy (pathname, filename, maxlen); + return 0; + } + else + { + // Using LD_LIBRARY_PATH + char *ld_path = ACE_OS::getenv (ACE_LD_SEARCH_PATH); + + if (ld_path != 0 && (ld_path = ACE_OS::strdup (ld_path)) != 0) + { + // Look at each dynamic lib directory in the search path. + char *path_entry = ACE_OS::strtok (ld_path, + ACE_LD_SEARCH_PATH_SEPARATOR_STR); + + int result = 0; + + while (path_entry != 0) + { + if (ACE_OS::strlen (path_entry) + 1 + ACE_OS::strlen (filename) >= maxlen) + { + errno = ENOMEM; + result = -1; + break; + } + ACE_OS::sprintf (pathname, "%s%c%s", + path_entry, + ACE_DIRECTORY_SEPARATOR_CHAR, + filename); + + if (ACE_OS::access (pathname, R_OK) == 0) + break; + path_entry = ACE_OS::strtok (0, ACE_LD_SEARCH_PATH_SEPARATOR_STR); + } + + ACE_OS::free ((void *) ld_path); + return result; + } + } + + errno = ENOENT; + return -1; +} + +FILE * +ACE::ldopen (const char *filename, const char *type) +{ + ACE_TRACE ("ACE::ldopen"); + char buf[MAXPATHLEN]; + + if (ACE::ldfind (filename, buf, sizeof buf) == -1) + return 0; + else + return ACE_OS::fopen (buf, type); +} + +const char * +ACE::basename (const char *pathname, char delim) +{ + ACE_TRACE ("ACE::basename"); + const char *temp = ::strrchr (pathname, delim); + + if (temp == 0) + return pathname; + else + return temp + 1; +} + +// Miscellaneous static methods used throughout ACE. + +ssize_t +ACE::send_n (ACE_HANDLE handle, const void *buf, size_t len) +{ + ACE_TRACE ("ACE::send_n"); + size_t bytes_written; + int n; + + for (bytes_written = 0; bytes_written < len; bytes_written += n) + if ((n = ACE::send (handle, (const char *) buf + bytes_written, + len - bytes_written)) == -1) + return -1; + + return bytes_written; +} + +ssize_t +ACE::send_n (ACE_HANDLE handle, const void *buf, size_t len, int flags) +{ + ACE_TRACE ("ACE::send_n"); + size_t bytes_written; + int n; + + for (bytes_written = 0; bytes_written < len; bytes_written += n) + if ((n = ACE_OS::send (handle, (const char *) buf + bytes_written, + len - bytes_written, flags)) == -1) + return -1; + + return bytes_written; +} + +ssize_t +ACE::recv_n (ACE_HANDLE handle, void *buf, size_t len) +{ + ACE_TRACE ("ACE::recv_n"); + size_t bytes_read; + int n; + + for (bytes_read = 0; bytes_read < len; bytes_read += n) + if ((n = ACE::recv (handle, (char *) buf + bytes_read, + len - bytes_read)) == -1) + return -1; + else if (n == 0) + break; + + return bytes_read; +} + +ssize_t +ACE::recv_n (ACE_HANDLE handle, void *buf, size_t len, int flags) +{ + ACE_TRACE ("ACE::recv_n"); + size_t bytes_read; + int n; + + for (bytes_read = 0; bytes_read < len; bytes_read += n) + if ((n = ACE_OS::recv (handle, (char *) buf + bytes_read, + len - bytes_read, flags)) == -1) + return -1; + else if (n == 0) + break; + + return bytes_read; +} + + // Receive bytes into from (uses the + // system call on UNIX and the call on Win32). +ssize_t +ACE::read_n (ACE_HANDLE handle, + void *buf, + size_t len) +{ + ACE_TRACE ("ACE::read_n"); + + size_t bytes_read; + int n; + + for (bytes_read = 0; bytes_read < len; bytes_read += n) + if ((n = ACE_OS::read (handle, (char *) buf + bytes_read, + len - bytes_read)) == -1) + return -1; + else if (n == 0) + break; + + return bytes_read; +} + +// Receive bytes into from (uses the +// system call on UNIX and the call on Win32). + +ssize_t +ACE::write_n (ACE_HANDLE handle, + const void *buf, + size_t len) +{ + ACE_TRACE ("ACE::write_n"); + + size_t bytes_written; + int n; + + for (bytes_written = 0; bytes_written < len; bytes_written += n) + if ((n = ACE_OS::write (handle, (const char *) buf + bytes_written, + len - bytes_written)) == -1) + return -1; + + return bytes_written; +} + +// Format buffer into printable format. This is useful for debugging. +// Portions taken from mdump by J.P. Knight (J.P.Knight@lut.ac.uk) +// Modifications by Todd Montgomery. + +int +ACE::format_hexdump (char *buffer, int size, char *obuf, int obuf_sz) +{ + ACE_TRACE ("ACE::format_hexdump"); + + u_char c; + char textver[16 + 1]; + + int maxlen = (obuf_sz / 68) * 16; + + if (size > maxlen) + size = maxlen; + + int i; + + for (i = 0; i < (size >> 4); i++) + { + int j; + + for (j = 0 ; j < 16; j++) + { + c = buffer[(i << 4) + j]; + ::sprintf (obuf, "%02x ", c); + obuf += 3; + if (j == 7) + { + ::sprintf (obuf, " "); + obuf++; + } + textver[j] = (c < 0x20 || c > 0x7e) ? '.' : c; + } + + textver[j] = 0; + + ::sprintf (obuf, " %s\n", textver); + + while (*obuf != '\0') + obuf++; + } + + if (size % 16) + { + for (i = 0 ; i < size % 16; i++) + { + c = buffer[size - size % 16 + i]; + ::sprintf (obuf,"%02x ",c); + obuf += 3; + if (i == 7) + { + ::sprintf (obuf, " "); + obuf++; + } + textver[i] = (c < 0x20 || c > 0x7e) ? '.' : c; + } + + for (i = size % 16; i < 16; i++) + { + ::sprintf (obuf, " "); + obuf += 3; + textver[i] = ' '; + } + + textver[i] = 0; + ::sprintf (obuf, " %s\n", textver); + } + return size; +} + +// Returns the current timestamp in the form +// "hour:minute:second:microsecond." The month, day, and year are +// also stored in the beginning of the date_and_time array. Returns 0 +// if unsuccessful, else returns pointer to beginning of the "time" +// portion of . + +char * +ACE::timestamp (char date_and_time[], int date_and_timelen) +{ + ACE_TRACE ("ACE::timestamp"); + + if (date_and_timelen < 35) + { + errno = EINVAL; + return 0; + } + +#if defined (WIN32) + // @@ Jesper, I think Win32 supports all the UNIX versions below. + // Therefore, we can probably remove this WIN32 ifdef altogether. + SYSTEMTIME local; + ::GetLocalTime (&local); + + ACE_OS::sprintf (date_and_time, "%02d/%02d/%04d%02d.%02d.%02d.%06d", + (int) local.wMonth, // new, also the %02d in sprintf + (int) local.wDay, // new, also the %02d in sprintf + (int) local.wYear, // new, also the %02d in sprintf + (int) local.wHour, + (int) local.wMinute, + (int) local.wSecond, + (int) local.wMilliseconds * 1000); +#else // UNIX + char timebuf[26]; // This magic number is based on the ctime(3c) man page. + ACE_Time_Value cur_time = ACE_OS::gettimeofday (); + time_t secs = cur_time.sec (); + ACE_OS::ctime_r (&secs, timebuf, sizeof timebuf); + ACE_OS::strncpy (date_and_time, timebuf, date_and_timelen); + ACE_OS::sprintf (&date_and_time[19], ".%06d", cur_time.usec ()); +#endif /* WIN32 */ + date_and_time[26] = '\0'; + return &date_and_time[11]; +} + +// This function rounds the request to a multiple of the page size. + +size_t +ACE::round_to_pagesize (off_t len) +{ + ACE_TRACE ("ACE::round_to_pagesize"); + return (len + (ACE_PAGE_SIZE - 1)) & ~(ACE_PAGE_SIZE - 1); +} + +ACE_HANDLE +ACE::handle_timed_complete (ACE_HANDLE h, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE::handle_timed_complete"); + ACE_Handle_Set rd_handles; + ACE_Handle_Set wr_handles; + + rd_handles.set_bit (h); + wr_handles.set_bit (h); + + int n = ACE_OS::select (int (h) + 1, + rd_handles, + wr_handles, + 0, timeout); + // If we failed to connect within the time period allocated by the + // caller, then we fail (e.g., the remote host might have been too + // busy to accept our call). + if (n <= 0) + { + if (n == 0) + errno = ETIMEDOUT; + return ACE_INVALID_HANDLE; + } + // Check if the handle is ready for reading and the handle is *not* + // ready for writing, which may indicate a problem. But we need to + // make sure... +#if defined (ACE_HAS_TLI) + else if (rd_handles.is_set (h) && !wr_handles.is_set (h)) +#else + else if (rd_handles.is_set (h)) +#endif /* ACE_HAS_TLI */ + { + char dummy; + // The following recv() won't block provided that the + // ACE_NONBLOCK flag has not been turned off . + + n = ACE::recv (h, &dummy, 1, MSG_PEEK); + if (n <= 0) + { + if (n == 0) + errno = ECONNREFUSED; + return ACE_INVALID_HANDLE; + } + } + + // 1. The HANDLE is ready for writing or 2. recv() returned that + // there are data to be read, which indicates the connection was + // successfully established. + return h; +} + +ACE_HANDLE +ACE::handle_timed_open (ACE_Time_Value *timeout, + LPCTSTR name, + int flags, + int perms) +{ + ACE_TRACE ("ACE::handle_timed_open"); + + if (timeout != 0) + { + // Open the named pipe or file using non-blocking mode... + ACE_HANDLE handle = ACE_OS::open (name, + flags | ACE_NONBLOCK, + perms); + if (handle == ACE_INVALID_HANDLE + && (errno == EWOULDBLOCK + && (timeout->sec () > 0 || timeout->usec () > 0))) + // This expression checks if we were polling. + errno = ETIMEDOUT; + + return handle; + } + else + return ACE_OS::open (name, flags, perms); +} + +// Wait up to amount of time to accept a connection. + +int +ACE::handle_timed_accept (ACE_HANDLE listener, + ACE_Time_Value *timeout, + int restart) +{ + ACE_TRACE ("ACE::handle_timed_accept"); + // Make sure we don't bomb out on erroneous values. + if (listener == ACE_INVALID_HANDLE) + return -1; + + // Use the select() implementation rather than poll(). + ACE_Handle_Set rd_handle; + rd_handle.set_bit (listener); + + // We need a loop here if is enabled. + + for (;;) + { + switch (ACE_OS::select (int (listener) + 1, + rd_handle, 0, 0, + timeout)) + { + case -1: + if (errno == EINTR && restart) + continue; + else + return -1; + /* NOTREACHED */ + case 0: + if (timeout != 0 && timeout->sec() == 0 && timeout->usec() == 0) + errno = EWOULDBLOCK; + else + errno = ETIMEDOUT; + return -1; + /* NOTREACHED */ + case 1: + return 0; + /* NOTREACHED */ + default: + errno = EINVAL; + return -1; + /* NOTREACHED */ + } + } + /* NOTREACHED */ + return 0; +} + +// Bind socket to an unused port. + +int +ACE::bind_port (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE::bind_port"); + sockaddr_in sin; + const int MAX_SHORT = 65535; + static int upper_limit = MAX_SHORT; + int lower_limit = IPPORT_RESERVED; + int round_trip = upper_limit; + + ACE_OS::memset ((void *) &sin, 0, sizeof sin); + sin.sin_family = AF_INET; +#if defined (ACE_HAS_SIN_LEN) + sin.sin_family = sizeof sin; +#endif /* ACE_HAS_SIN_LEN */ + sin.sin_addr.s_addr = INADDR_ANY; + + for (;;) + { + sin.sin_port = htons (upper_limit); + + if (ACE_OS::bind (handle, (sockaddr *) &sin, sizeof sin) >= 0) + return 0; + else if (errno != EADDRINUSE) + return -1; + else + { + upper_limit--; + + /* Wrap back around when we reach the bottom. */ + if (upper_limit <= lower_limit) + upper_limit = MAX_SHORT; + + /* See if we have already gone around once! */ + if (upper_limit == round_trip) + { + errno = EAGAIN; + return -1; + } + } + } +} + +// Make the current process a UNIX daemon. This is based on Stevens +// code from APUE. + +int +ACE::daemonize (void) +{ + ACE_TRACE ("ACE::daemonize"); +#if !defined (ACE_WIN32) + pid_t pid; + + if ((pid = ACE_OS::fork ()) == -1) + return -1; + else if (pid != 0) + ACE_OS::exit (0); /* parent exits */ + + /* child continues */ + ACE_OS::setsid (); /* become session leader */ + + ACE_OS::chdir ("/"); /* change working directory */ + + ACE_OS::umask (0); /* clear our file mode creation mask */ + return 0; +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_WIN32 */ +} + +int +ACE::max_handles (void) +{ + ACE_TRACE ("ACE::set_handle_limit"); +#if defined (_SC_OPEN_MAX) + return ACE_OS::sysconf (_SC_OPEN_MAX); +#elif defined (RLIMIT_NOFILE) + rlimit rl; + ACE_OS::getrlimit (RLIMIT_NOFILE, &rl); + rl.rlim_cur; +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_WIN32 */ +} + +// Set the number of currently open handles in the process. +// +// If NEW_LIMIT == -1 set the limit to the maximum allowable. +// Otherwise, set it to be the value of NEW_LIMIT. + +int +ACE::set_handle_limit (int new_limit) +{ + ACE_TRACE ("ACE::set_handle_limit"); +#if defined (RLIMIT_NOFILE) + struct rlimit rl; + + int max_handles = ACE::max_handles (); + + if (new_limit < 0 || new_limit > max_handles) + rl.rlim_cur = max_handles; + else + rl.rlim_cur = new_limit; + + return ACE_OS::setrlimit (RLIMIT_NOFILE, &rl); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_WIN32 */ +} + +// Flags are file status flags to turn on. + +int +ACE::set_flags (ACE_HANDLE handle, int flags) +{ + ACE_TRACE ("ACE::set_fl"); +#if defined (ACE_WIN32) + switch (flags) + { + case ACE_NONBLOCK: + // nonblocking argument (1) + // blocking: (0) + { + u_long nonblock = 1; + return ACE_OS::ioctl (handle, FIONBIO, &nonblock); + } + default: + errno = ENOTSUP; + return -1; + } +#else + int val; + + if ((val = ACE_OS::fcntl (handle, F_GETFL, 0)) == -1) + return -1; + + val |= flags; /* turn on flags */ + + if (ACE_OS::fcntl (handle, F_SETFL, val) == -1) + return -1; + else + return 0; +#endif /* ACE_WIN32 */ +} + +// Flags are the file status flags to turn off. + +int +ACE::clr_flags (ACE_HANDLE handle, int flags) +{ + ACE_TRACE ("ACE::clr_fl"); + +#if defined (ACE_WIN32) + switch (flags) + { + case ACE_NONBLOCK: + // nonblocking argument (1) + // blocking: (0) + { + u_long nonblock = 0; + return ACE_OS::ioctl (handle, FIONBIO, &nonblock); + } + default: + errno = ENOTSUP; + return -1; + } +#else + int val; + + if ((val = ACE_OS::fcntl (handle, F_GETFL, 0)) == -1) + return -1; + + val &= ~flags; /* turn flags off */ + + if (ACE_OS::fcntl (handle, F_SETFL, val) == -1) + return -1; + else + return 0; +#endif /* ACE_WIN32 */ +} + +int +ACE::map_errno (int error) +{ + switch (error) + { +#if defined (ACE_WIN32) + case WSAEWOULDBLOCK: + return EAGAIN; // Same as UNIX errno EWOULDBLOCK. +#endif /* ACE_WIN32 */ + } + + return error; +} diff --git a/ace/ACE.h b/ace/ACE.h new file mode 100644 index 00000000000..36536b0a57d --- /dev/null +++ b/ace/ACE.h @@ -0,0 +1,237 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// ACE.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_ACE_H) +#define ACE_ACE_H + +#include "ace/OS.h" + +// Forward declarations. +class ACE_Time_Value; +class ACE_Thread_Manager; +class ACE_Reactor; +class ACE_Event_Handler; + +class ACE_Export ACE +{ + // = TITLE + // Contains value added ACE methods that extend the behavior + // of the UNIX and Win32 OS calls. + // + // = DESCRIPTION + // This class consolidates all these ACE static methods in a + // single place in order to manage the namespace better. These + // methods are put here rather than in ACE_OS in order to + // separate concerns. +public: + // = Network I/O functions that factor out differences between Win32 + // and UNIX. + static ssize_t recv (ACE_HANDLE handle, + void *buf, + size_t len, + int flags); + // Receive up to bytes into from (uses the + // call). + + static ssize_t recv (ACE_HANDLE handle, + void *buf, + size_t len); + // Receive up to bytes into from (uses the + // system call on UNIX and the call on Win32). + + static ssize_t send (ACE_HANDLE handle, + const void *buf, + size_t len, + int flags); + // Send up to bytes into from (uses the + // call). + + static ssize_t send (ACE_HANDLE handle, + const void *buf, + size_t len); + // Send up to bytes into from (uses the + // system call on UNIX and the call on Win32). + + // = Network I/O functions that recv and send exactly n bytes. + static ssize_t recv_n (ACE_HANDLE handle, + void *buf, + size_t len, + int flags); + // Receive bytes into from (uses the + // call). + + static ssize_t recv_n (ACE_HANDLE handle, + void *buf, + size_t len); + // Receive bytes into from (uses the + // system call on UNIX and the call on Win32). + + static ssize_t send_n (ACE_HANDLE handle, + const void *buf, + size_t len, + int flags); + // Receive bytes into from (uses the + // system call). + + static ssize_t send_n (ACE_HANDLE handle, + const void *buf, + size_t len); + // Receive bytes into from (uses the + // system call on UNIX and the call on Win32). + + // = File system I/O functions that encapsulate differences between + // UNIX and Win32 and also send and recv exactly n bytes. + static ssize_t read_n (ACE_HANDLE handle, + void *buf, + size_t len); + // Receive bytes into from (uses the + // system call on UNIX and the call on Win32). + + static ssize_t write_n (ACE_HANDLE handle, + const void *buf, + size_t len); + // Receive bytes into from (uses the + // system call on UNIX and the call on Win32). + + // = Functions that perform useful behavior related to establishing + // socket connections active and passively. + static int bind_port (ACE_HANDLE handle); + // Bind a new unused port to . + + static int handle_timed_accept (ACE_HANDLE listener, + ACE_Time_Value *timeout, + int restart); + // Wait up to amount of time to passively establish a + // connection. This method doesn't perform the , it just + // does the timed wait... + + static ACE_HANDLE handle_timed_complete (ACE_HANDLE listener, + ACE_Time_Value *timeout); + // Wait up to amount of time to complete an actively + // established non-blocking connection. + + // = Operations on HANDLEs. + + static ACE_HANDLE handle_timed_open (ACE_Time_Value *timeout, + LPCTSTR name, + int flags, + int perms); + // Wait up to amount of time to actively open a device. + // This method doesn't perform the , it just does the timed + // wait... + + static int set_flags (ACE_HANDLE handle, + int flags); + // Set flags associated with . + + static int clr_flags (ACE_HANDLE handle, + int flags); + // Clear flags associated with . + + static int set_handle_limit (int new_limit = -1); + // Reset the limit on the number of open handles. If == + // -1 set the limit to the maximum allowable. Otherwise, set it to + // be the value of . + + static int max_handles (void); + // Returns the maximum number of open handles currently permitted in + // this process. This maximum may be extended using + // . + + // = Miscelleous functions. + static size_t round_to_pagesize (off_t length); + // Rounds the request to a multiple of the page size. + + static int format_hexdump (char *buffer, int size, char *obuf, int obuf_sz); + // Format buffer into printable format. This is useful for + // debugging. + + static char *strenvdup (const char *str); + // Return a dynamically allocated duplicate of , substituting + // the environment variable if . Note that the + // pointer is allocated with and must be freed by + // + + static char *strecpy (char *s, const char *t); + // Copies to , returning a pointer to the end of the copied + // region (rather than the beginning, a la . + + static const char *execname (const char *pathname); + // On Win32 returns if it already ends in ".exe," + // otherwise returns a dynamically allocated buffer containing + // ".exe". Always returns on UNIX. + + static const char *basename (const char *pathname, char delim); + // Returns the "basename" of a . + + static char *timestamp (char date_and_time[], int time_len); + // Returns the current timestamp in the form + // "hour:minute:second:microsecond." The month, day, and year are + // also stored in the beginning of the date_and_time array. Returns + // 0 if unsuccessful, else returns pointer to beginning of the + // "time" portion of . + + static int daemonize (void); + // Become a daemon process. + + // = Methods for searching and opening shared libraries using + // relative naming. + static int ldfind (const char *filename, + char *pathname, + size_t maxlen); + // Finds the file either using absolute path or using + // ACE_LD_SEARCH_PATH (e.g., $LD_LIBRARY_PATH on UNIX or $PATH on + // Win32). + + static FILE *ldopen (const char *filename, const char *type); + // Uses to locate and open the appropriate and + // returns a pointer to the file, else it returns a NULL + // pointer. specifies how the file should be open. + + static u_long hash_pjw (const char *str); + // Computes the hash value of using the ``Hash PJW'' routine... + + static int map_errno (int error); + // Map troublesome win32 errno values to values that standard C + // strerr function understands. Thank you Microsoft. + + static void *read_adapter (void *event_handler); + // Used to read from non-socket ACE_HANDLEs in our own thread to + // work around Win32 limitations that don't allow us to select() on + // non-sockets (such as ACE_STDIN). This is commonly used in + // situations where the Reactor is used to demultiplex read events + // on ACE_STDIN on UNIX. Note that must be a + // subclass of . If the method of + // this event handler returns we default to + // reading from ACE_STDIN. + + static int register_stdin_handler (ACE_Event_Handler *eh, + ACE_Reactor *reactor, + ACE_Thread_Manager *thr_mgr, + int flags = THR_DETACHED); + // Abstracts away from the differences between Win32 and ACE with + // respect to reading from ACE_STDIN (which is non-select()'able on + // Win32. + +private: + ACE (void); + // Ensure we can't define an instance of this class... +}; + +#include "ace/ACE.i" + +#endif /* ACE_ACE_H */ diff --git a/ace/ACE.i b/ace/ACE.i new file mode 100644 index 00000000000..c8467a5cde9 --- /dev/null +++ b/ace/ACE.i @@ -0,0 +1,61 @@ +/* -*- C++ -*- */ +// $Id$ + +// ACE.i +#include "ace/Log_Msg.h" + +// Miscellaneous static methods used throughout ACE. + +inline ssize_t +ACE::send (ACE_HANDLE handle, const void *buf, size_t len) +{ + ACE_TRACE ("ACE::send"); + +#if defined (ACE_WIN32) + return ACE_OS::send (handle, (const char *) buf, len); +#elif defined (VXWORKS) + return ::write (handle, (char *) buf, len); +#else + return ::write (handle, (const char *) buf, len); +#endif /* ACE_WIN32 */ +} + +inline ssize_t +ACE::send (ACE_HANDLE handle, const void *buf, size_t len, int flags) +{ + ACE_TRACE ("ACE::send"); + return ACE_OS::send (handle, (const char *) buf, len, flags); +} + +inline ssize_t +ACE::recv (ACE_HANDLE handle, void *buf, size_t len) +{ + ACE_TRACE ("ACE::recv"); +#if defined (ACE_WIN32) + return ACE_OS::recv (handle, (char *) buf, len); +#else + return ACE_OS::read (handle, (char *) buf, len); +#endif /* ACE_WIN32 */ +} + +inline ssize_t +ACE::recv (ACE_HANDLE handle, void *buf, size_t len, int flags) +{ + ACE_TRACE ("ACE::recv"); + + return ACE_OS::recv (handle, (char *) buf, len, flags); +} + +inline char * +ACE::strecpy (char *s, const char *t) +{ + ACE_TRACE ("ACE::strecpy"); + register char *dscan = s; + register const char *sscan = t; + + while ((*dscan++ = *sscan++) != '\0') + continue; + + return dscan - 1; +} + diff --git a/ace/ARGV.cpp b/ace/ARGV.cpp new file mode 100644 index 00000000000..2c54a2e9c25 --- /dev/null +++ b/ace/ARGV.cpp @@ -0,0 +1,202 @@ +// ARGV.cpp +// $Id$ + +// Transforms a string BUF into an ARGV-style vector of strings. + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/ARGV.h" + +#if !defined (__ACE_INLINE__) +#include "ace/ARGV.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_ARGV) + +void +ACE_ARGV::dump (void) const +{ + ACE_TRACE ("ACE_ARGV::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "argc_ = %d", this->argc_)); + + for (size_t i = 0; i < this->argc_; i++) + ACE_DEBUG ((LM_DEBUG, "\nargv_[%i] = %s", i, this->argv_[i])); + + ACE_DEBUG ((LM_DEBUG, "\nbuf = %s\n")); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_ARGV::ACE_ARGV (char buf[], + int substitute_env_args) + : argv_ (0), + argc_ (0), + buf_ (0) +{ + ACE_TRACE ("ACE_ARGV::ACE_ARGV"); + + if (buf == 0) + return; + + char *cp = buf; + + // First pass: count arguments. + + // '#' is the start-comment token.. + while (*cp != '\0' && *cp != '#') + { + // Skip whitespace.. + while (isspace (*cp)) + cp++; + + // Increment count and move to next whitespace.. + if (*cp != '\0') + this->argc_++; + + // Grok quotes.... + if (*cp == '\'' || *cp == '"') + { + char quote = *cp; + + // Scan past the string.. + for (cp++; *cp != '\0' && *cp != quote; cp++) + continue; + + // '\0' implies unmatched quote.. + if (*cp == '\0') + { + ACE_ERROR ((LM_ERROR, + "unmatched %c detected\n", quote)); + this->argc_--; + break; + } + else + cp++; + } + else // Skip over non-whitespace.... + while (*cp != '\0' && !isspace (*cp)) + cp++; + } + + // Second pass: copy arguments.. + char arg[BUFSIZ]; + + // Make a new argv vector of argc + 1 elements. + ACE_NEW (this->argv_, char *[this->argc_ + 1]); + + for (size_t i = 0; i < this->argc_; i++) + { + // Skip whitespace.. + while (isspace (*buf)) + buf++; + + // Copy next argument and move to next whitespace.. + if (*buf == '\'' || *buf == '"') + { + char quote = *buf++; + + for (cp = arg; + *buf != '\0' && *buf != quote; + buf++, cp++) + if (cp - arg < sizeof arg) + *cp = *buf; + + *cp = '\0'; + if (*buf == quote) + buf++; + } + else + { + for (cp = arg; + *buf && !isspace (*buf); + buf++, cp++) + if (cp - arg < sizeof arg) + *cp = *buf; + *cp = '\0'; + } + + // Check for environment variable substitution here. + if (substitute_env_args) + this->argv_[i] = ACE::strenvdup (arg); + else + this->argv_[i] = ACE_OS::strdup (arg); + } + + this->argv_[this->argc_] = 0; +} + +ACE_ARGV::ACE_ARGV (char *argv[], + int substitute_env_args) + : argv_ (0), + argc_ (0), + buf_ (0) +{ + ACE_TRACE ("ACE_ARGV::ACE_ARGV"); + + if (argv == 0 || argv[0] == 0) + return; + + int buf_len = 0; + + // Determine the length of the buffer. + + for (int i = 0; argv[i] != 0; i++) + { + char *temp; + + // Account for environment variables. + if (substitute_env_args + && (argv[i][0] == '$' + && (temp = ACE_OS::getenv (&argv[i][1])) != 0)) + buf_len += ACE_OS::strlen (temp); + else + buf_len += ACE_OS::strlen (argv[i]); + + // Add one for the extra space between each string. + buf_len++; + } + + // Step through all argv params and copy each one into buf; separate + // each param with white space. + + ACE_NEW (this->buf_, char[buf_len]); + + char *end = this->buf_; + + for (int j = 0; argv[j] != 0; j++) + { + char *temp; + + // Account for environment variables. + if (substitute_env_args + && (argv[j][0] == '$' + && (temp = ACE_OS::getenv (&argv[j][1])) != 0)) + end = ACE::strecpy (end, temp); + else + end = ACE::strecpy (end, argv[j]); + + // Add white space and advance the pointer. + *end++ = ' '; + } + + // Null terminate the string. + *end = '\0'; +} + +// Free up the space allocated by the constructor.. + +ACE_ARGV::~ACE_ARGV (void) +{ + ACE_TRACE ("ACE_ARGV::~ACE_ARGV"); + if (this->argv_ == 0) + return; + + for (int i = 0; this->argv_[i] != 0; i++) + ACE_OS::free ((void *) this->argv_[i]); + + ACE_OS::free ((void *) this->argv_); + delete this->buf_; +} + diff --git a/ace/ARGV.h b/ace/ARGV.h new file mode 100644 index 00000000000..75f087a5155 --- /dev/null +++ b/ace/ARGV.h @@ -0,0 +1,80 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// ARGV.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_ARGUMENT_VECTOR_H) +#define ACE_ARGUMENT_VECTOR_H + +#include "ace/ACE.h" + +class ACE_Export ACE_ARGV + // = TITLE + // Transforms a string into an style vector of + // strings or an style vector of string , performing + // environment variable substitutions if necessary. +{ +public: + // = Initialization and termination. + ACE_ARGV (char buf[], int substitute_env_args = 1); + // Converts into an -style vector of strings. If + // is enabled then we'll substitute the + // environment variables for each $ENV encountered in the string. + + ACE_ARGV (char *argv[], int substitute_env_args = 1); + // Converts into a linear string. If + // is enabled then we'll substitute the environment variables for + // each $ENV encountered in the string. + + ~ACE_ARGV (void); + // Destructor. + + // = Accessor arguments. + char *operator[] (int index) const; + // Returns the th string in the ARGV array. + + char **argv (void) const; + // Returns the array. Caller should not delete this memory + // since the destructor will delete it. + + size_t argc (void) const; + // Returns . + + char *buf (void) const; + // Returns the . Caller should not delete this memory since + // the destructor will delete it. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + size_t argc_; + // Number of arguments in the ARGV array. + + char **argv_; + // The array of string arguments. + + char *buf_; + // Buffer containing the contents. +}; + +#if defined (__ACE_INLINE__) +#include "ace/ARGV.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_ARGUMENT_VECTOR_H */ diff --git a/ace/ARGV.i b/ace/ARGV.i new file mode 100644 index 00000000000..5bb9d242252 --- /dev/null +++ b/ace/ARGV.i @@ -0,0 +1,32 @@ +/* -*- C++ -*- */ +// $Id$ + +// ARGV.i + +ACE_INLINE size_t +ACE_ARGV::argc (void) const +{ + ACE_TRACE ("ACE_ARGV::argc"); + return this->argc_; +} + +ACE_INLINE char * +ACE_ARGV::buf (void) const +{ + ACE_TRACE ("ACE_ARGV::buf"); + return this->buf_; +} + +ACE_INLINE char * +ACE_ARGV::operator[] (int i) const +{ + ACE_TRACE ("ACE_ARGV::operator[]"); + return this->argv_[i]; +} + +ACE_INLINE char ** +ACE_ARGV::argv (void) const +{ + ACE_TRACE ("ACE_ARGV::argv"); + return this->argv_; +} diff --git a/ace/Acceptor.cpp b/ace/Acceptor.cpp new file mode 100644 index 00000000000..d6994d0e957 --- /dev/null +++ b/ace/Acceptor.cpp @@ -0,0 +1,969 @@ +// Acceptor.cpp +// $Id$ + +#if !defined (ACE_ACCEPTOR_C) +#define ACE_ACCEPTOR_C + +#define ACE_BUILD_DLL +#include "ace/ACE.h" +#include "ace/Acceptor.h" + +// Shorthand names. +#define SH SVC_HANDLER +#define PR_AC_1 ACE_PEER_ACCEPTOR_1 +#define PR_AC_2 ACE_PEER_ACCEPTOR_2 +#define PR_AD ACE_PEER_ACCEPTOR_ADDR + +ACE_ALLOC_HOOK_DEFINE(ACE_Acceptor) + +template void +ACE_Acceptor::dump (void) const +{ + ACE_TRACE ("ACE_Acceptor::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "reactor_ = %x", this->reactor_)); + this->peer_acceptor_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +template +ACE_Acceptor::operator ACE_PEER_ACCEPTOR & () const +{ + ACE_TRACE ("ACE_Acceptor::operator ACE_PEER_ACCEPTOR &"); + return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_; +} + +template ACE_Reactor * +ACE_Acceptor::reactor (void) const +{ + ACE_TRACE ("ACE_Acceptor::reactor"); + return this->reactor_; +} + +template void +ACE_Acceptor::reactor (ACE_Reactor *r) +{ + ACE_TRACE ("ACE_Acceptor::reactor"); + this->reactor_ = r; +} + +template ACE_PEER_ACCEPTOR & +ACE_Acceptor::acceptor (void) const +{ + ACE_TRACE ("ACE_Acceptor::acceptor"); + return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_; +} + +// Returns ACE_HANDLE of the underlying Acceptor_Strategy. + +template ACE_HANDLE +ACE_Acceptor::get_handle (void) const +{ + ACE_TRACE ("ACE_Acceptor::get_handle"); + return this->peer_acceptor_.get_handle (); +} + +// Initialize the appropriate strategies for creation, passive +// connection acceptance, and concurrency, and then register +// with the Reactor and listen for connection requests at the +// designated . + +template int +ACE_Acceptor::open (const PR_AD &local_addr, + ACE_Reactor *reactor) +{ + ACE_TRACE ("ACE_Acceptor::open"); + this->reactor_ = reactor; + + // Must supply a valid Reactor to Acceptor::open()... + + if (reactor == 0) + { + errno = EINVAL; + return -1; + } + + if (this->peer_acceptor_.open (local_addr, 1) == -1) + return -1; + + return this->reactor_->register_handler + (this, ACE_Event_Handler::READ_MASK); +} + +// Simple constructor. + +template +ACE_Acceptor::ACE_Acceptor (ACE_Reactor *reactor) + : reactor_ (reactor) +{ + ACE_TRACE ("ACE_Acceptor::ACE_Acceptor"); +} + +template +ACE_Acceptor::ACE_Acceptor (const PR_AD &addr, + ACE_Reactor *reactor) +{ + ACE_TRACE ("ACE_Acceptor::ACE_Acceptor"); + if (this->open (addr, reactor) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Acceptor::ACE_Acceptor")); +} + +template +ACE_Acceptor::~ACE_Acceptor (void) +{ + ACE_TRACE ("ACE_Acceptor::~ACE_Acceptor"); + this->handle_close (); +} + +template int +ACE_Acceptor::fini (void) +{ + ACE_TRACE ("ACE_Acceptor::fini"); + return ACE_Acceptor::handle_close (); +} + +// Hook called by the explicit dynamic linking facility. + +template int +ACE_Acceptor::init (int, char *[]) +{ + ACE_TRACE ("ACE_Acceptor::init"); + return -1; +} + +template int +ACE_Acceptor::info (char **strp, size_t length) const +{ + ACE_TRACE ("ACE_Acceptor::info"); + char buf[BUFSIZ]; + char addr_str[BUFSIZ]; + PR_AD addr; + + if (this->acceptor ().get_local_addr (addr) == -1) + return -1; + else if (addr.addr_to_string (addr_str, sizeof addr) == -1) + return -1; + + ACE_OS::sprintf (buf, "%s\t %s %s", + "ACE_Acceptor", addr_str, "# acceptor factory\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +template int +ACE_Acceptor::suspend (void) +{ + ACE_TRACE ("ACE_Acceptor::suspend"); + return this->reactor_->suspend_handler (this); +} + +template int +ACE_Acceptor::resume (void) +{ + ACE_TRACE ("ACE_Acceptor::resume"); + return this->reactor_->resume_handler (this); +} + +// Perform termination activities when is removed from the +// . + +template int +ACE_Acceptor::handle_close (ACE_HANDLE, + ACE_Reactor_Mask) +{ + ACE_TRACE ("ACE_Acceptor::handle_close"); + // Guard against multiple closes. + if (this->reactor_ != 0) + { + ACE_HANDLE handle = this->get_handle (); + + // We must use the obtained *before* we deleted the + // accept_strategy_... + + this->reactor_->remove_handler + (handle, ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL); + + this->reactor_ = 0; + } + return 0; +} + +// Bridge method for creating a SVC_HANDLER. The strategy for +// creating a SVC_HANDLER are configured into the Acceptor via it's +// . The default is to create a new SVC_HANDLER. +// However, subclasses can override this strategy to perform +// SVC_HANDLER creation in any way that they like (such as creating +// subclass instances of SVC_HANDLER, using a singleton, dynamically +// linking the handler, etc.). + +template SH * +ACE_Acceptor::make_svc_handler (void) +{ + ACE_TRACE ("ACE_Acceptor::make_svc_handler"); + return new SH; +} + +// Bridge method for accepting the new connection into the +// . The default behavior delegates to the +// PEER_ACCEPTOR::accept() in the Acceptor_Strategy. + +template int +ACE_Acceptor::accept_svc_handler (SH *svc_handler) +{ + ACE_TRACE ("ACE_Acceptor::accept_svc_handler"); + if (this->peer_acceptor_.accept (*svc_handler) == -1) + { + // Close down handler to avoid memory leaks. + svc_handler->close (0); + return -1; + } + else + return 0; +} + +// Bridge method for activating a with the appropriate +// concurrency strategy. The default behavior of this method is to +// activate the SVC_HANDLER by calling its open() method (which allows +// the SVC_HANDLER to define its own concurrency strategy). However, +// subclasses can override this strategy to do more sophisticated +// concurrency activations (such as creating the SVC_HANDLER as an +// "active object" via multi-threading or multi-processing). + +template int +ACE_Acceptor::activate_svc_handler (SH *svc_handler) +{ + ACE_TRACE ("ACE_Acceptor::activate_svc_handler"); + if (svc_handler->open ((void *) this) == -1) + { + svc_handler->close (0); + return -1; + } + else + return 0; +} + +// Template Method that makes a SVC_HANDLER (using the appropriate +// creation strategy), accept the connection into the SVC_HANDLER, and +// then activate the SVC_HANDLER. + +template int +ACE_Acceptor::handle_input (ACE_HANDLE listener) +{ + ACE_TRACE ("ACE_Acceptor::handle_input"); + ACE_Handle_Set conn_handle; + + // Default is "timeout (0, 0)," which means "poll." + ACE_Time_Value timeout; + + // Accept connections from clients (note that a loop is used for two + // reasons: + // + // 1. It allows us to accept all pending connections without an + // extra trip through the ACE_Reactor and without having to use + // non-blocking I/O... + // + // 2. It allows the TLI_SAP::ACE_Acceptor class to work correctly (don't + // ask -- TLI is *horrible*...)). + + // @@ What should we do if any of the substrategies fail? Right + // now, we just log an error message and return 0 (which means that + // the Acceptor remains registered with the Reactor)... + do + { + // Create a service handler, using the appropriate creation + // strategy. + + SH *svc_handler = this->make_svc_handler (); + + if (svc_handler == 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "make_svc_handler"), 0); + + // Accept connection into the Svc_Handler. + + else if (this->accept_svc_handler (svc_handler) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "accept_svc_handler"), 0); + + // Activate the using the designated concurrency + // strategy (note that this method becomes responsible for + // handling errors and freeing up the memory if things go + // awry...). + + else if (this->activate_svc_handler (svc_handler) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "activate_svc_handler"), 0); + + conn_handle.set_bit (listener); + } + // Now, check to see if there is another connection pending and + // break out of the loop if there is none. + while (ACE_OS::select (int (listener) + 1, conn_handle, 0, 0, &timeout) == 1); + return 0; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Strategy_Acceptor) + +template int +ACE_Strategy_Acceptor::suspend (void) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::suspend"); + + // First suspend the SVC_HANDLER's we've created. + if (this->scheduling_strategy_->suspend () == -1) + return -1; + else // Then suspend ourselves. + return ACE_Acceptor::suspend (); +} + +template int +ACE_Strategy_Acceptor::resume (void) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::resume"); + + // First resume ourselves. + if (ACE_Acceptor::suspend () == -1) + return -1; + else // Then resume the SVC_HANDLER's we've created. + return this->scheduling_strategy_->resume (); +} + +template void +ACE_Strategy_Acceptor::dump (void) const +{ + ACE_TRACE ("ACE_Strategy_Acceptor::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_Acceptor::dump (); + this->creation_strategy_->dump (); + ACE_DEBUG ((LM_DEBUG, "delete_creation_strategy_ = %d", delete_creation_strategy_)); + this->accept_strategy_->dump (); + ACE_DEBUG ((LM_DEBUG, "delete_accept_strategy_ = %d", delete_accept_strategy_)); + this->concurrency_strategy_->dump (); + ACE_DEBUG ((LM_DEBUG, "delete_concurrency_strategy_ = %d", delete_concurrency_strategy_)); + this->scheduling_strategy_->dump (); + ACE_DEBUG ((LM_DEBUG, "delete_scheduling_strategy_ = %d", delete_scheduling_strategy_)); + ACE_DEBUG ((LM_DEBUG, "\nservice_name_ = %s", this->service_name_)); + ACE_DEBUG ((LM_DEBUG, "\nservice_description_ = %s", this->service_description_)); + ACE_DEBUG ((LM_DEBUG, "\nservice_port_ = %d", this->service_port_)); + this->service_addr_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +template ACE_PEER_ACCEPTOR & +ACE_Strategy_Acceptor::acceptor (void) const +{ + ACE_TRACE ("ACE_Strategy_Acceptor::acceptor"); + return this->accept_strategy_->acceptor (); +} + +template +ACE_Strategy_Acceptor::operator ACE_PEER_ACCEPTOR & () const +{ + ACE_TRACE ("ACE_Strategy_Acceptor::operator ACE_PEER_ACCEPTOR &"); + return this->accept_strategy_->acceptor (); +} + +// Returns ACE_HANDLE of the underlying Acceptor_Strategy. + +template ACE_HANDLE +ACE_Strategy_Acceptor::get_handle (void) const +{ + ACE_TRACE ("ACE_Strategy_Acceptor::get_handle"); + return this->accept_strategy_->get_handle (); +} + +// Initialize the appropriate strategies for creation, passive +// connection acceptance, and concurrency, and then register +// with the Reactor and listen for connection requests at the +// designated . + +template int +ACE_Strategy_Acceptor::open (const PR_AD &local_addr, + ACE_Reactor *reactor, + ACE_Creation_Strategy *cre_s, + ACE_Accept_Strategy *acc_s, + ACE_Concurrency_Strategy *con_s, + ACE_Scheduling_Strategy *sch_s, + const char service_name[], + const char service_description[]) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::open"); + + if (this->service_name_ == 0 && service_name != 0) + this->service_name_ = ACE_OS::strdup (service_name); + if (this->service_description_ == 0 && service_description != 0) + this->service_description_ = ACE_OS::strdup (service_description); + + this->reactor (reactor); + + // Must supply a valid Reactor to Acceptor::open()... + if (reactor == 0) + { + errno = EINVAL; + return -1; + } + + // Initialize the creation strategy. + + if (cre_s == 0) + { + ACE_NEW_RETURN (cre_s, CREATION_STRATEGY, -1); + this->delete_creation_strategy_ = 1; + } + this->creation_strategy_ = cre_s; + + // Initialize the accept strategy. + + if (acc_s == 0) + { + ACE_NEW_RETURN (acc_s, ACCEPT_STRATEGY, -1); + this->delete_accept_strategy_ = 1; + } + this->accept_strategy_ = acc_s; + + if (this->accept_strategy_->open (local_addr, 1) == -1) + return -1; + + // Initialize the concurrency strategy. + + if (con_s == 0) + { + ACE_NEW_RETURN (con_s, CONCURRENCY_STRATEGY, -1); + this->delete_concurrency_strategy_ = 1; + } + this->concurrency_strategy_ = con_s; + + // Initialize the scheduling strategy. + + if (sch_s == 0) + { + ACE_NEW_RETURN (sch_s, SCHEDULING_STRATEGY, -1); + this->delete_scheduling_strategy_ = 1; + } + this->scheduling_strategy_ = sch_s; + + return this->reactor ()->register_handler (this, + ACE_Event_Handler::READ_MASK); +} + +// Simple constructor. + +template +ACE_Strategy_Acceptor::ACE_Strategy_Acceptor (const char service_name[], + const char service_description[]) + : creation_strategy_ (0), + accept_strategy_ (0), + concurrency_strategy_ (0), + scheduling_strategy_ (0), + delete_creation_strategy_ (0), + delete_accept_strategy_ (0), + delete_concurrency_strategy_ (0), + delete_scheduling_strategy_ (0), + service_name_ (0), + service_description_ (0) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::ACE_Strategy_Acceptor"); + + if (service_name != 0) + this->service_name_ = ACE_OS::strdup (service_name); + if (service_description != 0) + this->service_description_ = ACE_OS::strdup (service_description); +} + +template +ACE_Strategy_Acceptor::ACE_Strategy_Acceptor (const PR_AD &addr, + ACE_Reactor *reactor, + ACE_Creation_Strategy *cre_s, + ACE_Accept_Strategy *acc_s, + ACE_Concurrency_Strategy *con_s, + ACE_Scheduling_Strategy *sch_s, + const char service_name[], + const char service_description[]) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::ACE_Strategy_Acceptor"); + if (this->open (addr, reactor, cre_s, acc_s, con_s, sch_s, + service_name, service_description) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Strategy_Acceptor::ACE_Strategy_Acceptor")); +} + +// Perform termination activities when is removed from the +// . + +template int +ACE_Strategy_Acceptor::handle_close (ACE_HANDLE, + ACE_Reactor_Mask) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::handle_close"); + // Guard against multiple closes. + if (this->creation_strategy_ != 0) + { + ACE_HANDLE handle = this->get_handle (); + + if (this->delete_creation_strategy_) + delete this->creation_strategy_; + this->delete_creation_strategy_ = 0; + this->creation_strategy_ = 0; + + if (this->delete_accept_strategy_) + delete this->accept_strategy_; + this->delete_accept_strategy_ = 0; + this->accept_strategy_ = 0; + + if (this->delete_concurrency_strategy_) + delete this->concurrency_strategy_; + this->delete_concurrency_strategy_ = 0; + this->concurrency_strategy_ = 0; + + if (this->delete_scheduling_strategy_) + delete this->scheduling_strategy_; + this->delete_scheduling_strategy_ = 0; + this->scheduling_strategy_ = 0; + + // We must use the obtained *before* we deleted the + // accept_strategy_... + + this->reactor ()->remove_handler + (handle, ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL); + + this->reactor (0); + } + return 0; +} + +// Bridge method for creating a SVC_HANDLER. The strategy for +// creating a SVC_HANDLER are configured into the Acceptor via it's +// . The default is to create a new SVC_HANDLER. +// However, subclasses can override this strategy to perform +// SVC_HANDLER creation in any way that they like (such as creating +// subclass instances of SVC_HANDLER, using a singleton, dynamically +// linking the handler, etc.). + +template SH * +ACE_Strategy_Acceptor::make_svc_handler (void) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::make_svc_handler"); + return this->creation_strategy_->make_svc_handler (); +} + +// Bridge method for accepting the new connection into the +// . The default behavior delegates to the +// in the Acceptor_Strategy. + +template int +ACE_Strategy_Acceptor::accept_svc_handler (SH *svc_handler) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::accept_svc_handler"); + return this->accept_strategy_->accept_svc_handler (svc_handler); +} + +// Bridge method for activating a with the appropriate +// concurrency strategy. The default behavior of this method is to +// activate the SVC_HANDLER by calling its open() method (which allows +// the SVC_HANDLER to define its own concurrency strategy). However, +// subclasses can override this strategy to do more sophisticated +// concurrency activations (such as creating the SVC_HANDLER as an +// "active object" via multi-threading or multi-processing). + +template int +ACE_Strategy_Acceptor::activate_svc_handler (SH *svc_handler) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::activate_svc_handler"); + return this->concurrency_strategy_->activate_svc_handler + (svc_handler, (void *) this); +} + +template +ACE_Strategy_Acceptor::~ACE_Strategy_Acceptor (void) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::~ACE_Strategy_Acceptor"); + ACE_OS::free ((void *) this->service_name_); + ACE_OS::free ((void *) this->service_description_); + this->handle_close (); +} + +// Signal the server to shutdown gracefully. + +template int +ACE_Strategy_Acceptor::handle_signal (int, siginfo_t *, ucontext_t *) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::handle_signal"); + ACE_Service_Config::end_reactor_event_loop (); + return 0; +} + +template int +ACE_Strategy_Acceptor::info (char **strp, + size_t length) const +{ + ACE_TRACE ("ACE_Strategy_Acceptor::info"); + char buf[BUFSIZ]; + char service_addr_str[BUFSIZ]; + PR_AD addr; + + if (this->acceptor ().get_local_addr (addr) == -1) + return -1; + else if (addr.addr_to_string (service_addr_str, sizeof addr) == -1) + return -1; + + // @@ Should add the protocol in... + ACE_OS::sprintf (buf, "%s\t %s #%s\n", + this->service_name_, + service_addr_str, + this->service_description_); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +template int +ACE_Strategy_Acceptor::fini (void) +{ + ACE_TRACE ("ACE_Strategy_Acceptor::fini"); + return this->ACE_Strategy_Acceptor::handle_close (); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Oneshot_Acceptor) + +template void +ACE_Oneshot_Acceptor::dump (void) const +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "reactor_ = %x", this->reactor_)); + ACE_DEBUG ((LM_DEBUG, "\nsvc_handler_ = %x", this->svc_handler_)); + ACE_DEBUG ((LM_DEBUG, "\nrestart_ = %d", this->restart_)); + this->peer_acceptor_.dump (); + ACE_DEBUG ((LM_DEBUG, "delete_concurrency_strategy_ = %d", + delete_concurrency_strategy_)); + this->concurrency_strategy_->dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +template int +ACE_Oneshot_Acceptor::open (const PR_AD &addr, + ACE_Reactor *reactor, + ACE_Concurrency_Strategy *con_s) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::open"); + this->reactor (reactor); + + // Initialize the concurrency strategy. + + if (con_s == 0) + { + ACE_NEW_RETURN (con_s, ACE_Concurrency_Strategy, -1); + this->delete_concurrency_strategy_ = 1; + } + this->concurrency_strategy_ = con_s; + + // Reuse the addr, even if it is already in use...! + return this->peer_acceptor_.open (addr, 1); +} + +template +ACE_Oneshot_Acceptor::ACE_Oneshot_Acceptor (void) + : delete_concurrency_strategy_ (0), + reactor_ (0) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::ACE_Oneshot_Acceptor"); +} + +template +ACE_Oneshot_Acceptor::ACE_Oneshot_Acceptor (const PR_AD &addr, + ACE_Reactor *reactor, + ACE_Concurrency_Strategy *cs) + : delete_concurrency_strategy_ (0) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::ACE_Oneshot_Acceptor"); + if (this->open (addr, reactor, cs) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", + "ACE_Oneshot_Acceptor::ACE_Oneshot_Acceptor")); +} + +template +ACE_Oneshot_Acceptor::~ACE_Oneshot_Acceptor (void) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::~ACE_Oneshot_Acceptor"); + this->handle_close (); +} + +template int +ACE_Oneshot_Acceptor::handle_close (ACE_HANDLE, + ACE_Reactor_Mask) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::handle_close"); + // Guard against multiple closes. + if (this->concurrency_strategy_ != 0) + { + if (this->delete_concurrency_strategy_) + delete this->concurrency_strategy_; + this->delete_concurrency_strategy_ = 0; + this->concurrency_strategy_ = 0; + + // Note that if we aren't actually registered with the + // ACE_Reactor then it's ok for this call to fail... + + this->reactor_ && this->reactor_->remove_handler (this, + ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL); + + this->reactor_ = 0; + + if (this->peer_acceptor_.close () == -1) + ACE_ERROR ((LM_ERROR, "close\n")); + } + return 0; +} + +template int +ACE_Oneshot_Acceptor::handle_timeout (const ACE_Time_Value &tv, + const void *arg) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::handle_timeout"); + errno = ETIMEDOUT; + this->svc_handler_->handle_timeout (tv, arg); + + // Since we aren't necessarily registered with the Reactor, don't + // bother to check the return value here... + this->reactor_ && this->reactor_->remove_handler + (this, ACE_Event_Handler::READ_MASK); + return 0; +} + +template int +ACE_Oneshot_Acceptor::cancel (void) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::cancel"); + return this->reactor_ && this->reactor_->cancel_timer (this); +} + +template int +ACE_Oneshot_Acceptor::register_handler (SH *svc_handler, + const ACE_Synch_Options &synch_options, + int restart) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::register_handler"); + // Can't do this if we don't have a Reactor. + if (this->reactor_ == 0) + return -1; + else + { + this->svc_handler_ = svc_handler; + this->restart_ = restart; + ACE_Time_Value *tv = (ACE_Time_Value *) synch_options.time_value (); + + if (tv != 0 + && this->reactor_->schedule_timer (this, synch_options.arg (), + *tv) == 0) + return -1; + else + return this->reactor_->register_handler (this, + ACE_Event_Handler::READ_MASK); + } +} + +// Bridge method for activating a with the appropriate +// concurrency strategy. The default behavior of this method is to +// activate the SVC_HANDLER by calling its open() method (which allows +// the SVC_HANDLER to define its own concurrency strategy). However, +// subclasses can override this strategy to do more sophisticated +// concurrency activations (such as creating the SVC_HANDLER as an +// "active object" via multi-threading or multi-processing). + +template int +ACE_Oneshot_Acceptor::activate_svc_handler (SH *svc_handler) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::activate_svc_handler"); + return this->concurrency_strategy_->activate_svc_handler + (svc_handler, (void *) this); +} + +// Factors out the code shared between the and +// methods. + +template int +ACE_Oneshot_Acceptor::shared_accept (SH *svc_handler, + PR_AD *remote_addr, + ACE_Time_Value *timeout, + int restart) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::shared_accept"); + if (svc_handler == 0) + return -1; + + // Accept connection into the Svc_Handler. + else if (this->peer_acceptor_.accept (*svc_handler, remote_addr, + timeout, restart) == -1) + { + // Check whether we just timed out or whether we failed... + if (!(errno == EWOULDBLOCK || errno == ETIMEDOUT)) + // Close down handler to avoid memory leaks. + svc_handler->close (0); + return -1; + } + // Activate the using the designated concurrency + // strategy (note that this method becomes responsible for + // handling errors and freeing up the memory if things go + // awry...) + else + return this->activate_svc_handler (svc_handler); +} + +// Make a SVC_HANDLER, accept the connection into the SVC_HANDLER, and +// then activate the SVC_HANDLER. Note that SVC_HANDLER::open() +// decides what type of concurrency strategy to use. + +template int +ACE_Oneshot_Acceptor::accept (SH *svc_handler, + PR_AD *remote_addr, + const ACE_Synch_Options &synch_options, + int restart) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::accept"); + // Note that if timeout == ACE_Time_Value (x, y) where (x > 0 || y > + // 0) then this->connector_.connect() will block synchronously. If + // is set then we don't want this to happen (since we + // want the ACE_Reactor to do the timeout asynchronously). + // Therefore, we'll force this->connector_ to use ACE_Time_Value (0, + // 0) in this case... + + ACE_Time_Value *timeout; + int use_reactor = synch_options[ACE_Synch_Options::USE_REACTOR]; + + if (use_reactor) + timeout = (ACE_Time_Value *) &ACE_Time_Value::zero; + else + timeout = (ACE_Time_Value *) synch_options.time_value (); + + if (this->shared_accept (svc_handler, remote_addr, timeout, restart) == -1) + { + if (use_reactor && errno == EWOULDBLOCK) + // We couldn't accept right away, so let's wait in the ACE_Reactor. + this->register_handler (svc_handler, synch_options, restart); + return -1; + } + return 0; +} + +// Accepts one pending connection from a client (since we're the +// "oneshot" Acceptor). + +template int +ACE_Oneshot_Acceptor::handle_input (ACE_HANDLE listener) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::handle_input"); + int result = 0; + + // Cancel any timer that might be pending. + this->cancel (); + + if (this->shared_accept (this->svc_handler_, 0, 0, this->restart_) == -1) + result = -1; + if (this->reactor_ && this->reactor_->remove_handler + (this, ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL) == -1) + result = -1; + return result; +} + +// Hook called by the explicit dynamic linking facility. + +template int +ACE_Oneshot_Acceptor::init (int, char *[]) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::init"); + return -1; +} + +template int +ACE_Oneshot_Acceptor::fini (void) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::fini"); + return this->handle_close (); +} + +template int +ACE_Oneshot_Acceptor::info (char **strp, + size_t length) const +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::info"); + char buf[BUFSIZ]; + char addr_str[BUFSIZ]; + PR_AD addr; + + if (this->peer_acceptor_.get_local_addr (addr) == -1) + return -1; + else if (addr.addr_to_string (addr_str, sizeof addr) == -1) + return -1; + + ACE_OS::sprintf (buf, "%s\t %s %s", "ACE_Oneshot_Acceptor", + addr_str, "#oneshot acceptor factory\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +template int +ACE_Oneshot_Acceptor::suspend (void) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::suspend"); + return this->reactor_ && this->reactor_->suspend_handler (this); +} + +template int +ACE_Oneshot_Acceptor::resume (void) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::resume"); + return this->reactor_ && this->reactor_->resume_handler (this); +} + +// Returns ACE_HANDLE of the underlying peer_acceptor. + +template ACE_HANDLE +ACE_Oneshot_Acceptor::get_handle (void) const +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::get_handle"); + return this->peer_acceptor_.get_handle (); +} + +template ACE_PEER_ACCEPTOR & +ACE_Oneshot_Acceptor::acceptor (void) const +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::acceptor"); + return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_; +} + +template +ACE_Oneshot_Acceptor::operator ACE_PEER_ACCEPTOR & () const +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::operator ACE_PEER_ACCEPTOR &"); + return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_; +} + +template ACE_Reactor * +ACE_Oneshot_Acceptor::reactor (void) const +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::reactor"); + return this->reactor_; +} + +template void +ACE_Oneshot_Acceptor::reactor (ACE_Reactor *r) +{ + ACE_TRACE ("ACE_Oneshot_Acceptor::reactor"); + this->reactor_ = r; +} + +#undef SH +#undef PR_AC_1 +#undef PR_AC_2 +#undef PR_AD +#endif /* ACE_ACCEPTOR_C */ diff --git a/ace/Acceptor.h b/ace/Acceptor.h new file mode 100644 index 00000000000..9b9ab8410bf --- /dev/null +++ b/ace/Acceptor.h @@ -0,0 +1,479 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Acceptor.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_ACCEPTOR_H) +#define ACE_ACCEPTOR_H + +#include "ace/Service_Config.h" +#include "ace/Service_Object.h" +#include "ace/Svc_Handler.h" +#include "ace/Strategies.h" + +template +class ACE_Acceptor : public ACE_Service_Object + // = TITLE + // Abstract factory for creating a service handler + // (SVC_HANDLER), accepting into the SVC_HANDLER, and + // activating the SVC_HANDLER. + // + // = DESCRIPTION + // Implements the basic strategy for passively establishing + // connections with clients. An ACE_Acceptor is parameterized + // by concrete types that conform to the interfaces of + // PEER_ACCEPTOR and SVC_HANDLER. The PEER_ACCEPTOR is + // instantiated with a transport mechanism that passively + // establishes connections. The SVC_HANDLER is instantiated + // with a concrete type that performs the application-specific + // service. An ACE_Acceptor inherits from ACE_Service_Object, + // which in turn inherits from ACE_Event_Handler. This enables + // the ACE_Reactor to dispatch the ACE_Acceptor's handle_input + // method when connection events occur. The handle_input method + // performs the ACE_Acceptor's default creation, connection + // establishment, and service activation strategies. These + // strategies can be overridden by subclasses individually or as + // a group. +{ +public: + // = Initialization and termination methods. + ACE_Acceptor (ACE_Reactor * = 0); + // "Do-nothing" constructor. + + ACE_Acceptor (const ACE_PEER_ACCEPTOR_ADDR &local_addr, + ACE_Reactor * = ACE_Service_Config::reactor ()); + // Initialize and register with the Reactor and listen for + // connection requests at the designated . + + int open (const ACE_PEER_ACCEPTOR_ADDR &, + ACE_Reactor * = ACE_Service_Config::reactor ()); + // Initialize and register with the Reactor and listen for + // connection requests at the designated . + + virtual ~ACE_Acceptor (void); + // Close down the Acceptor's resources. + + virtual operator ACE_PEER_ACCEPTOR &() const; + // Return the underlying PEER_ACCEPTOR object. + + virtual ACE_PEER_ACCEPTOR &acceptor (void) const; + // Return the underlying PEER_ACCEPTOR object. + + ACE_Reactor *reactor (void) const; + // Get the underlying Reactor *. + + void reactor (ACE_Reactor *); + // Set the underlying Reactor *. + + virtual ACE_HANDLE get_handle (void) const; + // Returns the listening acceptor's . + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + // = The following three methods define the Acceptor's strategies + // for creating, accepting, and activating SVC_HANDLER's, + // respectively. + + virtual SVC_HANDLER *make_svc_handler (void); + // Bridge method for creating a SVC_HANDLER. The default is to + // create a new SVC_HANDLER. However, subclasses can override this + // policy to perform SVC_HANDLER creation in any way that they like + // (such as creating subclass instances of SVC_HANDLER, using a + // singleton, dynamically linking the handler, etc.). + + virtual int accept_svc_handler (SVC_HANDLER *svc_handler); + // Bridge method for accepting the new connection into the + // . The default behavior delegates to the + // PEER_ACCEPTOR::accept. + + virtual int activate_svc_handler (SVC_HANDLER *svc_handler); + // Bridge method for activating a with the appropriate + // concurrency strategy. The default behavior of this method is to + // activate the SVC_HANDLER by calling its open() method (which + // allows the SVC_HANDLER to define its own concurrency strategy). + // However, subclasses can override this strategy to do more + // sophisticated concurrency activations (such as making the + // SVC_HANDLER as an "active object" via multi-threading or + // multi-processing). + + // = Demultiplexing hooks. + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::RWE_MASK); + // Perform termination activities when is removed from the + // . + + virtual int handle_input (ACE_HANDLE); + // Accepts all pending connections from clients, and creates and + // activates SVC_HANDLERs. + + // = Dynamic linking hooks. + virtual int init (int argc, char *argv[]); + // Default version does no work and returns -1. Must be overloaded + // by application developer to do anything meaningful. + + virtual int fini (void); + // Calls . + + virtual int info (char **buf, size_t) const; + // Default version returns address info in . + + // = Service management hooks. + virtual int suspend (void); + // This method calls . + + virtual int resume (void); + // This method calls . + +private: + ACE_Reactor *reactor_; + // Event demultiplexer associated with this object. + + ACE_PEER_ACCEPTOR peer_acceptor_; + // Concrete factory for accepting connections from clients... +}; + +template +class ACE_Strategy_Acceptor : public ACE_Acceptor + // = TITLE + // Abstract factory for creating a service handler + // (SVC_HANDLER), accepting into the SVC_HANDLER, and activating + // the SVC_HANDLER. + // + // = DESCRIPTION + // Implements a flexible and extensible set of strategies for + // passively establishing connections with clients. There are + // three main strategies: (1) creating a SVC_HANDLER, (2) + // passively accepting a new connection from a client into the + // SVC_HANDLER, and (3) activating the SVC_HANDLER with a + // particular concurrency mechanism. +{ +public: + // = Initialization and termination methods. + ACE_Strategy_Acceptor (const char service_name[] = 0, + const char service_description[] = 0); + // Default constructor. + + ACE_Strategy_Acceptor (const ACE_PEER_ACCEPTOR_ADDR &local_addr, + ACE_Reactor * = ACE_Service_Config::reactor (), + ACE_Creation_Strategy * = 0, + ACE_Accept_Strategy * = 0, + ACE_Concurrency_Strategy * = 0, + ACE_Scheduling_Strategy * = 0, + const char service_name[] = 0, + const char service_description[] = 0); + // Initialize the appropriate strategies for creation, passive + // connection acceptance, and concurrency, and then register + // with the Reactor and listen for connection requests at the + // designated . + + int open (const ACE_PEER_ACCEPTOR_ADDR &, + ACE_Reactor * = ACE_Service_Config::reactor (), + ACE_Creation_Strategy * = 0, + ACE_Accept_Strategy * = 0, + ACE_Concurrency_Strategy * = 0, + ACE_Scheduling_Strategy * = 0, + const char service_name[] = 0, + const char service_description[] = 0); + // Initialize the appropriate strategies for creation, passive + // connection acceptance, and concurrency, and then register + // with the Reactor and listen for connection requests at the + // designated . + + virtual ~ACE_Strategy_Acceptor (void); + // Close down the Strategy_Acceptor's resources. + + virtual operator ACE_PEER_ACCEPTOR &() const; + // Return the underlying PEER_ACCEPTOR object. + + virtual ACE_PEER_ACCEPTOR &acceptor (void) const; + // Return the underlying PEER_ACCEPTOR object. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + // = Service management hooks. + + virtual int suspend (void); + // This method delegates to the 's + // method. + + virtual int resume (void); + // This method delegates to the 's + // method. + + virtual int fini (void); + // Calls when dynamically unlinked. + + virtual int info (char **buf, size_t) const; + // Default version returns address info in . + + // = The following three methods define the 's strategies + // for creating, accepting, and activating 's, + // respectively. + + virtual SVC_HANDLER *make_svc_handler (void); + // Bridge method for creating a . The strategy for + // creating a are configured into the Acceptor via + // it's . The default is to create a new + // . However, subclasses can override this policy to + // perform creation in any way that they like (such as + // creating subclass instances of , using a singleton, + // dynamically linking the handler, etc.). + + virtual int accept_svc_handler (SVC_HANDLER *svc_handler); + // Bridge method for accepting the new connection into the + // . The default behavior delegates to the + // in the . + + virtual int activate_svc_handler (SVC_HANDLER *svc_handler); + // Bridge method for activating a with the appropriate + // concurrency strategy. The default behavior of this method is to + // activate the by calling its method (which + // allows the to define its own concurrency strategy). + // However, subclasses can override this strategy to do more + // sophisticated concurrency activations (such as creating the + // as an "active object" via multi-threading or + // multi-processing). + + // = Demultiplexing hooks. + virtual ACE_HANDLE get_handle (void) const; + // Returns the listening acceptor's . + + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::RWE_MASK); + // Perform termination activities when is removed from the + // . + + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + // Handle SIGINT. + + // = These data members are "logically private" but are put in the + // protected part in case subclasses want to access them. + + // = Define some useful typedefs. + typedef ACE_Creation_Strategy CREATION_STRATEGY; + typedef ACE_Accept_Strategy ACCEPT_STRATEGY; + typedef ACE_Concurrency_Strategy CONCURRENCY_STRATEGY; + typedef ACE_Scheduling_Strategy SCHEDULING_STRATEGY; + + // = Strategy objects. + + CREATION_STRATEGY *creation_strategy_; + // Creation strategy for an Acceptor. + + int delete_creation_strategy_; + // 1 if created the creation strategy and thus should + // delete it, else 0. + + ACCEPT_STRATEGY *accept_strategy_; + // Accept strategy for an . + + int delete_accept_strategy_; + // 1 if created the accept strategy and thus should delete + // it, else 0. + + CONCURRENCY_STRATEGY *concurrency_strategy_; + // Concurrency strategy for an . + + int delete_concurrency_strategy_; + // 1 if created the concurrency strategy and thus should + // delete it, else 0. + + SCHEDULING_STRATEGY *scheduling_strategy_; + // Scheduling strategy for an . + + int delete_scheduling_strategy_; + // 1 if created the scheduling strategy and thus should + // delete it, else 0. + + // = Service information objects. + + char *service_name_; + // Name of the service. + + char *service_description_; + // Description of the service. + + u_short service_port_; + // Port number for the server. + + ACE_PEER_ACCEPTOR_ADDR service_addr_; + // Address that the uses to listen for + // connections. +}; + +template +class ACE_Oneshot_Acceptor : public ACE_Service_Object + // = TITLE + // Generic factory for passively connecting clients and creating + // exactly one service handler (SVC_HANDLER). + // + // = DESCRIPTION + // This class works similarly to the regular acceptor except + // that this class doesn't need a Creation_Strategy (since the + // user supplies the SVC_HANDLER) or an Accept_Strategy (since + // this class only accepts one connection and then removes all + // traces (e.g., from the ACE_Reactor). +{ +public: + // = Initialization and termination methods. + ACE_Oneshot_Acceptor (void); + // "Do-nothing" constructor. + + ACE_Oneshot_Acceptor (const ACE_PEER_ACCEPTOR_ADDR &, + ACE_Reactor * = ACE_Service_Config::reactor (), + ACE_Concurrency_Strategy * = 0); + // Initialize the appropriate strategies for concurrency and + // creation and then register at the designated . + + int open (const ACE_PEER_ACCEPTOR_ADDR &, + ACE_Reactor * = ACE_Service_Config::reactor (), + ACE_Concurrency_Strategy * = 0); + // Initialize the appropriate strategies for concurrency and + // creation and then register at the designated . + + virtual ~ACE_Oneshot_Acceptor (void); + // Close down the . + + // = Explicit factory operation. + virtual int accept (SVC_HANDLER * = 0, + ACE_PEER_ACCEPTOR_ADDR *remote_addr = 0, + const ACE_Synch_Options &synch_options = ACE_Synch_Options::defaults, + int restart = 1); + // Create a SVC_HANDLER, accept the connection into the SVC_HANDLER, + // and activate the SVC_HANDLER. + + virtual int cancel (void); + // Cancel a oneshot acceptor that was started asynchronously. + + virtual operator ACE_PEER_ACCEPTOR &() const; + // Return the underlying PEER_ACCEPTOR object. + + virtual ACE_PEER_ACCEPTOR &acceptor (void) const; + // Return the underlying PEER_ACCEPTOR object. + + ACE_Reactor *reactor (void) const; + // Get the underlying Reactor *. + + void reactor (ACE_Reactor *); + // Set the underlying Reactor *. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + virtual int activate_svc_handler (SVC_HANDLER *svc_handler); + // Bridge method for activating a with the appropriate + // concurrency strategy. Default behavior is to activate the + // SVC_HANDLER as a "passive object." However, subclasses can + // override this strategy to do more sophisticated concurrency + // activations (such as creating the SVC_HANDLER as an "active + // object" via multi-threading or multi-processing). + + int shared_accept (SVC_HANDLER *svc_handler, + ACE_PEER_ACCEPTOR_ADDR *remote_addr, + ACE_Time_Value *timeout, + int restart); + // Factors out the code shared between the and + // methods. + + int register_handler (SVC_HANDLER *svc_handler, + const ACE_Synch_Options &options, + int restart); + // Insert ourselves into the ACE_Reactor so that we can + // continue accepting this connection asynchronously. + + // = Demultiplexing hooks. + virtual ACE_HANDLE get_handle (void) const; + // Returns the listening acceptor's . + + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::RWE_MASK); + // Perform termination activities when is removed from the + // . + + virtual int handle_input (ACE_HANDLE); + // Accept one connection from a client and activates the + // SVC_HANDLER. + + virtual int handle_timeout (const ACE_Time_Value &tv, + const void *arg); + // Called when an acceptor times out... + + // = Dynamic linking hooks. + virtual int init (int argc, char *argv[]); + // Default version does no work and returns -1. Must be overloaded + // by application developer to do anything meaningful. + + virtual int fini (void); + // Default version does no work and returns -1. Must be overloaded + // by application developer to do anything meaningful. + + virtual int info (char **, size_t) const; + // Default version returns address info in . + + // = Service management hooks. + virtual int suspend (void); + // Default version does no work and returns -1. Must be overloaded + // by application developer to do anything meaningful. + + virtual int resume (void); + // Default version does no work and returns -1. Must be overloaded + // by application developer to do anything meaningful. + +private: + ACE_Reactor *reactor_; + // Event demultiplexer associated with this object. + + SVC_HANDLER *svc_handler_; + // Hold the svc_handler_ across asynchrony boundaries. + + int restart_; + // Hold the restart flag across asynchrony boundaries. + + ACE_PEER_ACCEPTOR peer_acceptor_; + // Factory that establishes connections passively. + + ACE_Concurrency_Strategy *concurrency_strategy_; + // Concurrency strategy for an Acceptor. + + int delete_concurrency_strategy_; + // 1 if Acceptor created the concurrency strategy and thus should + // delete it, else 0. +}; + +#include "ace/Acceptor.i" + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Acceptor.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Acceptor.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_ACCEPTOR_H */ diff --git a/ace/Acceptor.i b/ace/Acceptor.i new file mode 100644 index 00000000000..3cf904fc7e2 --- /dev/null +++ b/ace/Acceptor.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// $Id$ + +// Acceptor.i diff --git a/ace/Activation_Queue.cpp b/ace/Activation_Queue.cpp new file mode 100644 index 00000000000..e536bfb030f --- /dev/null +++ b/ace/Activation_Queue.cpp @@ -0,0 +1,70 @@ +// Activation_Queue.cpp +// $Id$ + +#define ACE_BUILD_DLL + +#include "ace/Activation_Queue.h" + +// Dump the state of an object. + +void +ACE_Activation_Queue::dump (void) const +{ + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, + "delete_queue_ = %d\n", + this->delete_queue_)); + ACE_DEBUG ((LM_INFO,"queue_: \n")); + if (this->queue_) + this->queue_->dump(); + else + ACE_DEBUG ((LM_DEBUG,"(NULL)\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Activation_Queue::ACE_Activation_Queue (ACE_Message_Queue *new_queue) + : delete_queue_ (0) +{ + if (new_queue) + this->queue_ = new_queue; + else + { + ACE_NEW (this->queue_, ACE_Message_Queue); + this->delete_queue_ = 1; + } +} + +ACE_Activation_Queue::~ACE_Activation_Queue (void) +{ + if (this->delete_queue_ != 0) + delete this->queue_; +} + +ACE_Method_Object * +ACE_Activation_Queue::dequeue (ACE_Time_Value *tv) +{ + ACE_Message_Block *mb; + ACE_Method_Object *mo; + + // Dequeue the message. + this->queue_->dequeue_head (mb, tv); + + // Get the method object. + mo = (ACE_Method_Object *) mb->base (); + + // Delete the message block. + delete mb; + return mo; +} + +int +ACE_Activation_Queue::enqueue (ACE_Method_Object *mo, + ACE_Time_Value *tv) +{ + ACE_Message_Block *mb; + + ACE_NEW_RETURN (mb, ACE_Message_Block ((char *) mo), -1); + + return this->queue_->enqueue (mb, tv); +} + diff --git a/ace/Activation_Queue.h b/ace/Activation_Queue.h new file mode 100644 index 00000000000..2ab871dce7e --- /dev/null +++ b/ace/Activation_Queue.h @@ -0,0 +1,63 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Activation_Queue.h +// +// = AUTHOR +// Andres Kruse and Douglas C. Schmidt +// +// +// ============================================================================ + +#if !defined (ACE_ACTIVATION_QUEUE_H) +#define ACE_ACTIVATION_QUEUE_H + +#include "ace/Synch.h" +#include "ace/Message_Queue.h" +#include "ace/Method_Object.h" + +class ACE_Export ACE_Activation_Queue + // = TITLE + // Reifies a method into an object. Subclasses typically + // represent necessary state and behavior. + // + // = DESCRIPTION + // A is inserted in the , where + // it is subsequently removed by the and invoked. +{ +public: + // = Initialization and termination methods. + ACE_Activation_Queue (ACE_Message_Queue *new_queue = 0); + ~ACE_Activation_Queue (void); + + // = Queue operations. + ACE_Method_Object *dequeue (ACE_Time_Value *tv = 0); + // Dequeue the next available . + + int enqueue (ACE_Method_Object *new_method_object, + ACE_Time_Value *tv = 0); + // Enqueue the . + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Message_Queue *queue_; + // Stores the . + + int delete_queue_; + // Keeps track of whether we need to delete the queue. +}; + +#endif /* ACE_ACTIVATION_QUEUE_H */ + diff --git a/ace/Addr.cpp b/ace/Addr.cpp new file mode 100644 index 00000000000..39edb5fe6d2 --- /dev/null +++ b/ace/Addr.cpp @@ -0,0 +1,44 @@ +// Addr.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Addr.h" + +// This is a static class variable. +const ACE_Addr ACE_Addr::sap_any; + +#if !defined (__ACE_INLINE__) +#include "ace/Addr.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Addr) + +void +ACE_Addr::dump (void) const +{ + ACE_TRACE ("ACE_Addr::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "addr_type_ = %d", this->addr_type_)); + ACE_DEBUG ((LM_DEBUG, "\naddr_size_ = %d", this->addr_size_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// Initializes instance variables. + +void +ACE_Addr::base_set (int type, int size) +{ + this->addr_type_ = type; + this->addr_size_ = size; +} + +// Initializes instance variables. Note that 0 is an unspecified +// protocol family type... + +ACE_Addr::ACE_Addr (int type, int size) +{ + this->base_set (type, size); +} + diff --git a/ace/Addr.h b/ace/Addr.h new file mode 100644 index 00000000000..3108674edc3 --- /dev/null +++ b/ace/Addr.h @@ -0,0 +1,93 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Addr.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_ADDR_H) +#define ACE_ADDR_H + +#include "ace/ACE.h" + +class ACE_Export ACE_Addr + // = TITLE + // Defines the base class for the "address family independent" + // address format. +{ +public: + // = Initialization method. + + ACE_Addr (int type = 0, int size = 0); + // Initializes instance variables. + + // = Get/set the size of the address. + + int get_size (void) const; + // Return the size of the address. + + void set_size (int size); + // Sets the size of the address. + + // = Get/set the type of the address. + + int get_type (void) const; + // Get the type of the address. + + void set_type (int type); + // Set the type of the address. + + virtual void *get_addr (void) const; + // Return a pointer to the address. + + virtual void set_addr (void *, int len); + // Set a pointer to the address. + + virtual int addr_to_string (char addr[], size_t) const; + // Transform the current address into string format. + + virtual int string_to_addr (const char addr[]); + // Transform the string into the current addressing format. + + // = Equality/inequality tests + virtual int operator == (const ACE_Addr &sap) const; + // Check for address equality. + + virtual int operator != (const ACE_Addr &sap) const; + // Check for address inequality. + + void base_set (int type, int size); + // Initializes instance variables. + + static const ACE_Addr sap_any; + // Wild-card address. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + int addr_type_; + // e.g., AF_UNIX, AF_INET, AF_SPIPE, etc. + + int addr_size_; + // Number of bytes in the address. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Addr.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_ADDR_H */ diff --git a/ace/Addr.i b/ace/Addr.i new file mode 100644 index 00000000000..30ce46a1f62 --- /dev/null +++ b/ace/Addr.i @@ -0,0 +1,77 @@ +/* -*- C++ -*- */ +// $Id$ + +// Addr.i + +// Return the address of the address. + +ACE_INLINE void * +ACE_Addr::get_addr (void) const +{ + return 0; +} + +ACE_INLINE void +ACE_Addr::set_addr (void *, int) +{ +} + +// Transform the current address into string format. + +ACE_INLINE int +ACE_Addr::addr_to_string (char [], size_t) const +{ + return -1; +} + +// Transform the string into the current addressing format. + +ACE_INLINE int +ACE_Addr::string_to_addr (const char []) +{ + return -1; +} + +ACE_INLINE int +ACE_Addr::operator == (const ACE_Addr &sap) const +{ + return sap.addr_type_ == 0; +} + +ACE_INLINE int +ACE_Addr::operator != (const ACE_Addr &sap) const +{ + return sap.addr_type_ != 0; +} + +// Return the size of the address. + +ACE_INLINE int +ACE_Addr::get_size (void) const +{ + return this->addr_size_; +} + +// Sets the size of the address. + +ACE_INLINE void +ACE_Addr::set_size (int size) +{ + this->addr_size_ = size; +} + +// Return the type of the address. + +ACE_INLINE int +ACE_Addr::get_type (void) const +{ + return this->addr_type_; +} + +// Set the type of the address. + +ACE_INLINE void +ACE_Addr::set_type (int type) +{ + this->addr_type_ = type; +} diff --git a/ace/Auto_Ptr.cpp b/ace/Auto_Ptr.cpp new file mode 100644 index 00000000000..67bc370b505 --- /dev/null +++ b/ace/Auto_Ptr.cpp @@ -0,0 +1,50 @@ +// Auto_Ptr.cpp +// $Id$ + +#if !defined (ACE_AUTO_PTR_C) +#define ACE_AUTO_PTR_C + +#define ACE_BUILD_DLL +#include "ace/Auto_Ptr.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Auto_Ptr.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(auto_ptr) + +template void +auto_ptr::dump (void) const +{ + ACE_TRACE ("auto_ptr::dump"); +} + +template void +auto_ptr::remove (X *& x) +{ + ACE_TRACE ("auto_ptr::remove"); + + X *tp = x; + x = 0; + delete tp; +} + +ACE_ALLOC_HOOK_DEFINE(auto_array_ptr) + +template void +auto_array_ptr::dump (void) const +{ + ACE_TRACE ("auto_array_ptr::dump"); +} + +template void +auto_array_ptr::remove (X *& x) +{ + ACE_TRACE ("auto_array_ptr::remove"); + + X *tp = x; + x = 0; + delete [] tp; +} + +#endif /* ACE_AUTO_PTR_C */ diff --git a/ace/Auto_Ptr.h b/ace/Auto_Ptr.h new file mode 100644 index 00000000000..57251fec225 --- /dev/null +++ b/ace/Auto_Ptr.h @@ -0,0 +1,101 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Auto_Ptr.h +// +// = AUTHOR +// Doug Schmidt, based on code from Jack Reeves (jack@fx.com) and +// Dr. Harald M. Mueller (mueller@garwein.hai.siemens.co.at) +// +// ============================================================================ + +#if !defined (ACE_AUTO_PTR_H) +#define ACE_AUTO_PTR_H + +#include "ace/ACE.h" + +template +class auto_ptr + // = TITLE + // Implements the draft C++ standard auto_ptr abstraction. +{ +public: + // = Initialization and termination methods + auto_ptr (X *p = 0); + auto_ptr (auto_ptr &ap); + ~auto_ptr (void); + void operator= (auto_ptr &rhs); + + // = Accessor methods. + X &operator *() const; + X *operator-> () const; + X *get (void) const; + X *release (void); + X *reset (X *p); + + static void remove (X* &x); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + X *p_; +}; + +template +class auto_array_ptr + // = TITLE + // Implements an extension to the draft C++ standard auto_ptr + // abstraction. +{ +public: + // = Initialization and termination methods. + auto_array_ptr (X *p = 0); + auto_array_ptr (auto_array_ptr &ap); + ~auto_array_ptr (void); + void operator= (auto_array_ptr &rhs); + + // = Accessor methods. + X &operator* (); + X *operator-> (); + X &operator[] (int i); + X operator[] (int i) const; + X *get (void) const; + X *release (void); + X *reset (X *p); + + static void remove (X *&x); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + X *p_; +}; + +#if defined (__ACE_INLINE__) +#include "ace/Auto_Ptr.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Auto_Ptr.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Auto_Ptr.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_AUTO_PTR_H */ diff --git a/ace/Auto_Ptr.i b/ace/Auto_Ptr.i new file mode 100644 index 00000000000..f0209505c17 --- /dev/null +++ b/ace/Auto_Ptr.i @@ -0,0 +1,151 @@ +/* -*- C++ -*- */ +// $Id$ + +// Auto_Ptr.i + +template ACE_INLINE void +auto_ptr::operator= (auto_ptr &rhs) +{ + ACE_TRACE ("auto_ptr::operator="); + if (this != &rhs) + { + auto_ptr::remove (p_); + p_ = rhs.release (); + } +} + +template ACE_INLINE +auto_ptr::auto_ptr (X *p) + : p_ (p) +{ + ACE_TRACE ("auto_ptr::auto_ptr"); +} + +template ACE_INLINE +auto_ptr::auto_ptr (auto_ptr &ap) + : p_ (ap.release ()) +{ + ACE_TRACE ("auto_ptr::auto_ptr"); +} + +template ACE_INLINE +auto_ptr::~auto_ptr (void) +{ + ACE_TRACE ("auto_ptr::~auto_ptr"); + delete p_; +} + +template ACE_INLINE X & +auto_ptr::operator *() const +{ + return *p_; +} + +template ACE_INLINE X * +auto_ptr::operator-> () const +{ + ACE_TRACE ("auto_ptr::operator->"); + return p_; +} + +template ACE_INLINE X * +auto_ptr::get (void) const +{ + ACE_TRACE ("auto_ptr::get"); + return p_; +} + +template ACE_INLINE X * +auto_ptr::release (void) +{ + ACE_TRACE ("auto_ptr::release"); + return this->reset (0); +} + +template ACE_INLINE X * +auto_ptr::reset (X *p) +{ + ACE_TRACE ("auto_ptr::reset"); + X *tp = p_; + p_ = p; + return tp; +} + +template ACE_INLINE +auto_array_ptr::auto_array_ptr (X *p) + : p_ (p) +{ + ACE_TRACE ("auto_array_ptr::auto_array_ptr"); +} + +template ACE_INLINE +auto_array_ptr::auto_array_ptr (auto_array_ptr &ap) + : p_ (ap.release ()) +{ + ACE_TRACE ("auto_array_ptr::auto_array_ptr"); +} + +template ACE_INLINE +auto_array_ptr::~auto_array_ptr (void) +{ + ACE_TRACE ("auto_array_ptr::~auto_array_ptr"); + delete [] p_; +} + +template ACE_INLINE X & +auto_array_ptr::operator*() +{ + return *p_; +} + +template ACE_INLINE X * +auto_array_ptr::operator->() +{ + return p_; +} + +template ACE_INLINE X & +auto_array_ptr::operator[](int i) +{ + return p_[i]; +} + +template ACE_INLINE X +auto_array_ptr::operator[](int i) const +{ + return p_[i]; +} + +template ACE_INLINE X * +auto_array_ptr::get (void) const +{ + ACE_TRACE ("auto_array_ptr::get"); + return p_; +} + +template ACE_INLINE X * +auto_array_ptr::release (void) +{ + ACE_TRACE ("auto_array_ptr::release"); + return this->reset (0); +} + +template ACE_INLINE X * +auto_array_ptr::reset (X *p) +{ + ACE_TRACE ("auto_array_ptr::reset"); + X *tp = p_; + p_ = p; + return tp; +} + +template ACE_INLINE void +auto_array_ptr::operator= (auto_array_ptr &rhs) +{ + ACE_TRACE ("auto_array_ptr::operator="); + if (this != &rhs) + { + auto_array_ptr::remove (p_); + p_ = rhs.release (); + } +} diff --git a/ace/CORBA_Handler.cpp b/ace/CORBA_Handler.cpp new file mode 100644 index 00000000000..bd0fde609c4 --- /dev/null +++ b/ace/CORBA_Handler.cpp @@ -0,0 +1,522 @@ +// CORBA_Handler.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/CORBA_Handler.h" + +#if !defined (__ACE_INLINE__) +#include "ace/CORBA_Handler.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_HAS_ORBIX) +ACE_ALLOC_HOOK_DEFINE(ACE_ST_CORBA_Handler) +ACE_ALLOC_HOOK_DEFINE(ACE_CORBA_Handler) + +void +ACE_CORBA_Handler::dump (void) const +{ + ACE_TRACE ("ACE_CORBA_Handler::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "reactor_ = %x", this->reactor_)); + ACE_DEBUG ((LM_DEBUG, "\nreference_count_ = %d", this->reference_count_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_CORBA_Handler::ACE_CORBA_Handler (const ACE_CORBA_Handler &rhs) +{ + ACE_TRACE ("ACE_CORBA_Handler::ACE_CORBA_Handler"); +} + +const ACE_CORBA_Handler & +ACE_CORBA_Handler::operator= (const ACE_CORBA_Handler &rhs) +{ + ACE_TRACE ("ACE_CORBA_Handler::operator="); + return *this; +} + +void +ACE_ST_CORBA_Handler::dump (void) const +{ + ACE_TRACE ("ACE_ST_CORBA_Handler::dump"); + + ACE_CORBA_Handler::dump (); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "instance_ = %x", this->instance_)); + ACE_DEBUG ((LM_DEBUG, "\niteration_ = %d", this->iterations_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_CORBA_Handler::~ACE_CORBA_Handler (void) +{ + ACE_TRACE ("ACE_CORBA_Handler::~ACE_CORBA_Handler"); +} + +ACE_CORBA_Handler::ACE_CORBA_Handler (void) + : reactor_ (ACE_Service_Config::reactor ()) +{ + ACE_TRACE ("ACE_CORBA_Handler::ACE_CORBA_Handler"); +} + +// Only one ST CORBA Handler per-process... +/* static */ +ACE_ST_CORBA_Handler *ACE_ST_CORBA_Handler::instance_ = 0; + +// Insert a descriptor into the ACE_Reactor that Orbix has just added. + +/* static */ +void +ACE_ST_CORBA_Handler::insert_handle (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_ST_CORBA_Handler::insert_handle"); +// ACE_DEBUG ((LM_DEBUG, "+++ inserting %d\n", handle)); + + if (ACE_ST_CORBA_Handler::instance_->reactor_ != 0) + ACE_ST_CORBA_Handler::instance_->reactor_->register_handler + (handle, ACE_ST_CORBA_Handler::instance_, ACE_Event_Handler::READ_MASK); + else + ; +// ACE_DEBUG ((LM_DEBUG, "insert_handle: reactor NULL\n")); +} + +// Remove a descriptor from the ACE_Reactor that Orbix has just deleted. + +/* static */ +void +ACE_ST_CORBA_Handler::remove_handle (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_ST_CORBA_Handler::remove_handle"); +// ACE_DEBUG ((LM_DEBUG, "--- removing %d\n", handle)); + + if (ACE_ST_CORBA_Handler::instance_->reactor_ != 0) + ACE_ST_CORBA_Handler::instance_->reactor_->remove_handler + (handle, ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL); + else + ; +// ACE_DEBUG ((LM_DEBUG, "remove_handle: reactor NULL\n")); +} + +// Process the next Orbix event. + +int +ACE_ST_CORBA_Handler::handle_input (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_ST_CORBA_Handler::handle_input"); + // ACE_DEBUG ((LM_DEBUG, "dispatching Orbix handle = %d in process + // = %P\n", handle)); + + TRY { + // Loop up to dispatching the + // next event. Note the trade off between efficiency and + // fairness... + + for (size_t i = 0; i < this->iterations_; i++) + if (ACE_CORBA_1 (Orbix.isEventPending) (IT_X)) + // Process the next Orbix event (don't block). + ACE_CORBA_1 (Orbix.processNextEvent) (0, IT_X); + else + break; + } + CATCHANY { + // an error occured calling processNextEvent () - output the + // error. + cerr << IT_X << endl; + } ENDTRY; + return 0; +} + +int +ACE_ST_CORBA_Handler::suspend (void) +{ + // Create an iterator. + ACE_Handle_Set set (ACE_CORBA_1 (Orbix.getFileDescriptors) ()); + ACE_Handle_Set_Iterator orbix_descriptors (set); + + // Suspend all the HANDLEs registered by Orbix. + for (ACE_HANDLE h; + (h = orbix_descriptors ()) != ACE_INVALID_HANDLE; + ++orbix_descriptors) + this->reactor_->suspend_handler (h); + + return 0; +} + +int +ACE_ST_CORBA_Handler::resume (void) +{ + // Create an iterator. + ACE_Handle_Set set (ACE_CORBA_1 (Orbix.getFileDescriptors) ()); + ACE_Handle_Set_Iterator orbix_descriptors (set); + + // Resume all the HANDLEs registered by Orbix. + for (ACE_HANDLE h; + (h = orbix_descriptors ()) != ACE_INVALID_HANDLE; + ++orbix_descriptors) + this->reactor_->resume_handler (h); + + return 0; +} + +// Dummy constructor. +ACE_ST_CORBA_Handler::ACE_ST_CORBA_Handler (void) +{ + ACE_TRACE ("ACE_ST_CORBA_Handler::ACE_ST_CORBA_Handler"); + + // This is set by default for backward compatibility. The user can + // use the set/get operations to change the iterations + this->iterations_ = 5; + + // Set up the callbacks so that we get informed when Orbix changes + // its descriptors. + ACE_CORBA_1 (Orbix.registerIOCallback) ((OrbixIOCallback) &ACE_ST_CORBA_Handler::insert_handle, + FD_OPEN_CALLBACK); + ACE_CORBA_1 (Orbix.registerIOCallback) ((OrbixIOCallback) &ACE_ST_CORBA_Handler::remove_handle, + FD_CLOSE_CALLBACK); +} + +void +ACE_ST_CORBA_Handler::get_orbix_descriptors (void) +{ + // Create an iterator. + ACE_Handle_Set set (ACE_CORBA_1 (Orbix.getFileDescriptors) ()); + ACE_Handle_Set_Iterator orbix_descriptors (set); + + // Preinitialize anything that's already registered. + for (ACE_HANDLE h; + (h = orbix_descriptors ()) != ACE_INVALID_HANDLE; + ++orbix_descriptors) + ACE_ST_CORBA_Handler::insert_handle (h); +} + +// Register by doing a "putit" to register the +// using the at with +// orbixd. + +/* static */ +int +ACE_CORBA_Handler::register_service (const char *service_name, + const char *marker_name, + const char *service_location) +{ + ACE_TRACE ("ACE_CORBA_Handler::register_service"); + char buf[BUFSIZ * 2]; // I hope this is enough space... + + // Be defensive here... + if (service_name == 0 || service_location == 0) + { + errno = EINVAL; + return -1; + } + else if (marker_name == 0) + ACE_OS::sprintf (buf, "putit %s %s", service_name, service_location); + else + ACE_OS::sprintf (buf, "putit -marker %s %s %s", + marker_name, service_name, service_location); + + return ACE_OS::system (buf); // Use system(3S) to execute Orbix putit. +} + +// Register by doing a "putit" to register +// using the with orbixd. + +/* static */ +int +ACE_CORBA_Handler::remove_service (const char *service_name, + const char *marker_name) +{ + ACE_TRACE ("ACE_CORBA_Handler::remove_service"); + char buf[BUFSIZ * 2]; // I hope this is enough space! + if (service_name == 0) + { + errno = EINVAL; + return -1; + } + else if (marker_name == 0) + ACE_OS::sprintf (buf, "rmit %s\n", service_name); + else + ACE_OS::sprintf (buf, "rmit -marker %s %s\n", marker_name, service_name); + return ACE_OS::system (buf); // Use system(3S) to execute Orbix rmit. +} + +ACE_ST_CORBA_Handler::~ACE_ST_CORBA_Handler (void) +{ + ACE_TRACE ("ACE_ST_CORBA_Handler::~ACE_ST_CORBA_Handler"); + // Create an iterator. + ACE_Handle_Set set (ACE_CORBA_1 (Orbix.getFileDescriptors) ()); + ACE_Handle_Set_Iterator orbix_descriptors (set); + + // Remove everything! + + for (ACE_HANDLE h; + (h = orbix_descriptors ()) != ACE_INVALID_HANDLE; + ++orbix_descriptors) + ACE_ST_CORBA_Handler::remove_handle (h); + + // Keep Orbix from calling us back and crashing the system! + ACE_CORBA_1 (Orbix.registerIOCallback) (0, FD_OPEN_CALLBACK); + ACE_CORBA_1 (Orbix.registerIOCallback) (0, FD_CLOSE_CALLBACK); + ACE_ST_CORBA_Handler::instance_ = 0; +} + +// Decrement the reference count and free up all the resources if this +// is the last service to be using the ACE_ST_CORBA_Handler... + +/* static */ +int +ACE_CORBA_Handler::deactivate_service (const char *service_name, + const char *marker_name) +{ + ACE_TRACE ("ACE_CORBA_Handler::deactivate_service"); + if (service_name != 0 + && this->remove_service (service_name, marker_name) == -1) + return -1; + + int ref_count = this->reference_count_; + + this->reference_count_--; + + // Close everything down if the count drops to 0. + if (this->reference_count_ == 0) + // Commit suicide! + delete this; + + if (ref_count < 0) + ; +// ACE_DEBUG ((LM_DEBUG, "warning, reference count == %d\n", +// ref_count)); + return 0; +} + +/* static */ +ACE_CORBA_Handler * +ACE_ST_CORBA_Handler::instance (void) +{ + ACE_TRACE ("ACE_ST_CORBA_Handler::instance"); + + // Note that this does not need a double-check since it should be + // called from a single-threaded environment. + + if (ACE_ST_CORBA_Handler::instance_ == 0) + { + ACE_NEW_RETURN (ACE_ST_CORBA_Handler::instance_, ACE_ST_CORBA_Handler, 0); + ACE_ST_CORBA_Handler::instance_->get_orbix_descriptors (); + } + + return ACE_ST_CORBA_Handler::instance_; +} + +// Activate and register with the Orbix daemon. If +// and are != 0 then do a "putit" to +// register this service with orbixd. This method also increments the +// reference count of active services using the ACE_ST_CORBA_Handler. + +int +ACE_CORBA_Handler::activate_service (const char *service_name, + const char *marker_name, + const char *service_location) +{ + ACE_TRACE ("ACE_CORBA_Handler::activate_service"); + // Since the ACE_CORBA_Handler is a singleton, make sure not to + // allocate and initialize more than one copy. By incrementing the + // reference count we ensure this. + + this->reference_count_++; + + if (service_name != 0 && service_location != 0 + && this->register_service (service_name, marker_name, + service_location) == -1) + return -1; + + // Tell Orbix that we have completed the server's initialization. + // Note that we don't block by giving a timeout of 0... + + TRY { + ACE_CORBA_1 (Orbix.impl_is_ready) ((char *) service_name, 0, IT_X); + } CATCHANY { + return -1; + } ENDTRY + + return 0; +} + +#if defined (ACE_HAS_MT_ORBIX) + +ACE_ALLOC_HOOK_DEFINE(ACE_MT_CORBA_Handler) + +#if defined (ACE_MT_SAFE) +// Synchronize output operations. +ACE_Thread_Mutex ACE_MT_CORBA_Handler::ace_mt_corba_handler_lock_; +#endif /* ACE_MT_SAFE */ + +void +ACE_MT_CORBA_Handler::dump (void) const +{ + ACE_TRACE ("ACE_MT_CORBA_Handler::dump"); + ACE_CORBA_Handler::dump (); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "instance_ = %x", this->instance_)); + ACE_DEBUG ((LM_DEBUG, "\nthr_mgr_ = %x", this->thr_mgr_)); + this->pipe_.dump (); +#if defined (ACE_MT_SAFE) + // Double-Check lock. + ace_mt_corba_handler_lock_.dump (); +#endif /* ACE_MT_SAFE */ + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// Only one MT CORBA Handler per-process... +/* static */ +ACE_MT_CORBA_Handler *ACE_MT_CORBA_Handler::instance_ = 0; + +/* static */ +ACE_CORBA_Handler * +ACE_MT_CORBA_Handler::instance (void) +{ + ACE_TRACE ("ACE_MT_CORBA_Handler::instance"); + + if (ACE_MT_CORBA_Handler::instance_ == 0) + { + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, ACE_MT_CORBA_Handler::ace_mt_corba_handler_lock_, 0); + + if (ACE_MT_CORBA_Handler::instance_ == 0) + ACE_NEW_RETURN (ACE_MT_CORBA_Handler::instance_, + ACE_MT_CORBA_Handler, 0); + } + + return ACE_MT_CORBA_Handler::instance_; +} + +int +ACE_MT_CORBA_Handler::suspend (void) +{ + // Suspend the event handler listening for new CORBA requests to + // dispatch. + this->reactor_->suspend_handler (this->pipe_.read_handle ()); + + // Suspend the daemon thread. + this->thr_mgr ()->suspend_all (); + return 0; +} + +int +ACE_MT_CORBA_Handler::resume (void) +{ + // Resume the event handler listening for new CORBA requests to + // dispatch. + this->reactor_->resume_handler (this->pipe_.read_handle ()); + + // Resume the daemon thread. + this->thr_mgr ()->resume_all (); + return 0; +} + +ACE_MT_CORBA_Handler::ACE_MT_CORBA_Handler (void) +{ + ACE_TRACE ("ACE_MT_CORBA_Handler::ACE_MT_CORBA_Handler"); + this->thr_mgr (ACE_Service_Config::thr_mgr ()); + + int result = 0; + + if (this->pipe_.open () == -1) + result = -1; + // Register one end of the pipe with the reactor with a READ mask. + else if (this->reactor_->register_handler + (this->pipe_.read_handle (), this, ACE_Event_Handler::READ_MASK) == -1) + result = -1; + // Create a new thread that processes events for the Orbix event + // queue. + else if (this->thr_mgr ()->spawn (ACE_THR_FUNC (ACE_MT_CORBA_Handler::process_events), + 0, THR_DETACHED | THR_NEW_LWP) == -1) + result = -1; + + if (result == -1) + { + delete ACE_MT_CORBA_Handler::instance_; + ACE_MT_CORBA_Handler::instance_ = 0; + } +} + +void * +ACE_MT_CORBA_Handler::process_events (void *) +{ + ACE_TRACE ("ACE_MT_CORBA_Handler::process_events"); + + ACE_Thread_Control t (ACE_MT_CORBA_Handler::instance_->thr_mgr ()); + + // This thread only processes events. + TRY { + // it is OK to block + ACE_CORBA_1 (Orbix.processEvents) (ACE_CORBA_1 (Orbix.INFINITE_TIMEOUT), IT_X); + } CATCHANY { + // An error occured calling processEvents () - output the error. + cerr << IT_X << endl; + } ENDTRY; + + // Thread dies if we reach here : error occured in processEvents. + return 0; +} + +int +ACE_MT_CORBA_Handler::inRequestPreMarshal (ACE_CORBA_1 (Request) &req, + ACE_CORBA_1 (Environment) &IT_env) +{ + ACE_TRACE ("ACE_MT_CORBA_Handler::inRequestPreMarshal"); + + // Pump the request through the pipe. + u_long request_addr = (u_long) &req; + + ssize_t result = ACE::send (this->pipe_.write_handle (), + (const char *) &request_addr, + sizeof request_addr); + + if (result != sizeof request_addr) + { + // Don't continue with request + return 0; + } + + // Everything is fine: we have delegated the work to a different + // thread Tell Orbix we will dispatch the request later... + return -1; +} + +int +ACE_MT_CORBA_Handler::handle_input (ACE_HANDLE) +{ + ACE_TRACE ("ACE_MT_CORBA_Handler::handle_input"); + ACE_CORBA_1 (Request) *req = 0; + + u_long request_addr; + + // Read the request from the pipe. + ssize_t result = ACE::recv (this->pipe_.read_handle (), + (char *) &request_addr, + sizeof request_addr); + + if (result != sizeof request_addr) + // We are in trouble: bail out. + return -1; + + req = (ACE_CORBA_1 (Request) *) request_addr; + + // Tell Orbix to dispatch the request. + ACE_CORBA_1 (Orbix.continueThreadDispatch) (*req); + return 0; +} + +ACE_MT_CORBA_Handler::~ACE_MT_CORBA_Handler (void) +{ + ACE_TRACE ("ACE_MT_CORBA_Handler::~ACE_MT_CORBA_Handler"); + + // Unregister one end of the pipe with the reactor + this->reactor_->remove_handler + (this->pipe_.read_handle (), + ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL); + + this->pipe_.close (); + + ACE_MT_CORBA_Handler::instance_ = 0; +} +#endif /* ACE_HAS_MT_ORBIX */ +#endif /* ACE_HAS_ORBIX */ diff --git a/ace/CORBA_Handler.h b/ace/CORBA_Handler.h new file mode 100644 index 00000000000..4180600e85e --- /dev/null +++ b/ace/CORBA_Handler.h @@ -0,0 +1,238 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// CORBA_Handler.h +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) and +// Irfan Pyarali (irfan@wuerl.wustl.edu). +// +// ============================================================================ + +#if !defined (_CORBA_HANDLER_H) +#define _CORBA_HANDLER_H + +#include "ace/Service_Config.h" +#include "ace/Pipe.h" + +#if defined (ACE_HAS_ORBIX) || defined (ACE_HAS_MT_ORBIX) +#define EXCEPTIONS +#define WANT_ORBIX_FDS +#include +// #include +#undef EXCEPTIONS +#undef WANT_ORBIX_FDS + +#if defined (ACE_WIN32) +#define ACE_CORBA_1(NAME) CORBA_##NAME +#define ACE_CORBA_2(TYPE, NAME) CORBA_##TYPE##_##NAME +#define ACE_CORBA_3(TYPE, NAME) CORBA_##TYPE##::##NAME +#else +#define ACE_CORBA_1(NAME) CORBA::##NAME +#define ACE_CORBA_2(TYPE, NAME) CORBA::##TYPE##::##NAME +#define ACE_CORBA_3(TYPE, NAME) CORBA::##TYPE##::##NAME +#endif /* ACE_WIN32 */ + +class ACE_Export ACE_CORBA_Handler : public ACE_Service_Object + // = TITLE + // Handle CORBA requests in conjunction with the ACE ACE_Reactor. + // Note, do *NOT* inherit from this class! Instead, use the + // ACE_MT_CORBA_HAndler and ACE_ST_CORBA_Handler as Singletons. +{ +public: + // = Activation and deactivation methods. + + virtual int activate_service (const char *service_name, + const char *marker_name = 0, + const char *service_location = 0); + // Activate and register with the Orbix daemon. If + // and are != 0 then do a "putit" + // to register this service with orbixd. This method also + // increments the reference count of active services using the + // ACE_ST_CORBA_Handler. + + virtual int deactivate_service (const char *service_name = 0, + const char *marker_name = 0); + // Decrement the reference count and free up all the + // resources if this is the last service to be using + // the ACE_ST_CORBA_Handler... + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + + void reactor (ACE_Reactor *); + // Set the reactor instance. + + ACE_Reactor *reactor (void) ; + // Get the reactor instance. + +protected: + ACE_CORBA_Handler (void); + // Make this into an "abstract" class... + + virtual ~ACE_CORBA_Handler (void); + // Note virtual destructor... + + virtual int register_service (const char *service_name, + const char *marker_name, + const char *service_location); + // Register by doing a "putit" to register + // the using the at + // with orbixd. + + virtual int remove_service (const char *service_name, + const char *marker_name = 0); + // Register by doing a "putit" to register + // using the with orbixd. + + ACE_Reactor *reactor_; + // Event demultiplexor used by ACE_ST_CORBA_Handler + + ssize_t reference_count_; + // Keep track of the number of active CORBA_Handlers. + +private: + // = Disallow assignment and initialization (this applies to derived + // classes, as well!) + ACE_CORBA_Handler (const ACE_CORBA_Handler &rhs); + const ACE_CORBA_Handler &operator= (const ACE_CORBA_Handler &rhs); +}; + +class ACE_Export ACE_ST_CORBA_Handler : public ACE_CORBA_Handler + // = TITLE + // Handle single-threaded CORBA requests in conjunction with the + // ACE_Reactor. +{ +public: + static ACE_CORBA_Handler *instance (void); + // Returns a Singleton. + + virtual int handle_input (ACE_HANDLE); + // Process the next Orbix event. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + + // = The iterations are dictate how many processNextEvent() calls + // are run per-callback. + + size_t iterations (void); + // Get the current iteration. + + void iterations (size_t); + // Set the current iteration. + + // = Dynamic linking hooks. + virtual int suspend (void); + // Atomically suspend all the threads associated with the . + + virtual int resume (void); + // Atomically resume all the threads associated with the . + +protected: + void get_orbix_descriptors (void); + // Preinitialize any descriptors that Orbix is using. This is + // called in instance (). + + ACE_ST_CORBA_Handler (void); + // Constructors (ensure Singleton...). + + virtual ~ACE_ST_CORBA_Handler (void); + // Destructor cleans up resources. + + static void insert_handle (ACE_HANDLE); + // Insert a descriptor into the ACE_Reactor that Orbix has just added. + + static void remove_handle (ACE_HANDLE); + // Remove a descriptor from the ACE_Reactor that Orbix has just deleted. + + static ACE_ST_CORBA_Handler *instance_; + // ACE_ST_CORBA_Handler is a singleton object. + + size_t iterations_; + // Number of iterations to process per processNextEvent() call. +}; + +#if defined (ACE_HAS_MT_ORBIX) + +class ACE_Export ACE_MT_CORBA_Handler : public ACE_CORBA_Handler, public ACE_CORBA_1 (ThreadFilter) + // = TITLE + // Handle multi-threaded CORBA requests in conjunction with the + // ACE Reactor. +{ +public: + static ACE_CORBA_Handler *instance (void); + // Returns a Singleton. + + virtual int handle_input (ACE_HANDLE); + // Process the next Orbix event. + + void thr_mgr (ACE_Thread_Manager *tm); + // Set the Thread_Manager used by ACE_MT_CORBA_Handler + + ACE_Thread_Manager *thr_mgr (void) const; + // Get the Thread_Manager used by ACE_MT_CORBA_Handler + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + + // = Dynamic linking hooks. + virtual int suspend (void); + // Atomically suspend all the threads associated with the . + + virtual int resume (void); + // Atomically resume all the threads associated with the . + +protected: + static void *process_events (void *); + // function executed by new thread + + ACE_MT_CORBA_Handler (void); + // Constructors (ensure Singleton...). + + virtual ~ACE_MT_CORBA_Handler (void); + // Destructor cleans up resources. + + virtual int inRequestPreMarshal (ACE_CORBA_1 (Request) &r, + ACE_CORBA_1 (Environment) &IT_env = ACE_CORBA_1 (default_environment)); + // Take the incoming request and pass it to this->handle_input() but + // through the Reactor. + + static ACE_MT_CORBA_Handler *instance_; + // ACE_MT_CORBA_Handler is a singleton object. + + ACE_Thread_Manager *thr_mgr_; + // Event demultiplexor used by ACE_ST_CORBA_Handler. + + ACE_Pipe pipe_; + // Used to send CORBA::Requests through the server + +#if defined (ACE_MT_SAFE) + static ACE_Thread_Mutex ace_mt_corba_handler_lock_; + // Double-Check lock. +#endif /* ACE_MT_SAFE */ +}; +#endif /* ACE_HAS_MT_ORBIX */ + +#if defined (__INLINE__) +#include "ace/CORBA_Handler.i" +#endif /* __INLINE__ */ + +#endif /* ACE_HAS_ORBIX */ +#endif /* ACE_CORBA_HANDLER_H */ diff --git a/ace/CORBA_Handler.i b/ace/CORBA_Handler.i new file mode 100644 index 00000000000..794b6da5d09 --- /dev/null +++ b/ace/CORBA_Handler.i @@ -0,0 +1,56 @@ +/* -*- C++ -*- */ +// $Id$ + +// CORBA_Handler.i + +#if defined (ACE_HAS_ORBIX) +// = Set/get the number of iterations per processNextEvent() call. + +/* static */ +ACE_INLINE size_t +ACE_ST_CORBA_Handler::iterations (void) +{ + ACE_TRACE ("ACE_ST_CORBA_Handler::iterations"); + return this->iterations_; +} + +/* static */ +ACE_INLINE void +ACE_ST_CORBA_Handler::iterations (size_t i) +{ + ACE_TRACE ("ACE_ST_CORBA_Handler::iterations"); + this->iterations_ = i; +} + +/* static */ +ACE_INLINE void +ACE_CORBA_Handler::reactor (ACE_Reactor *reactor) +{ + ACE_TRACE ("ACE_CORBA_Handler::reactor"); + this->reactor_ = reactor; +} + +/* static */ +ACE_INLINE ACE_Reactor * +ACE_CORBA_Handler::reactor (void) +{ + ACE_TRACE ("ACE_CORBA_Handler::reactor"); + return this->reactor_; +} + +#if defined (ACE_HAS_MT_ORBIX) +ACE_INLINE void +ACE_MT_CORBA_Handler::thr_mgr (ACE_Thread_Manager *tm) +{ + ACE_TRACE ("ACE_MT_CORBA_Handler::thr_mgr"); + this->thr_mgr_ = tm; +} + +ACE_INLINE ACE_Thread_Manager * +ACE_MT_CORBA_Handler::thr_mgr (void) const +{ + ACE_TRACE ("ACE_MT_CORBA_Handler::thr_mgr"); + return this->thr_mgr_; +} +#endif /* ACE_HAS_MT_ORBIX */ +#endif /* ACE_HAS_ORBIX */ diff --git a/ace/CORBA_Ref.cpp b/ace/CORBA_Ref.cpp new file mode 100644 index 00000000000..5bfec4317ae --- /dev/null +++ b/ace/CORBA_Ref.cpp @@ -0,0 +1,86 @@ +// CORBA_Ref.cpp +// $Id$ + +#if !defined (ACE_CORBA_REF_C) +#define ACE_CORBA_REF_C + +#define ACE_BUILD_DLL +#include "ace/CORBA_Ref.h" + +#if !defined (__ACE_INLINE__) +#include "ace/CORBA_Ref.i" +#endif /* __ACE_INLINE__ */ + +template +ACE_CORBA_Ref::ACE_CORBA_Ref (void) + : ref_ (0) +{ + ACE_TRACE ("ACE_CORBA_Ref::ACE_CORBA_Ref"); +} + +template +ACE_CORBA_Ref::ACE_CORBA_Ref (CORBA_REF *ref) +{ + ACE_TRACE ("ACE_CORBA_Ref::ACE_CORBA_Ref"); + if (ref != 0) + ref_ = ref->_duplicate (); + else + ref_ = 0; +} + +template CORBA_REF * +ACE_CORBA_Ref::operator= (CORBA_REF *ref) +{ + ACE_TRACE ("ACE_CORBA_Ref::operator="); + if (ref_ != 0) + ref_->_release (); + if (ref == 0) + { + ref_ = 0; + return 0; + } + else + return ref_ = ref->_duplicate (); +} + +template +ACE_CORBA_Ref::operator CORBA_REF * (void) const +{ + ACE_TRACE ("ACE_CORBA_Ref::operator CORBA_REF *"); + ACE_ASSERT (ref_ != 0); + return ref_; +} + +template CORBA_REF * +ACE_CORBA_Ref::operator-> (void) const +{ + ACE_TRACE ("ACE_CORBA_Ref::operator->"); + ACE_ASSERT (ref_ != 0); + return ref_; +} + +template int +ACE_CORBA_Ref::operator== (CORBA_REF *rhs) const +{ + ACE_TRACE ("ACE_CORBA_Ref::operator=="); + // pointer comparison. + return ref_ == rhs; +} + +template int +ACE_CORBA_Ref::operator!= (CORBA_REF *rhs) const +{ + ACE_TRACE ("ACE_CORBA_Ref::operator!="); + // pointer comparison. + return ref_ != rhs; +} + +template +ACE_CORBA_Ref::~ACE_CORBA_Ref () +{ + ACE_TRACE ("ACE_CORBA_Ref::~ACE_CORBA_Ref"); + if (ref_ != 0) + ref_->_release (); +} + +#endif // ACE_CORBA_REF_C diff --git a/ace/CORBA_Ref.h b/ace/CORBA_Ref.h new file mode 100644 index 00000000000..c344cc401c6 --- /dev/null +++ b/ace/CORBA_Ref.h @@ -0,0 +1,80 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// CORBA_Ref +// +// = AUTHOR +// Irfan Pyarali (irfan@wuerl.wustl.edu). +// Tim Harrison (harrison@cs.wustl.edu) +// +// = DESCRIPTION +// A wrapper for helping with Orbix object references. +// +// ============================================================================ + +#if !defined (ACE_CORBA_REF_H) +#define ACE_CORBA_REF_H + +template +class ACE_CORBA_Ref + // = TITLE + // A wrapper for helping with orbix object references. + // + // = DESCRIPTION + // ACE_CORBA_Ref is parameterized by the type of orbix object + // reference to be used. The construtor, operator=, and the + // destructor of ACE_CORBA_Ref perform implicit duplicates and + // releases in order to help make the use of orbix object + // references transparent. +{ +public: + ACE_CORBA_Ref (void); + // Null construction. + + ACE_CORBA_Ref (CORBA_REF *ref); + // Contruction with an orbix ref. + // performs a ref->_duplicate(). + + CORBA_REF *operator= (CORBA_REF *ref); + // Assignment performs a ref->_duplicate(). + + operator CORBA_REF *(void) const; + // Type operator + + CORBA_REF *operator-> (void) const; + // Smart pointer to forward all CORBA_REF calls to the underlying + // orbix reference. + + int operator== (CORBA_REF *) const; + // Pointer comparison. + + int operator!= (CORBA_REF *) const; + // Pointer comparison. + + ~ACE_CORBA_Ref (void); + // Destruction: calls ref_->_release + +private: + CORBA_REF *ref_; +}; + +#if defined (__ACE_INLINE__) +#include "ace/CORBA_Ref.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/CORBA_Ref.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("CORBA_Ref.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* CORBA_REF_H */ diff --git a/ace/CORBA_Ref.i b/ace/CORBA_Ref.i new file mode 100644 index 00000000000..3002ddac574 --- /dev/null +++ b/ace/CORBA_Ref.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// $Id$ + +// CORBA_Ref.i diff --git a/ace/Connector.cpp b/ace/Connector.cpp new file mode 100644 index 00000000000..917c6ce9ada --- /dev/null +++ b/ace/Connector.cpp @@ -0,0 +1,533 @@ +// Connector.cpp +// $Id$ + +#if !defined (ACE_CONNECTOR_C) +#define ACE_CONNECTOR_C + +#define ACE_BUILD_DLL +#include "ace/Connector.h" + +/* Shorthand names */ +#define SH SVC_HANDLER +#define PR_CO_1 ACE_PEER_CONNECTOR_1 +#define PR_CO_2 ACE_PEER_CONNECTOR_2 +#define PR_AD ACE_PEER_CONNECTOR_ADDR + +ACE_ALLOC_HOOK_DEFINE(ACE_Connector) + +template ACE_Reactor * +ACE_Connector::reactor (void) const +{ + ACE_TRACE ("ACE_Connector::reactor"); + return this->reactor_; +} + +template void +ACE_Connector::reactor (ACE_Reactor *r) +{ + ACE_TRACE ("ACE_Connector::reactor"); + this->reactor_ = r; +} + +template void +ACE_Connector::dump (void) const +{ + ACE_TRACE ("ACE_Connector::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->handler_map_.dump (); + this->connector_.dump (); + ACE_DEBUG ((LM_DEBUG, "reactor_ = %x", this->reactor_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +template int +ACE_Connector::activate_svc_handler (SVC_HANDLER *svc_handler) +{ + ACE_TRACE ("ACE_Connector::activate_svc_handler"); + // We are connected now, so try to open things up. + if (svc_handler->open ((void *) this) == -1) + { + // Make sure to close down the Channel to avoid descriptor leaks. + svc_handler->close (0); + return -1; + } + else + return 0; +} + +template int +ACE_Connector::connect_svc_handler (SVC_HANDLER *svc_handler, + const PR_AD &remote_addr, + const ACE_Synch_Options &synch_options, + const PR_AD &local_addr, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_Connector::connect_svc_handler"); + // Note that if timeout == ACE_Time_Value (x, y) where (x > 0 || y > + // 0) then this->connector_.connect() will block synchronously. If + // is set then we don't want this to happen (since we + // want the ACE_Reactor to do the timeout asynchronously). + // Therefore, we'll force this->connector_ to use ACE_Time_Value (0, + // 0) in this case... + + ACE_Time_Value *timeout; + int use_reactor = synch_options[ACE_Synch_Options::USE_REACTOR]; + + if (use_reactor) + timeout = (ACE_Time_Value *) &ACE_Time_Value::zero; + else + timeout = (ACE_Time_Value *) synch_options.time_value (); + + if (this->connector_.connect (*svc_handler, + remote_addr, + timeout, + local_addr, + reuse_addr, + flags, + perms) == -1) + { + if (use_reactor && errno == EWOULDBLOCK) + { + // If the connection hasn't completed and we are using + // non-blocking semantics then register ourselves with the + // ACE_Reactor so that it will call us back when the + // connection is complete or we timeout, whichever comes + // first... Note that we needn't check the return value + // here because if something goes wrong that will reset + // errno this will be detected by the caller (since -1 is + // being returned...). + this->create_AST (svc_handler, synch_options); + } + else + // Make sure to close down the Channel to avoid descriptor leaks. + svc_handler->close (0); + return -1; + } + else + // Activate immediately if we are connected. + return this->activate_svc_handler (svc_handler); +} + +template PEER_CONNECTOR & +ACE_Connector::connector (void) const +{ + ACE_TRACE ("ACE_Connector::connector"); + return (PEER_CONNECTOR &) this->connector_; +} + +template int +ACE_Connector::open (ACE_Reactor *reactor) +{ + ACE_TRACE ("ACE_Connector::open"); + this->reactor_ = reactor; + return 0; +} + +// Register the SVC_HANDLER with the map of pending connections so +// that it can be activated when the connection completes. + +template ACE_HANDLE +ACE_Connector::get_handle (void) const +{ + ACE_TRACE ("ACE_Connector::get_handle"); + return this->connector_.get_handle (); +} + +template +ACE_Svc_Tuple::ACE_Svc_Tuple (SVC_HANDLER *sh, + ACE_HANDLE handle, + const void *arg, + int id) + : svc_handler_ (sh), + handle_ (handle), + arg_ (arg), + cancellation_id_ (id) +{ + ACE_TRACE ("ACE_Svc_Tuple::ACE_Svc_Tuple"); +} + +template SVC_HANDLER * +ACE_Svc_Tuple::svc_handler (void) +{ + ACE_TRACE ("ACE_Svc_Tuple::svc_handler"); + return this->svc_handler_; +} + +template const void * +ACE_Svc_Tuple::arg (void) +{ + ACE_TRACE ("ACE_Svc_Tuple::arg"); + return this->arg_; +} + +template void +ACE_Svc_Tuple::arg (const void *v) +{ + ACE_TRACE ("ACE_Svc_Tuple::arg"); + this->arg_ = v; +} + +template ACE_HANDLE +ACE_Svc_Tuple::handle (void) +{ + ACE_TRACE ("ACE_Svc_Tuple::handle"); + return this->handle_; +} + +template void +ACE_Svc_Tuple::handle (ACE_HANDLE h) +{ + ACE_TRACE ("ACE_Svc_Tuple::handle"); + this->handle_ = h; +} + +template int +ACE_Svc_Tuple::cancellation_id (void) +{ + ACE_TRACE ("ACE_Svc_Tuple::cancellation_id"); + return this->cancellation_id_; +} + +template void +ACE_Svc_Tuple::cancellation_id (int id) +{ + ACE_TRACE ("ACE_Svc_Tuple::cancellation_id"); + this->cancellation_id_ = id; +} + +template void +ACE_Svc_Tuple::dump (void) const +{ + ACE_TRACE ("ACE_Svc_Tuple::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "svc_handler_ = %x", this->svc_handler_)); + ACE_DEBUG ((LM_DEBUG, "\narg_ = %x", this->arg_)); + ACE_DEBUG ((LM_DEBUG, "\ncancellation_id_ = %d", this->cancellation_id_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +template +ACE_Connector::ACE_Connector (ACE_Reactor *reactor) + : reactor_ (reactor) +{ + ACE_TRACE ("ACE_Connector::ACE_Connector"); +} + +// This method is called if a connection times out before completing. +// In this case, we call our cleanup_AST() method to cleanup the +// descriptor from the ACE_Connector's table. + +template int +ACE_Connector::handle_timeout (const ACE_Time_Value &tv, + const void *arg) +{ + ACE_TRACE ("ACE_Connector::handle_timeout"); + AST *ast = 0; + + if (this->cleanup_AST (((AST *) arg)->handle (), + ast) == -1) + return -1; + else + { + ACE_ASSERT (((AST *) arg) == ast); + + // We may need this seemingly unnecessary assignment to work + // around a bug with MSVC++? + SH *sh = ast->svc_handler (); + + // Forward to the SVC_HANDLER the that was passed in as a + // magic cookie during ACE_Connector::connect(). + sh->handle_timeout (tv, ast->arg ()); + + delete ast; + return 0; + } +} + +template int +ACE_Connector::cleanup_AST (ACE_HANDLE handle, + ACE_Svc_Tuple *&ast) +{ + ACE_TRACE ("ACE_Connector::cleanup_AST"); + + // Locate the ACE_Svc_Handler corresponding to the socket descriptor. + if (this->handler_map_.find (handle, ast) == -1) + { + // Error, entry not found in map. + errno = ENOENT; + ACE_ERROR_RETURN ((LM_ERROR, "%p %d not found in map\n", + "find", handle), -1); + } + + // Try to remove from ACE_Timer_Queue but if it's not there we ignore + // the error. + this->reactor_->cancel_timer (ast->cancellation_id ()); + + // Remove ACE_HANDLE from ACE_Reactor. + this->reactor_->remove_handler (handle, ACE_Event_Handler::RWE_MASK + | ACE_Event_Handler::DONT_CALL); + + // Remove ACE_HANDLE from the map. + this->handler_map_.unbind (handle); + return 0; +} + +// Called when a failure occurs during asynchronous connection +// establishment. Simply delegate all work to this->handle_output(). + +template int +ACE_Connector::handle_input (ACE_HANDLE h) +{ + ACE_TRACE ("ACE_Connector::handle_input"); + AST *ast = 0; + + if (this->cleanup_AST (h, ast) != -1) + { + ast->svc_handler ()->close (0); + delete ast; + } + return 0; // Already removed from the ACE_Reactor. +} + +// Finalize a connection established in non-blocking mode. When a +// non-blocking connect *succeeds* the descriptor becomes enabled for +// writing... Likewise, it is generally the case that when a +// non-blocking connect *fails* the descriptor becomes enabled for +// reading. + +template int +ACE_Connector::handle_output (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_Connector::handle_output"); + AST *ast = 0; + + if (this->cleanup_AST (handle, ast) == -1) + return 0; + + ACE_ASSERT (ast != 0); // This shouldn't happen! + + // Transfer ownership of the ACE_HANDLE to the SVC_HANDLER. + ast->svc_handler ()->set_handle (handle); + + PR_AD raddr; + + // Check to see if we're connected. + if (ast->svc_handler ()->peer ().get_remote_addr (raddr) != -1) + this->activate_svc_handler (ast->svc_handler ()); + else // Somethings gone wrong, so close down... + ast->svc_handler ()->close (0); + + delete ast; + return 0; +} + +// Initiate connection to peer. + +template int +ACE_Connector::connect (SH *sh, + const PR_AD &remote_addr, + const ACE_Synch_Options &synch_options, + const PR_AD &local_addr, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_Connector::connect"); + // Delegate to connection strategy. + return this->connect_svc_handler (sh, remote_addr, synch_options, + local_addr, reuse_addr, + flags, perms); + +} + +// Cancel a that was started asynchronously. +template int +ACE_Connector::cancel (SH *sh) +{ + ACE_TRACE ("ACE_Connector::cancel"); + MAP_ITERATOR mi (this->handler_map_); + + for (MAP_ENTRY *me = 0; + mi.next (me) != 0; + mi.advance ()) + if (me->int_id_->svc_handler () == sh) + { + AST *ast = 0; + this->cleanup_AST (me->ext_id_, ast); + ACE_ASSERT (ast == me->int_id_); + delete me->int_id_; + return 0; + } + + return -1; +} + +// Register the pending SVC_HANDLER with the map so that it can be +// activated later on when the connection complets. + +template int +ACE_Connector::create_AST (SH *sh, + const ACE_Synch_Options &synch_options) +{ + ACE_TRACE ("ACE_Connector::create_AST"); + AST *ast; + + ACE_NEW_RETURN (ast, AST (sh, this->get_handle (), synch_options.arg ()), -1); + + // Register this with the reactor for both reading and writing + // events. + if (this->reactor_->register_handler (this, + ACE_Event_Handler::READ_MASK + | ACE_Event_Handler::WRITE_MASK) == -1) + goto fail1; + + // Bind ACE_Svc_Tuple with the ACE_HANDLE we're trying to connect. + else if (this->handler_map_.bind (this->get_handle (), ast) == -1) + goto fail2; + // If we're starting connection under timer control then we need to + // schedule a timeout with the ACE_Reactor. + else + { + ACE_Time_Value *tv = (ACE_Time_Value *) synch_options.time_value (); + + if (tv != 0) + { + int cancellation_id = + this->reactor_->schedule_timer (this, + (const void *) ast, + *tv); + if (cancellation_id == -1) + goto fail3; + + ast->cancellation_id (cancellation_id); + return 0; + } + else + { + // Reset this because something might have gone wrong + // elsewhere... + errno = EWOULDBLOCK; + return 0; // Ok, everything worked just fine... + } + } + + // Undo previous actions using the ol' "goto label and fallthru" + // trick... +fail3: + this->handler_map_.unbind (this->get_handle ()); + /* FALLTHRU */ +fail2: + this->reactor_->remove_handler (this, + ACE_Event_Handler::READ_MASK + | ACE_Event_Handler::WRITE_MASK + | ACE_Event_Handler::DONT_CALL); + /* FALLTHRU */ +fail1: + delete ast; + return -1; +} + +// Terminate the Client ACE_Connector by iterating over any +// unconnected ACE_Svc_Handler's and removing them from the +// ACE_Reactor. Note that we can't call handle_close() back at this +// point since we own these things and we'll just get called +// recursively! + +template int +ACE_Connector::handle_close (ACE_HANDLE, ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Connector::handle_close"); + // Remove all timer objects from the Reactor's Timer_Queue. + this->reactor_->cancel_timer (this); + + MAP_ITERATOR mi (this->handler_map_); + + // Iterate through the map and shut down all the pending handlers. + + for (MAP_ENTRY *me = 0; + mi.next (me) != 0; + mi.advance ()) + { + this->reactor_->remove_handler (me->ext_id_, + mask | ACE_Event_Handler::DONT_CALL); + + AST *ast = 0; + this->cleanup_AST (me->ext_id_, ast); + ACE_ASSERT (ast == me->int_id_); + delete me->int_id_; + } + return 0; +} + +template int +ACE_Connector::fini (void) +{ + ACE_TRACE ("ACE_Connector::fini"); + // Make sure we call our handle_close(), not a subclass's! + return ACE_Connector::handle_close (); +} + +// Hook called by the explicit dynamic linking facility. + +template int +ACE_Connector::init (int, char *[]) +{ + ACE_TRACE ("ACE_Connector::init"); + return -1; +} + +template int +ACE_Connector::suspend (void) +{ + ACE_TRACE ("ACE_Connector::suspend"); + return -1; +} + +template int +ACE_Connector::resume (void) +{ + ACE_TRACE ("ACE_Connector::resume"); + return -1; +} + +template int +ACE_Connector::info (char **strp, size_t length) const +{ + ACE_TRACE ("ACE_Connector::info"); + char buf[BUFSIZ]; + char addr_str[BUFSIZ]; + PR_AD addr; + + if (this->connector ().get_local_addr (addr) == -1) + return -1; + else if (addr.addr_to_string (addr_str, sizeof addr) == -1) + return -1; + + ACE_OS::sprintf (buf, "%s\t %s %s", + "ACE_Connector", addr_str, "# connector factory\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +template +ACE_Connector::~ACE_Connector (void) +{ + ACE_TRACE ("ACE_Connector::~ACE_Connector"); + // We will call our handle_close(), not a subclass's, due to the way + // that C++ destructors work. + this->handle_close (); +} + +#undef SH +#undef PR_CO_1 +#undef PR_CO_2 +#undef PR_AD +#endif /* ACE_CONNECTOR_C */ diff --git a/ace/Connector.h b/ace/Connector.h new file mode 100644 index 00000000000..8d9e7d44a5c --- /dev/null +++ b/ace/Connector.h @@ -0,0 +1,279 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Connector.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_CONNECTOR_H) +#define ACE_CONNECTOR_H + +#include "ace/Service_Config.h" +#include "ace/Service_Object.h" +#include "ace/Timer_Queue.h" +#include "ace/Map_Manager.h" +#include "ace/Svc_Handler.h" +#include "ace/Strategies.h" + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) +#define ACE_PEER_CONNECTOR_1 class PEER_CONNECTOR +#define ACE_PEER_CONNECTOR_2 PEER_CONNECTOR +#define ACE_PEER_CONNECTOR PEER_CONNECTOR +#define ACE_PEER_CONNECTOR_ADDR PEER_CONNECTOR::PEER_ADDR +#else +#define ACE_PEER_CONNECTOR_1 class PEER_CONNECTOR, class PEER_ADDR +#define ACE_PEER_CONNECTOR_2 PEER_CONNECTOR, PEER_ADDR +#define ACE_PEER_CONNECTOR PEER_CONNECTOR +#define ACE_PEER_CONNECTOR_ADDR PEER_ADDR +#endif /* ACE_TEMPLATE_TYPEDEFS */ + +template +class ACE_Svc_Tuple + // = TITLE + // Holds the ACE_Svc_Handler and its argument and + // until an asynchronous connection completes. + // + // = DESCRIPTION + // This is a no-brainer... +{ +public: + // = Initialization methods. + ACE_Svc_Tuple (SVC_HANDLER *, + ACE_HANDLE, + const void * = 0, + int timer_id = 0); + + // = Get SVC_HANDLER. + SVC_HANDLER *svc_handler (void); + + // = Get/set handle. + ACE_HANDLE handle (void); + // Get handle. + void handle (ACE_HANDLE); + // Set handle. + + // = Get/set argument. + const void *arg (void); + // Get argument. + void arg (const void *); + // Set argument. + + // = Set/get cancellation handle. + int cancellation_id (void); + // Get cancellation id. + void cancellation_id (int timer_id); + // Set cancellation id. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + SVC_HANDLER *svc_handler_; + // Associated SVC_HANDLER. + + ACE_HANDLE handle_; + // IPC that we are trying to connect. + + const void *arg_; + // Associated argument. + + int cancellation_id_; + // Associated cancellation id. +}; + +template +class ACE_Connector : public ACE_Service_Object + // = TITLE + // Generic factory for actively connecting clients and creating + // service handlers (SVC_HANDLERs). + // + // = DESCRIPTION + // Implements the strategy for actively establishing connections + // with clients. An ACE_Connector is parameterized by concrete + // types that conform to the interfaces of PEER_CONNECTOR and + // SVC_HANDLER. The PEER_CONNECTOR is instantiated with a + // transport mechanism that passively establishes connections. + // The SVC_HANDLER is instantiated with a concrete type that + // performs the application-specific service. An ACE_Connector + // inherits from ACE_Service_Object, which in turn inherits from + // ACE_Event_Handler. This enables the ACE_Reactor to dispatch + // the ACE_Connector's handle_output method when connections + // complete asynchronously. The handle_output method performs + // the connector's active connection establishment and service + // activation strategy. +{ +public: + // = Initialization and termination methods. + + ACE_Connector (ACE_Reactor *r = ACE_Service_Config::reactor ()); + // Initialize a connector. + + virtual int open (ACE_Reactor *r = ACE_Service_Config::reactor ()); + // Initialize a connector. + + ~ACE_Connector (void); + // Shutdown a connector and release resources. + + // = Connection establishment method + + virtual int connect (SVC_HANDLER *svc_handler, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + const ACE_Synch_Options &synch_options = ACE_Synch_Options::defaults, + const ACE_PEER_CONNECTOR_ADDR &local_addr + = (ACE_PEER_CONNECTOR_ADDR &) ACE_PEER_CONNECTOR_ADDR::sap_any, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0); + // Initiate connection to at using + // . If the caller wants to designate the selected + // they can (and can also insist that the + // be reused by passing a value == 1). and + // can be used to pass any flags that are needed to perform + // specific operations such as opening a file within connect with + // certain permissions. + + virtual int cancel (SVC_HANDLER *svc_handler); + // Cancel a that was started asynchronously. + + ACE_PEER_CONNECTOR &connector (void) const; + // Return the underlying PEER_CONNECTOR object. + + ACE_Reactor *reactor (void) const; + // Get the underlying Reactor *. + + void reactor (ACE_Reactor *); + // Set the underlying Reactor *. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + // = Helpful typedefs. + + typedef ACE_Svc_Tuple AST; + +#if defined (ACE_MT_SAFE) + typedef ACE_Map_Manager *, ACE_RW_Mutex> MAP_MANAGER; + typedef ACE_Map_Iterator *, ACE_RW_Mutex> MAP_ITERATOR; + typedef ACE_Map_Entry *> MAP_ENTRY; +// ACE_Thread_Mutex lock_; +#else + typedef ACE_Map_Manager *, ACE_Null_Mutex> MAP_MANAGER; + typedef ACE_Map_Iterator *, ACE_Null_Mutex> MAP_ITERATOR; + typedef ACE_Map_Entry *> MAP_ENTRY; +#endif /* ACE_MT_SAFE */ + + // = The following two methods define the Connector's strategies for + // connecting and activating SVC_HANDLER's, respectively. + + virtual int connect_svc_handler (SVC_HANDLER *svc_handler, + const ACE_PEER_CONNECTOR_ADDR &remote_addr, + const ACE_Synch_Options &synch_options, + const ACE_PEER_CONNECTOR_ADDR &local_addr, + int reuse_addr, + int flags, + int perms); + // Bridge method for connecting the to the + // . The default behavior delegates to the + // PEER_CONNECTOR::connect. + + virtual int activate_svc_handler (SVC_HANDLER *svc_handler); + // Bridge method for activating a with the appropriate + // concurrency strategy. The default behavior of this method is to + // activate the SVC_HANDLER by calling its open() method (which + // allows the SVC_HANDLER to define its own concurrency strategy). + // However, subclasses can override this strategy to do more + // sophisticated concurrency activations (such as creating the + // SVC_HANDLER as an "active object" via multi-threading or + // multi-processing). + + virtual int handle_input (ACE_HANDLE); + // Called by ACE_Reactor when asynchronous connections fail. + + virtual int handle_output (ACE_HANDLE); + // Called by ACE_Reactor when asynchronous connections succeed. + + // = Dynamic linking hooks. + virtual int init (int argc, char *argv[]); + // Default version does no work and returns -1. Must be overloaded + // by application developer to do anything meaningful. + + virtual int fini (void); + // Calls to shutdown the Connector gracefully. + + virtual int info (char **, size_t) const; + // Default version returns address info in . + + // = Demultiplexing hooks. + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::RWE_MASK); + // Terminate the Client ACE_Connector by iterating over any + // unconnected ACE_Svc_Handler's and removing them from the + // ACE_Reactor. + + virtual ACE_HANDLE get_handle (void) const; + // Return the underlying handle that's associated with the + // SVC_HANDLER we're currently trying to connect (or + // ACE_INVALID_HANDLER if there isn't one). + + virtual int handle_timeout (const ACE_Time_Value &tv, + const void *arg); + // This method is called if a connection times out before + // completing. + + // = Service management hooks. + virtual int suspend (void); + // Default version does no work and returns -1. Must be overloaded + // by application developer to do anything meaningful. + + virtual int resume (void); + // Default version does no work and returns -1. Must be overloaded + // by application developer to do anything meaningful. + + int create_AST (SVC_HANDLER *, + const ACE_Synch_Options &); + // Creates and inserts an ACE_Svc_Tuple into the . + // so that we can continue accepting this connection asynchronously. + + int cleanup_AST (ACE_HANDLE, AST *&); + // Cleanup the and returns the appropriate + // ACE_Svc_Tuple (which is 0 if there is no associated tuple). + + MAP_MANAGER handler_map_; + // Lookup table that maps an I/O handle to a SVC_HANDLER *. + +private: + ACE_PEER_CONNECTOR connector_; + // Factor that establishes connections actively. + + ACE_Reactor *reactor_; + // Event demultiplex associated with this object. +}; + +#include "ace/Connector.i" + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Connector.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Connector.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_CONNECTOR_H */ diff --git a/ace/Connector.i b/ace/Connector.i new file mode 100644 index 00000000000..7c7afcc0184 --- /dev/null +++ b/ace/Connector.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// $Id$ + +// Connector.i diff --git a/ace/DEV.cpp b/ace/DEV.cpp new file mode 100644 index 00000000000..6adf55737d5 --- /dev/null +++ b/ace/DEV.cpp @@ -0,0 +1,54 @@ +// DEV.cpp +// $Id$ + + +#define ACE_BUILD_DLL +#include "ace/DEV.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_DEV) + +void +ACE_DEV::dump (void) const +{ + ACE_TRACE ("ACE_DEV::dump"); +} + +// Return the local endpoint address. + +int +ACE_DEV::get_local_addr (ACE_DEV_Addr &addr) const +{ + ACE_TRACE ("ACE_DEV::get_local_addr"); + + addr = this->addr_; + return 0; +} + +// Return the address of the remotely connected peer (if there is +// one). + +int +ACE_DEV::get_remote_addr (ACE_DEV_Addr &addr) const +{ + ACE_TRACE ("ACE_DEV::get_remote_addr"); + addr = this->addr_; + return 0; +} + +// This is the do-nothing constructor. + +ACE_DEV::ACE_DEV (void) +{ + ACE_TRACE ("ACE_DEV::ACE_DEV"); +} + +// Close the device + +int +ACE_DEV::close (void) +{ + ACE_TRACE ("ACE_DEV::close"); + int result = ACE_OS::close (this->get_handle ()); + this->set_handle (ACE_INVALID_HANDLE); + return result; +} diff --git a/ace/DEV.h b/ace/DEV.h new file mode 100644 index 00000000000..4d4cdd0ace8 --- /dev/null +++ b/ace/DEV.h @@ -0,0 +1,71 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// DEV.h +// +// = AUTHOR +// Gerhard Lenzer +// +// ============================================================================ + +#if !defined (ACE_DEV_H) +#define ACE_DEV_H + +#include "ace/IO_SAP.h" +#include "ace/DEV_Addr.h" + +// The following is necessary since many C++ compilers don't support +// typedef'd types inside of classes used as formal template +// arguments... ;-(. Luckily, using the C++ preprocessor I can hide +// most of this nastiness! + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) +#define ACE_DEV_CONNECTOR ACE_DEV_Connector +#define ACE_DEV_STREAM ACE_DEV_Stream +#else /* TEMPLATES are broken (must be a cfront-based compiler...) */ +#define ACE_DEV_CONNECTOR ACE_DEV_Connector, ACE_DEV_Addr +#define ACE_DEV_STREAM ACE_DEV_Stream, ACE_DEV_Addr +#endif /* ACE_TEMPLATE_TYPEDEFS */ + +class ACE_Export ACE_DEV : public ACE_IO_SAP + // = TITLE + // Defines the member functions for the base class of the + // ACE_DEV abstraction. +{ +public: + int close (void); + // Close down the DEVICE + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + + // = The following two methods are no-ops to keep the + // happy. + int get_local_addr (ACE_DEV_Addr &) const; + // Return the local endpoint address. + + int get_remote_addr (ACE_DEV_Addr &) const; + // Return the address of the remotely connected peer (if there is + // one). + +protected: + ACE_DEV (void); + // Ensure that this class is an abstract base class + + ACE_DEV_Addr addr_; + // Address of device we are connected to. +}; + +#include "ace/DEV.i" + +#endif /* ACE_DEV_H */ diff --git a/ace/DEV.i b/ace/DEV.i new file mode 100644 index 00000000000..86d5e6b511d --- /dev/null +++ b/ace/DEV.i @@ -0,0 +1,6 @@ +/* -*- C++ -*- */ +// $Id$ + +// DEV.i + + diff --git a/ace/DEV_Addr.cpp b/ace/DEV_Addr.cpp new file mode 100644 index 00000000000..01833806e62 --- /dev/null +++ b/ace/DEV_Addr.cpp @@ -0,0 +1,65 @@ +// DEV_Addr.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/DEV_Addr.h" + +#if !defined (__ACE_INLINE__) +#include "ace/DEV_Addr.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_DEV_Addr) + +void +ACE_DEV_Addr::dump (void) const +{ + ACE_TRACE ("ACE_DEV_Addr::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "devname_ = %s", this->devname_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// Do nothing constructor. + +ACE_DEV_Addr::ACE_DEV_Addr (void) + : ACE_Addr (AF_DEV, sizeof this->devname_) +{ + ACE_TRACE ("ACE_DEV_Addr::ACE_DEV_Addr"); + + (void) ACE_OS::memset ((void *) &this->devname_, + 0, sizeof this->devname_); +} + +// Copy constructor. + +ACE_DEV_Addr::ACE_DEV_Addr (const ACE_DEV_Addr &sa) + : ACE_Addr (AF_DEV, ACE_OS::strlen (this->devname_)) +{ + ACE_TRACE ("ACE_DEV_Addr::ACE_DEV_Addr"); + + (void) ACE_OS::memcpy ((void *) &this->devname_, + (void *) &sa.devname_, + sa.get_size ()); +} + +ACE_DEV_Addr::ACE_DEV_Addr (LPCTSTR devname) +{ + ACE_TRACE ("ACE_DEV_Addr::ACE_DEV_Addr"); + + this->set (devname); +} + +ACE_DEV_Addr & +ACE_DEV_Addr::operator= (const ACE_DEV_Addr &sa) +{ + ACE_TRACE ("ACE_DEV_Addr::operator="); + + if (this != &sa) + (void) ACE_OS::memcpy ((void *) &this->devname_, + (void *) &sa.devname_, + sa.get_size ()); + return *this; +} + diff --git a/ace/DEV_Addr.h b/ace/DEV_Addr.h new file mode 100644 index 00000000000..1a00dc166f9 --- /dev/null +++ b/ace/DEV_Addr.h @@ -0,0 +1,75 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// DEV_Addr.h +// +// = AUTHOR +// Gerhard Lenzer and Douglas C. Schmidt +// +// ============================================================================ + +#if !defined (ACE_DEV_ADDR_H) +#define ACE_DEV_ADDR_H + +#include "ace/Addr.h" +#include "ace/ACE.h" + +class ACE_Export ACE_DEV_Addr : public ACE_Addr + // = TITLE + // Defines device address family address format. +{ +public: + // = Initialization methods. + ACE_DEV_Addr (void); + // Default constructor. + + ACE_DEV_Addr (const ACE_DEV_Addr &sa); + // Copy constructor. + + ACE_DEV_Addr (LPCTSTR devname); + // Create a ACE_DEV_Addr from a device name. + + void set (LPCTSTR devname); + // Create a ACE_Addr from a ACE_DEV pathname. + + ACE_DEV_Addr &operator= (const ACE_DEV_Addr &); + // Assignment operator. + + virtual void *get_addr (void) const; + // Return a pointer to the address. + + virtual int addr_to_string (char addr[], size_t) const; + // Transform the current address into string format. + + virtual int operator == (const ACE_Addr &SAP) const; + // Compare two addresses for equality. + + virtual int operator != (const ACE_Addr &SAP) const; + // Compare two addresses for inequality. + + LPCTSTR get_path_name (void) const; + // Return the path name used for the rendezvous point. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + TCHAR devname_[MAXNAMLEN + 1]; + // Name of the device. +}; + +#if defined (__ACE_INLINE__) +#include "ace/DEV_Addr.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_DEV_ADDR_H */ diff --git a/ace/DEV_Addr.i b/ace/DEV_Addr.i new file mode 100644 index 00000000000..4507b0da782 --- /dev/null +++ b/ace/DEV_Addr.i @@ -0,0 +1,65 @@ +/* -*- C++ -*- */ +// $Id$ + + +ACE_INLINE void +ACE_DEV_Addr::set (LPCTSTR devname) +{ + ACE_TRACE ("ACE_DEV_Addr::set"); + + this->ACE_Addr::base_set (AF_DEV, ACE_OS::strlen (devname)); + ACE_OS::strncpy (this->devname_, devname, MAXNAMLEN); +} + +// Transform the current address into string format. + +ACE_INLINE int +ACE_DEV_Addr::addr_to_string (char s[], size_t len) const +{ + ACE_TRACE ("ACE_DEV_Addr::addr_to_string"); + + ACE_OS::strncpy (s, this->devname_, len); + return 0; +} + +// Return a pointer to the address. + +ACE_INLINE void * +ACE_DEV_Addr::get_addr (void) const +{ + ACE_TRACE ("ACE_DEV_Addr::get_addr"); + + return (void *) &this->devname_; +} + +// Compare two addresses for equality. + +ACE_INLINE int +ACE_DEV_Addr::operator == (const ACE_Addr &sap) const +{ + ACE_TRACE ("ACE_DEV_Addr::operator="); + + return ACE_OS::strcmp (this->devname_, + ((ACE_DEV_Addr &) sap).devname_) == 0; +} + +// Compare two addresses for inequality. + +ACE_INLINE int +ACE_DEV_Addr::operator != (const ACE_Addr &sap) const +{ + ACE_TRACE ("ACE_DEV_Addr::operator!="); + + return !((*this) == sap); // This is lazy, of course... ;-). +} + +// Return the path name used for the rendezvous point. + +ACE_INLINE LPCTSTR +ACE_DEV_Addr::get_path_name (void) const +{ + ACE_TRACE ("ACE_DEV_Addr::get_path_name"); + + return this->devname_; +} + diff --git a/ace/DEV_Connector.cpp b/ace/DEV_Connector.cpp new file mode 100644 index 00000000000..967e7adb6f6 --- /dev/null +++ b/ace/DEV_Connector.cpp @@ -0,0 +1,40 @@ +// DEV_Connector.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/DEV_Connector.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_DEV_Connector) + +void +ACE_DEV_Connector::dump (void) const +{ + ACE_TRACE ("ACE_DEV_Connector::dump"); + + ACE_DEV::dump (); +} + +ACE_DEV_Connector::ACE_DEV_Connector (void) +{ + ACE_TRACE ("ACE_DEV_Connector::ACE_DEV_Connector"); +} + +int +ACE_DEV_Connector::connect (ACE_DEV_IO &new_io, + const ACE_DEV_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &, + int, + int flags, + int perms) +{ + ACE_TRACE ("ACE_DEV_Connector::connect"); + + ACE_HANDLE handle = ACE::handle_timed_open (timeout, + remote_sap.get_path_name (), + flags, perms); + new_io.set_handle (handle); + new_io.addr_ = remote_sap; // class copy. + return handle == ACE_INVALID_HANDLE ? -1 : 0; +} + diff --git a/ace/DEV_Connector.h b/ace/DEV_Connector.h new file mode 100644 index 00000000000..8a7e70941ff --- /dev/null +++ b/ace/DEV_Connector.h @@ -0,0 +1,86 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// DEV_Connector.h +// +// = AUTHOR +// Gerhard Lenzer and Douglas C. Schmidt +// +// ============================================================================ + +#if !defined (ACE_DEV_CONNECTOR_H) +#define ACE_DEV_CONNECTOR_H + +#include "ace/DEV_IO.h" + +class ACE_Export ACE_DEV_Connector : public ACE_DEV + // = TITLE + // Defines an active connection factory for the ACE_DEV wrappers. +{ +public: + ACE_DEV_Connector (void); + // Default constructor. + + ACE_DEV_Connector (ACE_DEV_IO &new_io, + const ACE_DEV_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0); + // Actively connect and produce a if things go well. + // The is the address that we are trying to connect + // with. The is the amount of time to wait to connect. + // If it's 0 then we block indefinitely. If *timeout == {0, 0} then + // the connection is done using non-blocking mode. In this case, if + // the connection can't be made immediately the value of -1 is + // returned with . If *timeout > {0, 0} then + // this is the amount of time to wait before timing out. If the + // time expires before the connection is made . + // The is the value of local address to bind to. If + // it's the default value of then the user is + // letting the OS do the binding. If == 1 then the + // is reused, even if it hasn't been cleanedup yet. + // The and arguments are passed down to the open() + // method. + + int connect (ACE_DEV_IO &new_io, + const ACE_DEV_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0); + // Actively connect and produce a if things go well. + // The is the address that we are trying to connect + // with. The is the amount of time to wait to connect. + // If it's 0 then we block indefinitely. If *timeout == {0, 0} then + // the connection is done using non-blocking mode. In this case, if + // the connection can't be made immediately the value of -1 is + // returned with . If *timeout > {0, 0} then + // this is the amount of time to wait before timing out. If the + // time expires before the connection is made . + // The is the value of local address to bind to. If + // it's the default value of then the user is + // letting the OS do the binding. If == 1 then the + // is reused, even if it hasn't been cleanedup yet. + // The and arguments are passed down to the open() + // method. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#include "ace/DEV_Connector.i" + +#endif /* ACE_DEV_CONNECTOR_H */ diff --git a/ace/DEV_Connector.i b/ace/DEV_Connector.i new file mode 100644 index 00000000000..14e3f988137 --- /dev/null +++ b/ace/DEV_Connector.i @@ -0,0 +1,25 @@ +/* -*- C++ -*- */ +// $Id$ + +// DEV_Connector.i + +#include "ace/Log_Msg.h" + +// Creates a Local ACE_DEV. + +inline +ACE_DEV_Connector::ACE_DEV_Connector (ACE_DEV_IO &new_io, + const ACE_DEV_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_DEV_Connector::ACE_DEV_Connector"); + if (this->connect (new_io, remote_sap, timeout, local_sap, + reuse_addr, flags, perms) == ACE_IO_SAP::INVALID_HANDLE + && timeout != 0 && !(errno == EWOULDBLOCK || errno == ETIMEDOUT)) + ACE_ERROR ((LM_ERROR, "address %s, %p\n", + remote_sap.get_path_name (), "ACE_DEV_IO")); +} diff --git a/ace/DEV_IO.cpp b/ace/DEV_IO.cpp new file mode 100644 index 00000000000..52b077a3ad3 --- /dev/null +++ b/ace/DEV_IO.cpp @@ -0,0 +1,97 @@ +// DEV_IO.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/DEV_IO.h" +#include "ace/Log_Msg.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_DEV_IO) + +void +ACE_DEV_IO::dump (void) const +{ + ACE_TRACE ("ACE_DEV_IO::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->addr_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// Simple-minded do nothing constructor. + +ACE_DEV_IO::ACE_DEV_IO (void) +{ + ACE_TRACE ("ACE_DEV_IO::ACE_DEV_IO"); +} + +// Send N char *ptrs and int lengths. Note that the char *'s precede +// the ints (basically, an varargs version of writev). The count N is +// the *total* number of trailing arguments, *not* a couple of the +// number of tuple pairs! + +ssize_t +ACE_DEV_IO::send (size_t n, ...) const +{ + ACE_TRACE ("ACE_DEV_IO::send"); + va_list argp; + size_t total_tuples = n / 2; + ssize_t result; +#if defined (ACE_HAS_ALLOCA) + iovec *iovp = (iovec *) alloca (total_tuples * sizeof (iovec)); +#else + iovec *iovp; + ACE_NEW_RETURN (iovp, iovec[total_tuples], -1); +#endif /* !defined (ACE_HAS_ALLOCA) */ + + va_start (argp, n); + + for (size_t i = 0; i < total_tuples; i++) + { + iovp[i].iov_base = va_arg (argp, char *); + iovp[i].iov_len = va_arg (argp, int); + } + + result = ACE_OS::writev (this->get_handle (), iovp, total_tuples); +#if !defined (ACE_HAS_ALLOCA) + delete [] iovp; +#endif /* !defined (ACE_HAS_ALLOCA) */ + va_end (argp); + return result; +} + +// This is basically an interface to ACE_OS::readv, that doesn't use the +// struct iovec explicitly. The ... can be passed as an arbitrary +// number of (char *ptr, int len) tuples. However, the count N is the +// *total* number of trailing arguments, *not* a couple of the number +// of tuple pairs! + +ssize_t +ACE_DEV_IO::recv (size_t n, ...) const +{ + ACE_TRACE ("ACE_DEV_IO::recv"); + va_list argp; + size_t total_tuples = n / 2; + ssize_t result; +#if defined (ACE_HAS_ALLOCA) + iovec *iovp = (iovec *) alloca (total_tuples * sizeof (iovec)); +#else + iovec *iovp; + ACE_NEW_RETURN (iovp, iovec[total_tuples], -1); +#endif /* !defined (ACE_HAS_ALLOCA) */ + + va_start (argp, n); + + for (size_t i = 0; i < total_tuples; i++) + { + iovp[i].iov_base = va_arg (argp, char *); + iovp[i].iov_len = va_arg (argp, int); + } + + result = ACE_OS::readv (this->get_handle (), iovp, total_tuples); +#if !defined (ACE_HAS_ALLOCA) + delete [] iovp; +#endif /* !defined (ACE_HAS_ALLOCA) */ + va_end (argp); + return result; +} + diff --git a/ace/DEV_IO.h b/ace/DEV_IO.h new file mode 100644 index 00000000000..60368bf1d1e --- /dev/null +++ b/ace/DEV_IO.h @@ -0,0 +1,104 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// DEV_IO.h +// +// = AUTHOR +// Gerhard Lenzer and Douglas C. Schmidt +// +// ============================================================================ + +#if !defined (ACE_DEV_IO_H) +#define ACE_DEV_IO_H + +#include "ace/DEV.h" +#include "ace/DEV_Addr.h" + +class ACE_Export ACE_DEV_IO : public ACE_DEV + // = TITLE + // Read/Write operations on Devices. +{ +friend class ACE_DEV_Connector; +public: + ACE_DEV_IO (void); + // Default constructor. + + // = Various send operations. + ssize_t send (const void *buf, size_t n) const; + // send upto bytes in . + + ssize_t recv (void *buf, size_t n) const; + // Recv upto bytes in . + + ssize_t send_n (const void *buf, size_t n) const; + // Send n bytes, keep trying until n are sent. + + ssize_t recv_n (void *buf, size_t n) const; + // Recv n bytes, keep trying until n are received. + +#if defined (ACE_HAS_STREAM_PIPES) + ssize_t recv (ACE_Str_Buf *cntl, + ACE_Str_Buf *data, + int *band, + int *flags) const; + // Recv bytes via STREAM pipes using "band" mode. + + ssize_t send (const ACE_Str_Buf *cntl, + const ACE_Str_Buf *data, + int band, + int flags = 0) const; + // Send bytes via STREAM pipes using "band" mode. + + ssize_t recv (ACE_Str_Buf *cntl, + ACE_Str_Buf *data, + int *flags) const; + // Recv and via STREAM pipes. + + ssize_t send (const ACE_Str_Buf *cntl, + const ACE_Str_Buf *data, + int flags = 0) const; + // Send and via STREAM pipes. +#endif /* ACE_HAS_STREAM_PIPES */ + + ssize_t send (const iovec iov[], size_t n) const; + // Send iovecs via <::writev>. + + ssize_t recv (iovec iov[], size_t n) const; + // Recv iovecs via <::readv>. + + ssize_t send (size_t n, ...) const; + // Send N char *ptrs and int lengths. Note that the char *'s + // precede the ints (basically, an varargs version of writev). The + // count N is the *total* number of trailing arguments, *not* a + // couple of the number of tuple pairs! + + ssize_t recv (size_t n, ...) const; + // This is an interface to ::readv, that doesn't use the struct + // iovec explicitly. The ... can be passed as an arbitrary number + // of (char *ptr, int len) tuples. However, the count N is the + // *total* number of trailing arguments, *not* a couple of the + // number of tuple pairs! + + ssize_t send (const void *buf, size_t n, ACE_OVERLAPPED *overlapped) const; + // Send bytes via Win32 WriteFile using overlapped I/O. + + ssize_t recv (void *buf, size_t n, ACE_OVERLAPPED *overlapped) const; + // Recv bytes via Win32 ReadFile using overlapped I/O. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#include "ace/DEV_IO.i" + +#endif /* ACE_DEV_IO_H */ diff --git a/ace/DEV_IO.i b/ace/DEV_IO.i new file mode 100644 index 00000000000..0597aa44b55 --- /dev/null +++ b/ace/DEV_IO.i @@ -0,0 +1,102 @@ +/* -*- C++ -*- */ +// $Id$ + +// DEV_IO.i + + +// Send exactly N bytes from BUF to this device. Keeping trying until +// this many bytes are sent. + +inline ssize_t +ACE_DEV_IO::send_n (const void *buf, size_t n) const +{ + ACE_TRACE ("ACE_DEV_IO::send_n"); + return ACE::write_n (this->get_handle (), buf, n); +} + +// Receive exactly N bytes from this file into BUF. Keep trying until +// this many bytes are received. + +inline ssize_t +ACE_DEV_IO::recv_n (void *buf, size_t n) const +{ + ACE_TRACE ("ACE_DEV_IO::recv_n"); + return ACE::read_n (this->get_handle (), buf, n); +} + +inline ssize_t +ACE_DEV_IO::send (const void *buf, size_t n) const +{ + ACE_TRACE ("ACE_DEV_IO::send"); + return ACE_OS::write (this->get_handle (), (const char *) buf, n); +} + +inline ssize_t +ACE_DEV_IO::recv (void *buf, size_t n) const +{ + ACE_TRACE ("ACE_DEV_IO::recv"); + return ACE_OS::read (this->get_handle (), (char *) buf, n); +} + +inline ssize_t +ACE_DEV_IO::send (const iovec iov[], size_t n) const +{ + ACE_TRACE ("ACE_DEV_IO::send"); + return ACE_OS::writev (this->get_handle (), (iovec *) iov, n); +} + +inline ssize_t +ACE_DEV_IO::recv (iovec iov[], size_t n) const +{ + ACE_TRACE ("ACE_DEV_IO::recv"); + return ACE_OS::readv (this->get_handle (), (iovec *) iov, n); +} + +inline ssize_t +ACE_DEV_IO::send (const void *buf, size_t n, + ACE_OVERLAPPED *overlapped) const +{ + ACE_TRACE ("ACE_DEV_IO::send"); + return ACE_OS::write (this->get_handle (), + (const char *) buf, n, + overlapped); +} + +inline ssize_t +ACE_DEV_IO::recv (void *buf, size_t n, + ACE_OVERLAPPED *overlapped) const +{ + ACE_TRACE ("ACE_DEV_IO::recv"); + return ACE_OS::read (this->get_handle (), (char *) buf, n, + overlapped); +} + +#if defined (ACE_HAS_STREAM_PIPES) +inline ssize_t +ACE_DEV_IO::recv (ACE_Str_Buf *cntl, ACE_Str_Buf *data, int *band, int *flags) const +{ + ACE_TRACE ("ACE_DEV_IO::recv"); + return ACE_OS::getpmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, band, flags); +} + +inline ssize_t +ACE_DEV_IO::send (const ACE_Str_Buf *cntl, const ACE_Str_Buf *data, int band, int flags) const +{ + ACE_TRACE ("ACE_DEV_IO::send"); + return ACE_OS::putpmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, band, flags); +} + +inline ssize_t +ACE_DEV_IO::recv (ACE_Str_Buf *cntl, ACE_Str_Buf *data, int *flags) const +{ + ACE_TRACE ("ACE_DEV_IO::recv"); + return ACE_OS::getmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, flags); +} + +inline ssize_t +ACE_DEV_IO::send (const ACE_Str_Buf *cntl, const ACE_Str_Buf *data, int flags) const +{ + ACE_TRACE ("ACE_DEV_IO::send"); + return ACE_OS::putmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, flags); +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/ace/Date_Time.cpp b/ace/Date_Time.cpp new file mode 100644 index 00000000000..0aeb72780f0 --- /dev/null +++ b/ace/Date_Time.cpp @@ -0,0 +1,5 @@ +// Date_Time.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Date_Time.h" diff --git a/ace/Date_Time.h b/ace/Date_Time.h new file mode 100644 index 00000000000..7f7dcbd33ad --- /dev/null +++ b/ace/Date_Time.h @@ -0,0 +1,92 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// ACE_Date_Time.h +// +// = AUTHOR +// Tim Harrison (harrison@cs.wustl.edu) (and he's darn proud of this ;-)) +// +// ============================================================================ + +#if !defined (ACE_DATE_TIME_H) +#define ACE_DATE_TIME_H + +#include "ace/ACE.h" + +class ACE_Export ACE_Date_Time + // = TITLE + // System independent representation of date and time. +{ +public: + // constructor with init values, no check for validy + ACE_Date_Time (long day = 0, + long month = 0, + long year = 0, + long hour = 0, + long minute = 0, + long second = 0, + long microsec = 0); + // Set/get portions of ACE_Date_Time, no check for validity. + + long day (void); + // Get day. + + void day (long day); + // Set day. + + long month (void); + // Get month. + + void month (long month); + // Set month. + + long year (void); + // Get year. + + void year (long year); + // Set year. + + long hour (void); + // Get hour. + + void hour (long hour); + // Set hour. + + long minute (void); + // Get minute. + + void minute (long minute); + // Set minute. + + long second (void); + // Get second. + + void second (long second); + // Set second. + + long microsec (void); + // Get microsec. + + void microsec (long microsec); + // Set microsec. + +private: + long day_; + long month_; + long year_; + long hour_; + long minute_; + long second_; + long microsec_; +}; + +#include "ace/Date_Time.i" + +#endif /* ACE_DATE_TIME_H */ diff --git a/ace/Date_Time.i b/ace/Date_Time.i new file mode 100644 index 00000000000..829e91c003f --- /dev/null +++ b/ace/Date_Time.i @@ -0,0 +1,140 @@ +/* -*- C++ -*- */ +// $Id$ + +// Date_Time.i + +// constructor with init values, no check for validy +inline +ACE_Date_Time::ACE_Date_Time(long day, + long month, + long year, + long hour, + long minute, + long second, + long microsec) +: day_ (day), + month_ (month), + year_ (year), + hour_ (hour), + minute_ (minute), + second_ (second), + microsec_ (microsec) +{ + ACE_TRACE ("ACE_Date_Time::ACE_Date_Time"); +} + +// set/get portions of ACE_Date_Time, no check for validy + +// get day +inline long +ACE_Date_Time::day (void) +{ + ACE_TRACE ("ACE_Date_Time::day"); + return day_; +} + +// set day +inline void +ACE_Date_Time::day (long day) +{ + ACE_TRACE ("ACE_Date_Time::day"); + day_ = day; +} + +// get month +inline long +ACE_Date_Time::month (void) +{ + ACE_TRACE ("ACE_Date_Time::month"); + return month_; +} + +// set month +inline void +ACE_Date_Time::month (long month) +{ + ACE_TRACE ("ACE_Date_Time::month"); + month_ = month; +} + +// get year +inline long +ACE_Date_Time::year (void) +{ + ACE_TRACE ("ACE_Date_Time::year"); + return year_; +} + +// set year +inline void +ACE_Date_Time::year (long year) +{ + ACE_TRACE ("ACE_Date_Time::year"); + year_ = year; +} + +// get hour +inline long +ACE_Date_Time::hour (void) +{ + ACE_TRACE ("ACE_Date_Time::hour"); + return hour_; +} + +// set hour +inline void +ACE_Date_Time::hour (long hour) +{ + ACE_TRACE ("ACE_Date_Time::hour"); + hour_ = hour; +} + +// get minute +inline long +ACE_Date_Time::minute (void) +{ + ACE_TRACE ("ACE_Date_Time::minute"); + return minute_; +} + +// set minute +inline void +ACE_Date_Time::minute (long minute) +{ + ACE_TRACE ("ACE_Date_Time::minute"); + minute_ = minute; +} + +// get second +inline long +ACE_Date_Time::second (void) +{ + ACE_TRACE ("ACE_Date_Time::second"); + return second_; +} + +// set second +inline void +ACE_Date_Time::second (long second) +{ + ACE_TRACE ("ACE_Date_Time::second"); + second_ = second; +} + +// get microsec +inline long +ACE_Date_Time::microsec (void) +{ + ACE_TRACE ("ACE_Date_Time::microsec"); + return microsec_; +} + +// set microsec +inline void +ACE_Date_Time::microsec (long microsec) +{ + ACE_TRACE ("ACE_Date_Time::microsec"); + microsec_ = microsec; +} + + diff --git a/ace/Dump.cpp b/ace/Dump.cpp new file mode 100644 index 00000000000..ea231f6b243 --- /dev/null +++ b/ace/Dump.cpp @@ -0,0 +1,132 @@ +// Dump.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Dump.h" + +#if defined (ACE_MT_SAFE) +// Synchronize output operations. +ACE_Thread_Mutex ACE_ODB::ace_dump_lock_; +#endif /* ACE_MT_SAFE */ + +// Implementations (very simple for now...) + +ACE_Dumpable::~ACE_Dumpable (void) +{ + ACE_TRACE ("ACE_Dumpable::~ACE_Dumpable"); +} + +ACE_Dumpable::ACE_Dumpable (const void *this_ptr) + : this_ (this_ptr) +{ + ACE_TRACE ("ACE_Dumpable::ACE_Dumpable"); +} + +ACE_Dumpable_Ptr::ACE_Dumpable_Ptr (const ACE_Dumpable *dumper) + : dumper_ (dumper) +{ + ACE_TRACE ("ACE_Dumpable_Ptr::ACE_Dumpable_Ptr"); +} + +const ACE_Dumpable * +ACE_Dumpable_Ptr::operator->() const +{ + ACE_TRACE ("ACE_Dumpable_Ptr::operator->"); + return this->dumper_; +} + +void +ACE_Dumpable_Ptr::operator= (const ACE_Dumpable *dumper) const +{ + ACE_TRACE ("ACE_Dumpable_Ptr::operator="); + if (this->dumper_ != dumper) + { + delete (ACE_Dumpable_Ptr *) this->dumper_; + ((ACE_Dumpable_Ptr *) this)->dumper_ = dumper; + } +} + +ACE_ODB::ACE_ODB (void) +{ + ACE_TRACE ("ACE_ODB::ACE_ODB"); +} + +ACE_ODB * +ACE_ODB::instance (void) +{ + ACE_TRACE ("ACE_ODB::instance"); + + if (ACE_ODB::instance_ == 0) + { + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, ACE_ODB::ace_dump_lock_, 0)); + + if (ACE_ODB::instance_ == 0) + ACE_NEW_RETURN (ACE_ODB::instance_, ACE_ODB, 0); + } + + return ACE_ODB::instance_; +} + +void +ACE_ODB::dump_objects (void) +{ + ACE_TRACE ("ACE_ODB::dump_objects"); + for (int i = 0; i < this->current_size_; i++) + { + if (this->object_table_[i].this_ != 0) + // Dump the state of the object. + this->object_table_[i].dumper_->dump (); + } +} + +// This method registers a new . It detects +// duplicates and simply overwrites them. + +void +ACE_ODB::register_object (const ACE_Dumpable *dumper) +{ + ACE_TRACE ("ACE_ODB::register_object"); + int i; + int slot; + + for (i = 0; i < this->current_size_; i++) + { + if (this->object_table_[i].this_ == 0) + slot = i; + else if (this->object_table_[i].this_ == dumper->this_) + { + slot = i; + break; + } + } + + if (i == this->current_size_) + { + slot = this->current_size_++; + ACE_ASSERT (this->current_size_ < ACE_ODB::MAX_TABLE_SIZE); + } + this->object_table_[slot].this_ = dumper->this_; + this->object_table_[slot].dumper_ = dumper; +} + +void +ACE_ODB::remove_object (const void *this_ptr) +{ + ACE_TRACE ("ACE_ODB::remove_object"); + int i; + + for (i = 0; i < this->current_size_; i++) + { + if (this->object_table_[i].this_ == this_ptr) + break; + } + + if (i < this->current_size_) + { + this->object_table_[i].this_ = 0; + this->object_table_[i].dumper_ = 0; + } +} + +ACE_ODB *ACE_ODB::instance_ = 0; + diff --git a/ace/Dump.h b/ace/Dump.h new file mode 100644 index 00000000000..51e8e0d5a9b --- /dev/null +++ b/ace/Dump.h @@ -0,0 +1,166 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Dump.h +// +// = DESCRIPTION +// +// A prototype mechanism that allow all ACE objects to be registered +// with a central in-memory "database" that can dump the state of all +// live ACE objects (e.g., from within a debugger). +// +// To turn on this feature simply compile with -DACE_NDEBUG +// +// There are several interesting aspects to this design: +// +// 1. It uses the External Polymorphism pattern to avoid having to +// derive all ACE classes from a common base class that has virtual +// methods (this is crucial to avoid unnecessary overhead). In +// addition, there is no additional space added to ACE objects +// (this is crucial to maintain binary layout compatibility). +// +// 2. This mechanism can be conditionally compiled in order to +// completely disable this feature entirely. Moreover, by +// using macros there are relatively few changes to ACE code. +// +// 3. This mechanism copes with single-inheritance hierarchies of +// dumpable classes. In such cases we typically want only one +// dump, corresponding to the most derived instance. Thanks to +// Christian Millour (chris@etca.fr) for illustrating how to do +// this. Note, however, that this scheme doesn't generalize to +// work with multiple-inheritance or virtual base classes. +// +// Future work includes: +// +// 1. Using a dynamic object table rather than a static table +// +// 2. Adding support to allow particular classes of objects to +// be selectively dumped. +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_DUMP_H) +#define ACE_DUMP_H + +#include "ace/Synch.h" + +class ACE_Export ACE_Dumpable + // = TITLE + // Base class that defines a uniform interface for all object + // dumping. +{ +friend class ACE_ODB; +friend class ACE_Dumpable_Ptr; +public: + ACE_Dumpable (const void *); + + virtual void dump (void) const = 0; + // This pure virtual method must be filled in by a subclass. + +protected: + virtual ~ACE_Dumpable (void); + +private: + const void *this_; + // Pointer to the object that is being stored. +}; + +class ACE_Export ACE_Dumpable_Ptr + // = TITLE + // A smart pointer stored in the in-memory object database + // ACE_ODB. The pointee (if any) is deleted when reassigned. +{ +public: + ACE_Dumpable_Ptr (const ACE_Dumpable *dumper = 0); + const ACE_Dumpable *operator->() const; + void operator= (const ACE_Dumpable *dumper) const; + +private: + const ACE_Dumpable *dumper_; + // "Real" pointer to the underlying abstract base class + // pointer that does the real work. +}; + +class ACE_Export ACE_ODB + // = TITLE + // This is the object database (ODB) that keeps track of all + // live ACE objects. +{ +public: + enum {MAX_TABLE_SIZE = 100000}; // This is clearly inadequate and should be dynamic... + + void dump_objects (void); + // Iterates through the entire set of registered objects and + // dumps their state. + + void register_object (const ACE_Dumpable *dumper); + // Add the tuple to the list of registered ACE objects. + + void remove_object (const void *this_); + // Use to locate and remove the associated from the + // list of registered ACE objects. + + static ACE_ODB *instance (void); + // Interface to the Singleton instance of the object database. + +private: + ACE_ODB (void); // Ensure we have a Singleton... + + struct Tuple + { + const void *this_; + // Pointer to the object that is registered. + + const ACE_Dumpable_Ptr dumper_; + // Smart pointer to the ACE_Dumpable object associated with this_. + // This uses an ACE_Dumpable_Ptr, instead of a bare pointer, to + // cope with hierarchies of dumpable classes. In such cases we + // typically want only one dump, corresponding to the most derived + // instance. To achieve this, the handle registered for the + // subobject corresponding to the base class is destroyed (hence + // on destruction of the subobject its handle won't exist anymore + // and we'll have to check for that). + Tuple() : dumper_(0) {} + }; + + static ACE_ODB *instance_; + // Singleton instance of this class. + + Tuple object_table_[ACE_ODB::MAX_TABLE_SIZE]; + // The current implementation is very simple-minded and will be + // changed to be dynamic. + + int current_size_; + // Current size of . + +#if defined (ACE_MT_SAFE) + static ACE_Thread_Mutex ace_dump_lock_; + // Double-Check lock. +#endif /* ACE_MT_SAFE */ +}; + +#include "ace/Dump_T.h" + +// Some useful macros for conditionally compiling this feature... +#if defined (ACE_NDEBUG) +#define ACE_REGISTER_OBJECT(CLASS) +#define ACE_REMOVE_OBJECT +#else +#define ACE_REGISTER_OBJECT(CLASS) \ + ACE_ODB::instance ()->register_object \ + (new ACE_Dumpable_Adapter (this)); +#define ACE_REMOVE_OBJECT \ + ACE_ODB::instance ()->remove_object \ + ((void *) this); +#endif /* ACE_NDEBUG */ +#endif /* ACE_DUMP_H */ diff --git a/ace/Dump_T.cpp b/ace/Dump_T.cpp new file mode 100644 index 00000000000..71c2cbeed30 --- /dev/null +++ b/ace/Dump_T.cpp @@ -0,0 +1,35 @@ +// Dump_T.cpp +// $Id$ + +#if !defined (ACE_DUMP_T_C) +#define ACE_DUMP_T_C + +#include "ace/Dump_T.h" + +template +ACE_Dumpable_Adapter::~ACE_Dumpable_Adapter (void) +{ + ACE_TRACE ("ACE_Dumpable_Adapter::~ACE_Dumpable_Adapter"); +} + +template +ACE_Dumpable_Adapter::ACE_Dumpable_Adapter (const Concrete *t) + : this_ (t), ACE_Dumpable ((const void *) t) +{ + ACE_TRACE ("ACE_Dumpable_Adapter::ACE_Dumpable_Adapter"); +} + +template Concrete * +ACE_Dumpable_Adapter::operator->() const +{ + return (Concrete *) this->this_; +} + +template void +ACE_Dumpable_Adapter::dump (void) const +{ + ACE_TRACE ("ACE_Dumpable_Adapter::dump"); + this->this_->dump (); +} + +#endif /* ACE_DUMP_T_C */ diff --git a/ace/Dump_T.h b/ace/Dump_T.h new file mode 100644 index 00000000000..f1031796341 --- /dev/null +++ b/ace/Dump_T.h @@ -0,0 +1,61 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Dump.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_DUMP_T_H) +#define ACE_DUMP_T_H + +#include "ace/Dump.h" + +template +class ACE_Dumpable_Adapter : public ACE_Dumpable + // = TITLE + // This class inherits the interface of the abstract ACE_Dumpable + // class and is instantiated with the implementation of the + // concrete component class . + // + // = DESCRIPTION + // This design is similar to the Adapter and Decorator patterns + // from the ``Gang of Four'' book. Note that + // need not inherit from a common class since ACE_Dumpable + // provides the uniform virtual interface! +{ +public: + // = Initialization and termination methods. + ACE_Dumpable_Adapter (const Concrete *t); + ~ACE_Dumpable_Adapter (void); + + virtual void dump (void) const; + // Concrete dump method (simply delegates to the method of + // ). + + Concrete *operator->() const; + // Delegate to methods in the Concrete class. + +private: + const Concrete *this_; + // Pointer to of . +}; + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Dump_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Dump_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_DUMP_T_H */ diff --git a/ace/Dynamic.cpp b/ace/Dynamic.cpp new file mode 100644 index 00000000000..a94654b56a8 --- /dev/null +++ b/ace/Dynamic.cpp @@ -0,0 +1,16 @@ +// Dynamic.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Dynamic.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Dynamic.i" +#endif /* __ACE_INLINE__ */ + +ACE_Dynamic::ACE_Dynamic (void) + : instance_ (0) +{ + ACE_TRACE ("ACE_Dynamic::ACE_Dynamic"); +} + diff --git a/ace/Dynamic.h b/ace/Dynamic.h new file mode 100644 index 00000000000..569f029b6c6 --- /dev/null +++ b/ace/Dynamic.h @@ -0,0 +1,52 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// ACE_Dynamic.h +// +// = AUTHOR +// Doug Schmidt and Irfan Pyrarli. +// +// ============================================================================ + +#if !defined (ACE_DYNAMIC_H) +#define ACE_DYNAMIC_H + +#include "ace/ACE.h" + +class ACE_Export ACE_Dynamic + // = TITLE + // Checks to see if a Svc_Handler was dynamically allocated. + // + // = DESCRIPTION + // This class holds the pointer in a thread-safe manner between + // the call to operator new and the call to the constructor. +{ +public: + ACE_Dynamic (void); + + void *set (void *x); + // Assign the new pointer to in order to keep it safe + // until we can compare it in the constructor. + + int is_dynamic (void *x); + // 1 if we were allocated dynamically, else 0. + +private: + void *instance_; + // Holds the pointer in a thread-safe manner between the call to + // operator new and the call to the constructor. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Dynamic.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_DYNAMIC_H */ + diff --git a/ace/Dynamic.i b/ace/Dynamic.i new file mode 100644 index 00000000000..9f051363c30 --- /dev/null +++ b/ace/Dynamic.i @@ -0,0 +1,18 @@ +/* -*- C++ -*- */ +// $Id$ + +// Dynamic.i + +ACE_INLINE void * +ACE_Dynamic::set (void *x) +{ + ACE_TRACE ("ACE_Dynamic::set"); + return this->instance_ = x; +} + +ACE_INLINE int +ACE_Dynamic::is_dynamic (void *x) +{ + ACE_TRACE ("ACE_Dynamic::is_dynamic"); + return this->instance_ == x; +} diff --git a/ace/Dynamic_Service.cpp b/ace/Dynamic_Service.cpp new file mode 100644 index 00000000000..05fec7a0913 --- /dev/null +++ b/ace/Dynamic_Service.cpp @@ -0,0 +1,46 @@ +// Dynamic_Service.cpp +// $Id$ + +#if !defined (ACE_DYNAMIC_SERVICE_C) +#define ACE_DYNAMIC_SERVICE_C + +#define ACE_BUILD_DLL +#include "ace/Service_Config.h" +#include "ace/Service_Repository.h" +#include "ace/Dynamic_Service.h" + +template void +ACE_Dynamic_Service::dump (void) const +{ + ACE_TRACE ("ACE_Dynamic_Service::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// Get the instance using . + +template SERVICE * +ACE_Dynamic_Service::instance (const char *name) +{ + ACE_TRACE ("ACE_Dynamic_Service::instance"); + const ACE_Service_Record *svc_rec; + + if (ACE_Service_Config::svc_rep ()->find (name, &svc_rec) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "svc_rep"), 0); + + const ACE_Service_Type *type = svc_rec->type (); + + if (type == 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "type"), 0); + else + { + const void *obj = type->object (); + // This should be an RTTI typesafe downcast... + SERVICE *n = (SERVICE *) obj; + return n; + } +} + +#endif /* ACE_DYNAMIC_SERVICE_C */ diff --git a/ace/Dynamic_Service.h b/ace/Dynamic_Service.h new file mode 100644 index 00000000000..35ac1d94c25 --- /dev/null +++ b/ace/Dynamic_Service.h @@ -0,0 +1,47 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Dynamic_Service.h +// +// = AUTHOR +// Prashant Jain, Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_DYNAMIC_SERVICE_H) +#define ACE_DYNAMIC_SERVICE_H + +template +class ACE_Dynamic_Service + // = TITLE + // Provides a general interface to retrieve arbitrary objects + // from the ACE service repository. + // + // = DESCRIPTION + // Uses "name" for lookup in the ACE service repository. Obtains + // the object and returns it as the appropriate type. +{ +public: + static SERVICE *instance (const char *name); + // Return instance using to search the Service_Repository. + + void dump (void) const; + // Dump the current state of the object. +}; + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Dynamic_Service.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Dynamic_Service.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_DYNAMIC_SERVICE_H */ diff --git a/ace/Dynamic_Service.i b/ace/Dynamic_Service.i new file mode 100644 index 00000000000..a29b996d459 --- /dev/null +++ b/ace/Dynamic_Service.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// $Id$ + +// Dynamic_Service.i diff --git a/ace/Event_Handler.cpp b/ace/Event_Handler.cpp new file mode 100644 index 00000000000..c0cc76fbd09 --- /dev/null +++ b/ace/Event_Handler.cpp @@ -0,0 +1,11 @@ +// Event_Handler.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Event_Handler.h" +#include "ace/Message_Block.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Event_Handler.i" +#endif /* __ACE_INLINE__ */ + diff --git a/ace/Event_Handler.h b/ace/Event_Handler.h new file mode 100644 index 00000000000..bbe19e5b7fa --- /dev/null +++ b/ace/Event_Handler.h @@ -0,0 +1,150 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Event_Handler.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_EVENT_HANDLER_H) +#define ACE_EVENT_HANDLER_H + +#include "ace/ACE.h" + +// Forward declaration. +class ACE_Message_Block; + +typedef u_long ACE_Reactor_Mask; + +class ACE_Export ACE_Event_Handler + // = TITLE + // Provides an abstract interface for handling various types of + // I/O, timer, and signal events. + // + // = DESCRIPTION + // Derived classes read/write input/output on an I/O + // descriptor, handle an exception raised on an I/O + // descriptor, handle a timer's expiration, or handle a + // signal. +{ +public: + enum + { + LO_PRIORITY = 0, + HI_PRIORITY = 10, + NULL_MASK = 0, +#if defined (ACE_USE_POLL) + READ_MASK = POLLIN, + WRITE_MASK = POLLOUT, + EXCEPT_MASK = POLLPRI, +#else /* USE SELECT */ + READ_MASK = 0x1, + WRITE_MASK = 0x4, + EXCEPT_MASK = 0x2, +#endif /* ACE_USE_POLL */ + RWE_MASK = READ_MASK | WRITE_MASK | EXCEPT_MASK, + DONT_CALL = 0x100 + }; + + virtual ~ACE_Event_Handler (void); + // Destructor is virtual to enable proper cleanup. + + // = The following methods must be supplied by subclasses in order + // to specialize the behavior of an Event_Handler. + virtual ACE_HANDLE get_handle (void) const; + // Get the I/O handle. + virtual void set_handle (ACE_HANDLE); + // Set the I/O handle. + + // = Priority runs from MIN_PRIORITY (which is the "lowest + // priority") to MAX_PRIORITY (which is the "highest priority"). + virtual int get_priority (void) const; + // Get the priority of the Event_Handler. + virtual void set_priority (int priority); + // Set the priority of the Event_Handler. + + virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE); + // Called when input events occur (e.g., connection or data). + + virtual int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE); + // Called when output events are possible (e.g., flow control + // abates). + + virtual int handle_exception (ACE_HANDLE fd = ACE_INVALID_HANDLE); + // Called when execption events occur (e.g., SIGURG). + + virtual int handle_timeout (const ACE_Time_Value &tv, + const void *arg = 0); + // Called when timer expires. + + virtual int handle_close (ACE_HANDLE fd, + ACE_Reactor_Mask close_mask); + // Called when object is removed from the ACE_Reactor + + virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); + // Called when object is signaled by OS (either via UNIX signals or + // when a Win32 object becomes signaled). + + // = Proactor callbacks. + // Win32 specific. An Event_Handler can be given to a Proactor + // with a {RECV,SEND}_MASK. The Proactor calls back + // and to perform the correct + // operations (send/recv). When the send/recv is complete, + // handle_{input,output} is called. Thus, Event_Handlers are + // used for "proactive I/O" where they are told WHEN THE + // OPERATION IS COMPLETE. Alternatively, the _Reactor_ tells + // Event_Handlers WHEN THE OPERATION CAN BE PERFORMED. + + virtual int handle_input_complete (ACE_Message_Block *message, + long bytes_transferred); + // Called back by the Proactor when an asynchronous input operation + // is complete. If this method returns > 0 the Proactor will + // initiate another asynchronous receive; if a 0 is returned the + // Proactor will not reinitiate a receive; and if a -1 is returned, + // then no receive is reinitiated and is called. If + // >= 0, then the I/O operation completed + // successfully. If == -1, then the I/O + // operation failed. Check for total bytes received and + // errno for reason. + + virtual int handle_output_complete (ACE_Message_Block *message, + long bytes_transferred); + // Called back by the Proactor when an asynchronous output operation + // is complete. If this method returns > 0 the Proactor will + // initiate another asynchronous send; if a 0 is returned the + // Proactor will not reinitiate a send; and if a -1 is returned, + // then no send is reinitiated and is called. If + // >= 0, then the I/O operation completed + // successfully. If == -1, then the I/O + // operation failed. Check for total bytes received and + // errno for reason. + + virtual ACE_Message_Block *get_message (void); + // Factory that creates an that is used by the + // Proactor to send or receive a message asynchronously. When the + // asynchronous call completes, this message is returned to the + // with its contents filled in. By default, + // get_message dynamically creates a new ACE_Message_Block. + +protected: + ACE_Event_Handler (void); + // Force ACE_Event_Handler to be an abstract base class. + + int priority_; + // Priority of this Event_Handler. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Event_Handler.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_EVENT_HANDLER_H */ diff --git a/ace/Event_Handler.i b/ace/Event_Handler.i new file mode 100644 index 00000000000..a1211800662 --- /dev/null +++ b/ace/Event_Handler.i @@ -0,0 +1,135 @@ +/* -*- C++ -*- */ +// $Id$ + +#include "ace/Event_Handler.h" +// Event_Handler.i + +// Implement conceptually abstract virtual functions in the base class +// so derived classes don't have to implement unused ones. + +ACE_INLINE +ACE_Event_Handler::ACE_Event_Handler (void) + : priority_ (ACE_Event_Handler::LO_PRIORITY) +{ + ACE_TRACE ("ACE_Event_Handler::ACE_Event_Handler"); +} + +ACE_INLINE +ACE_Event_Handler::~ACE_Event_Handler (void) +{ + ACE_TRACE ("ACE_Event_Handler::~ACE_Event_Handler"); +} + +// Gets the file descriptor associated with this I/O device. + +ACE_INLINE ACE_HANDLE +ACE_Event_Handler::get_handle (void) const +{ + ACE_TRACE ("ACE_Event_Handler::get_handle"); + return ACE_INVALID_HANDLE; +} + +// Sets the file descriptor associated with this I/O device. + +ACE_INLINE void +ACE_Event_Handler::set_handle (ACE_HANDLE) +{ + ACE_TRACE ("ACE_Event_Handler::set_handle"); +} + +// Gets the priority of this handler. + +ACE_INLINE int +ACE_Event_Handler::get_priority (void) const +{ + ACE_TRACE ("ACE_Event_Handler::get_priority"); + return this->priority_; +} + +// Sets the priority + +ACE_INLINE void +ACE_Event_Handler::set_priority (int priority) +{ + ACE_TRACE ("ACE_Event_Handler::set_priority"); + this->priority_ = priority; +} + +// Called when the object is about to be removed from the Dispatcher +// tables. + +ACE_INLINE int +ACE_Event_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + ACE_TRACE ("ACE_Event_Handler::handle_close"); + return -1; +} + +// Called when input becomes available on fd. + +ACE_INLINE int +ACE_Event_Handler::handle_input (ACE_HANDLE) +{ + ACE_TRACE ("ACE_Event_Handler::handle_input"); + return -1; +} + +// Called when output is possible on fd. + +ACE_INLINE int +ACE_Event_Handler::handle_output (ACE_HANDLE) +{ + ACE_TRACE ("ACE_Event_Handler::handle_output"); + return -1; +} + +// Called when urgent data is available on fd. + +ACE_INLINE int +ACE_Event_Handler::handle_exception (ACE_HANDLE) +{ + ACE_TRACE ("ACE_Event_Handler::handle_exception"); + return -1; +} + +// Called when timer expires, TV stores the current time. + +ACE_INLINE int +ACE_Event_Handler::handle_timeout (const ACE_Time_Value &, const void *) +{ + ACE_TRACE ("ACE_Event_Handler::handle_timeout"); + return -1; +} + +// Called when a registered signal occurs. + +ACE_INLINE int +ACE_Event_Handler::handle_signal (int, siginfo_t *, ucontext_t *) +{ + ACE_TRACE ("ACE_Event_Handler::handle_signal"); + return -1; +} + +ACE_INLINE int +ACE_Event_Handler::handle_input_complete (ACE_Message_Block *message, + long bytes_transfered) +{ + ACE_TRACE ("ACE_Event_Handler::handle_input_complete"); + return -1; +} + +ACE_INLINE int +ACE_Event_Handler::handle_output_complete (ACE_Message_Block *message, + long bytes_transfered) +{ + ACE_TRACE ("ACE_Event_Handler::handle_input_complete"); + return -1; +} + +ACE_INLINE ACE_Message_Block * +ACE_Event_Handler::get_message (void) +{ + ACE_TRACE ("ACE_Event_Handler::get_message"); + return 0; +} + diff --git a/ace/Event_Handler_T.cpp b/ace/Event_Handler_T.cpp new file mode 100644 index 00000000000..dcc36466413 --- /dev/null +++ b/ace/Event_Handler_T.cpp @@ -0,0 +1,54 @@ +// Event_Handler_T.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Event_Handler_T.h" + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) + +#if !defined (__ACE_INLINE__) +#include "ace/Event_Handler_T.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Event_Handler_T) + +template void +ACE_Event_Handler_T::dump (void) const +{ + ACE_TRACE ("ACE_Event_Handler_T::dump"); +} + +template +ACE_Event_Handler_T::~ACE_Event_Handler_T (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::~ACE_Event_Handler_T"); + if (this->delete_handler_) + delete this->op_handler_; +} + +template +ACE_Event_Handler_T::ACE_Event_Handler_T (T *op_handler, int delete_handler, + GET_HANDLE get_handle, + IO_HANDLER input_h, + CL_HANDLER close_h, + SIG_HANDLER sig_h, + TO_HANDLER timeout_h, + IO_HANDLER output_h, + SET_HANDLE set_handle, + IO_HANDLER except_h) + : op_handler_ (op_handler), + delete_handler_ (delete_handler), + get_handle_ (get_handle), + input_handler_ (input_h), + cl_handler_ (close_h), + sig_handler_ (sig_h), + to_handler_ (timeout_h), + output_handler_ (output_h), + set_handle_ (set_handle), + except_handler_ (except_h) +{ + ACE_TRACE ("ACE_Event_Handler_T::ACE_Event_Handler_T"); +} + +#endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ + diff --git a/ace/Event_Handler_T.h b/ace/Event_Handler_T.h new file mode 100644 index 00000000000..c78ace07609 --- /dev/null +++ b/ace/Event_Handler_T.h @@ -0,0 +1,180 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Event_Handler_T.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_EVENT_HANDLER_T_H) +#define ACE_EVENT_HANDLER_T_H + +#include "ace/Event_Handler.h" + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) + +template +class ACE_Export ACE_Event_Handler_T : public ACE_Event_Handler + // = TITLE + // Enable a class that doesn't inherit from the + // ACE_Event_Handler to be incorporated into the ACE_Reactor + // framework. Thanks to Greg Lavender (g.lavender@isode.com) + // for sharing this idea. + // + // = DESCRIPTION + // It is sometimes the case that an application has a hierarchy + // of operation dispatcher classes that have their own inheritance + // hierarchy but also would like to integrate with the ACE_Reactor. + // Rather than adopt a "mixin" approach, it is often cleaner to + // define a template as a subclass of ACE_Event_Handler and paramterize it + // with an operation dispatcher type. + // + // When constructing an instantiation of the ACE_Event_Handler_T object, + // a set of pointers to member functions must be provided so that + // when one of the handle_* methods is called by the ACE_Reactor, + // the appropriate method is called on the underlying operations + // object. This is done since in some cases it is useful to + // map any event that happens to the same method on an object. + // + // The ACE_Event_Handler_T template is instantiated by an operations + // object and registered with the ACE_Reactor, and it then calls the + // appropriate op_handler. So, it's basically just another + // level of indirection in event dispatching. The coupling + // betweent the ultimate handler of the event and the + // ACE_Event_Handler class is relaxed a bit by have this + // intermediate object of type around. The client + // object can then dynamically change the bindings for the + // various handlers so that during the life of one of the + // operation objects, it can change how it wants events to be + // handled. It just instantiates a new instance of the template + // with different bindings and reregisters this new object with + // the ACE_Reactor. +{ +public: + // = Typedefs to simplify pointer-to-member-function registration. + + // Get/set the underlying handle. + typedef ACE_HANDLE (T::*GET_HANDLE) (void) const; + typedef void (T::*SET_HANDLE) (ACE_HANDLE); + + typedef int (T::*IO_HANDLER) (ACE_HANDLE); + // Handle I/O events. + + typedef int (T::*TO_HANDLER) (const ACE_Time_Value &, const void *); + // Handle timeout events. + + typedef int (T::*CL_HANDLER) (ACE_HANDLE, ACE_Reactor_Mask); + // Handle close events. + + typedef int (T::*SIG_HANDLER) (ACE_HANDLE +#if defined(ACE_HAS_SIGINFO_T) +, siginfo_t*, ucontext_t* +#endif /* ACE_HAS_SIGINFO_T */ +); + // = Initialization and termination methods. + + ACE_Event_Handler_T (T *op_handler, + int delete_handler, + GET_HANDLE get_handle = 0, + IO_HANDLER input = 0, + CL_HANDLER close = 0, + SIG_HANDLER sig = 0, + TO_HANDLER timeout = 0, + IO_HANDLER output = 0, + SET_HANDLE set_handle = 0, + IO_HANDLER except = 0); + // Initialize the op_handler. + + ~ACE_Event_Handler_T (void); + // Close down and delete the + + // = Override all the ACE_Event_Handler methods and have them call + // through to the operations handler. + virtual ACE_HANDLE get_handle (void) const; + virtual void set_handle (ACE_HANDLE); + virtual int handle_input (ACE_HANDLE fd = -1); + virtual int handle_output (ACE_HANDLE fd = -1); + virtual int handle_exception (ACE_HANDLE fd = -1); + virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg = 0); + virtual int handle_close (ACE_HANDLE fd, ACE_Reactor_Mask close_mask); + virtual int handle_signal (ACE_HANDLE signum, siginfo_t * = 0, ucontext_t * = 0); + + // = Get/set the operations handler. + T *op_handler (void); + void op_handler (T *); + + // = Get/set the target pointer-to-member-function used for + // dispatching. + + GET_HANDLE handle_get (void); + void handle_get (GET_HANDLE); + + SET_HANDLE handle_set (void); + void handle_set (SET_HANDLE); + + IO_HANDLER input_handler (void); + void input_handler (IO_HANDLER); + + IO_HANDLER output_handler (void); + void output_handler (IO_HANDLER); + + IO_HANDLER except_handler (void); + void except_handler (IO_HANDLER); + + TO_HANDLER to_handler (void); + void to_handler (TO_HANDLER); + + CL_HANDLER cl_handler (void); + void cl_handler (CL_HANDLER); + + SIG_HANDLER sig_handler (void); + void sig_handler (SIG_HANDLER); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + T *op_handler_; + // Pointer to the object that handles all the delegated operations. + + // = Handle input, output, and exception events. + IO_HANDLER input_handler_; + IO_HANDLER output_handler_; + IO_HANDLER except_handler_; + + TO_HANDLER to_handler_; + // Handle timeout events. + + CL_HANDLER cl_handler_; + // Handle close events. + + SIG_HANDLER sig_handler_; + // Handle signal events. + + int delete_handler_; + // Keeps track of whether we need to delete the handler in the + // destructor. + + // = Get/set underlying handle. + SET_HANDLE set_handle_; + GET_HANDLE get_handle_; +}; + +#if defined (__ACE_INLINE__) +#include "ace/Event_Handler_T.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ +#endif /* ACE_EVENT_HANDLER_H */ diff --git a/ace/Event_Handler_T.i b/ace/Event_Handler_T.i new file mode 100644 index 00000000000..2f7b5e6deb7 --- /dev/null +++ b/ace/Event_Handler_T.i @@ -0,0 +1,187 @@ +/* -*- C++ -*- */ +// $Id$ + +// Event_Handler_T.i + +template void ACE_INLINE +ACE_Event_Handler_T::op_handler (T *op) +{ + ACE_TRACE ("ACE_Event_Handler_T::op_handler"); + this->op_handler_ = op; +} + +template ACE_INLINE T * +ACE_Event_Handler_T::op_handler (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::op_handler"); + return this->op_handler_; +} + +template ACE_HANDLE ACE_INLINE +ACE_Event_Handler_T::get_handle (void) const +{ + ACE_TRACE ("ACE_Event_Handler_T::get_handle"); + return this->get_handle_ == 0 ? -1 : (this->op_handler_->*get_handle_) (); +} + +template void ACE_INLINE +ACE_Event_Handler_T::set_handle (ACE_HANDLE h) +{ + ACE_TRACE ("ACE_Event_Handler_T::set_handle"); + if (this->set_handle_ != 0) + (this->op_handler_->*set_handle_) (h); +} + +template int ACE_INLINE +ACE_Event_Handler_T::handle_input (ACE_HANDLE fd) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_input"); + return this->input_handler_ == 0 ? 0 : (this->op_handler_->*input_handler_) (fd); +} + +template int ACE_INLINE +ACE_Event_Handler_T::handle_output (ACE_HANDLE fd) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_output"); + return this->output_handler_ == 0 ? 0 : (this->op_handler_->*output_handler_) (fd); +} + +template ACE_INLINE int +ACE_Event_Handler_T::handle_exception (ACE_HANDLE fd) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_exception"); + return this->except_handler_ == 0 ? 0 : (this->op_handler_->*except_handler_) (fd); +} + +template ACE_INLINE int +ACE_Event_Handler_T::handle_timeout (const ACE_Time_Value &tv, const void *arg) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_timeout"); + return this->to_handler_ == 0 ? 0 : (this->op_handler_->*to_handler_) (tv, arg); +} + +template ACE_INLINE int +ACE_Event_Handler_T::handle_close (ACE_HANDLE fd, ACE_Reactor_Mask close_mask) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_close"); + return this->cl_handler_ == 0 ? 0 : (this->op_handler_->*cl_handler_) (fd, close_mask); +} + +template ACE_INLINE int +ACE_Event_Handler_T::handle_signal (ACE_HANDLE signum, siginfo_t *s, ucontext_t *u) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_signal"); + return this->sig_handler_ == 0 ? 0 : (this->op_handler_->*sig_handler_) (signum, s, u); +} + +template ACE_INLINE ACE_Event_Handler_T::GET_HANDLE +ACE_Event_Handler_T::handle_get (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_get"); + return this->get_handle_; +} + +template ACE_INLINE void +ACE_Event_Handler_T::handle_get (ACE_Event_Handler_T::GET_HANDLE h) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_get"); + this->get_handle_ = h; +} + +template ACE_INLINE ACE_Event_Handler_T::SET_HANDLE +ACE_Event_Handler_T::handle_set (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_set"); + return this->set_handle_; +} + +template ACE_INLINE void +ACE_Event_Handler_T::handle_set (ACE_Event_Handler_T::SET_HANDLE h) +{ + ACE_TRACE ("ACE_Event_Handler_T::handle_set"); + this->set_handle_ = h; +} + +template ACE_INLINE ACE_Event_Handler_T::IO_HANDLER +ACE_Event_Handler_T::input_handler (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::input_handler"); + return this->input_handler_; +} + +template ACE_INLINE void +ACE_Event_Handler_T::input_handler (ACE_Event_Handler_T::IO_HANDLER h) +{ + ACE_TRACE ("ACE_Event_Handler_T::input_handler"); + this->input_handler_ = h; +} + +template ACE_INLINE ACE_Event_Handler_T::IO_HANDLER +ACE_Event_Handler_T::output_handler (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::output_handler"); + return this->output_handler_; +} + +template ACE_INLINE void +ACE_Event_Handler_T::output_handler (ACE_Event_Handler_T::IO_HANDLER h) +{ + ACE_TRACE ("ACE_Event_Handler_T::output_handler"); + this->output_handler_ = h; +} + +template ACE_INLINE ACE_Event_Handler_T::IO_HANDLER +ACE_Event_Handler_T::except_handler (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::except_handler"); + return this->except_handler_; +} + +template ACE_INLINE void +ACE_Event_Handler_T::except_handler (ACE_Event_Handler_T::IO_HANDLER h) +{ + ACE_TRACE ("ACE_Event_Handler_T::except_handler"); + this->except_handler_ = h; +} + +template ACE_INLINE ACE_Event_Handler_T::TO_HANDLER +ACE_Event_Handler_T::to_handler (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::to_handler"); + return this->to_handler_; +} + +template ACE_INLINE void +ACE_Event_Handler_T::to_handler (ACE_Event_Handler_T::TO_HANDLER h) +{ + ACE_TRACE ("ACE_Event_Handler_T::to_handler"); + this->to_handler_ = h; +} + +template ACE_INLINE ACE_Event_Handler_T::CL_HANDLER +ACE_Event_Handler_T::cl_handler (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::cl_handler"); + return this->cl_handler_; +} + +template ACE_INLINE void +ACE_Event_Handler_T::cl_handler (ACE_Event_Handler_T::CL_HANDLER h) +{ + ACE_TRACE ("ACE_Event_Handler_T::cl_handler"); + this->cl_handler_ = h; +} + +template ACE_INLINE ACE_Event_Handler_T::SIG_HANDLER +ACE_Event_Handler_T::sig_handler (void) +{ + ACE_TRACE ("ACE_Event_Handler_T::sig_handler"); + return this->sig_handler_; +} + +template ACE_INLINE void +ACE_Event_Handler_T::sig_handler (ACE_Event_Handler_T::SIG_HANDLER h) +{ + ACE_TRACE ("ACE_Event_Handler_T::sig_handler"); + this->sig_handler_ = h; +} diff --git a/ace/FIFO.cpp b/ace/FIFO.cpp new file mode 100644 index 00000000000..8c1f4d1b980 --- /dev/null +++ b/ace/FIFO.cpp @@ -0,0 +1,67 @@ +// FIFO.cpp +// $Id$ + +/* -*- C++ -*- */ + +#define ACE_BUILD_DLL +#include "ace/FIFO.h" + +#if !defined (__ACE_INLINE__) +#include "ace/FIFO.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_FIFO) + +void +ACE_FIFO::dump (void) const +{ + ACE_TRACE ("ACE_FIFO::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "rendezvous_ = %s", this->rendezvous_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +int +ACE_FIFO::open (const char *r, int flags, int perms) +{ + ACE_TRACE ("ACE_FIFO::open"); + ACE_OS::strncpy (this->rendezvous_, r, MAXPATHLEN); + + if ((flags & O_CREAT) != 0 + && ACE_OS::mkfifo (this->rendezvous_, perms) == -1 + && !(errno == EEXIST)) + return -1; + + this->set_handle (ACE_OS::open (this->rendezvous_, flags)); + return this->get_handle () == ACE_INVALID_HANDLE ? -1 : 0; +} + +ACE_FIFO::ACE_FIFO (const char *fifo_name, + int flags, + int perms) +{ + ACE_TRACE ("ACE_FIFO::ACE_FIFO"); + if (this->open (fifo_name, flags, perms) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_FIFO")); +} + +ACE_FIFO::ACE_FIFO (void) +{ +// ACE_TRACE ("ACE_FIFO::ACE_FIFO"); +} + +int +ACE_FIFO::close (void) +{ + ACE_TRACE ("ACE_FIFO::close"); + int result = 0; + + if (this->get_handle () != ACE_INVALID_HANDLE) + { + result = ACE_OS::close (this->get_handle ()); + this->set_handle (ACE_INVALID_HANDLE); + } + return result; +} + diff --git a/ace/FIFO.h b/ace/FIFO.h new file mode 100644 index 00000000000..dc4ffac7f40 --- /dev/null +++ b/ace/FIFO.h @@ -0,0 +1,66 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// FIFO.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_FIFO_H) +#define ACE_FIFO_H + +#include "ace/IPC_SAP.h" + +class ACE_Export ACE_FIFO : public ACE_IPC_SAP + // = TITLE + // Abstract base class for UNIX FIFOs (a.k.a. Named Pipes). +{ +public: + int open (const char *rendezvous, int flags, int perms); + // Open up the named pipe on the in accordance with the + // flags. + + int close (void); + // Close down the ACE_FIFO without removing the rendezvous point. + + int remove (void); + // Close down the ACE_FIFO and remove the rendezvous point from the + // file system. + + int get_local_addr (const char *&rendezvous) const; + // Return the local address of this endpoint. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + // = Make these protected to ensure that the class is "abstract." + ACE_FIFO (void); + // Default constructor. + + ACE_FIFO (const char *rendezvous, int flags, int perms); + // Open up the named pipe on the in accordance with the + // flags. + +private: + char rendezvous_[MAXPATHLEN + 1]; + // Rendezvous point in the file system. +}; + +#if defined (__ACE_INLINE__) +#include "ace/FIFO.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_FIFO_H */ diff --git a/ace/FIFO.i b/ace/FIFO.i new file mode 100644 index 00000000000..be1481b954a --- /dev/null +++ b/ace/FIFO.i @@ -0,0 +1,23 @@ +/* -*- C++ -*- */ +// $Id$ + +// FIFO.i + +#include "ace/Log_Msg.h" + +ACE_INLINE int +ACE_FIFO::get_local_addr (const char *&r) const +{ + ACE_TRACE ("ACE_FIFO::get_local_addr"); + r = this->rendezvous_; + return 0; +} + +ACE_INLINE int +ACE_FIFO::remove (void) +{ + ACE_TRACE ("ACE_FIFO::remove"); + int result = this->close (); + return ACE_OS::unlink (this->rendezvous_) == -1 || result == -1 ? -1 : 0; +} + diff --git a/ace/FIFO_Recv.cpp b/ace/FIFO_Recv.cpp new file mode 100644 index 00000000000..ff05686d6a1 --- /dev/null +++ b/ace/FIFO_Recv.cpp @@ -0,0 +1,63 @@ +// FIFO_Recv.cpp +// $Id$ + +/* -*- C++ -*- */ + +#define ACE_BUILD_DLL +#include "ace/FIFO_Recv.h" +#include "ace/Log_Msg.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_FIFO_Recv) + +void +ACE_FIFO_Recv::dump (void) const +{ + ACE_TRACE ("ACE_FIFO_Recv::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_FIFO::dump (); + ACE_DEBUG ((LM_DEBUG, "aux_handle_ = %d", this->aux_handle_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +int +ACE_FIFO_Recv::close (void) +{ + ACE_TRACE ("ACE_FIFO_Recv::close"); + int result = ACE_FIFO::close (); + if (this->aux_handle_ != ACE_INVALID_HANDLE) + return ACE_OS::close (this->aux_handle_); + else + return result; +} + +// Note that persistent means "open fifo for writing, as well as +// reading." This ensures that the fifo never gets EOF, even if there +// aren't any writers at the moment! + +int +ACE_FIFO_Recv::open (const char *fifo_name, int flags, int perms, int persistent) +{ + ACE_TRACE ("ACE_FIFO_Recv::open"); + if (ACE_FIFO::open (fifo_name, ACE_NONBLOCK | flags, perms) == -1) + return -1; + else if (this->disable (ACE_NONBLOCK) == -1) + return -1; + else if (persistent && (this->aux_handle_ = + ACE_OS::open (fifo_name, O_WRONLY)) == ACE_INVALID_HANDLE) + return -1; + else + return this->get_handle () == ACE_INVALID_HANDLE ? -1 : 0; +} + +ACE_FIFO_Recv::ACE_FIFO_Recv (void): aux_handle_ (ACE_INVALID_HANDLE) +{ + ACE_TRACE ("ACE_FIFO_Recv::ACE_FIFO_Recv"); +} + +ACE_FIFO_Recv::ACE_FIFO_Recv (const char *fifo_name, int flags, int perms, int persistent) +{ + ACE_TRACE ("ACE_FIFO_Recv::ACE_FIFO_Recv"); + if (this->ACE_FIFO_Recv::open (fifo_name, flags, perms, persistent) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_FIFO_Recv")); +} + diff --git a/ace/FIFO_Recv.h b/ace/FIFO_Recv.h new file mode 100644 index 00000000000..046ec39db0a --- /dev/null +++ b/ace/FIFO_Recv.h @@ -0,0 +1,67 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// FIFO_Recv.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_FIFO_RECV_H) +#define ACE_FIFO_RECV_H + +#include "ace/FIFO.h" + +class ACE_Export ACE_FIFO_Recv : public ACE_FIFO + // = TITLE + // Receiver side of the bytestream C++ wrapper for UNIX + // FIFOs. +{ +public: + // = Initialization methods. + ACE_FIFO_Recv (void); + // Default constructor. + + ACE_FIFO_Recv (const char *rendezvous, + int flags = O_CREAT | O_RDONLY, + int perms = ACE_DEFAULT_PERMS, + int persistent = 1); + // Open up a bytestream named pipe for reading. + + int open (const char *rendezvous, + int flags = O_CREAT | O_RDONLY, + int perms = ACE_DEFAULT_PERMS, + int persistent = 1); + // Open up a bytestream named pipe for reading. + + int close (void); + // Close down the named pipe. + + ssize_t recv (void *buf, size_t len); + // Recv of up to bytes. + + ssize_t recv_n (void *buf, size_t len); + // Recv of exactly bytes (block until done). + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_HANDLE aux_handle_; + // Auxiliary handle that is used to implement persistent FIFOs. +}; + +#include "ace/FIFO_Recv.i" + +#endif /* ACE_FIFO_RECV_H */ diff --git a/ace/FIFO_Recv.i b/ace/FIFO_Recv.i new file mode 100644 index 00000000000..51ae81efca8 --- /dev/null +++ b/ace/FIFO_Recv.i @@ -0,0 +1,18 @@ +/* -*- C++ -*- */ +// $Id$ + +// FIFO_Recv.i + +inline ssize_t +ACE_FIFO_Recv::recv (void *buf, size_t len) +{ + ACE_TRACE ("ACE_FIFO_Recv::recv"); + return ACE_OS::read (this->get_handle (), (char *) buf, len); +} + +inline ssize_t +ACE_FIFO_Recv::recv_n (void *buf, size_t n) +{ + ACE_TRACE ("ACE_FIFO_Recv::recv_n"); + return ACE::recv_n (this->get_handle (), buf, n); +} diff --git a/ace/FIFO_Recv_Msg.cpp b/ace/FIFO_Recv_Msg.cpp new file mode 100644 index 00000000000..002efd735a9 --- /dev/null +++ b/ace/FIFO_Recv_Msg.cpp @@ -0,0 +1,41 @@ +// FIFO_Recv_Msg.cpp +// $Id$ + +/* -*- C++ -*- */ + +#define ACE_BUILD_DLL +#include "ace/FIFO_Recv_Msg.h" +#include "ace/Log_Msg.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_FIFO_Recv_Msg) + +void +ACE_FIFO_Recv_Msg::dump (void) const +{ + ACE_TRACE ("ACE_FIFO_Recv_Msg::dump"); + ACE_FIFO_Recv::dump (); +} + +/* Note that persistent means "open fifo for writing, as well as reading." + This ensures that the fifo never gets EOF, even if there aren't + any writers at the moment! */ + +int +ACE_FIFO_Recv_Msg::open (const char *fifo_name, int flags, int perms, int persistent) +{ + ACE_TRACE ("ACE_FIFO_Recv_Msg::open"); + return ACE_FIFO_Recv::open (fifo_name, flags, perms, persistent); +} + +ACE_FIFO_Recv_Msg::ACE_FIFO_Recv_Msg (void) +{ + ACE_TRACE ("ACE_FIFO_Recv_Msg::ACE_FIFO_Recv_Msg"); +} + +ACE_FIFO_Recv_Msg::ACE_FIFO_Recv_Msg (const char *fifo_name, int flags, int perms, int persistent) +{ + ACE_TRACE ("ACE_FIFO_Recv_Msg::ACE_FIFO_Recv_Msg"); + if (this->ACE_FIFO_Recv_Msg::open (fifo_name, flags, perms, + persistent) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_FIFO_Recv_Msg")); +} diff --git a/ace/FIFO_Recv_Msg.h b/ace/FIFO_Recv_Msg.h new file mode 100644 index 00000000000..d3d3109134b --- /dev/null +++ b/ace/FIFO_Recv_Msg.h @@ -0,0 +1,72 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// FIFO_Recv_Msg.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_FIFO_RECV_MSG_H) +#define ACE_FIFO_RECV_MSG_H + +#include "ace/FIFO_Recv.h" + +class ACE_Export ACE_FIFO_Recv_Msg : public ACE_FIFO_Recv + // = TITLE + // Receiver side for the record oriented C++ wrapper for UNIX FIFOs. +{ +public: + // = Initialization methods. + ACE_FIFO_Recv_Msg (void); + // Default constructor. + + ACE_FIFO_Recv_Msg (const char *rendezvous, + int flags = O_CREAT | O_RDONLY, + int perms = ACE_DEFAULT_PERMS, + int persistent = 1); + // Open up a record-oriented named pipe for reading. + + int open (const char *rendezvous, + int flags = O_CREAT | O_RDONLY, + int perms = ACE_DEFAULT_PERMS, + int persistent = 1); + // Open up a record-oriented named pipe for reading. + + ssize_t recv (ACE_Str_Buf &msg); + // Recv as an ACE_Str_Buf. + + ssize_t recv (void *buf, size_t len); + // Recv as a buffer. + +#if defined (ACE_HAS_STREAM_PIPES) + ssize_t recv (ACE_Str_Buf *data, + ACE_Str_Buf *cntl, + int *flags); + // Recv and message via Stream pipes. + + ssize_t recv (int *band, + ACE_Str_Buf *data, + ACE_Str_Buf *cntl, + int *flags); + // Recv and message via Stream pipes in "band" mode. +#endif /* ACE_HAS_STREAM_PIPES */ + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#include "ace/FIFO_Recv_Msg.i" + +#endif /* ACE_FIFO_RECV_MSG_H */ diff --git a/ace/FIFO_Recv_Msg.i b/ace/FIFO_Recv_Msg.i new file mode 100644 index 00000000000..7ee7f74ee10 --- /dev/null +++ b/ace/FIFO_Recv_Msg.i @@ -0,0 +1,55 @@ +/* -*- C++ -*- */ +// $Id$ + +// FIFO_Recv_Msg.i + +// Note that the return values mean different things if +// ACE_HAS_STREAM_PIPES vs. if it doesn't... See the manual page on +// getmsg(2) and read(2) for more details. + +inline ssize_t +ACE_FIFO_Recv_Msg::recv (ACE_Str_Buf &recv_msg) +{ + ACE_TRACE ("ACE_FIFO_Recv_Msg::recv"); +#if defined (ACE_HAS_STREAM_PIPES) + int i = 0; + return ACE_OS::getmsg (this->get_handle (), (strbuf *) 0, (strbuf *) &recv_msg, &i); +#else /* Do the ol' 2-read trick... */ + if (ACE_OS::read (this->get_handle (), + (char *) &recv_msg.len, + sizeof recv_msg.len) != sizeof recv_msg.len) + return -1; + else + return ACE_OS::read (this->get_handle (), + (char *) recv_msg.buf, + (int) recv_msg.len); +#endif /* ACE_HAS_STREAM_PIPES */ +} + +inline ssize_t +ACE_FIFO_Recv_Msg::recv (void *buf, size_t max_len) +{ + ACE_TRACE ("ACE_FIFO_Recv_Msg::recv"); + ACE_Str_Buf recv_msg ((char *) buf, 0, max_len); + + return this->recv (recv_msg); +} + +#if defined (ACE_HAS_STREAM_PIPES) +inline ssize_t +ACE_FIFO_Recv_Msg::recv (ACE_Str_Buf *data, ACE_Str_Buf *cntl, int *flags) +{ + ACE_TRACE ("ACE_FIFO_Recv_Msg::recv"); + return ACE_OS::getmsg (this->get_handle (), + (strbuf *) cntl, (strbuf *) data, flags); +} + +inline ssize_t +ACE_FIFO_Recv_Msg::recv (int *band, ACE_Str_Buf *data, ACE_Str_Buf *cntl, int *flags) +{ + ACE_TRACE ("ACE_FIFO_Recv_Msg::recv"); + return ACE_OS::getpmsg (this->get_handle (), + (strbuf *) cntl, (strbuf *) data, band, flags); +} + +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/ace/FIFO_Send.cpp b/ace/FIFO_Send.cpp new file mode 100644 index 00000000000..6d463af5ae8 --- /dev/null +++ b/ace/FIFO_Send.cpp @@ -0,0 +1,36 @@ +// FIFO_Send.cpp +// $Id$ + +/* -*- C++ -*- */ + +#define ACE_BUILD_DLL +#include "ace/FIFO_Send.h" +#include "ace/Log_Msg.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_FIFO_Send) + +void +ACE_FIFO_Send::dump (void) const +{ + ACE_TRACE ("ACE_FIFO_Send::dump"); + ACE_FIFO::dump (); +} + +ACE_FIFO_Send::ACE_FIFO_Send (void) +{ +// ACE_TRACE ("ACE_FIFO_Send::ACE_FIFO_Send"); +} + +int +ACE_FIFO_Send::open (const char *rendezvous_name, int flags, int perms) +{ + ACE_TRACE ("ACE_FIFO_Send::open"); + return ACE_FIFO::open (rendezvous_name, flags | O_WRONLY, perms); +} + +ACE_FIFO_Send::ACE_FIFO_Send (const char *fifo_name, int flags, int perms) +{ + ACE_TRACE ("ACE_FIFO_Send::ACE_FIFO_Send"); + if (this->ACE_FIFO_Send::open (fifo_name, flags, perms) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_FIFO_Send::ACE_FIFO_Send")); +} diff --git a/ace/FIFO_Send.h b/ace/FIFO_Send.h new file mode 100644 index 00000000000..c413ed12635 --- /dev/null +++ b/ace/FIFO_Send.h @@ -0,0 +1,58 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// FIFO_Send.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_FIFO_SEND_H) +#define ACE_FIFO_SEND_H + +#include "ace/FIFO.h" + +class ACE_Export ACE_FIFO_Send : public ACE_FIFO + // = TITLE + // Sender side for the bytestream C++ wrapper for UNIX FIFOs +{ +public: + // = Initialization methods. + ACE_FIFO_Send (void); + // Default constructor. + + ACE_FIFO_Send (const char *rendezvous, + int flags = O_WRONLY, + int perms = ACE_DEFAULT_PERMS); + // Open up a bytestream named pipe for writing. + + int open (const char *rendezvous, + int flags = O_WRONLY, + int perms = ACE_DEFAULT_PERMS); + // Open up a bytestream named pipe for writing. + + ssize_t send (const void *buf, size_t len); + // Send of up to bytes. + + ssize_t send_n (const void *buf, size_t len); + // Send of exactly bytes (block until done). + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#include "ace/FIFO_Send.i" + +#endif /* ACE_FIFO_SEND_H */ + diff --git a/ace/FIFO_Send.i b/ace/FIFO_Send.i new file mode 100644 index 00000000000..5785229f167 --- /dev/null +++ b/ace/FIFO_Send.i @@ -0,0 +1,18 @@ +/* -*- C++ -*- */ +// $Id$ + +// FIFO_Send.i + +inline ssize_t +ACE_FIFO_Send::send (const void *buf, size_t len) +{ + ACE_TRACE ("ACE_FIFO_Send::send"); + return ACE_OS::write (this->get_handle (), (const char *) buf, len); +} + +inline ssize_t +ACE_FIFO_Send::send_n (const void *buf, size_t n) +{ + ACE_TRACE ("ACE_FIFO_Send::send_n"); + return ACE::send_n (this->get_handle (), buf, n); +} diff --git a/ace/FIFO_Send_Msg.cpp b/ace/FIFO_Send_Msg.cpp new file mode 100644 index 00000000000..88848c779ca --- /dev/null +++ b/ace/FIFO_Send_Msg.cpp @@ -0,0 +1,62 @@ +// FIFO_Send_Msg.cpp +// $Id$ + +/* -*- C++ -*- */ + +#define ACE_BUILD_DLL +#include "ace/FIFO_Send_Msg.h" +#include "ace/Log_Msg.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_FIFO_Send_Msg) + +void +ACE_FIFO_Send_Msg::dump (void) const +{ + ACE_TRACE ("ACE_FIFO_Send_Msg::dump"); + ACE_FIFO_Send::dump (); +} + +ssize_t +ACE_FIFO_Send_Msg::send (const ACE_Str_Buf &send_msg) +{ + ACE_TRACE ("ACE_FIFO_Send_Msg::send"); +#if defined (ACE_HAS_STREAM_PIPES) + return ACE_OS::putmsg (this->get_handle (), + (strbuf *) 0, + (strbuf *) &send_msg, + 0); +#else + struct iovec iov[2]; + + iov[0].iov_base = (char *) &send_msg.len; + iov[0].iov_len = sizeof send_msg.len; + + iov[1].iov_base = (char *) send_msg.buf; + iov[1].iov_len = int (send_msg.len); + + return ACE_OS::writev (this->get_handle (), iov, 2); +#endif /* ACE_HAS_STREAM_PIPES */ +} + +ACE_FIFO_Send_Msg::ACE_FIFO_Send_Msg (void) +{ +// ACE_TRACE ("ACE_FIFO_Send_Msg::ACE_FIFO_Send_Msg"); +} + +int +ACE_FIFO_Send_Msg::open (const char *fifo_name, + int flags, + int perms) +{ + ACE_TRACE ("ACE_FIFO_Send_Msg::open"); + return ACE_FIFO_Send::open (fifo_name, flags | O_WRONLY, perms); +} + +ACE_FIFO_Send_Msg::ACE_FIFO_Send_Msg (const char *fifo_name, + int flags, + int perms) +{ + ACE_TRACE ("ACE_FIFO_Send_Msg::ACE_FIFO_Send_Msg"); + if (this->ACE_FIFO_Send_Msg::open (fifo_name, flags, perms) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_FIFO_Send_Msg")); +} diff --git a/ace/FIFO_Send_Msg.h b/ace/FIFO_Send_Msg.h new file mode 100644 index 00000000000..8898bc320f9 --- /dev/null +++ b/ace/FIFO_Send_Msg.h @@ -0,0 +1,72 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// FIFO_Send_Msg.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_FIFO_SEND_MSG_H) +#define ACE_FIFO_SEND_MSG_H + +#include "ace/FIFO_Send.h" + +class ACE_Export ACE_FIFO_Send_Msg : public ACE_FIFO_Send + // = TITLE + // Sender side for the Record oriented C++ wrapper for UNIX + // FIFOs. +{ +public: + // = Initialization methods. + ACE_FIFO_Send_Msg (void); + // Default constructor. + + ACE_FIFO_Send_Msg (const char *rendezvous, + int flags = O_WRONLY, + int perms = ACE_DEFAULT_PERMS); + // Open up a record-oriented named pipe for writing. + + int open (const char *rendezvous, + int flags = O_WRONLY, + int perms = ACE_DEFAULT_PERMS); + // Open up a record-oriented named pipe for writing. + + ssize_t send (const ACE_Str_Buf &msg); + // Send of up to bytes. + + ssize_t send (const void *buf, size_t len); + // Send of exactly bytes (block until done). + +#if defined (ACE_HAS_STREAM_PIPES) + ssize_t send (const ACE_Str_Buf *data, + const ACE_Str_Buf *cntl = 0, + int flags = 0); + // Send and message via Stream pipes. + + ssize_t send (int band, + const ACE_Str_Buf *data, + const ACE_Str_Buf *cntl = 0, + int flags = MSG_BAND); + // Send and message via Stream pipes in "band" mode. +#endif /* ACE_HAS_STREAM_PIPES */ + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#include "ace/FIFO_Send_Msg.i" + +#endif /* ACE_FIFO_SEND_MSG_H */ + diff --git a/ace/FIFO_Send_Msg.i b/ace/FIFO_Send_Msg.i new file mode 100644 index 00000000000..7d6b767cc4b --- /dev/null +++ b/ace/FIFO_Send_Msg.i @@ -0,0 +1,41 @@ +/* -*- C++ -*- */ +// $Id$ + +// FIFO_Send_Msg.i + +inline ssize_t +ACE_FIFO_Send_Msg::send (const void *buf, size_t len) +{ + ACE_TRACE ("ACE_FIFO_Send_Msg::send"); + ACE_Str_Buf send_msg ((char *) buf, len); + + return this->send (send_msg); +} + +#if defined (ACE_HAS_STREAM_PIPES) +inline ssize_t +ACE_FIFO_Send_Msg::send (const ACE_Str_Buf *data, + const ACE_Str_Buf *cntl, + int flags) +{ + ACE_TRACE ("ACE_FIFO_Send_Msg::send"); + return ACE_OS::putmsg (this->get_handle (), + (strbuf *) cntl, + (strbuf *) data, + flags); +} + +inline ssize_t +ACE_FIFO_Send_Msg::send (int band, + const ACE_Str_Buf *data, + const ACE_Str_Buf *cntl, + int flags) +{ + ACE_TRACE ("ACE_FIFO_Send_Msg::send"); + return ACE_OS::putpmsg (this->get_handle (), + (strbuf *) cntl, + (strbuf *) data, + band, + flags); +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/ace/FILE.cpp b/ace/FILE.cpp new file mode 100644 index 00000000000..a6928173f98 --- /dev/null +++ b/ace/FILE.cpp @@ -0,0 +1,72 @@ +// FILE.cpp +// $Id$ + +/* Defines the member functions for the base class of the ACE_IO_SAP + ACE_FILE abstraction. */ + +#define ACE_BUILD_DLL +#include "ace/FILE.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_FILE) + +void +ACE_FILE::dump (void) const +{ + ACE_TRACE ("ACE_FILE::dump"); + ACE_IO_SAP::dump (); +} + +/* This is the do-nothing constructor. */ + +ACE_FILE::ACE_FILE (void) +{ + ACE_TRACE ("ACE_FILE::ACE_FILE"); +} + +// Close the file + +int +ACE_FILE::close (void) +{ + ACE_TRACE ("ACE_FILE::close"); + int result = ACE_OS::close (this->get_handle ()); + this->set_handle (ACE_INVALID_HANDLE); + return result; +} + +int +ACE_FILE::get_info (ACE_FILE_Info *finfo) +{ + ACE_TRACE ("ACE_FILE::get_info"); + struct stat filestatus; + int result = ACE_OS::fstat (this->get_handle (), &filestatus); + + if (result == 0) + { + finfo->mode_ = filestatus.st_mode; + finfo->nlink_ = filestatus.st_nlink; + finfo->size_ = filestatus.st_size; + } + return result; +} + +int +ACE_FILE::truncate (off_t length) +{ + ACE_TRACE ("ACE_FILE::truncate"); + return ACE_OS::ftruncate (this->get_handle(), length); +} + +off_t +ACE_FILE::position (long offset, int startpos) +{ + ACE_TRACE ("ACE_FILE::position"); + return ACE_OS::lseek (this->get_handle (), offset, startpos); +} + +off_t +ACE_FILE::position (void) +{ + ACE_TRACE ("ACE_FILE::position"); + return ACE_OS::lseek (this->get_handle (), 0, SEEK_CUR); +} diff --git a/ace/FILE.h b/ace/FILE.h new file mode 100644 index 00000000000..778fd95b925 --- /dev/null +++ b/ace/FILE.h @@ -0,0 +1,83 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// FILE.h +// +// = AUTHOR +// Gerhard Lenzer +// +// ============================================================================ + +#if !defined (ACE_FILE_H) +#define ACE_FILE_H + +#include "ace/IO_SAP.h" +#include "ace/FILE_Addr.h" + +// The following is necessary since many C++ compilers don't support +// typedef'd types inside of classes used as formal template +// arguments... ;-(. Luckily, using the C++ preprocessor I can hide +// most of this nastiness! + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) +#define ACE_FILE_CONNECTOR ACE_FILE_Connector +#define ACE_FILE_STREAM ACE_FILE_Stream +#else /* TEMPLATES are broken (must be a cfront-based compiler...) */ +#define ACE_FILE_CONNECTOR ACE_FILE_Connector, ACE_FILE_Addr +#define ACE_FILE_STREAM ACE_FILE_Stream, ACE_FILE_Addr +#endif /* ACE_TEMPLATE_TYPEDEFS */ + +struct ACE_FILE_Info +{ + mode_t mode_; + // mode of file + + nlink_t nlink_; + // no of links + + off_t size_; + // size of file +}; + +class ACE_Export ACE_FILE : public ACE_IO_SAP + // = TITLE + // Defines the member functions for the base class of the + // ACE_FILE abstraction. +{ +public: + int close (void); + // Close down the ACE_FILE + + int get_info (ACE_FILE_Info *finfo); + // get informations on the ACE_FILE + + int truncate (off_t length); + // set filesize to length byte + + off_t position (long offset, int startpos); + // set the filepointer to the specified position + + off_t position (void); + // get current filepointer + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + ACE_FILE (void); + // Ensure that this class is an abstract base class +}; + +#include "ace/FILE.i" + +#endif /* ACE_FILE_H */ diff --git a/ace/FILE.i b/ace/FILE.i new file mode 100644 index 00000000000..961d2bdc766 --- /dev/null +++ b/ace/FILE.i @@ -0,0 +1,6 @@ +/* -*- C++ -*- */ +// $Id$ + +// FILE.i + + diff --git a/ace/FILE_Addr.cpp b/ace/FILE_Addr.cpp new file mode 100644 index 00000000000..3ff02900990 --- /dev/null +++ b/ace/FILE_Addr.cpp @@ -0,0 +1,23 @@ +// FILE_Addr.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/FILE_Addr.h" + +#if !defined (__ACE_INLINE__) +#include "ace/FILE_Addr.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_FILE_Addr) + +void +ACE_FILE_Addr::dump (void) const +{ + ACE_TRACE ("ACE_FILE_Addr::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "filename_ = %s", this->filename_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + diff --git a/ace/FILE_Addr.h b/ace/FILE_Addr.h new file mode 100644 index 00000000000..978ea3e0608 --- /dev/null +++ b/ace/FILE_Addr.h @@ -0,0 +1,75 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// FILE_Addr.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_FILE_ADDR_H) +#define ACE_FILE_ADDR_H + +#include "ace/Addr.h" +#include "ace/ACE.h" + +class ACE_Export ACE_FILE_Addr : public ACE_Addr + // = TITLE + // Defines the FILE address family address format. +{ +public: + // = Initialization methods. + ACE_FILE_Addr (void); + // Default constructor. + + ACE_FILE_Addr (const ACE_FILE_Addr &sa); + // Copy constructor. + + ACE_FILE_Addr (LPCTSTR filename); + // Create a ACE_FILE_Addr from a pathname. + + void set (LPCTSTR filename); + // Create a ACE_FILE_Addr from a pathname. + + ACE_FILE_Addr &operator= (const ACE_FILE_Addr &); + // Assignment operator. + + virtual void *get_addr (void) const; + // Return a pointer to the address. + + virtual int addr_to_string (char addr[], size_t) const; + // Transform the current address into string format. + + virtual int operator == (const ACE_Addr &SAP) const; + // Compare two addresses for equality. + + virtual int operator != (const ACE_Addr &SAP) const; + // Compare two addresses for inequality. + + LPCTSTR get_path_name (void) const; + // Return the path name used for the rendezvous point. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + TCHAR filename_[MAXNAMLEN + 1]; + // Name of the file. +}; + +#if defined (__ACE_INLINE__) +#include "ace/FILE_Addr.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_FILE_ADDR_H */ diff --git a/ace/FILE_Addr.i b/ace/FILE_Addr.i new file mode 100644 index 00000000000..c6237feac46 --- /dev/null +++ b/ace/FILE_Addr.i @@ -0,0 +1,93 @@ +/* -*- C++ -*- */ +// $Id$ + +// FILE_Addr.i + +// Do nothing constructor. + +ACE_INLINE +ACE_FILE_Addr::ACE_FILE_Addr (void) + : ACE_Addr (AF_FILE, sizeof this->filename_) +{ + (void) ACE_OS::memset ((void *) &this->filename_, + 0, sizeof this->filename_); +} + +// Copy constructor. + +ACE_INLINE +ACE_FILE_Addr::ACE_FILE_Addr (const ACE_FILE_Addr &sa) + : ACE_Addr (AF_FILE, ACE_OS::strlen (sa.filename_)) +{ + (void) ACE_OS::memcpy ((void *) &this->filename_, + (void *) &sa.filename_, sa.get_size ()); +} + +ACE_INLINE ACE_FILE_Addr & +ACE_FILE_Addr::operator= (const ACE_FILE_Addr &sa) +{ + if (this != &sa) + (void) ACE_OS::memcpy ((void *) &this->filename_, + (void *) &sa.filename_, + sa.get_size ()); + return *this; +} + +ACE_INLINE void +ACE_FILE_Addr::set (LPCTSTR filename) +{ + + this->ACE_Addr::base_set (AF_FILE, ACE_OS::strlen (filename) ); + (void) ACE_OS::strcpy (this->filename_, filename); +} + +// Create a ACE_Addr from a ACE_FILE pathname. + +ACE_INLINE +ACE_FILE_Addr::ACE_FILE_Addr (LPCTSTR filename) +{ + this->set (filename); +} + +// Transform the current address into string format. + +ACE_INLINE int +ACE_FILE_Addr::addr_to_string (char s[], size_t len) const +{ + ACE_OS::strncpy (s, this->filename_, len); + return 0; +} + +// Return the address. + +ACE_INLINE void * +ACE_FILE_Addr::get_addr (void) const +{ + return (void *) &this->filename_; +} + +// Compare two addresses for equality. + +ACE_INLINE int +ACE_FILE_Addr::operator == (const ACE_Addr &sap) const +{ + return ACE_OS::strcmp (this->filename_, + ((ACE_FILE_Addr &) sap).filename_) == 0; +} + +// Compare two addresses for inequality. + +ACE_INLINE int +ACE_FILE_Addr::operator != (const ACE_Addr &sap) const +{ + return !((*this) == sap); // This is lazy, of course... ;-) +} + +// Return the path name used for the rendezvous point. + +ACE_INLINE LPCTSTR +ACE_FILE_Addr::get_path_name (void) const +{ + return this->filename_; +} + diff --git a/ace/FILE_Connector.cpp b/ace/FILE_Connector.cpp new file mode 100644 index 00000000000..7ddf41e4506 --- /dev/null +++ b/ace/FILE_Connector.cpp @@ -0,0 +1,43 @@ +// FILE_Connector.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/FILE_Connector.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_FILE_Connector) + +void +ACE_FILE_Connector::dump (void) const +{ + ACE_TRACE ("ACE_FILE_Connector::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_FILE_Connector::ACE_FILE_Connector (void) +{ + ACE_TRACE ("ACE_FILE_Connector::ACE_FILE_Connector"); +} + +int +ACE_FILE_Connector::connect (ACE_FILE_IO &new_io, + const ACE_FILE_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &, + int, + int flags, + int perms) +{ + ACE_TRACE ("ACE_FILE_Connector::connect"); + ACE_ASSERT (new_io.get_handle () == ACE_INVALID_HANDLE); + + ACE_HANDLE handle = ACE::handle_timed_open (timeout, + remote_sap.get_path_name (), + flags, perms); + new_io.set_handle (handle); + new_io.remote_addr_ = remote_sap; // class copy. + return handle == ACE_INVALID_HANDLE ? -1 : 0; +} + diff --git a/ace/FILE_Connector.h b/ace/FILE_Connector.h new file mode 100644 index 00000000000..0a36bde7764 --- /dev/null +++ b/ace/FILE_Connector.h @@ -0,0 +1,87 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// FILE_Connector.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_FILE_CONNECTOR_H) +#define ACE_FILE_CONNECTOR_H + +#include "ace/FILE_IO.h" + +class ACE_Export ACE_FILE_Connector : public ACE_FILE + // = TITLE + // Defines an active connection factory for the ACE_FILE wrappers. +{ +public: + // = Initialization methods. + ACE_FILE_Connector (void); + // Default constructor. + + ACE_FILE_Connector (ACE_FILE_IO &new_io, + const ACE_FILE_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0); + // Actively connect and produce a if things go well. + // The is the address that we are trying to connect + // with. The is the amount of time to wait to connect. + // If it's 0 then we block indefinitely. If *timeout == {0, 0} then + // the connection is done using non-blocking mode. In this case, if + // the connection can't be made immediately the value of -1 is + // returned with . If *timeout > {0, 0} then + // this is the amount of time to wait before timing out. If the + // time expires before the connection is made . + // The is the value of local address to bind to. If + // it's the default value of then the user is + // letting the OS do the binding. If == 1 then the + // is reused, even if it hasn't been cleanedup yet. + // The and arguments are passed down to the open() + // method. + + int connect (ACE_FILE_IO &new_io, + const ACE_FILE_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0); + // Actively connect and produce a if things go well. + // The is the address that we are trying to connect + // with. The is the amount of time to wait to connect. + // If it's 0 then we block indefinitely. If *timeout == {0, 0} then + // the connection is done using non-blocking mode. In this case, if + // the connection can't be made immediately the value of -1 is + // returned with . If *timeout > {0, 0} then + // this is the amount of time to wait before timing out. If the + // time expires before the connection is made . + // The is the value of local address to bind to. If + // it's the default value of then the user is + // letting the OS do the binding. If == 1 then the + // is reused, even if it hasn't been cleanedup yet. + // The and arguments are passed down to the open() + // method. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#include "ace/FILE_Connector.i" + +#endif /* ACE_FILE_CONNECTOR_H */ diff --git a/ace/FILE_Connector.i b/ace/FILE_Connector.i new file mode 100644 index 00000000000..14e8d809a68 --- /dev/null +++ b/ace/FILE_Connector.i @@ -0,0 +1,25 @@ +/* -*- C++ -*- */ +// $Id$ + +// FILE_Connector.i + +#include "ace/Log_Msg.h" + +// Creates a Local ACE_FILE. + +inline +ACE_FILE_Connector::ACE_FILE_Connector (ACE_FILE_IO &new_io, + const ACE_FILE_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_FILE_Connector::ACE_FILE_Connector"); + if (this->connect (new_io, remote_sap, timeout, local_sap, + reuse_addr, flags, perms) == ACE_IO_SAP::INVALID_HANDLE + && timeout != 0 && !(errno == EWOULDBLOCK || errno == ETIMEDOUT)) + ACE_ERROR ((LM_ERROR, "address %s, %p\n", + remote_sap.get_path_name (), "ACE_FILE_IO")); +} diff --git a/ace/FILE_IO.cpp b/ace/FILE_IO.cpp new file mode 100644 index 00000000000..b77bcaf98fc --- /dev/null +++ b/ace/FILE_IO.cpp @@ -0,0 +1,100 @@ +// FILE_IO.cpp +// $Id$ + + +#define ACE_BUILD_DLL +#include "ace/FILE_IO.h" +#include "ace/Log_Msg.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_FILE_IO) + +void +ACE_FILE_IO::dump (void) const +{ + ACE_TRACE ("ACE_FILE_IO::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + remote_addr_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// Simple-minded do nothing constructor. + +ACE_FILE_IO::ACE_FILE_IO (void) +{ + ACE_TRACE ("ACE_FILE_IO::ACE_FILE_IO"); +} + +// Send N char *ptrs and int lengths. Note that the char *'s precede +// the ints (basically, an varargs version of writev). The count N is +// the *total* number of trailing arguments, *not* a couple of the +// number of tuple pairs! + +ssize_t +ACE_FILE_IO::send (size_t n, ...) const +{ + ACE_TRACE ("ACE_FILE_IO::send"); + va_list argp; + size_t total_tuples = n / 2; + ssize_t result; +#if defined (ACE_HAS_ALLOCA) + iovec *iovp = (iovec *) alloca (total_tuples * sizeof (iovec)); +#else + iovec *iovp; + + ACE_NEW_RETURN (iovp, iovec[total_tuples], -1); +#endif /* !defined (ACE_HAS_ALLOCA) */ + + va_start (argp, n); + + for (size_t i = 0; i < total_tuples; i++) + { + iovp[i].iov_base = va_arg (argp, char *); + iovp[i].iov_len = va_arg (argp, int); + } + + result = ACE_OS::writev (this->get_handle (), iovp, total_tuples); +#if !defined (ACE_HAS_ALLOCA) + delete [] iovp; +#endif /* !defined (ACE_HAS_ALLOCA) */ + va_end (argp); + return result; +} + +// This is basically an interface to ACE_OS::readv, that doesn't use +// the struct iovec explicitly. The ... can be passed as an arbitrary +// number of (char *ptr, int len) tuples. However, the count N is the +// *total* number of trailing arguments, *not* a couple of the number +// of tuple pairs! + +ssize_t +ACE_FILE_IO::recv (size_t n, ...) const +{ + ACE_TRACE ("ACE_FILE_IO::recv"); + va_list argp; + size_t total_tuples = n / 2; + ssize_t result; +#if defined (ACE_HAS_ALLOCA) + iovec *iovp = (iovec *) alloca (total_tuples * sizeof (iovec)); +#else + iovec *iovp; + + ACE_NEW_RETURN (iovp, iovec[total_tuples], -1); +#endif /* !defined (ACE_HAS_ALLOCA) */ + + va_start (argp, n); + + for (size_t i = 0; i < total_tuples; i++) + { + iovp[i].iov_base = va_arg (argp, char *); + iovp[i].iov_len = va_arg (argp, int); + } + + result = ACE_OS::readv (this->get_handle (), iovp, total_tuples); +#if !defined (ACE_HAS_ALLOCA) + delete [] iovp; +#endif /* !defined (ACE_HAS_ALLOCA) */ + va_end (argp); + return result; +} + diff --git a/ace/FILE_IO.h b/ace/FILE_IO.h new file mode 100644 index 00000000000..436621ff518 --- /dev/null +++ b/ace/FILE_IO.h @@ -0,0 +1,109 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// FILE_IO.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_FILE_IO_H) +#define ACE_FILE_IO_H + +#include "ace/FILE.h" +#include "ace/FILE_Addr.h" + +class ACE_Export ACE_FILE_IO : public ACE_FILE + // = TITLE + // Read/Write operations on Files +{ +friend class ACE_FILE_Connector; +public: + // = Initialization method. + ACE_FILE_IO (void); + // Default constructor. + + ssize_t send (const void *buf, size_t n) const; + // send upto bytes in . + + ssize_t recv (void *buf, size_t n) const; + // Recv upto bytes in . + + ssize_t send_n (const void *buf, size_t n) const; + // Send n bytes, keep trying until n are sent. + + ssize_t recv_n (void *buf, size_t n) const; + // Recv n bytes, keep trying until n are received. + +#if defined (ACE_HAS_STREAM_PIPES) + ssize_t send (const ACE_Str_Buf *cntl, + const ACE_Str_Buf *data, + int flags = 0) const; + // Send bytes via STREAM pipes. + + ssize_t recv (ACE_Str_Buf *cntl, + ACE_Str_Buf *data, + int *flags) const; + // Recv bytes via STREAM pipes. + + ssize_t send (const ACE_Str_Buf *cntl, + const ACE_Str_Buf *data, + int band, + int flags = 0) const; + // Send bytes via STREAM pipes using "band" mode. + + ssize_t recv (ACE_Str_Buf *cntl, + ACE_Str_Buf *data, + int *band, + int *flags) const; + // Recv bytes via STREAM pipes using "band" mode. + +#endif /* ACE_HAS_STREAM_PIPES */ + + ssize_t send (const iovec iov[], size_t n) const; + // Send iovecs via <::writev>. + + ssize_t recv (iovec iov[], size_t n) const; + // Recv iovecs via <::readv>. + + ssize_t send (size_t n, ...) const; + // Send N char *ptrs and int lengths. Note that the char *'s + // precede the ints (basically, an varargs version of writev). The + // count N is the *total* number of trailing arguments, *not* a + // couple of the number of tuple pairs! + + ssize_t recv (size_t n, ...) const; + // This is an interface to ::readv, that doesn't use the struct + // iovec explicitly. The ... can be passed as an arbitrary number + // of (char *ptr, int len) tuples. However, the count N is the + // *total* number of trailing arguments, *not* a couple of the + // number of tuple pairs! + + ssize_t send (const void *buf, size_t n, ACE_OVERLAPPED *overlapped) const; + // Send bytes via Win32 WriteFile using overlapped I/O. + + ssize_t recv (void *buf, size_t n, ACE_OVERLAPPED *overlapped) const; + // Recv bytes via Win32 ReadFile using overlapped I/O. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_FILE_Addr remote_addr_; + // File we are "connected" with... +}; + +#include "ace/FILE_IO.i" + +#endif /* ACE_FILE_IO_H */ diff --git a/ace/FILE_IO.i b/ace/FILE_IO.i new file mode 100644 index 00000000000..fffffd1de1c --- /dev/null +++ b/ace/FILE_IO.i @@ -0,0 +1,101 @@ +/* -*- C++ -*- */ +// $Id$ + +// FILE_IO.i + +// Send exactly N bytes from BUF to this file. Keeping trying until +// this many bytes are sent. + +inline ssize_t +ACE_FILE_IO::send_n (const void *buf, size_t n) const +{ + ACE_TRACE ("ACE_FILE_IO::send_n"); + return ACE::send_n (this->get_handle (), buf, n); +} + +// Receive exactly N bytes from this file into BUF. Keep trying until +// this many bytes are received. + +inline ssize_t +ACE_FILE_IO::recv_n (void *buf, size_t n) const +{ + ACE_TRACE ("ACE_FILE_IO::recv_n"); + return ACE::recv_n (this->get_handle (), buf, n); +} + +inline ssize_t +ACE_FILE_IO::send (const void *buf, size_t n) const +{ + ACE_TRACE ("ACE_FILE_IO::send"); + return ACE_OS::write (this->get_handle (), (const char *) buf, n); +} + +inline ssize_t +ACE_FILE_IO::recv (void *buf, size_t n) const +{ + ACE_TRACE ("ACE_FILE_IO::recv"); + return ACE_OS::read (this->get_handle (), (char *) buf, n); +} + +inline ssize_t +ACE_FILE_IO::send (const iovec iov[], size_t n) const +{ + ACE_TRACE ("ACE_FILE_IO::send"); + return ACE_OS::writev (this->get_handle (), (iovec *) iov, n); +} + +inline ssize_t +ACE_FILE_IO::recv (iovec iov[], size_t n) const +{ + ACE_TRACE ("ACE_FILE_IO::recv"); + return ACE_OS::readv (this->get_handle (), (iovec *) iov, n); +} + +#if defined (ACE_HAS_STREAM_PIPES) +inline ssize_t +ACE_FILE_IO::recv (ACE_Str_Buf *cntl, ACE_Str_Buf *data, int *band, int *flags) const +{ + ACE_TRACE ("ACE_FILE_IO::recv"); + return ACE_OS::getpmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, band, flags); +} + +inline ssize_t +ACE_FILE_IO::send (const ACE_Str_Buf *cntl, const ACE_Str_Buf *data, int band, int flags) const +{ + ACE_TRACE ("ACE_FILE_IO::send"); + return ACE_OS::putpmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, band, flags); +} + +inline ssize_t +ACE_FILE_IO::recv (ACE_Str_Buf *cntl, ACE_Str_Buf *data, int *flags) const +{ + ACE_TRACE ("ACE_FILE_IO::recv"); + return ACE_OS::getmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, flags); +} + +inline ssize_t +ACE_FILE_IO::send (const ACE_Str_Buf *cntl, const ACE_Str_Buf *data, int flags) const +{ + ACE_TRACE ("ACE_FILE_IO::send"); + return ACE_OS::putmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, flags); +} + +inline ssize_t +ACE_FILE_IO::send (const void *buf, size_t n, + ACE_OVERLAPPED *overlapped) const +{ + ACE_TRACE ("ACE_FILE_IO::send"); + return ACE_OS::write (this->get_handle (), + (const char *) buf, n, + overlapped); +} + +inline ssize_t +ACE_FILE_IO::recv (void *buf, size_t n, + ACE_OVERLAPPED *overlapped) const +{ + ACE_TRACE ("ACE_FILE_IO::recv"); + return ACE_OS::read (this->get_handle (), (char *) buf, n, + overlapped); +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/ace/Future.cpp b/ace/Future.cpp new file mode 100644 index 00000000000..3114afaf637 --- /dev/null +++ b/ace/Future.cpp @@ -0,0 +1,346 @@ +// Future.cpp +// $Id$ + +#define ACE_BUILD_DLL + +#if !defined (ACE_FUTURE_CPP) +#define ACE_FUTURE_CPP + +#include "ace/Future.h" + +#if defined (ACE_HAS_THREADS) + +// Dump the state of an object. + +template void +ACE_Future_Rep::dump (void) const +{ + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, + "ref_count_ = %d\n", + this->ref_count_)); + ACE_DEBUG ((LM_INFO,"value_: \n")); + if (this->value_) + ACE_DEBUG ((LM_DEBUG," (NON-NULL)\n")); + else + ACE_DEBUG ((LM_DEBUG," (NULL)\n")); + ACE_DEBUG ((LM_INFO,"value_ready_: \n")); + this->value_ready_.dump (); + ACE_DEBUG ((LM_INFO,"value_ready_mutex_: \n")); + this->value_ready_mutex_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +template +ACE_Future_Rep::ACE_Future_Rep (void) + : ref_count_ (0), + value_ (0), + value_ready_ (this->value_ready_mutex_) +{ +} + +template +ACE_Future_Rep::~ACE_Future_Rep (void) +{ + delete this->value_; + this->value_ = 0; +} + +template int +ACE_Future_Rep::ready (void) +{ + return this->value_ != 0; +} + +template int +ACE_Future_Rep::set (const T &r) +{ + // If the value is already produced, ignore it... + if (this->value_ == 0) + { + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->value_ready_mutex_, -1)); + // Otherwise, create a new result value. Note the use of the + // Double-checked locking pattern to avoid multiple allocations. + + if (this->value_ == 0) + ACE_NEW_RETURN (this->value_, T (r), -1); + + // Signal all the waiting threads. + return this->value_ready_.broadcast (); + + // Destructor releases the lock. + } + return 0; +} + +template int +ACE_Future_Rep::get (T &value, ACE_Time_Value *tv) +{ + // If the value is already produced, return it. + if (this->value_ == 0) + { + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->value_ready_mutex_, -1)); + + // If the value is not yet defined we must block until the + // producer writes to it. + + while (this->value_ == 0) + { + // Perform a timed wait. + if (this->value_ready_.wait (tv) == -1) + return -1; + } + // Destructor releases the lock. + } + + value = *this->value_; + return 0; +} + +template +ACE_Future_Rep::operator T () +{ + // If the value is already produced, return it. + if (this->value_ == 0) + { + // constructor of ace_mon acquires the mutex + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->value_ready_mutex_, 0)); + + // If the value is not yet defined we must block until the + // producer writes to it. + + while (this->value_ == 0) + { + // wait forever + if (this->value_ready_.wait () == -1) + return 0; + } + + // Destructor releases the mutex + + } + + return *this->value_; +} + + +template +ACE_Future::ACE_Future (void) + : future_rep_ (0) +{ +} + +template +ACE_Future::ACE_Future (const ACE_Future &r) +{ + + // copy constructor: + // + // bind to the same as . + + // @@ not really clear if this is needed... after all this + // ACE_Future is just being instantiated... + ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->mutex_)); + + // acquire the mutex on . We have to make sure + // that does not delete its future_rep_... + + ACE_MT (ACE_GUARD (ACE_Thread_Mutex, r_mon, (ACE_Thread_Mutex &) r.mutex_)); + + // Check if 'r' has already a ACE_Future_rep bound to it. + if (r.future_rep_ == 0) + this->future_rep_ = r.create_rep_i (); + else + // ACE_Future_rep exists already, we can just link to it. + this->future_rep_ = r.future_rep_; + + this->future_rep_->ref_count_++; + +} + +template +ACE_Future::ACE_Future (const T &r) +{ + ACE_DEBUG ((LM_DEBUG," (%t) funny constructor\n")); + ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->mutex_)); + this->create_rep_i ()->set (r); +} + +template +ACE_Future::~ACE_Future (void) +{ + ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->mutex_)); + + if (this->future_rep_) + { + this->future_rep_->ref_count_--; + + if (this->future_rep_->ref_count_ == 0) + { + delete this->future_rep_; + this->future_rep_ = 0; + } + } + +} + +template int +ACE_Future::operator== (const ACE_Future &r) const +{ + return r.future_rep_ == this->future_rep_; +} + +template int +ACE_Future::operator!= (const ACE_Future &r) const +{ + return r.future_rep_ != this->future_rep_; +} + +template int +ACE_Future::cancel (const T &r) +{ + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->mutex_, -1)); + + // If this ACE_Future is already attached to a ACE_Future_Rep, + // detach it (maybe delete the ACE_Future_Rep). + if (this->future_rep_) + { + this->future_rep_->ref_count_--; + + if (this->future_rep_->ref_count_ == 0) + delete this->future_rep_; + } + + // Make a new ACE_Future_Rep and immediately assign + // the new value to it. + this->create_rep_i (); + return this->future_rep_->set (r); +} + +template int +ACE_Future::set (const T &r) +{ + if (this->future_rep_) + // Give the pointer to the result to the ACE_Future_Rep. + return this->future_rep_->set (r); + else + // @@ Maybe this should return a special value to indicate that + // there's no yet? + return 0; +} + +template ACE_Future_Rep * +ACE_Future::create_rep_i (void) const +{ + // Should only be called internally with locks held. + ACE_NEW_RETURN (((ACE_Future *) this)->future_rep_, ACE_Future_Rep, 0); + this->future_rep_->ref_count_ = 1; + return this->future_rep_; +} + +template int +ACE_Future::ready (void) +{ + // We're ready if the ACE_Future_rep is ready... + if (this->future_rep_) + return this->future_rep_->ready (); + else + return 0; +} + +template int +ACE_Future::get (T &value, ACE_Time_Value *tv) +{ + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->mutex_, -1)); + + if (this->future_rep_ == 0) + // Oops, we have to create a ACE_Future_Rep first. + this->create_rep_i (); + + // We return the ACE_Future_rep. + return this->future_rep_->get (value, tv); +} + +template +ACE_Future::operator T () +{ + // note that this will fail (and COREDUMP!) + // if future_rep_ == 0 ! + // + // but... + // this is impossible unless somebody is so stupid to + // try something like this: + // + // Future futT; + // T t; + // t = futT; + + // perform type conversion on Future_Rep. + return *future_rep_; +} + +template void +ACE_Future::operator = (const ACE_Future &r) +{ + // assignment: + // + // bind to the same as . + + ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->mutex_)); + + // if there is already a we have + // to disconnect from it... + if (this->future_rep_) + { + // Disconnect from the . + this->future_rep_->ref_count_--; + + if (this->future_rep_->ref_count_ == 0) + delete this->future_rep_; + } + + // Acquire the mutex on . We have to make sure + // that does not delete it's future_rep_... + + ACE_MT (ACE_GUARD (ACE_Thread_Mutex, r_mon, (ACE_Thread_Mutex &) r.mutex_)); + + // Check if 'r' has already a ACE_Future_rep bound to it. + if (r.future_rep_ == 0) + this->future_rep_ = r.create_rep_i (); + else + // ACE_Future_rep exists already, we can just link to it. + this->future_rep_ = r.future_rep_; + + this->future_rep_->ref_count_++; +} + +template void +ACE_Future::dump (void) const +{ + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + if (this->future_rep_) + this->future_rep_->dump (); + + this->mutex_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +template void * +ACE_Future::operator new (size_t nbytes) +{ + return 0; +} + +template void +ACE_Future::operator delete (void *) +{ +} + +template void +ACE_Future::operator &() +{ +} + +#endif /* ACE_HAS_THREADS */ +#endif /* ACE_FUTURE_CPP */ diff --git a/ace/Future.h b/ace/Future.h new file mode 100644 index 00000000000..1d0a13e057d --- /dev/null +++ b/ace/Future.h @@ -0,0 +1,167 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Future.h +// +// = AUTHOR +// Andres Kruse and Douglas C. Schmidt +// +// +// ============================================================================ + +#if !defined (ACE_FUTURE_H) +#define ACE_FUTURE_H + +#include "ace/Synch.h" + +#if defined (ACE_HAS_THREADS) + +// Forward decl. +template class ACE_Future; + +template class ACE_Future_Rep +// = TITLE +// +// ACE_Future_Rep +// +// = DESCRIPTION +// An ACE_Future_Rep object encapsules a pointer to an +// object of class T which is the result of an asynchronous +// method invocation. It is pointed to by ACE_Future object[s] +// and only accessible through them. +{ + friend class ACE_Future; + +private: + + int set (const T &r); + // Set the result value. + + int get (T &value, ACE_Time_Value *tv); + // Wait up to time to get the . + + operator T(); + // Type conversion. will block forever until the + // result is available. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + + // = constructor and destructor private + ACE_Future_Rep (void); + ~ACE_Future_Rep (void); + + int ready (void); + // Is result available? + + T *value_; + // Pointer to the result. + + ACE_Atomic_Op ref_count_; + // Reference count. + + // = Condition variable and mutex that protect the . + ACE_Condition_Thread_Mutex value_ready_; + ACE_Thread_Mutex value_ready_mutex_; +}; + +template class ACE_Future + // = TITLE + // This class implements a ``single write, multiple read'' pattern + // that can be used to return results from asynchronous method + // invocations. + // = DESCRIPTION +{ +public: + // = Initialization and termination methods. + ACE_Future (void); + // Constructor. + + ACE_Future (const ACE_Future &r); + // Copy constructor binds and to the same + // . An is created if necessary. + + ACE_Future (const T &r); + // Constructor that initialises an to point to the + // result immediately. + + ~ACE_Future (void); + // Destructor. + + void operator = (const ACE_Future &r); + // Assignment operator that binds and to the same + // . An is created if necessary. + + int cancel (const T &r); + // Cancel an and assign the value . It is used if a + // client does not want to wait for to be produced. + + int operator == (const ACE_Future &r) const; + // Equality operator that returns 1 if both ACE_Future objects + // point to the same ACE_Future_Rep object. Attention: It also + // returns 1 if both objects have just been instantiated and not + // used yet. + + int operator != (const ACE_Future &r) const; + // Inequality operator, which is the opposite of equality. + + int set (const T &r); + // Make the result available. Is used by the server thread to give + // the result to all waiting clients. + + int get (T &value, ACE_Time_Value *tv = 0); + // Wait up to time to get the . + + operator T (); + // type conversion. obtain the result of the asynchronous method + // invocation. will block forever. + + int ready (void); + // Check if the result is available. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Future_Rep *create_rep_i (void) const; + // Create the object. + + void* operator new (size_t nbytes); + // Do not allow new operator. + + void operator delete(void *); + // Do not allow delete operator + + void operator &(); + // Do not allow address-of operator. + + ACE_Future_Rep *future_rep_; + // the ACE_Future_Rep + + ACE_Thread_Mutex mutex_; + // Protect operations on the . + +}; + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Future.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Future.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ +#endif /* ACE_HAS_THREADS */ +#endif /* ACE_FUTURE_H */ diff --git a/ace/Get_Opt.cpp b/ace/Get_Opt.cpp new file mode 100644 index 00000000000..5279d4c6912 --- /dev/null +++ b/ace/Get_Opt.cpp @@ -0,0 +1,133 @@ +// Get_Opt.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Get_Opt.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Get_Opt) + +void +ACE_Get_Opt::dump (void) const +{ + ACE_TRACE ("ACE_Get_Opt::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +int +ACE_Get_Opt::operator () (void) +{ + ACE_TRACE ("ACE_Get_Opt::operator"); + if (this->nextchar == 0 || *this->nextchar == 0) + { + /* Special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (this->optind != this->nargc && !::strcmp (this->nargv[this->optind], "--")) + { + this->optind++; + + if (this->first_nonopt == this->last_nonopt) + this->first_nonopt = this->optind; + this->last_nonopt = this->nargc; + + this->optind = this->nargc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (this->optind == this->nargc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (this->first_nonopt != this->last_nonopt) + this->optind = this->first_nonopt; + return EOF; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (this->nargv[this->optind][0] != '-' || this->nargv[this->optind][1] == 0) + return EOF; + + /* We have found another option-ARGV-element. + Start decoding its characters. */ + + this->nextchar = this->nargv[this->optind] + 1; + } + + /* Look at and handle the next option-character. */ + + { + char c = *this->nextchar++; + char *temp = (char *) strchr (this->noptstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*this->nextchar == 0) + this->optind++; + + if (temp == 0 || c == ':') + { + if (this->opterr != 0) + { + if (c < 040 || c >= 0177) + ACE_ERROR ((LM_ERROR, "%s: unrecognized option, character code 0%o\n", + this->nargv[0], c)); + else + ACE_ERROR ((LM_ERROR, "%s: unrecognized option `-%c'\n", + this->nargv[0], c)); + } + return '?'; + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*this->nextchar != 0) + { + this->optarg = this->nextchar; + this->optind++; + } + else + this->optarg = 0; + this->nextchar = 0; + } + else + { + /* This is an option that requires an argument. */ + if (*this->nextchar != 0) + { + this->optarg = this->nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + this->optind++; + } + else if (this->optind == this->nargc) + { + if (this->opterr != 0) + ACE_ERROR ((LM_ERROR, "%s: no argument for `-%c' option\n", + this->nargv[0], c)); + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + this->optarg = this->nargv[this->optind++]; + this->nextchar = 0; + } + } + return c; + } +} diff --git a/ace/Get_Opt.h b/ace/Get_Opt.h new file mode 100644 index 00000000000..0e26a51e807 --- /dev/null +++ b/ace/Get_Opt.h @@ -0,0 +1,161 @@ +/* -*- C++ -*- */ +// $Id$ + +/* ACE_Get_Opt for GNU. + Copyright (C) 1987, 1989 Free Software Foundation, Inc. (Modified + by Douglas C. Schmidt for use with C++.) + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 1, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Get_Opt.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_GET_OPT_H) +#define ACE_GET_OPT_H + +#include "ace/ACE.h" + +class ACE_Export ACE_Get_Opt + // = TITLE + // Iterator for parsing command-line arguments. + // + // = DESCRIPTION + // This version of `get_opt' appears to the caller like standard + // Unix `get_opt' but it behaves differently for the user, since it + // allows the user to intersperse the options with the other + // arguments. + // + // As `get_opt' works, it permutes the elements of `argv' so that, + // when it is done, all the options precede everything else. Thus + // all application programs are extended to handle flexible argument order. + // + // Setting the environment variable _POSIX_OPTION_ORDER disables permutation. + // Then the behavior is completely standard. + // + // GNU application programs can use a third alternative mode in which + // they can distinguish the relative order of options and other arguments. + +{ +public: + ACE_Get_Opt (int argc, char **argv, char *optstring, int skip_argv0 = 1, int report_errors = 0); + // Initialize the internal data when the first call is made. Start + // processing options with ARGV-element 0 + ; the + // sequence of previously skipped non-option ARGV-elements is empty. + + int operator () (void); + // Scan elements of ARGV (whose length is ARGC) for option + // characters given in OPTSTRING. + // + // If an element of ARGV starts with '-', and is not exactly "-" or "--", + // then it is an option element. The characters of this element + // (aside from the initial '-') are option characters. If `get_opt' + // is called repeatedly, it returns successively each of the option characters + // from each of the option elements. + // + // If `get_opt' finds another option character, it returns that character, + // updating `optind' and `nextchar' so that the next call to `get_opt' can + // resume the scan with the following option character or ARGV-element. + // + // If there are no more option characters, `get_opt' returns `EOF'. + // Then `optind' is the index in ARGV of the first ARGV-element + // that is not an option. (The ARGV-elements have been permuted + // so that those that are not options now come last.) + // + // OPTSTRING is a string containing the legitimate option characters. + // A colon in OPTSTRING means that the previous character is an option + // that wants an argument. The argument is taken from the rest of the + // current ARGV-element, or from the following ARGV-element, + // and returned in `optarg'. + // + // If an option character is seen that is not listed in OPTSTRING, + // return '?' after printing an error message. If you set `opterr' to + // zero, the error message is suppressed but we still return '?'. + // + // If a char in OPTSTRING is followed by a colon, that means it wants an arg, + // so the following text in the same ARGV-element, or the text of the following + // ARGV-element, is returned in `optarg. Two colons mean an option that + // wants an optional arg; if there is text in the current ARGV-element, + // it is returned in `optarg'. + // + // If OPTSTRING starts with `-', it requests a different method of handling the + // non-option ARGV-elements. See the comments about RETURN_IN_ORDER, above. */ + + // = Public data members (should be hidden...). + + char *optarg; + // For communication from `get_opt' to the caller. When `get_opt' + // finds an option that takes an argument, the argument value is + // returned here. Also, when `ordering' is RETURN_IN_ORDER, each + // non-option ARGV-element is returned here. + + int optind; + // Index in ARGV of the next element to be scanned. This is used + // for communication to and from the caller and for communication + // between successive calls to `get_opt'. On entry to `get_opt', + // zero means this is the first call; initialize. + // + // When `get_opt' returns EOF, this is the index of the first of the + // non-option elements that the caller should itself scan. + // + // Otherwise, `optind' communicates from one call to the next + // how much of ARGV has been scanned so far. + + int opterr; + // Callers store zero here to inhibit the error message for + // unrecognized options. + + // = GNU extensions + int nargc; + char **nargv; + char *noptstring; + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + + char *nextchar; + // The next char to be scanned in the option-element in which the + // last option character we returned was found. This allows us to + // pick up the scan where we left off. + // + // If this is zero, or a null string, it means resume the scan + // by advancing to the next ARGV-element. + + int first_nonopt; + int last_nonopt; + // Describe the part of ARGV that contains non-options that have + // been skipped. `first_nonopt' is the index in ARGV of the first + // of them; `last_nonopt' is the index after the last of them. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Get_Opt.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_GET_OPT_H */ diff --git a/ace/Get_Opt.i b/ace/Get_Opt.i new file mode 100644 index 00000000000..9481fc30145 --- /dev/null +++ b/ace/Get_Opt.i @@ -0,0 +1,23 @@ +/* -*- C++ -*- */ +// $Id$ + +// Get_Opt.i + +ACE_INLINE +ACE_Get_Opt::ACE_Get_Opt (int argc, + char **argv, + char *optstring, + int skip, + int report_errors) + : opterr (report_errors), + nextchar (0), + optarg (0), + first_nonopt (skip), + last_nonopt (skip), + optind (skip), + noptstring (optstring), + nargc (argc), + nargv (argv) +{ + ACE_TRACE ("ACE_Get_Opt::ACE_Get_Opt"); +} diff --git a/ace/Handle_Set.cpp b/ace/Handle_Set.cpp new file mode 100644 index 00000000000..d20f114cb05 --- /dev/null +++ b/ace/Handle_Set.cpp @@ -0,0 +1,213 @@ +// Handle_Set.cpp +// $Id$ + +/* Wrapper for the ACE_HANDLE set abstraction. */ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Handle_Set.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Handle_Set.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Handle_Set) + +void +ACE_Handle_Set::dump (void) const +{ + ACE_TRACE ("ACE_Handle_Set::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + ACE_DEBUG ((LM_DEBUG, "[ ")); + ACE_DEBUG ((LM_DEBUG, "size_ = %d", this->size_)); + ACE_DEBUG ((LM_DEBUG, "\nmax_handle_ = %d", this->max_handle_)); + +#if defined(ACE_WIN32) + for (size_t i = 0; i < this->mask_.fd_count + 1; i++) + ACE_DEBUG ((LM_DEBUG, " %x ", this->mask_.fd_array[i])); +#else /* !ACE_WIN32 */ + for (size_t i = 0; i < this->max_handle_ + 1; i++) + if (this->is_set (i)) + ACE_DEBUG ((LM_DEBUG, " %d ", i)); +#endif /* ACE_WIN32 */ + + ACE_DEBUG ((LM_DEBUG, " ]")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +#if defined (ACE_HAS_BROKEN_BITSHIFT) +static const ACE_UINT32 MSB_MASK = ~(ACE_UINT32 (1) << ACE_UINT32 (NFDBITS - 1)); +#else +// This needs to go here to avoid overflow problems on some compilers. +static const ACE_UINT32 MSB_MASK = ~(1 << (NFDBITS - 1)); +#endif /* ACE_HAS_BROKEN_BITSHIFT */ + +// Table that maps bytes to counts of the enabled bits. + +const char ACE_Handle_Set::nbits_[256] = +{ + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, +}; + +// Constructor, initializes the bitmask to all 0s. + +ACE_Handle_Set::ACE_Handle_Set (void) +{ + ACE_TRACE ("ACE_Handle_Set::ACE_Handle_Set"); + this->reset (); +} + +ACE_Handle_Set::ACE_Handle_Set (const ACE_FD_SET_TYPE &fd_mask) +{ + ACE_TRACE ("ACE_Handle_Set::ACE_Handle_Set"); + this->reset (); + ACE_OS::memcpy ((void *) &this->mask_, (void *) &fd_mask, sizeof + this->mask_); +#if !defined(ACE_WIN32) + this->sync (ACE_Handle_Set::MAXSIZE); +#endif /* !ACE_WIN32 */ +} + +// Counts the number of bits enabled in N. Uses a table lookup to +// speed up the count. + +int +ACE_Handle_Set::count_bits (unsigned long n) const +{ + ACE_TRACE ("ACE_Handle_Set::count_bits"); + return (ACE_Handle_Set::nbits_[n & 0xff] + ACE_Handle_Set::nbits_[(n >> 8) & 0xff] + + ACE_Handle_Set::nbits_[(n >> 16) & 0xff] + ACE_Handle_Set::nbits_[n >> 24]); +} + +// Synchronize the underlying FD_SET with the MAX_FD and the SIZE. + +void +ACE_Handle_Set::sync (ACE_HANDLE max) +{ + ACE_TRACE ("ACE_Handle_Set::sync"); +#if !defined(ACE_WIN32) + this->size_ = 0; + + for (int i = (max - 1) / ACE_Handle_Set::WORDSIZE; i >= 0; i--) + this->size_ += count_bits (this->mask_.fds_bits[i]); + + this->set_max (max); +#endif /* !ACE_WIN32 */ +} + +// Resets the MAX_FD after a clear of the original MAX_FD. + +void +ACE_Handle_Set::set_max (ACE_HANDLE current_max) +{ + ACE_TRACE ("ACE_Handle_Set::set_max"); +#if !defined(ACE_WIN32) + if (this->size_ == 0) + this->max_handle_ = -1; + else + { + int i; + + for (i = (current_max - 1) / ACE_Handle_Set::WORDSIZE; + this->mask_.fds_bits[i] == 0; + i--) + continue; + + this->max_handle_ = i * ACE_Handle_Set::WORDSIZE; + for (fd_mask val = this->mask_.fds_bits[i]; + (val & ~1) != 0; + val = (val >> 1) & MSB_MASK) + this->max_handle_++; + } + + // Do some sanity checking... + if (this->max_handle_ >= ACE_Handle_Set::MAXSIZE) + this->max_handle_ = ACE_Handle_Set::MAXSIZE - 1; +#endif /* !ACE_WIN32 */ +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Handle_Set_Iterator) + +void +ACE_Handle_Set_Iterator::dump (void) const +{ + ACE_TRACE ("ACE_Handle_Set_Iterator::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "num_ = %d", this->num_)); + ACE_DEBUG ((LM_DEBUG, "\nindex_ = %d", this->index_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +void +ACE_Handle_Set_Iterator::operator++ (void) +{ + ACE_TRACE ("ACE_Handle_Set_Iterator::operator++"); + +#if defined(ACE_WIN32) + this->index_++; +#else /* !ACE_WIN32 */ + this->val_ = (this->val_ >> 1) & MSB_MASK; + this->num_++; + + + if (this->val_ == 0) + { + for (this->index_++; + this->index_ < ACE_Handle_Set::NUM_WORDS + && this->handles_.mask_.fds_bits[this->index_] == 0; + this->index_++) + continue; + + if (this->index_ >= ACE_Handle_Set::NUM_WORDS) + { + this->num_ = this->handles_.max_handle_ + 1; + return; + } + else + { + this->val_ = this->handles_.mask_.fds_bits[this->index_]; + this->num_ = this->index_ * ACE_Handle_Set::WORDSIZE; + } + } + + for (; ACE_BIT_DISABLED (this->val_, 1); this->num_++) + this->val_ = (this->val_ >> 1) & MSB_MASK; +#endif /* !ACE_WIN32 */ +} + +ACE_Handle_Set_Iterator::ACE_Handle_Set_Iterator (const ACE_Handle_Set &f) + : handles_ (f), + index_ (0), + num_ (0) +{ + ACE_TRACE ("ACE_Handle_Set_Iterator::ACE_Handle_Set_Iterator"); +#if !defined(ACE_WIN32) + for (; + this->handles_.mask_.fds_bits[this->index_] == 0; + this->index_++) + this->num_ += ACE_Handle_Set::WORDSIZE; + + for (this->val_ = this->handles_.mask_.fds_bits[this->index_]; + (ACE_BIT_DISABLED (this->val_, 1)) && this->num_ < ACE_Handle_Set::MAXSIZE; + this->num_++) + this->val_ = (this->val_ >> 1) & MSB_MASK; +#endif /* !ACE_WIN32 */ +} diff --git a/ace/Handle_Set.h b/ace/Handle_Set.h new file mode 100644 index 00000000000..8789ddde300 --- /dev/null +++ b/ace/Handle_Set.h @@ -0,0 +1,153 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Handle_Set.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_HANDLE_SET_H) +#define ACE_HANDLE_SET_H + +#include "ace/ACE.h" + +// This wrapper design is not very portable to DEC OSF/1 I had to +// redefine NFDBITS to 32. On OSF/1 NFDBITS is a macro that expands to +// (sizeof(fd_mask)*8) which is 4096 by default. This was an +// inappropriate value for defining the MSB_MASK default value. Any +// ideas? The workaround is a pretty severe restriction for OSF/1. +// DJT +// #if defined (__osf__) +// #define NFDBITS 32 +// #endif + +class ACE_Export ACE_Handle_Set +{ + // = TITLE + // C++ wrapper for the socket abstraction. +friend class ACE_Handle_Set_Iterator; +public: + // = Initialization and termination. + + enum + { + MAXSIZE = ACE_DEFAULT_REACTOR_SIZE + }; + + // = Initialization methods. + ACE_Handle_Set (void); + // Constructor, initializes the bitmask to all 0s. + + ACE_Handle_Set (const ACE_FD_SET_TYPE &mask); + + // = Methods for manipulating bitsets. + void reset (void); + // Initialize the bitmask to all 0s and reset the associated fields. + + int is_set (ACE_HANDLE) const; + // Checks whether handle is enabled. + + void set_bit (ACE_HANDLE); + // Enables the handle. + + void clr_bit (ACE_HANDLE); + // Disables the handle. + + int num_set (void) const; + // Returns a count of the number of enabled bits. + + ACE_HANDLE max_set (void) const; + // Returns the number of the large bit. + + void sync (ACE_HANDLE max); + // Synchronize the underlying FD_SET with the MAX_FD and the SIZE. + + operator fd_set *(); + // Returns a pointer to the underlying fd_set. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + int size_; + // Size of the set. + + ACE_HANDLE max_handle_; + // Current max handle. + + fd_set mask_; + // Bitmask. + + enum + { + WORDSIZE = NFDBITS, +#if !defined(ACE_WIN32) + NUM_WORDS = howmany (MAXSIZE, NFDBITS), +#endif + NBITS = 256 + }; + + int count_bits (unsigned long n) const; + // Counts the number of bits enabled in N. Uses a table lookup to + // speed up the count. + + void set_max (ACE_HANDLE max); + // Resets the MAX_FD after a clear of the original MAX_FD. + + static const char nbits_[ACE_Handle_Set::NBITS]; + // Table that maps bytes to counts of the enabled bits. +}; + +class ACE_Export ACE_Handle_Set_Iterator + // = TITLE + // Iterator for the ACE_Handle_Set abstraction. +{ +public: + ACE_Handle_Set_Iterator (const ACE_Handle_Set &); + // Constructor. + + ACE_HANDLE operator ()(void); + // "Next" operator. + + void operator++ (void); + // Advance by "one." + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + const ACE_Handle_Set &handles_; + // The we are iterating through. + + int num_; + // Number of the word we're iterating on. + + size_t index_; + // Index of the current word. + +#if !defined (ACE_WIN32) + fd_mask val_; +#endif /* ACE_WIN32 */ + // Value of the bits in the word we're iterating on. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Handle_Set.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HANDLE_SET */ diff --git a/ace/Handle_Set.i b/ace/Handle_Set.i new file mode 100644 index 00000000000..d7577404ea3 --- /dev/null +++ b/ace/Handle_Set.i @@ -0,0 +1,107 @@ +/* -*- C++ -*- */ +// $Id$ + +// Handle_Set.i + +// Initialize the bitmask to all 0s and reset the associated fields. + +ACE_INLINE void +ACE_Handle_Set::reset (void) +{ + ACE_TRACE ("ACE_Handle_Set::reset"); + this->max_handle_ = ACE_INVALID_HANDLE; + this->size_ = 0; + FD_ZERO (&this->mask_); +} + +// Returns the number of the large bit. + +ACE_INLINE ACE_HANDLE +ACE_Handle_Set::max_set (void) const +{ + ACE_TRACE ("ACE_Handle_Set::max_set"); + return this->max_handle_; +} + +// Checks whether handle is enabled. + +ACE_INLINE int +ACE_Handle_Set::is_set (ACE_HANDLE handle) const +{ + ACE_TRACE ("ACE_Handle_Set::is_set"); + return FD_ISSET (handle, &this->mask_); +} + +// Enables the handle. + +ACE_INLINE void +ACE_Handle_Set::set_bit (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_Handle_Set::set_bit"); + if (!this->is_set (handle)) + { +#if defined(ACE_WIN32) + FD_SET ((SOCKET)handle, &this->mask_); +#else /* !ACE_WIN32 */ + FD_SET (handle, &this->mask_); + this->size_++; + if (handle > this->max_handle_) + this->max_handle_ = handle; +#endif /* ACE_WIN32 */ + } +} + +// Disables the handle. + +ACE_INLINE void +ACE_Handle_Set::clr_bit (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_Handle_Set::clr_bit"); + if (this->is_set (handle)) + { +#if defined(ACE_WIN32) + FD_CLR ((SOCKET)handle, &this->mask_); +#else /* !ACE_WIN32 */ + FD_CLR (handle, &this->mask_); + this->size_--; + + if (handle == this->max_handle_) + this->set_max (this->max_handle_); +#endif /* ACE_WIN32 */ + } +} + +// Returns a count of the number of enabled bits. + +ACE_INLINE int +ACE_Handle_Set::num_set (void) const +{ + ACE_TRACE ("ACE_Handle_Set::num_set"); +#if defined(ACE_WIN32) + return this->mask_.fd_count; +#else /* !ACE_WIN32 */ + return this->size_; +#endif /* ACE_WIN32 */ +} + +// Returns a pointer to the underlying fd_set. + +ACE_INLINE +ACE_Handle_Set::operator fd_set *() +{ + ACE_TRACE ("ACE_Handle_Set::operator ACE_FD_SET_TYPE *"); + return (fd_set *) &this->mask_; +} + +ACE_INLINE ACE_HANDLE +ACE_Handle_Set_Iterator::operator () (void) +{ + ACE_TRACE ("ACE_Handle_Set_Iterator::operator"); +#if defined(ACE_WIN32) + return this->index_ < this->handles_.mask_.fd_count + ? (ACE_HANDLE)this->handles_.mask_.fd_array[this->index_] + : ACE_INVALID_HANDLE; +#else /* !ACE_WIN32 */ + return this->num_ <= this->handles_.max_handle_ ? this->num_ : -1; +#endif /* ACE_WIN32 */ +} diff --git a/ace/High_Res_Timer.cpp b/ace/High_Res_Timer.cpp new file mode 100644 index 00000000000..aad19e26799 --- /dev/null +++ b/ace/High_Res_Timer.cpp @@ -0,0 +1,74 @@ +// High_Res_Timer.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/High_Res_Timer.h" + +#if !defined (__ACE_INLINE__) +#include "ace/High_Res_Timer.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_HAS_HI_RES_TIMER) + +ACE_ALLOC_HOOK_DEFINE(ACE_High_Res_Timer) + +void +ACE_High_Res_Timer::dump (void) const +{ + ACE_TRACE ("ACE_High_Res_Timer::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +void +ACE_High_Res_Timer::reset (void) +{ + ACE_TRACE ("ACE_High_Res_Timer::reset"); + (void) ACE_OS::memset (&this->start_, 0, sizeof this->start_); + (void) ACE_OS::memset (&this->end_, 0, sizeof this->end_); + (void) ACE_OS::memset (&this->total_, 0, sizeof this->total_); + (void) ACE_OS::memset (&this->temp_, 0, sizeof this->temp_); +} + +ACE_High_Res_Timer::ACE_High_Res_Timer (void) +{ + ACE_TRACE ("ACE_High_Res_Timer::ACE_High_Res_Timer"); + this->reset (); +} + +void +ACE_High_Res_Timer::print_ave (char *str, int count, ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_High_Res_Timer::print_ave"); +#if defined (ACE_HAS_LONGLONG_T) + hrtime_t total = this->end_ - this->start_; + hrtime_t avg_nsecs = total / count; + hrtime_t total_secs = total / (1000 * 1000 * 1000); + hrtime_t extra_nsecs = total - (total_secs * (1000 * 1000 * 1000)); + char buf[100]; + + ACE_OS::sprintf (buf, "%s count = %d, total (secs %lld, usecs %lld), avg usecs = %lld\n", + str, count, total_secs, extra_nsecs / 1000, avg_nsecs / 1000); + ACE_OS::write (handle, buf, strlen (buf)); +#endif /* ACE_HAS_LONGLONG_T */ +} + +void +ACE_High_Res_Timer::print_total (char *str, int count, ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_High_Res_Timer::print_total"); +#if defined (ACE_HAS_LONGLONG_T) + hrtime_t avg_nsecs = this->total_ / count; + hrtime_t total_secs = this->total_ / (1000 * 1000 * 1000); + hrtime_t extra_nsecs = this->total_ - (total_secs * (1000 * 1000 * 1000)); + char buf[100]; + + ACE_OS::sprintf (buf, "%s count = %d, total (secs %lld, usecs %lld), avg usecs = %lld\n", + str, count, total_secs, extra_nsecs / 1000, avg_nsecs / 1000); + ACE_OS::write (handle, buf, strlen (buf)); +#endif /* ACE_HAS_LONGLONG_T */ +} +#endif /* ACE_HAS_HI_RES_TIMER */ diff --git a/ace/High_Res_Timer.h b/ace/High_Res_Timer.h new file mode 100644 index 00000000000..76ac9409fff --- /dev/null +++ b/ace/High_Res_Timer.h @@ -0,0 +1,86 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// High_Res_Timer.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_HIGH_RES_TIMER_H) +#define ACE_HIGH_RES_TIMER_H + +#include "ace/ACE.h" + +#if defined (ACE_HAS_HI_RES_TIMER) + +class ACE_Export ACE_High_Res_Timer + // = TITLE + // A high resolution timer class wrapper that encapsulates + // Solaris timers. +{ +public: + // = Initialization method. + + ACE_High_Res_Timer (void); + // Initialize the timer. + + void reset (void); + // Reinitialize the timer. + + void start (void); + // Start timing. + + void stop (void); + // Stop timing. + + void start_incr (void); + // Start incremental timing. + + void stop_incr (void); + // Stop incremental timing. + + void print_total (char *message, + int iterations, + ACE_HANDLE handle); + // Print total time. + + void print_ave (char *message, + int iterations, + ACE_HANDLE handle); + // Print average time. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + hrtime_t start_; + // Starting time. + + hrtime_t end_; + // Ending time. + + hrtime_t total_; + // Total elapsed time. + + hrtime_t temp_; + // Temp time used for incremental timing. +}; + +#if defined (__ACE_INLINE__) +#include "ace/High_Res_Timer.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_HI_RES_TIMER */ +#endif /* ACE_HIGH_RES_TIMER_H */ diff --git a/ace/High_Res_Timer.i b/ace/High_Res_Timer.i new file mode 100644 index 00000000000..c33a1ded0c4 --- /dev/null +++ b/ace/High_Res_Timer.i @@ -0,0 +1,37 @@ +/* -*- C++ -*- */ +// $Id$ + +// High_Res_Timer.i + +#if defined (ACE_HAS_HI_RES_TIMER) + +ACE_INLINE void +ACE_High_Res_Timer::start (void) +{ + ACE_TRACE ("ACE_High_Res_Timer::start"); + this->start_ = ACE_OS::gethrtime (); +} + +ACE_INLINE void +ACE_High_Res_Timer::stop (void) +{ + ACE_TRACE ("ACE_High_Res_Timer::stop"); + this->end_ = ACE_OS::gethrtime (); +} + +ACE_INLINE void +ACE_High_Res_Timer::start_incr (void) +{ + ACE_TRACE ("ACE_High_Res_Timer::start_incr"); + this->temp_ = ACE_OS::gethrtime (); +} + +ACE_INLINE void +ACE_High_Res_Timer::stop_incr (void) +{ + ACE_TRACE ("ACE_High_Res_Timer::stop_incr"); +#if defined (ACE_HAS_LONGLONG_T) + this->total_ += (ACE_OS::gethrtime () - this->temp_); +#endif /* ACE_HAS_LONGLONG_T */ +} +#endif /* ACE_HAS_HI_RES_TIMER */ diff --git a/ace/INET_Addr.cpp b/ace/INET_Addr.cpp new file mode 100644 index 00000000000..1f131f1b7f2 --- /dev/null +++ b/ace/INET_Addr.cpp @@ -0,0 +1,413 @@ +// INET_Addr.cpp +// $Id$ + +/* Defines the Internet domain address family address format. */ + +#define ACE_BUILD_DLL +#include "ace/INET_Addr.h" + +#if !defined (__ACE_INLINE__) +#include "ace/INET_Addr.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_INET_Addr) + +void +ACE_INET_Addr::dump (void) const +{ + ACE_TRACE ("ACE_INET_Addr::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + char s[MAXNAMELEN]; + ACE_OS::sprintf (s, "%s:%d", this->get_host_addr (), this->get_port_number ()); + ACE_DEBUG ((LM_DEBUG, "%s", s)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// Compare two addresses for inequality. + +int +ACE_INET_Addr::operator != (const ACE_Addr &sap) const +{ + ACE_TRACE ("ACE_INET_Addr::operator !="); + return !((*this) == sap); +} + +// Compare two addresses for equality. + +int +ACE_INET_Addr::operator == (const ACE_Addr &sap) const +{ + ACE_TRACE ("ACE_INET_Addr::operator =="); + const sockaddr_in &inet_sap = ((const ACE_INET_Addr &) sap).inet_addr_; + + return this->inet_addr_.sin_port == inet_sap.sin_port + && ACE_OS::memcmp ((void *) &this->inet_addr_.sin_addr, + (void *) &inet_sap.sin_addr, + sizeof (this->inet_addr_.sin_addr)) == 0; +} + +ACE_INET_Addr::ACE_INET_Addr (void) + : ACE_Addr (AF_INET, sizeof this->inet_addr_) +{ + ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr"); + (void) ACE_OS::memset ((void *) &this->inet_addr_, 0, + sizeof this->inet_addr_); +} + +int +ACE_INET_Addr::set (const ACE_INET_Addr &sa) +{ + ACE_TRACE ("ACE_INET_Addr::set"); + this->ACE_Addr::base_set (AF_INET, sizeof this->inet_addr_); + (void) ACE_OS::memcpy ((void *) &this->inet_addr_, + (void *) &sa.inet_addr_, + sizeof this->inet_addr_); + return 0; +} + +// Transform the string into the current addressing format. + +ACE_INLINE int +ACE_INET_Addr::string_to_addr (const char s[]) +{ + ACE_TRACE ("ACE_INET_Addr::string_to_addr"); + // Need to make a duplicate since we'll be overwriting the string. + char *t = ACE_OS::strdup (s); + if (t == 0) + return -1; + + char *ip_addr = ACE_OS::strchr (t, ':'); + int result; + + if (ip_addr == 0) // Assume it's a port number. + { + u_short port = ACE_OS::atoi (t); + result = this->set (port, ACE_UINT32 (INADDR_ANY)); + } + else + { + *ip_addr = '\0'; + u_short port = ACE_OS::atoi (ip_addr + 1); // Skip over ':' + result = this->set (port, t); + } + ACE_OS::free (ACE_MALLOC_T (t)); + return result; +} + +int +ACE_INET_Addr::set (const char address[]) +{ + ACE_TRACE ("ACE_INET_Addr::set"); + return this->string_to_addr (address); +} + +ACE_INET_Addr::ACE_INET_Addr (const char address[]) +{ + ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr"); + this->set (address); +} + +// Copy constructor. + +ACE_INET_Addr::ACE_INET_Addr (const ACE_INET_Addr &sa) +{ + ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr"); + this->set (sa); +} + +// Initializes a ACE_INET_Addr from a PORT_NUMBER and an Internet +// address. + +int +ACE_INET_Addr::set (u_short port_number, + ACE_UINT32 inet_address, + int encode) +{ + ACE_TRACE ("ACE_INET_Addr::set"); + this->ACE_Addr::base_set (AF_INET, sizeof this->inet_addr_); + (void) ACE_OS::memset ((void *) &this->inet_addr_, + 0, sizeof this->inet_addr_); + this->inet_addr_.sin_family = AF_INET; +#if defined (ACE_HAS_SIN_LEN) + this->inet_addr_.sin_len = sizeof this->inet_addr_; +#endif /* ACE_HAS_SIN_LEN */ + + if (encode) + { + inet_address = htonl (inet_address); + this->inet_addr_.sin_port = htons (port_number); + } + else + this->inet_addr_.sin_port = port_number; + + (void) ACE_OS::memcpy ((void *) &this->inet_addr_.sin_addr, + (void *) &inet_address, + sizeof this->inet_addr_.sin_addr); + return 0; +} + +// Initializes a ACE_INET_Addr from a PORT_NUMBER and the remote +// HOST_NAME. + +int +ACE_INET_Addr::set (u_short port_number, + const char host_name[], + int encode) +{ + ACE_TRACE ("ACE_INET_Addr::set"); + ACE_UINT32 addr; + + this->ACE_Addr::base_set (AF_INET, sizeof this->inet_addr_); + (void) ACE_OS::memset ((void *) &this->inet_addr_, 0, sizeof + this->inet_addr_); + + // Yow, someone gave us a NULL host_name! + if (host_name == 0) + { + errno = EINVAL; + return -1; + } + else if ((addr = ACE_OS::inet_addr (host_name)) != (ACE_UINT32) -1 + // Broadcast addresses are weird... + || ACE_OS::strcmp (host_name, "255.255.255.255") == 0) + return this->set (port_number, encode ? ntohl (addr) : addr, encode); + + else + { +#if defined (VXWORKS) + int address = ::hostGetByName ((char *) host_name); + return this->set (port_number, encode ? ntohl (address) : address, encode); +#else + hostent hentry; + ACE_HOSTENT_DATA buf; + int error; + + hostent *hp = ACE_OS::gethostbyname_r (host_name, &hentry, + buf, &error); + + if (hp == 0) + { + errno = EINVAL; + return -1; + } + else + { + (void) ACE_OS::memcpy ((void *) &addr, hp->h_addr, hp->h_length); + return this->set (port_number, encode ? ntohl (addr) : addr, encode); + } +#endif /* VXWORKS */ + } +} + +// Initializes a ACE_INET_Addr from a and the remote +// . + +int +ACE_INET_Addr::set (const char port_name[], + const char host_name[]) +{ + ACE_TRACE ("ACE_INET_Addr::set"); + +#if defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + servent sentry; + ACE_SERVENT_DATA buf; + + servent *sp = ACE_OS::getservbyname_r ((char *) port_name, + "tcp", &sentry, buf); + if (sp == 0) + return -1; + else + return this->set (sp->s_port, host_name, 0); +#endif /* VXWORKS */ +} + +// Initializes a ACE_INET_Addr from a and an Internet +// address. + +int +ACE_INET_Addr::set (const char port_name[], + ACE_UINT32 inet_address) +{ + ACE_TRACE ("ACE_INET_Addr::set"); + +#if defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + servent sentry; + ACE_SERVENT_DATA buf; + + servent *sp = ACE_OS::getservbyname_r ((char *) port_name, + "tcp", &sentry, buf); + if (sp == 0) + return -1; + else + return this->set (sp->s_port, inet_address, 0); +#endif /* VXWORKS */ +} + +// Creates a ACE_INET_Addr from a PORT_NUMBER and the remote +// HOST_NAME. + + +ACE_INET_Addr::ACE_INET_Addr (u_short port_number, + const char host_name[]) +{ + ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr"); + if (this->set (port_number, host_name) == -1) + ACE_ERROR ((LM_ERROR, "ACE_INET_Addr::ACE_INET_Addr")); +} + +// Creates a ACE_INET_Addr from a sockaddr_in structure. + +int +ACE_INET_Addr::set (const sockaddr_in *addr, int len) +{ + ACE_TRACE ("ACE_INET_Addr::set"); + this->ACE_Addr::base_set (AF_INET, len); + ACE_OS::memcpy ((void *) &this->inet_addr_, + (void *) addr, len); + return 0; +} + +// Set a pointer to the address. +void +ACE_INET_Addr::set_addr (void *addr, int len) +{ + ACE_TRACE ("ACE_INET_Addr::set_addr"); + + this->ACE_Addr::base_set (AF_INET, len); + ACE_OS::memcpy ((void *) &this->inet_addr_, + (void *) addr, len); +} + +// Creates a ACE_INET_Addr from a sockaddr_in structure. + + +ACE_INET_Addr::ACE_INET_Addr (const sockaddr_in *addr, int len) +{ + ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr"); + this->set (addr, len); +} + +// Creates a ACE_INET_Addr from a PORT_NUMBER and an Internet address. + + +ACE_INET_Addr::ACE_INET_Addr (u_short port_number, + ACE_UINT32 inet_address) +{ + ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr"); + if (this->set (port_number, inet_address) == -1) + ACE_ERROR ((LM_ERROR, "ACE_INET_Addr::ACE_INET_Addr")); +} + +// Creates a ACE_INET_Addr from a PORT_NAME and the remote +// HOST_NAME. + +ACE_INET_Addr::ACE_INET_Addr (const char port_name[], + const char host_name[]) +{ + ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr"); + if (this->set (port_name, host_name) == -1) + ACE_ERROR ((LM_ERROR, "ACE_INET_Addr::ACE_INET_Addr")); +} + +// Creates a ACE_INET_Addr from a PORT_NAME and an Internet address. + + +ACE_INET_Addr::ACE_INET_Addr (const char* port_name, + ACE_UINT32 inet_address) +{ + ACE_TRACE ("ACE_INET_Addr::ACE_INET_Addr"); + if (this->set (port_name, inet_address) == -1) + ACE_ERROR ((LM_ERROR, "ACE_INET_Addr::ACE_INET_Addr")); +} + +int +ACE_INET_Addr::get_host_name (char hostname[], size_t len) const +{ + ACE_TRACE ("ACE_INET_Addr::get_host_name"); +#if defined (VXWORKS) + char name [MAXHOSTNAMELEN + 1]; + int error = ::hostGetByAddr ((int) this->inet_addr_.sin_addr.s_addr, name); + if (error == OK) + { + if (ACE_OS::strlen (name) >= len) + return -1; + else + { + ACE_OS::strcpy (hostname, name); + return 0; + } + } + else + { + errno = error; + return -1; + } +#else + int a_len = sizeof this->inet_addr_.sin_addr.s_addr; + + hostent hentry; + int error; + ACE_HOSTENT_DATA buf; + hostent *hp; + + hp = ACE_OS::gethostbyaddr_r ((char *) &this->inet_addr_.sin_addr, + a_len, this->addr_type_, + &hentry, buf, &error); + if (hp == 0) + { + errno = error; + return -1; + } + else + { + if (ACE_OS::strlen (hp->h_name) >= len) + return -1; + else + { + ACE_OS::strcpy (hostname, hp->h_name); + return 0; + } + } +#endif /* VXWORKS */ +} + +// Return the character representation of the hostname. + +const char * +ACE_INET_Addr::get_host_name (void) const +{ + ACE_TRACE ("ACE_INET_Addr::get_host_name"); + +#if defined (VXWORKS) + static char buf[MAXHOSTNAMELEN + 1]; + + ::gethostname (buf, MAXHOSTNAMELEN + 1); +#else + int a_len = sizeof this->inet_addr_.sin_addr.s_addr; + + hostent *hp = ACE_OS::gethostbyaddr ((char *) &this->inet_addr_.sin_addr, + a_len, this->addr_type_); + + if (hp == 0) + return 0; + else + return hp->h_name; +#endif /* VXWORKS */ +} + +void +ACE_INET_Addr::set_port_number (u_short port_number, + int encode) +{ + ACE_TRACE ("ACE_INET_Addr::set_port_number"); + + if (encode) + port_number = htons (port_number); + + this->inet_addr_.sin_port = port_number; +} diff --git a/ace/INET_Addr.h b/ace/INET_Addr.h new file mode 100644 index 00000000000..8fa8b80c7d4 --- /dev/null +++ b/ace/INET_Addr.h @@ -0,0 +1,169 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// INET_Addr.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_INET_ADDR_H) +#define ACE_INET_ADDR_H + +#include "ace/ACE.h" +#include "ace/Addr.h" + +class ACE_Export ACE_INET_Addr : public ACE_Addr + // = TITLE + // Defines the Internet domain address family address format. +{ +public: + // = Initialization methods. + ACE_INET_Addr (void); + // Default constructor. + + ACE_INET_Addr (const ACE_INET_Addr &); + // Copy constructor. + + ACE_INET_Addr (const sockaddr_in *, int len); + // Creates an from a sockaddr_in structure. + + ACE_INET_Addr (u_short port_number, const char host_name[]); + // Creates an from a and the remote + // . + + ACE_INET_Addr (const char address[]); + // Initializes an from the
, which can be + // "ip-number:port-number" (e.g., "tango.cs.wustl.edu:1234" or + // "128.252.166.57:1234"). If there is no ':' in the
it + // is assumed to be a port number, with the IP address being + // INADDR_ANY. + + ACE_INET_Addr (u_short port_number, ACE_UINT32 ip_addr = INADDR_ANY); + // Creates an from a and an Internet + // . This method assumes that and + // are in host byte order. + + ACE_INET_Addr (const char port_name[], const char host_name[]); + // Uses to create an from a + // and the remote . + + ACE_INET_Addr (const char port_name[], ACE_UINT32 ip_addr); + // Uses to create an from a + // and an Internet . This method assumes that + // is in host byte order. + + // = Direct initialization methods (useful after the object has been + // constructed). + int set (const ACE_INET_Addr &); + // Initializes from another . + + int set (u_short port_number, const char host_name[], + int encode = 1); + // Initializes an from a and the + // remote . If is enabled then is + // converted into network byte order, otherwise it is assumed to be + // in network byte order already and are passed straight through. + + int set (u_short port_number, + ACE_UINT32 ip_addr = INADDR_ANY, + int encode = 1); + // Initializes an from a and an + // Internet . If is enabled then + // and are converted into network byte order, otherwise + // they are assumed to be in network byte order already and are + // passed straight through. + + int set (const char port_name[], const char host_name[]); + // Uses to initialize an from a + // and the remote . + + int set (const char port_name[], ACE_UINT32 ip_addr); + // Uses to initialize an from a + // and an Internet address. This assumes that + // is already in network byte order. + + int set (const char addr[]); + // Initializes an from the , which can be + // "ip-number:port-number" (e.g., "tango.cs.wustl.edu:1234" or + // "128.252.166.57:1234"). If there is no ':' in the
it + // is assumed to be a port number, with the IP address being + // INADDR_ANY. + + int set (const sockaddr_in *, int len); + // Creates an from a sockaddr_in structure. + + virtual void *get_addr (void) const; + // Return a pointer to the underlying network address. + + virtual void set_addr (void *, int len); + // Set a pointer to the address. + + virtual int addr_to_string (char addr[], size_t) const; + // Transform the current address into string format, + // which is in the form "ip-number:port-number" (e.g., + // "tango.cs.wustl.edu:1234" or "128.252.166.57:1234"). + + virtual int string_to_addr (const char address[]); + // Initializes an from the
, which can be + // "ip-number:port-number" (e.g., "tango.cs.wustl.edu:1234" or + // "128.252.166.57:1234"). If there is no ':' in the
it + // is assumed to be a port number, with the IP address being + // INADDR_ANY. + + void set_port_number (u_short, int encode = 1); + // Sets the port number without affecting the host name. If + // is enabled then is converted into network + // byte order, otherwise it is assumed to be in network byte order + // already and are passed straight through. + + u_short get_port_number (void) const; + // Return the port number, converting it into host byte order. + + int get_host_name (char hostname[], size_t hostnamelen) const; + // Return the character representation of the name of the host, + // storing it in the (which is assumed to be + // bytes long). This version is reentrant. + + const char *get_host_name (void) const; + // Return the character representation of the hostname (this version + // is non-reentrant since it returns a pointer to a static data + // area). + + const char *get_host_addr (void) const; + // Return the dotted Internet address. + + ACE_UINT32 get_ip_address (void) const; + // Return the 4-byte IP address, converting it into host byte + // order. + + virtual int operator == (const ACE_Addr &SAP) const; + // Compare two addresses for equality. The addresses are considered + // equal if they contain the same IP address and port number. + + virtual int operator != (const ACE_Addr &SAP) const; + // Compare two addresses for inequality. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + sockaddr_in inet_addr_; + // Underlying representation. +}; + +#if defined (__ACE_INLINE__) +#include "ace/INET_Addr.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_INET_ADDR_H */ diff --git a/ace/INET_Addr.i b/ace/INET_Addr.i new file mode 100644 index 00000000000..1629dc0ecb0 --- /dev/null +++ b/ace/INET_Addr.i @@ -0,0 +1,56 @@ +/* -*- C++ -*- */ +// $Id$ + +// INET_Addr.i + +#include "ace/Log_Msg.h" + +// Return the port number, converting it into host byte order... + +ACE_INLINE u_short +ACE_INET_Addr::get_port_number (void) const +{ + ACE_TRACE ("ACE_INET_Addr::get_port_number"); + return ntohs (this->inet_addr_.sin_port); +} + +// Return the address. + +ACE_INLINE void * +ACE_INET_Addr::get_addr (void) const +{ + ACE_TRACE ("ACE_INET_Addr::get_addr"); + return (void *) &this->inet_addr_; +} + +// Return the dotted Internet address. + +ACE_INLINE const char * +ACE_INET_Addr::get_host_addr (void) const +{ + ACE_TRACE ("ACE_INET_Addr::get_host_addr"); + return ACE_OS::inet_ntoa (this->inet_addr_.sin_addr); +} + +// Transform the current address into string format. + +ACE_INLINE int +ACE_INET_Addr::addr_to_string (char s[], size_t) const +{ + ACE_TRACE ("ACE_INET_Addr::addr_to_string"); + // This should check to make sure len is long enough... + ACE_OS::sprintf (s, "%s:%d", + this->get_host_addr (), + this->get_port_number ()); + return 0; +} + +// Return the 4-byte IP address, converting it into host byte order. + +ACE_INLINE ACE_UINT32 +ACE_INET_Addr::get_ip_address (void) const +{ + ACE_TRACE ("ACE_INET_Addr::get_ip_address"); + return ntohl (ACE_UINT32 (this->inet_addr_.sin_addr.s_addr)); +} + diff --git a/ace/IO_Cntl_Msg.cpp b/ace/IO_Cntl_Msg.cpp new file mode 100644 index 00000000000..2b0d38b8355 --- /dev/null +++ b/ace/IO_Cntl_Msg.cpp @@ -0,0 +1,34 @@ +// IO_Cntl_Msg.cpp +// $Id$ + +#if 0 +/* Forward decl */ +template class ACE_Module; + + +class ACE_Module_Link +{ + // = TITLE + // Data structure used to link two modules together + // + // = DESCRIPTION + // +public: + ACE_Module_Link (ACE_Module *m1, ACE_Module *m2): mod_upper_ (m1), mod_lower_ (m2), count_ (0) {} + + ACE_Module *upper (void) { return this->mod_upper_; } + void upper (ACE_Module *u) { this->mod_upper_ = u; } + + ACE_Module *lower (void) { return this->mod_lower_; } + void lower (ACE_Module *l) { this->mod_lower_ = l; } + + int count (void) { return this->count_; } + void count (int c) { this->count_ = c; } + +private: + ACE_Module *mod_upper_; + ACE_Module *mod_lower_; + int count_; +}; +#endif + diff --git a/ace/IO_Cntl_Msg.h b/ace/IO_Cntl_Msg.h new file mode 100644 index 00000000000..7a0fb272cc7 --- /dev/null +++ b/ace/IO_Cntl_Msg.h @@ -0,0 +1,85 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// IO_Cntl_Msg.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_IO_CNTL_MSG_H) +#define ACE_IO_CNTL_MSG_H + +class ACE_Export ACE_IO_Cntl_Msg + // = TITLE + // Data format for IOCTL messages +{ +public: + enum ACE_IO_Cntl_Cmds + { + SET_LWM = 1, // Set the low water mark. + GET_LWM = 2, // Get the low water mark. + SET_HWM = 3, // Set the high water mark. + GET_HWM = 4, // Get the high water mark. + MOD_LINK = 5, // Link modules + MOD_UNLINK = 6 // Unlink modules + }; + + // = Initialization method. + ACE_IO_Cntl_Msg (ACE_IO_Cntl_Cmds c) { this->cmd_ = c; } + // Initialize the control message. + + // = Get/set methods + + ACE_IO_Cntl_Cmds cmd (void) { return this->cmd_; } + // Get command. + + void cmd (ACE_IO_Cntl_Cmds c) { this->cmd_ = c; } + // Set command. + + size_t count (void) { return this->count_; } + // Get count. + + void count (size_t c) { this->count_ = c; } + // Set count. + + int error (void) { return this->error_; } + // Get error. + + void error (int e) { this->error_ = e; } + // Set error. + + int rval (void) { return this->rval_; } + // Get return value. + + void rval (int r) { this->rval_ = r; } + // Set return value. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_IO_Cntl_Cmds cmd_; + // Command. + + size_t count_; + // Count. + + int error_; + // Error. + + int rval_; + // Return value +}; + +#endif /* ACE_IO_CNTL_MSG_H */ diff --git a/ace/IO_Cntl_Msg.i b/ace/IO_Cntl_Msg.i new file mode 100644 index 00000000000..8ab50e712bb --- /dev/null +++ b/ace/IO_Cntl_Msg.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// $Id$ + +// IO_Cntl_Msg.i diff --git a/ace/IO_SAP.cpp b/ace/IO_SAP.cpp new file mode 100644 index 00000000000..d6fbaca169d --- /dev/null +++ b/ace/IO_SAP.cpp @@ -0,0 +1,124 @@ +// IO_SAP.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/IO_SAP.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_IO_SAP) + +// This is the do-nothing constructor. It does not perform a +// ACE_OS::open system call. + +ACE_IO_SAP::ACE_IO_SAP (void) + : handle_ (ACE_INVALID_HANDLE) +{ + ACE_TRACE ("ACE_IO_SAP::ACE_IO_SAP"); +} + +void +ACE_IO_SAP::dump (void) const +{ + ACE_TRACE ("ACE_IO_SAP::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "handle_ = %d", this->handle_)); + ACE_DEBUG ((LM_DEBUG, "\npid_ = %d", this->pid_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// Cache for the process ID. +pid_t ACE_IO_SAP::pid_ = 0; + +// Make the HANDLE_ available for asynchronous I/O (SIGIO), urgent +// data (SIGURG), or non-blocking I/O (ACE_NONBLOCK). + +int +ACE_IO_SAP::enable (int signum) const +{ + ACE_TRACE ("ACE_IO_SAP::enable"); + /* First-time in initialization. */ + if (ACE_IO_SAP::pid_ == 0) + ACE_IO_SAP::pid_ = ACE_OS::getpid (); + +#if !defined(ACE_WIN32) + + switch (signum) + { +#if defined (SIGURG) + case SIGURG: +#if defined (F_SETOWN) + if (ACE_OS::fcntl (this->handle_, F_SETOWN, ACE_IO_SAP::pid_) < 0) + return ACE_IO_SAP::INVALID_HANDLE; + break; +#else + return ACE_IO_SAP::INVALID_HANDLE; +#endif /* F_SETOWN */ +#endif /* SIGURG */ + case SIGIO: +#if defined (F_SETOWN) && defined (FASYNC) + if (ACE_OS::fcntl (this->handle_, F_SETOWN, ACE_IO_SAP::pid_) == ACE_IO_SAP::INVALID_HANDLE) + return ACE_IO_SAP::INVALID_HANDLE; + if (ACE::set_flags (this->handle_, FASYNC) == ACE_IO_SAP::INVALID_HANDLE) + return ACE_IO_SAP::INVALID_HANDLE; + break; +#else + return ACE_IO_SAP::INVALID_HANDLE; +#endif /* F_SETOWN && FASYNC */ + case ACE_NONBLOCK: + if (ACE::set_flags (this->handle_, ACE_NONBLOCK) == ACE_IO_SAP::INVALID_HANDLE) + return ACE_IO_SAP::INVALID_HANDLE; + break; + default: + return ACE_IO_SAP::INVALID_HANDLE; + } + +#endif /* !ACE_WIN32 */ + + return 0; +} + +// Restore the IO_SAP by turning off synchronous I/O or urgent delivery. + +int +ACE_IO_SAP::disable (int signum) const +{ + ACE_TRACE ("ACE_IO_SAP::disable"); + +#if !defined(ACE_WIN32) + + switch (signum) + { +#if defined (SIGURG) + case SIGURG: +#if defined (F_SETOWN) + if (ACE_OS::fcntl (this->handle_, F_SETOWN, 0) == ACE_IO_SAP::INVALID_HANDLE) + return ACE_IO_SAP::INVALID_HANDLE; +#else + return ACE_IO_SAP::INVALID_HANDLE; +#endif /* F_SETOWN */ + break; +#endif /* SIGURG */ + case SIGIO: +#if defined (F_SETOWN) && defined (FASYNC) + if (ACE_OS::fcntl (this->handle_, F_SETOWN, 0) == ACE_IO_SAP::INVALID_HANDLE) + return ACE_IO_SAP::INVALID_HANDLE; + if (ACE::clr_flags (this->handle_, FASYNC) == ACE_IO_SAP::INVALID_HANDLE) + return ACE_IO_SAP::INVALID_HANDLE; +#else + return ACE_IO_SAP::INVALID_HANDLE; +#endif /* F_SETOWN && FASYNC */ + break; + case ACE_NONBLOCK: + if (ACE::clr_flags (this->handle_, ACE_NONBLOCK) == ACE_IO_SAP::INVALID_HANDLE) + return ACE_IO_SAP::INVALID_HANDLE; + break; + default: + return ACE_IO_SAP::INVALID_HANDLE; + } + +#endif /* !ACE_WIN32 */ + + return 0; +} + diff --git a/ace/IO_SAP.h b/ace/IO_SAP.h new file mode 100644 index 00000000000..a57d501c03d --- /dev/null +++ b/ace/IO_SAP.h @@ -0,0 +1,70 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// IO_SAP.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_IO_SAP_H) +#define ACE_IO_SAP_H + +#include "ace/ACE.h" + +class ACE_Export ACE_IO_SAP + // = TITLE + // Defines the member functions for the base class of the ACE_IO_SAP + // abstraction. +{ +public: + enum + { + INVALID_HANDLE = -1 // Be consistent with Winsock + }; + + int control (int cmd, void *) const; + // Interface for ioctl. + + // = Methods for manipulating common I/O descriptor options related to + // files. + int enable (int signum) const; + // Enable signal . + int disable (int signum) const; + // Disable signal . + + ACE_HANDLE get_handle (void) const; + // Get the underlying descriptor. + + void set_handle (ACE_HANDLE handle); + // Set the underlying descriptor. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + ACE_IO_SAP (void); + // Ensure that ACE_IO_SAP is an abstract base class. + +private: + ACE_HANDLE handle_; + // Underlying I/O descriptor. + + static pid_t pid_; + // Cache the process ID. +}; + +#include "ace/IO_SAP.i" + +#endif /* ACE_IO_SAP_H */ diff --git a/ace/IO_SAP.i b/ace/IO_SAP.i new file mode 100644 index 00000000000..f13fe9db8d7 --- /dev/null +++ b/ace/IO_SAP.i @@ -0,0 +1,33 @@ +/* -*- C++ -*- */ +// $Id$ + +// IO_SAP.i + +// Used to return the underlying handle_. + +inline ACE_HANDLE +ACE_IO_SAP::get_handle (void) const +{ + ACE_TRACE ("ACE_IO_SAP::get_handle"); + return this->handle_; +} + +// Used to set the underlying handle_. + +inline void +ACE_IO_SAP::set_handle (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_IO_SAP::set_handle"); + this->handle_ = handle; +} + +// Provides access to the ACE_OS::ioctl system call. + +inline int +ACE_IO_SAP::control (int cmd, void *arg) const +{ + ACE_TRACE ("ACE_IO_SAP::control"); + return ACE_OS::ioctl (this->handle_, cmd, arg); +} + + diff --git a/ace/IPC_SAP.cpp b/ace/IPC_SAP.cpp new file mode 100644 index 00000000000..74d914d1c4f --- /dev/null +++ b/ace/IPC_SAP.cpp @@ -0,0 +1,148 @@ +// IPC_SAP.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/IPC_SAP.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_IPC_SAP) + +void +ACE_IPC_SAP::dump (void) const +{ + ACE_TRACE ("ACE_IPC_SAP::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "handle_ = %d", this->handle_)); + ACE_DEBUG ((LM_DEBUG, "\npid_ = %d", this->pid_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// Cache for the process ID. +pid_t ACE_IPC_SAP::pid_ = 0; + +// This is the do-nothing constructor. It does not perform a +// ACE_OS::socket system call. + +ACE_IPC_SAP::ACE_IPC_SAP (void) + : handle_ (ACE_INVALID_HANDLE) +{ +// ACE_TRACE ("ACE_IPC_SAP::ACE_IPC_SAP"); +} + +// Make the HANDLE_ available for asynchronous I/O (SIGIO), urgent +// data (SIGURG), or non-blocking I/O (ACE_NONBLOCK). + +int +ACE_IPC_SAP::enable (int signum) const +{ + ACE_TRACE ("ACE_IPC_SAP::enable"); + + // First-time in initialization. + if (ACE_IPC_SAP::pid_ == 0) + ACE_IPC_SAP::pid_ = ACE_OS::getpid (); + +#if defined(ACE_WIN32) + switch (signum) + { + case ACE_NONBLOCK: + // nonblocking argument (1) + // blocking: (0) + { + u_long nonblock = 1; + return ACE_OS::ioctl (this->handle_, FIONBIO, &nonblock); + } + default: + errno = ENOTSUP; + return -1; + } +#else + switch (signum) + { +#if defined (SIGURG) + case SIGURG: +#if defined (F_SETOWN) + if (ACE_OS::fcntl (this->handle_, F_SETOWN, ACE_IPC_SAP::pid_) < 0) + return -1; +#else + return -1; +#endif /* F_SETOWN */ + break; +#endif /* SIGURG */ + case SIGIO: +#if defined (F_SETOWN) && defined (FASYNC) + if (ACE_OS::fcntl (this->handle_, F_SETOWN, ACE_IPC_SAP::pid_) == -1) + return -1; + if (ACE::set_flags (this->handle_, FASYNC) == -1) + return -1; +#else + return -1; +#endif /* F_SETOWN && FASYNC */ + break; + case ACE_NONBLOCK: + if (ACE::set_flags (this->handle_, ACE_NONBLOCK) == ACE_INVALID_HANDLE) + return -1; + break; + default: + return -1; + } +#endif /* !ACE_WIN32 */ + return 0; +} + +// Restore the IPC_SAPet by turning off synchronous I/O or urgent +// delivery. + +int +ACE_IPC_SAP::disable (int signum) const +{ + ACE_TRACE ("ACE_IPC_SAP::disable"); + +#if defined(ACE_WIN32) + switch (signum) + { + case ACE_NONBLOCK: + // nonblocking argument (1) + // blocking: (0) + { + u_long nonblock = 0; + return ACE_OS::ioctl (this->handle_, FIONBIO, &nonblock); + } + default: + errno = ENOTSUP; + return -1; + } +#else + switch (signum) + { +#if defined (SIGURG) + case SIGURG: +#if defined (F_SETOWN) + if (ACE_OS::fcntl (this->handle_, F_SETOWN, 0) == -1) + return -1; + break; +#else + return -1; +#endif /* F_SETOWN */ +#endif /* SIGURG */ + case SIGIO: +#if defined (F_SETOWN) && defined (FASYNC) + if (ACE_OS::fcntl (this->handle_, F_SETOWN, 0) == -1) + return -1; + if (ACE::clr_flags (this->handle_, FASYNC) == -1) + return -1; + break; +#else + return -1; +#endif /* F_SETOWN && FASYNC */ + case ACE_NONBLOCK: + if (ACE::clr_flags (this->handle_, ACE_NONBLOCK) == -1) + return -1; + break; + default: + return -1; + } +#endif /* !ACE_WIN32 */ + return 0; +} + diff --git a/ace/IPC_SAP.h b/ace/IPC_SAP.h new file mode 100644 index 00000000000..ee7a4ede41c --- /dev/null +++ b/ace/IPC_SAP.h @@ -0,0 +1,67 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// IPC_SAP.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_IPC_SAP_H) +#define ACE_IPC_SAP_H + +#include "ace/ACE.h" + +class ACE_Export ACE_IPC_SAP + // = TITLE + // Defines the member functions for the base class of the + // ACE_IPC_SAP abstraction. +{ +public: + int control (int cmd, void *) const; + // Interface for ioctl. + + // = Methods for manipulating common I/O descriptor options related + // to sockets. + int enable (int signum) const; + // Enable signal . + + int disable (int signum) const; + // Disable signal . + + ACE_HANDLE get_handle (void) const; + // Get the underlying descriptor. + + void set_handle (ACE_HANDLE handle); + // Set the underlying descriptor. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + // = Ensure that ACE_IPC_SAP is an abstract base class. + ACE_IPC_SAP (void); + // Default constructor. + +private: + ACE_HANDLE handle_; + // Underlying I/O descriptor. + + static pid_t pid_; + // Cache the process ID. +}; + +#include "ace/IPC_SAP.i" + +#endif /* ACE_IPC_SAP_H */ diff --git a/ace/IPC_SAP.i b/ace/IPC_SAP.i new file mode 100644 index 00000000000..930be9c991e --- /dev/null +++ b/ace/IPC_SAP.i @@ -0,0 +1,31 @@ +/* -*- C++ -*- */ +// $Id$ + +// IPC_SAP.i + +// Used to return the underlying handle_. + +inline ACE_HANDLE +ACE_IPC_SAP::get_handle (void) const +{ + ACE_TRACE ("ACE_IPC_SAP::get_handle"); + return this->handle_; +} + +// Used to set the underlying handle_. + +inline void +ACE_IPC_SAP::set_handle (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_IPC_SAP::set_handle"); + this->handle_ = handle; +} + +// Provides access to the ACE_OS::ioctl system call. + +inline int +ACE_IPC_SAP::control (int cmd, void *arg) const +{ + ACE_TRACE ("ACE_IPC_SAP::control"); + return ACE_OS::ioctl (this->handle_, cmd, arg); +} diff --git a/ace/LSOCK.cpp b/ace/LSOCK.cpp new file mode 100644 index 00000000000..8b60716ef46 --- /dev/null +++ b/ace/LSOCK.cpp @@ -0,0 +1,121 @@ +// LSOCK.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/LSOCK.h" + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +ACE_ALLOC_HOOK_DEFINE(ACE_LSOCK) + +void +ACE_LSOCK::dump (void) const +{ + ACE_TRACE ("ACE_LSOCK::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "aux_handle_ = %d", this->aux_handle_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +#if defined (ACE_HAS_MSG) +// This routine sends an open file descriptor to handle_>. + +int +ACE_LSOCK::send_handle (const ACE_HANDLE fd) const +{ + ACE_TRACE ("ACE_LSOCK::send_handle"); + unsigned char a[2]; + iovec iov; + msghdr send_msg; + + a[0] = 0xab; + a[1] = 0xcd; + iov.iov_base = (char *) a; + iov.iov_len = sizeof a; + send_msg.msg_iov = &iov; + send_msg.msg_iovlen = 1; + send_msg.msg_name = (char *) 0; + send_msg.msg_namelen = 0; + send_msg.msg_accrights = (char *) &fd; + send_msg.msg_accrightslen = sizeof fd; + + return ACE_OS::sendmsg (this->get_handle (), &send_msg, 0); +} + +// This file receives an open file descriptor from THIS->SOK_FD. +// Note, this routine returns -1 if problems occur, 0 if we recv a +// message that does not have file descriptor in it, and 1 otherwise. + +int +ACE_LSOCK::recv_handle (ACE_HANDLE &fd, char *pbuf, int *len) const +{ + ACE_TRACE ("ACE_LSOCK::recv_handle"); + unsigned char a[2]; + iovec iov; + msghdr recv_msg; + + if (pbuf != 0 && len != 0) + { + iov.iov_base = pbuf; + iov.iov_len = *len; + } + else + { + iov.iov_base = (char *) a; + iov.iov_len = sizeof a; + } + + recv_msg.msg_iov = &iov; + recv_msg.msg_iovlen = 1; + recv_msg.msg_name = (char *) 0; + recv_msg.msg_namelen = 0; + recv_msg.msg_accrights = (char *) &fd; + recv_msg.msg_accrightslen = sizeof fd; + +#if defined (ACE_HAS_STREAMS) + ssize_t nbytes = ACE_OS::recvmsg (this->get_handle (), &recv_msg, 0); + + if (nbytes != ACE_INVALID_HANDLE) + { + if (len != 0) + *len = nbytes; + + if (nbytes == sizeof a + && ((unsigned char *) iov.iov_base)[0] == 0xab + && ((unsigned char *) iov.iov_base)[1] == 0xcd) + return 1; + else + return 0; + } +#else + ssize_t nbytes = ACE_OS::recvmsg (this->get_handle (), &recv_msg, MSG_PEEK); + + if (nbytes != ACE_INVALID_HANDLE) + { + if (nbytes == sizeof a + && ((unsigned char *) iov.iov_base)[0] == 0xab + && ((unsigned char *) iov.iov_base)[1] == 0xcd) + { + recv_msg.msg_accrights = (char *) &fd; + recv_msg.msg_accrightslen = sizeof fd; + + if (ACE_OS::recvmsg (this->get_handle (), &recv_msg, 0) == ACE_INVALID_HANDLE) + return ACE_INVALID_HANDLE; + else + return 1; + } + else + { + if (len != 0) + *len = nbytes; + return 0; + } + } +#endif /* ACE_HAS_STREAMS */ + else + return ACE_INVALID_HANDLE; +} +#endif /* ACE_HAS_MSG */ +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ diff --git a/ace/LSOCK.h b/ace/LSOCK.h new file mode 100644 index 00000000000..6c7c922a830 --- /dev/null +++ b/ace/LSOCK.h @@ -0,0 +1,70 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// LSOCK.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_LOCAL_SOCK_H) +#define ACE_LOCAL_SOCK_H + +#include "ace/SOCK.h" + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +class ACE_Export ACE_LSOCK + // = TITLE + // Create a Local ACE_SOCK, which is used for passing file + // descriptors. +{ +public: +#if defined (ACE_HAS_MSG) + int send_handle (const ACE_HANDLE handle) const; + // Send an open FD to another process. + + int recv_handle (ACE_HANDLE &handles, + char *pbuf = 0, + int *len = 0) const; + // Recv an open FD from another process. +#endif /* ACE_HAS_MSG */ + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + // = Ensure that ACE_LSOCK is an abstract base class + + ACE_LSOCK (void); + // Default constructor. + + ACE_LSOCK (ACE_HANDLE handle); + // Initialize based on + + ACE_HANDLE get_handle (void) const; + // Get handle. + + void set_handle (ACE_HANDLE handle); + // Set handle. + +private: + ACE_HANDLE aux_handle_; + // An auxiliary handle used to avoid virtual base classes... +}; + +#include "ace/LSOCK.i" + +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ +#endif /* ACE_LOCAL_SOCK_H */ diff --git a/ace/LSOCK.i b/ace/LSOCK.i new file mode 100644 index 00000000000..cddc2db5812 --- /dev/null +++ b/ace/LSOCK.i @@ -0,0 +1,39 @@ +/* -*- C++ -*- */ +// $Id$ + +// LSOCK.i + +// Simple-minded constructor. + +inline +ACE_LSOCK::ACE_LSOCK (void) +{ + ACE_TRACE ("ACE_LSOCK::ACE_LSOCK"); +} + +// Sets the underlying file descriptor. + +inline void +ACE_LSOCK::set_handle (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_LSOCK::set_handle"); + this->aux_handle_ = handle; +} + +// Gets the underlying file descriptor. + +inline ACE_HANDLE +ACE_LSOCK::get_handle (void) const +{ + ACE_TRACE ("ACE_LSOCK::get_handle"); + return this->aux_handle_; +} + +// Sets the underlying file descriptor. + +inline +ACE_LSOCK::ACE_LSOCK (ACE_HANDLE handle) + : aux_handle_ (handle) +{ + ACE_TRACE ("ACE_LSOCK::ACE_LSOCK"); +} diff --git a/ace/LSOCK_Acceptor.cpp b/ace/LSOCK_Acceptor.cpp new file mode 100644 index 00000000000..db8c374d519 --- /dev/null +++ b/ace/LSOCK_Acceptor.cpp @@ -0,0 +1,98 @@ +// LSOCK_Acceptor.cpp +// $Id$ + + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/LSOCK_Acceptor.h" + +#if !defined (__ACE_INLINE__) +#include "ace/LSOCK_Acceptor.i" +#endif /* __ACE_INLINE__ */ + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +ACE_ALLOC_HOOK_DEFINE(ACE_LSOCK_Acceptor) + +// Return the local endpoint address. + +int +ACE_LSOCK_Acceptor::get_local_addr (ACE_Addr &a) const +{ + ACE_TRACE ("ACE_LSOCK_Acceptor::get_local_addr"); + a = this->local_addr_; + return 0; +} + +void +ACE_LSOCK_Acceptor::dump (void) const +{ + ACE_TRACE ("ACE_LSOCK_Acceptor::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->local_addr_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// Do nothing routine for constructor. + +ACE_LSOCK_Acceptor::ACE_LSOCK_Acceptor (void) +{ + ACE_TRACE ("ACE_LSOCK_Acceptor::ACE_LSOCK_Acceptor"); +} + +int +ACE_LSOCK_Acceptor::open (const ACE_Addr &remote_sap, + int reuse_addr, + int protocol_family, + int backlog, + int protocol) +{ + ACE_TRACE ("ACE_LSOCK_Acceptor::open"); + this->local_addr_ = *((ACE_UNIX_Addr *) &remote_sap); // This is a gross hack... + return ACE_SOCK_Acceptor::open (remote_sap, reuse_addr, + protocol_family, backlog, protocol); +} + +// General purpose routine for performing server ACE_SOCK creation. + +ACE_LSOCK_Acceptor::ACE_LSOCK_Acceptor (const ACE_Addr &remote_sap, + int reuse_addr, + int protocol_family, + int backlog, + int protocol) +{ + ACE_TRACE ("ACE_LSOCK_Acceptor::ACE_LSOCK_Acceptor"); + if (this->open (remote_sap, reuse_addr, + protocol_family, backlog, protocol) == -1) + ACE_ERROR ((LM_ERROR, "ACE_LSOCK_Acceptor::ACE_LSOCK_Acceptor")); +} + +// General purpose routine for accepting new connections. + +int +ACE_LSOCK_Acceptor::accept (ACE_LSOCK_Stream &new_local_ipc_sap, + ACE_Addr *remote_addr, + ACE_Time_Value *timeout, + int restart) const +{ + ACE_TRACE ("ACE_LSOCK_Acceptor::accept"); + ACE_HANDLE new_handle = + ACE_SOCK_Acceptor::shared_accept (remote_addr, timeout, restart); + new_local_ipc_sap.set_handle (new_handle); + return new_handle == ACE_INVALID_HANDLE ? -1 : 0; +} + +// Close down the UNIX domain stream and remove the rendezvous point +// from the file system. + +int +ACE_LSOCK_Acceptor::remove (void) +{ + ACE_TRACE ("ACE_LSOCK_Acceptor::remove"); + int result = this->close (); + return ACE_OS::unlink (this->local_addr_.get_path_name ()) == -1 + || result == -1 ? -1 : 0; +} + +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ diff --git a/ace/LSOCK_Acceptor.h b/ace/LSOCK_Acceptor.h new file mode 100644 index 00000000000..2c262e2b66a --- /dev/null +++ b/ace/LSOCK_Acceptor.h @@ -0,0 +1,84 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// LSOCK_Aceeptor.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_LOCAL_SOCK_ACCEPTOR_H) +#define ACE_LOCAL_SOCK_ACCEPTOR_H + +#include "ace/SOCK_Acceptor.h" +#include "ace/UNIX_Addr.h" +#include "ace/LSOCK_Stream.h" + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +class ACE_Export ACE_LSOCK_Acceptor : public ACE_SOCK_Acceptor + // = TITLE + // Defines the format and interface for the acceptor side of the + // local ACE_SOCK ACE_Stream. +{ +public: + // = Initialization methods. + ACE_LSOCK_Acceptor (void); + // Default constructor. + + ACE_LSOCK_Acceptor (const ACE_Addr &local_sap, + int reuse_addr = 0, + int protocol_family = PF_UNIX, + int backlog = 5, + int protocol = 0); + // Initiate a passive mode socket. + + int open (const ACE_Addr &local_sap, + int reuse_addr = 0, + int protocol_family = PF_UNIX, + int backlog = 5, + int protocol = 0); + // Initiate a passive mode socket. + + int accept (ACE_LSOCK_Stream &new_ipc_sap, + ACE_Addr * = 0, + ACE_Time_Value *timeout = 0, + int restart = 1) const; + // Accept a new data transfer connection. + + int remove (void); + // Close down the ACE_LSOCK and remove the rendezvous point from the + // file system. + + int get_local_addr (ACE_Addr &) const; + // Return the local endpoint address. + + // = Meta-type info + typedef ACE_UNIX_Addr PEER_ADDR; + typedef ACE_LSOCK_Stream PEER_STREAM; + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_UNIX_Addr local_addr_; + // Address of our rendezvous point. +}; + +#if defined (__ACE_INLINE__) +#include "ace/LSOCK_Acceptor.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ +#endif /* ACE_LOCAL_SOCK_ACCEPTOR_H */ diff --git a/ace/LSOCK_Acceptor.i b/ace/LSOCK_Acceptor.i new file mode 100644 index 00000000000..e873fd02822 --- /dev/null +++ b/ace/LSOCK_Acceptor.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// $Id$ + +// LSOCK_Acceptor.i diff --git a/ace/LSOCK_CODgram.cpp b/ace/LSOCK_CODgram.cpp new file mode 100644 index 00000000000..f2c357ebd0d --- /dev/null +++ b/ace/LSOCK_CODgram.cpp @@ -0,0 +1,54 @@ +// LSOCK_CODgram.cpp +// $Id$ + +/* Contains the definitions for the Local ACE_SOCK connection-oriented + datagram abstraction. */ + +#define ACE_BUILD_DLL +#include "ace/LSOCK_CODgram.h" +#include "ace/Log_Msg.h" + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +ACE_ALLOC_HOOK_DEFINE(ACE_LSOCK_CODgram) + +void +ACE_LSOCK_CODgram::dump (void) const +{ + ACE_TRACE ("ACE_LSOCK_CODgram::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_SOCK_CODgram::dump (); + ACE_LSOCK::dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +/* Here's the general-purpose open routine. */ + +int +ACE_LSOCK_CODgram::open (const ACE_Addr &remote, + const ACE_Addr &local, + int protocol_family, + int protocol) +{ + ACE_TRACE ("ACE_LSOCK_CODgram::open"); + if (ACE_SOCK_CODgram::open (remote, local, protocol_family, + protocol) == -1) + return -1; + ACE_LSOCK::set_handle (this->get_handle ()); + return 0; +} + +/* Create a local ACE_SOCK datagram. */ + +ACE_LSOCK_CODgram::ACE_LSOCK_CODgram (const ACE_Addr &remote, + const ACE_Addr &local, + int protocol_family, + int protocol) +{ + ACE_TRACE ("ACE_LSOCK_CODgram::ACE_LSOCK_CODgram"); + if (this->open (remote, local, protocol_family, + protocol) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_LSOCK_CODgram")); +} +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ diff --git a/ace/LSOCK_CODgram.h b/ace/LSOCK_CODgram.h new file mode 100644 index 00000000000..360148cbbf7 --- /dev/null +++ b/ace/LSOCK_CODgram.h @@ -0,0 +1,65 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// LSOCK_CODgram.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_LOCAL_SOCK_CODGRAM_H) +#define ACE_LOCAL_SOCK_CODGRAM_H + +#include "ace/LSOCK.h" +#include "ace/SOCK_CODgram.h" +#include "ace/Addr.h" + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +class ACE_Export ACE_LSOCK_CODgram : public ACE_SOCK_CODgram, public ACE_LSOCK + // = TITLE + // Defines the member functions for the ACE_LSOCK + // connected datagram abstraction. +{ +public: + // = Initialization methods. + ACE_LSOCK_CODgram (void); + // Default constructor. + + ACE_LSOCK_CODgram (const ACE_Addr &remote_sap, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int protocol_family = PF_UNIX, + int protocol = 0); + // Initiate a connected-datagram. + + int open (const ACE_Addr &remote_sap, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int protocol_family = PF_UNIX, + int protocol = 0); + // Initiate a connected-datagram. + + ACE_HANDLE get_handle (void) const; + // Get underlying handle. + + void set_handle (ACE_HANDLE); + // Set underlying handle. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#include "ace/LSOCK_CODgram.i" + +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ +#endif /* ACE_LOCAL_SOCK_CODGRAM_H */ diff --git a/ace/LSOCK_CODgram.i b/ace/LSOCK_CODgram.i new file mode 100644 index 00000000000..40b2330cdcd --- /dev/null +++ b/ace/LSOCK_CODgram.i @@ -0,0 +1,27 @@ +/* -*- C++ -*- */ +// $Id$ + +// LSOCK_CODgram.i + +// Do nothing constructor. + +inline +ACE_LSOCK_CODgram::ACE_LSOCK_CODgram (void) +{ + ACE_TRACE ("ACE_LSOCK_CODgram::ACE_LSOCK_CODgram"); +} + +inline void +ACE_LSOCK_CODgram::set_handle (ACE_HANDLE h) +{ + ACE_TRACE ("ACE_LSOCK_CODgram::set_handle"); + this->ACE_SOCK_CODgram::set_handle (h); + this->ACE_LSOCK::set_handle (h); +} + +inline ACE_HANDLE +ACE_LSOCK_CODgram::get_handle (void) const +{ + ACE_TRACE ("ACE_LSOCK_CODgram::get_handle"); + return this->ACE_SOCK_CODgram::get_handle (); +} diff --git a/ace/LSOCK_Connector.cpp b/ace/LSOCK_Connector.cpp new file mode 100644 index 00000000000..07c1317d341 --- /dev/null +++ b/ace/LSOCK_Connector.cpp @@ -0,0 +1,49 @@ +// LSOCK_Connector.cpp +// $Id$ + +/* Defines the format and interface for the connector side of the + local ACE_SOCK ACE_Stream. */ + +#define ACE_BUILD_DLL +#include "ace/LSOCK_Connector.h" + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +ACE_ALLOC_HOOK_DEFINE(ACE_LSOCK_Connector) + +void +ACE_LSOCK_Connector::dump (void) const +{ + ACE_TRACE ("ACE_LSOCK_Connector::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_LSOCK_Connector::ACE_LSOCK_Connector (void) +{ + ACE_TRACE ("ACE_LSOCK_Connector::ACE_LSOCK_Connector"); +} + +// Establish a connection. +ACE_LSOCK_Connector::ACE_LSOCK_Connector (ACE_LSOCK_Stream &new_stream, + const ACE_UNIX_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms, + int protocol_family, + int protocol) + : ACE_SOCK_Connector (new_stream, remote_sap, timeout, + local_sap, reuse_addr, flags, perms, + protocol_family, protocol) +{ + ACE_TRACE ("ACE_LSOCK_Connector::ACE_LSOCK_Connector"); + // This is necessary due to the weird inheritance relationships of + // ACE_LSOCK_Stream. + new_stream.set_handle (new_stream.get_handle ()); +} + +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ diff --git a/ace/LSOCK_Connector.h b/ace/LSOCK_Connector.h new file mode 100644 index 00000000000..0abd55045f3 --- /dev/null +++ b/ace/LSOCK_Connector.h @@ -0,0 +1,97 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// LSOCK_Connector.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_LOCAL_SOCK_CONNECTOR_H) +#define ACE_LOCAL_SOCK_CONNECTOR_H + +#include "ace/SOCK_Connector.h" +#include "ace/LSOCK_Stream.h" +#include "ace/UNIX_Addr.h" + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +class ACE_Export ACE_LSOCK_Connector : public ACE_SOCK_Connector + // = TITLE + // Defines the format and interface for the connector side of the + // local ACE_SOCK ACE_Stream. +{ +public: + // = Initialization methods. + ACE_LSOCK_Connector (void); + // Default constructor. + + ACE_LSOCK_Connector (ACE_LSOCK_Stream &new_stream, + const ACE_UNIX_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = 0, + int perms = 0, + int protocol_family = PF_UNIX, + int protocol = 0); + // Actively connect and produce a if things go well. + // The is the address that we are trying to connect + // with. The is the amount of time to wait to connect. + // If it's 0 then we block indefinitely. If *timeout == {0, 0} then + // the connection is done using non-blocking mode. In this case, if + // the connection can't be made immediately the value of -1 is + // returned with . If *timeout > {0, 0} then + // this is the amount of time to wait before timing out. If the + // time expires before the connection is made . + // The is the value of local address to bind to. If + // it's the default value of then the user is + // letting the OS do the binding. If == 1 then the + // is reused, even if it hasn't been cleanedup yet. + + int connect (ACE_LSOCK_Stream &new_stream, + const ACE_UNIX_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = 0, + int perms = 0, + int protcol_family = PF_UNIX, + int protocol = 0); + // Actively connect and produce a if things go well. + // The is the address that we are trying to connect + // with. The is the amount of time to wait to connect. + // If it's 0 then we block indefinitely. If *timeout == {0, 0} then + // the connection is done using non-blocking mode. In this case, if + // the connection can't be made immediately the value of -1 is + // returned with . If *timeout > {0, 0} then + // this is the amount of time to wait before timing out. If the + // time expires before the connection is made . + // The is the value of local address to bind to. If + // it's the default value of then the user is + // letting the OS do the binding. If == 1 then the + // is reused, even if it hasn't been cleanedup yet. + + // = Meta-type info + typedef ACE_UNIX_Addr PEER_ADDR; + typedef ACE_LSOCK_Stream PEER_STREAM; + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#include "ace/LSOCK_Connector.i" + +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ +#endif /* ACE_LOCAL_SOCK_CONNECTOR_H */ diff --git a/ace/LSOCK_Connector.i b/ace/LSOCK_Connector.i new file mode 100644 index 00000000000..fdd9834a444 --- /dev/null +++ b/ace/LSOCK_Connector.i @@ -0,0 +1,29 @@ +/* -*- C++ -*- */ +// $Id$ + +// LSOCK_Connector.i + +// Establish a connection. + +inline int +ACE_LSOCK_Connector::connect (ACE_LSOCK_Stream &new_stream, + const ACE_UNIX_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms, + int protocol_family, + int protocol) +{ + ACE_TRACE ("ACE_LSOCK_Connector::connect"); + int result = ACE_SOCK_Connector::connect (new_stream, remote_sap, + timeout, local_sap, + reuse_addr, flags, perms, + protocol_family, protocol); + if (result != -1) + // This is necessary due to the weird inheritance relationships of ACE_LSOCK_Stream. + new_stream.set_handle (new_stream.get_handle ()); + return result; +} + diff --git a/ace/LSOCK_Dgram.cpp b/ace/LSOCK_Dgram.cpp new file mode 100644 index 00000000000..621cebbdaf5 --- /dev/null +++ b/ace/LSOCK_Dgram.cpp @@ -0,0 +1,60 @@ +// LSOCK_Dgram.cpp +// $Id$ + +/* Defines the member functions for the Local ACE_SOCK datagram + abstraction. */ + +#define ACE_BUILD_DLL +#include "ace/LSOCK_Dgram.h" +#include "ace/Log_Msg.h" + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +ACE_ALLOC_HOOK_DEFINE(ACE_LSOCK_Dgram) + +void +ACE_LSOCK_Dgram::dump (void) const +{ + ACE_TRACE ("ACE_LSOCK_Dgram::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_SOCK_Dgram::dump (); + ACE_LSOCK::dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +/* The "do nothing" constructor. */ + +ACE_LSOCK_Dgram::ACE_LSOCK_Dgram (void) +{ + ACE_TRACE ("ACE_LSOCK_Dgram::ACE_LSOCK_Dgram"); +} + +/* Here's the general-purpose open routine. */ + +int +ACE_LSOCK_Dgram::open (const ACE_Addr &local, + int protocol_family, + int protocol) +{ + ACE_TRACE ("ACE_LSOCK_Dgram::open"); + if (ACE_SOCK_Dgram::open (local, protocol_family, + protocol) == -1) + return -1; + ACE_LSOCK::set_handle (this->ACE_SOCK_Dgram::get_handle ()); + return 0; +} + +/* Create a local ACE_SOCK datagram. */ + +ACE_LSOCK_Dgram::ACE_LSOCK_Dgram (const ACE_Addr &local, + int protocol_family, + int protocol) +{ + ACE_TRACE ("ACE_LSOCK_Dgram::ACE_LSOCK_Dgram"); + if (this->open (local, protocol_family, + protocol) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_LSOCK_Dgram")); +} + +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ diff --git a/ace/LSOCK_Dgram.h b/ace/LSOCK_Dgram.h new file mode 100644 index 00000000000..ec63e15a34e --- /dev/null +++ b/ace/LSOCK_Dgram.h @@ -0,0 +1,61 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// LSOCK_Dgram.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_LOCAL_SOCK_DGRAM_H) +#define ACE_LOCAL_SOCK_DGRAM_H + +#include "ace/SOCK_Dgram.h" +#include "ace/LSOCK.h" + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +class ACE_Export ACE_LSOCK_Dgram : public ACE_SOCK_Dgram, public ACE_LSOCK + // = TITLE + // Create a Local ACE_SOCK datagram. +{ +public: + // = Initialization methods. + ACE_LSOCK_Dgram (void); + // Default constructor. + + ACE_LSOCK_Dgram (const ACE_Addr &local, + int protocol_family = PF_UNIX, + int protocol = 0); + // Initiate a local dgram. + + int open (const ACE_Addr &local, + int protocol_family = PF_UNIX, + int protocol = 0); + // Initiate a local dgram. + + ACE_HANDLE get_handle (void) const; + // Get handle. + + void set_handle (ACE_HANDLE); + // Set handle. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#include "ace/LSOCK_Dgram.i" + +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ +#endif /* ACE_LOCAL_SOCK_DGRAM_H */ diff --git a/ace/LSOCK_Dgram.i b/ace/LSOCK_Dgram.i new file mode 100644 index 00000000000..51b03bb8c89 --- /dev/null +++ b/ace/LSOCK_Dgram.i @@ -0,0 +1,20 @@ +/* -*- C++ -*- */ +// $Id$ + +// LSOCK_Dgram.i + +inline void +ACE_LSOCK_Dgram::set_handle (ACE_HANDLE h) +{ + ACE_TRACE ("ACE_LSOCK_Dgram::set_handle"); + this->ACE_SOCK_Dgram::set_handle (h); + this->ACE_LSOCK::set_handle (h); +} + +inline ACE_HANDLE +ACE_LSOCK_Dgram::get_handle (void) const +{ + ACE_TRACE ("ACE_LSOCK_Dgram::get_handle"); + return this->ACE_SOCK_Dgram::get_handle (); +} + diff --git a/ace/LSOCK_Stream.cpp b/ace/LSOCK_Stream.cpp new file mode 100644 index 00000000000..108401fc1a1 --- /dev/null +++ b/ace/LSOCK_Stream.cpp @@ -0,0 +1,69 @@ +// LSOCK_Stream.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/LSOCK_Stream.h" + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +ACE_ALLOC_HOOK_DEFINE(ACE_LSOCK_Stream) + +void +ACE_LSOCK_Stream::dump (void) const +{ + ACE_TRACE ("ACE_LSOCK_Stream::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_SOCK_Stream::dump (); + ACE_LSOCK::dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +#if defined (ACE_HAS_MSG) + +// Send a readv-style vector of buffers, along with an open I/O +// handle. + +ssize_t +ACE_LSOCK_Stream::send_msg (const iovec iov[], + size_t n, + int fd) +{ + ACE_TRACE ("ACE_LSOCK_Stream::send_msg"); + msghdr send_msg; + + send_msg.msg_iov = (iovec *) iov; + send_msg.msg_iovlen = n; + send_msg.msg_name = (char *) 0; + send_msg.msg_namelen = 0; + send_msg.msg_accrights = (char *) &fd; + send_msg.msg_accrightslen = sizeof fd; + + return ACE_OS::sendmsg (this->ACE_SOCK_Stream::get_handle (), + &send_msg, 0); +} + +// Read a readv-style vector of buffers, along with an open I/O +// handle. + +ssize_t +ACE_LSOCK_Stream::recv_msg (iovec iov[], + size_t n, + int &fd) +{ + ACE_TRACE ("ACE_LSOCK_Stream::recv_msg"); + msghdr recv_msg; + + recv_msg.msg_iov = (iovec *) iov; + recv_msg.msg_iovlen = n; + recv_msg.msg_name = (char *) 0; + recv_msg.msg_namelen = 0; + recv_msg.msg_accrights = (char *) &fd; + recv_msg.msg_accrightslen = sizeof fd; + + return ACE_OS::recvmsg (this->ACE_SOCK_Stream::get_handle (), + &recv_msg, 0); +} +#endif /* ACE_HAS_MSG */ +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ diff --git a/ace/LSOCK_Stream.h b/ace/LSOCK_Stream.h new file mode 100644 index 00000000000..be37419b15b --- /dev/null +++ b/ace/LSOCK_Stream.h @@ -0,0 +1,57 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// LSOCK_Stream.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_LOCAL_SOCK_STREAM_H) +#define ACE_LOCAL_SOCK_STREAM_H + +#include "ace/SOCK_Stream.h" +#include "ace/LSOCK.h" + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +class ACE_Export ACE_LSOCK_Stream : public ACE_SOCK_Stream, public ACE_LSOCK + // = TITLE + // Create a Local ACE_SOCK stream. +{ +public: + // = Send/recv methods. + ssize_t send_msg (const iovec iov[], size_t n, int fd); + // Send iovecs via <::writev>. + + ssize_t recv_msg (iovec iov[], size_t n, int &fd); + // Send iovecs via <::writev>. + + ACE_HANDLE get_handle (void) const; + // Get handle. + void set_handle (ACE_HANDLE fd); + // Overrides set_handle from the base classes. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + int get_remote_addr (ACE_Addr &) const; + // Do not allow this function to percolate up to this interface... +}; + +#include "ace/LSOCK_Stream.i" + +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ +#endif /* ACE_LOCAL_SOCK_STREAM_H */ diff --git a/ace/LSOCK_Stream.i b/ace/LSOCK_Stream.i new file mode 100644 index 00000000000..e76afa8d240 --- /dev/null +++ b/ace/LSOCK_Stream.i @@ -0,0 +1,25 @@ +/* -*- C++ -*- */ +// $Id$ + +// LSOCK_Stream.i + +// Sets both the file descriptors... Overrides handle from the base +// classes. + +inline void +ACE_LSOCK_Stream::set_handle (ACE_HANDLE fd) +{ + ACE_TRACE ("ACE_LSOCK_Stream::set_handle"); + this->ACE_SOCK_Stream::set_handle (fd); + this->ACE_LSOCK::set_handle (fd); +} + +inline ACE_HANDLE +ACE_LSOCK_Stream::get_handle (void) const +{ + ACE_TRACE ("ACE_LSOCK_Stream::get_handle"); + return this->ACE_SOCK_Stream::get_handle (); +} + + + diff --git a/ace/Local_Name_Space.cpp b/ace/Local_Name_Space.cpp new file mode 100644 index 00000000000..444e7507a13 --- /dev/null +++ b/ace/Local_Name_Space.cpp @@ -0,0 +1,155 @@ +// Local_Name_Space.cpp +// $Id$ + +#if !defined (ACE_LOCAL_NAME_SPACE_C) +#define ACE_LOCAL_NAME_SPACE_C + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/ACE.h" +#include "ace/Local_Name_Space.h" + +ACE_USHORT16 * +ACE_NS_String::fast_rep (void) const +{ + ACE_TRACE ("ACE_NS_String::fast_rep"); + return this->rep_; +} + +ACE_NS_String::operator ACE_WString () const +{ + ACE_TRACE ("ACE_NS_String::operator ACE_WString"); + return ACE_WString (this->rep_, (this->len_ / sizeof (ACE_USHORT16)) - 1); +} + +size_t +ACE_NS_String::len (void) const +{ + ACE_TRACE ("ACE_NS_String::len"); + return this->len_; +} + +char * +ACE_NS_String::char_rep (void) const +{ + ACE_TRACE ("ACE_NS_String::char_rep"); + ACE_WString w_string (this->rep_, (this->len_ / sizeof (ACE_USHORT16)) - 1); + return w_string.char_rep (); +} + +ACE_NS_String::ACE_NS_String (void) + : rep_ (0), + len_ (0) +{ + ACE_TRACE ("ACE_NS_String::ACE_NS_String"); +} + +ACE_NS_String::ACE_NS_String (const ACE_WString &s) + : rep_ (s.fast_rep ()), + len_ ((s.length () + 1) * sizeof (ACE_USHORT16)) +{ + ACE_TRACE ("ACE_NS_String::ACE_NS_String"); +} + +int +ACE_NS_String::strstr (const ACE_NS_String &s) const +{ + ACE_TRACE ("ACE_NS_String::strstr"); + + if (this->len_ < s.len_) + // If they're larger than we are they can't be a substring of us! + return -1; + else if (this->len_ == s.len_) + // Check if we're equal. + return *this == s ? 0 : -1; + else + { + // They're smaller than we are... + size_t len = (this->len_ - s.len_) / sizeof (ACE_USHORT16); + size_t pat_len = s.len_ / sizeof (ACE_USHORT16) - 1; + + for (size_t i = 0; i <= len; i++) + { + size_t j; + + for (j = 0; j < pat_len; j++) + if (this->rep_[i + j] != s.rep_[j]) + break; + + if (j == pat_len) + // Found a match! Return the index. + return i; + } + + return -1; + } +} + +int +ACE_NS_String::operator == (const ACE_NS_String &s) const +{ + ACE_TRACE ("ACE_NS_String::operator =="); + return this->len_ == s.len_ + && ACE_OS::memcmp ((void *) this->rep_, + (void *) s.rep_, this->len_) == 0; +} + +ACE_NS_String::ACE_NS_String (ACE_USHORT16 *dst, + const ACE_USHORT16 *src, + size_t bytes) + : len_ (bytes), + rep_ (dst) +{ + ACE_TRACE ("ACE_NS_String::ACE_NS_String"); + ACE_OS::memcpy (this->rep_, src, bytes); +} + +ACE_NS_Internal::ACE_NS_Internal (void) +{ +} + +ACE_NS_Internal::ACE_NS_Internal (ACE_NS_String &value, const char *type) + : value_ (value), + type_ (type) +{ + ACE_TRACE ("ACE_NS_Internal::ACE_NS_Internal"); +} + +int +ACE_NS_Internal::operator == (const ACE_NS_Internal &s) const +{ + ACE_TRACE ("ACE_NS_Internal::operator =="); + return this->value_ == s.value_; +} + +ACE_NS_String +ACE_NS_Internal::value (void) +{ + ACE_TRACE ("ACE_NS_Internal::value"); + return this->value_; +} + +const char * +ACE_NS_Internal::type (void) +{ + ACE_TRACE ("ACE_NS_Internal::type"); + return this->type_; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Unbounded_Set; +template class ACE_Unbounded_Set_Iterator; +template class ACE_Unbounded_Set; +template class ACE_Unbounded_Set_Iterator; +template class ACE_Set_Node; +template class ACE_Set_Node; +template class ACE_Guard; +template class ACE_Read_Guard; +template class ACE_Write_Guard; +template class ACE_Malloc; +template class ACE_Map_Manager; +template class ACE_Map_Iterator; +template class ACE_Map_Entry ; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ + +#endif /* ACE_LOCAL_NAME_SPACE_C */ diff --git a/ace/Local_Name_Space.h b/ace/Local_Name_Space.h new file mode 100644 index 00000000000..e02d9c288b6 --- /dev/null +++ b/ace/Local_Name_Space.h @@ -0,0 +1,113 @@ +/* -*- C++ -*- */ +// $Id$ + +/*-*- C++ -*- */ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// ACE_Local_Name_Space +// +// = AUTHOR +// Prashant Jain (pjain@cs.wustl.edu), Irfan Pyarali +// (irfan@wuerl.wustl.edu), and Douglas C. Schmidt +// (schmidt@cs.wustl.edu). +// +// ============================================================================ + +#if !defined (ACE_LOCAL_NAME_SPACE_H) +#define ACE_LOCAL_NAME_SPACE_H + +#include "ace/Map_Manager.h" +#include "ace/Service_Config.h" +#include "ace/SString.h" +#include "ace/Set.h" +#include "ace/Malloc.h" +#include "ace/Synch.h" + +class ACE_Export ACE_NS_String + // = TITLE + // This class and ACE_NS_Internal are used as Adapters to work + // with the Map_Manager. + // + // = DESCRIPTION + // In order to work correctly, this class must be able to + // convert back and forth with ACE_WStrings. Note that this + // class must not have a destructor since otherwise we'll have + // problems... +{ +public: + // = Initialization. + ACE_NS_String (void); + // Default "no-op" constructor. + + ACE_NS_String (ACE_USHORT16 *dst, + const ACE_USHORT16 *src, + size_t len); + // Initialization method. + + ACE_NS_String (const ACE_WString &); + // Converts an ACE_WString to an ACE_NS_String; + + operator ACE_WString () const; + // Converts an ACE_NS_String to fresh copy of an ACE_WString; + + char *char_rep (void) const; + // Return the ASCII character representation. + + int strstr (const ACE_NS_String &) const; + // Matches on substrings. + + int operator == (const ACE_NS_String &) const; + // Compare an ACE_NS_String. + + size_t len (void) const; + // Returns length of the string + + ACE_USHORT16 *fast_rep (void) const; + // Returns the underlying representation. + +private: + size_t len_; + // Length of the string. + + ACE_USHORT16 *rep_; + // This actually points into shared/persistent memory. +}; + +class ACE_Export ACE_NS_Internal + // = TITLE + // This class and ACE_NS_String are used as Adapters to work + // with the Map_Manager. +{ +public: + ACE_NS_Internal (void); + // No-op constructor. + + ACE_NS_Internal (ACE_NS_String &value, const char *type); + // Constructor. + + int operator == (const ACE_NS_Internal &) const; + // Compare an ACE_NS_Internal + + ACE_NS_String value (void); + // Return value. + + const char *type (void); + // Return type. + +private: + ACE_NS_String value_; + // Contains the value of the string. + + const char *type_; + // Contains the type of the string. +}; + +// Include the ACE_Local_Name_Space templates stuff at this point. +#include "ace/Local_Name_Space_T.h" + +#endif /* ACE_LOCAL_NAME_SPACE_H */ diff --git a/ace/Local_Name_Space_T.cpp b/ace/Local_Name_Space_T.cpp new file mode 100644 index 00000000000..557ed0888d6 --- /dev/null +++ b/ace/Local_Name_Space_T.cpp @@ -0,0 +1,673 @@ +// Local_Name_Space_T.cpp +// $Id$ + +#if !defined (ACE_LOCAL_NAME_SPACE_T_C) +#define ACE_LOCAL_NAME_SPACE_T_C + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/ACE.h" +#include "ace/Local_Name_Space.h" + +template +ACE_Name_Space_Map::ACE_Name_Space_Map (ALLOCATOR *allocator) + : MAP_MANAGER (allocator) +{ + ACE_TRACE ("ACE_Name_Space_Map::ACE_Name_Space_Map"); +} + +#if defined (ACE_WIN32) +template int +ACE_Name_Space_Map::remap (EXCEPTION_POINTERS *ep, + ALLOCATOR* allocator) +{ + ACE_TRACE ("ACE_Name_Space_Map::remap"); + + void *addr = (void *) ep->ExceptionRecord->ExceptionInformation[1]; + + // The following requires Memory Pool to have ::remap() + // defined. Thus currently this will only work for + // ACE_MMap_Memory_Pool. + if (allocator->allocator ().memory_pool ().remap (addr) == -1) + // Kick it upstairs... + return (DWORD) 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__ */ + // Resume execution at the original point of "failure." + return (DWORD) EXCEPTION_CONTINUE_EXECUTION; +} +#endif /* ACE_WIN32 */ + +template int +ACE_Name_Space_Map::close (ALLOCATOR* allocator) +{ + ACE_TRACE ("ACE_Name_Space_Map::close"); + + this->allocator_ = allocator; + return this->close_i (); +} + +template int +ACE_Name_Space_Map::bind (const ACE_NS_String &ext_id, + const ACE_NS_Internal &int_id, + ALLOCATOR* allocator) +{ + ACE_TRACE ("ACE_Name_Space_Map::bind"); + int result = 0; + + this->allocator_ = allocator; + + // Note that we *must* use structured exception handling here + // because (1) we may need to commit virtual memory pages and (2) + // C++ exception handling doesn't support resumption. + ACE_SEH_TRY { + result = this->bind_i (ext_id, int_id); + } + ACE_SEH_EXCEPT (this->remap (GetExceptionInformation (), allocator)) { + } + return result; +} + +template int +ACE_Name_Space_Map::unbind (const ACE_NS_String &ext_id, + ACE_NS_Internal &int_id, + ALLOCATOR* allocator) +{ + ACE_TRACE ("ACE_Name_Space_Map::unbind"); + int result = 0; + this->allocator_ = allocator; + + // Note that we *must* use structured exception handling here + // because (1) we may need to commit virtual memory pages and (2) + // C++ exception handling doesn't support resumption. + ACE_SEH_TRY { + result = this->unbind_i (ext_id, int_id); + } + ACE_SEH_EXCEPT (this->remap (GetExceptionInformation (), allocator)) { + } + return result; +} + +template int +ACE_Name_Space_Map::rebind (const ACE_NS_String &ext_id, + const ACE_NS_Internal &int_id, + ACE_NS_String &old_ext_id, + ACE_NS_Internal &old_int_id, + ALLOCATOR* allocator) +{ + ACE_TRACE ("ACE_Name_Space_Map::rebind"); + int result = 0; + this->allocator_ = allocator; + + // Note that we *must* use structured exception handling here + // because (1) we may need to commit virtual memory pages and (2) + // C++ exception handling doesn't support resumption. + ACE_SEH_TRY { + result = this->rebind_i (ext_id, int_id, old_ext_id, old_int_id); + } + ACE_SEH_EXCEPT (this->remap (GetExceptionInformation (), allocator)) { + } + return result; +} + +template int +ACE_Name_Space_Map::find (const ACE_NS_String &ext_id, + ACE_NS_Internal &int_id, + ALLOCATOR* allocator) +{ + ACE_TRACE ("ACE_Name_Space_Map::find"); + int result = 0; + this->allocator_ = allocator; + + // Note that we *must* use structured exception handling here + // because (1) we may need to commit virtual memory pages and (2) + // C++ exception handling doesn't support resumption. + ACE_SEH_TRY { + result = this->find_i (ext_id, int_id); + } + ACE_SEH_EXCEPT (this->remap (GetExceptionInformation (), allocator)) { + } + return result; +} + +template int +ACE_Local_Name_Space::shared_bind (const ACE_WString &name, + const ACE_WString &value, + const char *type, + int rebind) +{ + ACE_TRACE ("ACE_Local_Name_Space::shared_bind"); + size_t name_len = (name.length () + 1) * sizeof (ACE_USHORT16); + size_t value_len = (value.length () + 1) * sizeof (ACE_USHORT16); + size_t type_len = ACE_OS::strlen (type) + 1; + size_t total_len = name_len + value_len + type_len; + char *ptr = (char *) this->allocator_->malloc (total_len); + + if (ptr == 0) + return -1; + else + { + // Note that the value_rep *must* come first to make sure we can + // retrieve this pointer later on in unbind(). + ACE_USHORT16 *value_rep = (ACE_USHORT16 *) (ptr); + ACE_USHORT16 *name_rep = (ACE_USHORT16 *) (ptr + value_len); + char *new_type = (char *) (ptr + value_len + name_len); + ACE_NS_String new_name (name_rep, name.fast_rep (), name_len); + ACE_NS_String new_value (value_rep, value.fast_rep (), value_len); + ACE_OS::strcpy (new_type, type); + ACE_NS_Internal new_internal (new_value, new_type); + int result = -1; + + if (rebind == 0) + { + // Do a normal bind. This will fail if there's already an + // with the same name. + result = this->name_space_map_->bind (new_name, new_internal, this->allocator_); + + if (result == 1) + { + // Entry already existed so bind failed. Free our dynamically allocated memory. + this->allocator_->free ((void *) ptr); + return result; + } + } + else + { + // Do a rebind. If there's already any entry, this will return the existing + // and and overwrite the existing name binding. + ACE_NS_String old_name; + ACE_NS_Internal old_internal; + + result = this->name_space_map_->rebind (new_name, new_internal, + old_name, old_internal, + this->allocator_); + if (result == 1) + { + // Free up the memory we allocated in shared_bind(). Note that this + // assumes that the "value" pointer comes first and that the value, + // name, and type are contiguously allocated (see above for details) + this->allocator_->free ((void *) (old_internal.value ()).fast_rep ()); + } + } + + if (result == -1) + // Free our dynamically allocated memory. + this->allocator_->free ((void *) ptr); + else + // If bind() or rebind() succeed, they will automatically sync + // up the map manager entry. However, we must sync up our + // name/value memory. + this->allocator_->sync (ptr, total_len); + + return result; + } +} + +template int +ACE_Local_Name_Space::unbind (const ACE_WString &name) +{ + ACE_TRACE ("ACE_Local_Name_Space::unbind"); + + ACE_WRITE_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + ACE_NS_String ns_name (name); + ACE_NS_Internal ns_internal; + if (this->name_space_map_->unbind (ns_name, ns_internal, this->allocator_) != 0) + return -1; + else + { + // Free up the memory we allocated in shared_bind(). Note that + // this assumes that the "value" pointer comes first and that + // the value, name and type are contiguously allocated (see + // shared_bind() for details) + this->allocator_->free ((void *) (ns_internal.value ()).fast_rep ()); + return 0; + } +} + +template int +ACE_Local_Name_Space::bind (const ACE_WString &name, + const ACE_WString &value, + const char *type) +{ + ACE_TRACE ("ACE_Local_Name_Space::bind"); + ACE_WRITE_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + + return this->shared_bind (name, value, type, 0); +} + +template int +ACE_Local_Name_Space::rebind (const ACE_WString &name, + const ACE_WString &value, + const char *type) +{ + ACE_TRACE ("ACE_Local_Name_Space::rebind"); + ACE_WRITE_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + + return this->shared_bind (name, value, type, 1); +} + +template int +ACE_Local_Name_Space::resolve (const ACE_WString &name, + ACE_WString &value, + char *&type) +{ + ACE_TRACE ("ACE_Local_Name_Space::resolve"); + ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + + ACE_NS_String ns_name (name); + ACE_NS_Internal ns_internal; + ACE_NS_String nbc_string; // Note the classy variable name! :) + int result = -1; + if (this->name_space_map_->find (ns_name, ns_internal, this->allocator_) != 0) + return -1; + else + { + // Calls conversion operator and then calls the ACE_WString + // assignment operator to get a fresh copy. (*#*(@#&!*@!!*@&( + // HP compiler causes us to add an extra copy explicitly !! :) + nbc_string = ns_internal.value (); + value = nbc_string; + + // Gets type and then the actual reprsentation which is a ACE_USHORT16 + const char *temp = ns_internal.type (); + + size_t len = ACE_OS::strlen (ns_internal.type ()); + // Makes a copy here. Caller needs to call delete to free up memory + char *new_type; + ACE_NEW_RETURN (new_type, char [len + 1], -1); + ACE_OS::strncpy (new_type, temp, len); + new_type[len] = '\0'; // Null terminate the string + type = new_type; + + return 0; + } +} + +template int +ACE_Local_Name_Space::open (ACE_Naming_Context::Context_Scope_Type scope_in) +{ + ACE_TRACE ("ACE_Local_Name_Space::open"); + this->ns_scope_ = scope_in; + + return this->create_manager (); +} + +template +ACE_Local_Name_Space::ACE_Local_Name_Space (void) + : name_space_map_ (0), + name_options_ (0), + allocator_ (0) +{ + ACE_TRACE ("ACE_Local_Name_Space::ACE_Local_Name_Space"); +} + +template +ACE_Local_Name_Space::ACE_Local_Name_Space (ACE_Naming_Context::Context_Scope_Type scope_in, + ACE_Name_Options *name_options) + : name_options_ (name_options) +{ + ACE_TRACE ("ACE_Local_Name_Space::ACE_Local_Name_Space"); + if (this->open (scope_in) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Local_Name_Space::ACE_Local_Name_Space")); +} + +template +ACE_Local_Name_Space::~ACE_Local_Name_Space (void) +{ + ACE_TRACE ("ACE_Local_Name_Space::~ACE_Local_Name_Space"); + + // Remove the map + delete this->allocator_; +} + +template int +ACE_Local_Name_Space::create_manager (void) +{ + ACE_TRACE ("ACE_Local_Name_Space::create_manager"); + // Get directory name + const char *dir = this->name_options_->namespace_dir (); + + // Use process name as the file name. + size_t len = ACE_OS::strlen (dir); + len += ACE_OS::strlen (this->name_options_->database ()) + 1; + + if (len >= MAXNAMELEN) + { + errno = ENAMETOOLONG; + return -1; + } + + ACE_OS::strcpy (this->context_file_, dir); + ACE_OS::strcat (this->context_file_, ACE_DIRECTORY_SEPARATOR_STR); + ACE_OS::strcat (this->context_file_, this->name_options_->database ()); + + ACE_DEBUG ((LM_DEBUG, "contextfile is %s\n", + this->context_file_)); + + ACE_NEW_RETURN (this->allocator_, ALLOCATOR (this->context_file_), -1); + + // Now check if the backing store has been created successfully + if (ACE_OS::access (this->context_file_, F_OK) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "create_manager\n"), -1); + + void *ns_map = 0; + + // This is the easy case since if we find the Name Server Map + // Manager we know it's already initialized. + if (this->allocator_->find (ACE_NAME_SERVER_MAP, ns_map) == 0) + { + this->name_space_map_ = (ACE_Name_Space_Map *) ns_map; + ACE_DEBUG ((LM_DEBUG, "name_space_map_ = %d, ns_map = %d\n", + this->name_space_map_, ns_map)); + } + + // This is the hard part since we have to avoid potential race + // conditions... + else + { + size_t map_size = sizeof *this->name_space_map_; + ns_map = this->allocator_->malloc (map_size); + + // Initialize the map into its memory location (e.g., shared memory). + ACE_NEW_RETURN (this->name_space_map_, + (ns_map) ACE_Name_Space_Map (this->allocator_), + -1); + + // Don't allow duplicates (atomically return existing int_id, if + // there is one). + if (this->allocator_->trybind (ACE_NAME_SERVER_MAP, ns_map) == 1) + { + // We're not the first one in, so free up the map and assign + // the map to the pointer that was allocated by the caller + // that was the first time in! + this->name_space_map_->close (this->allocator_); + + // Note that we can't free since that was overwritten + // in the call to bind()! + this->allocator_->free ((void *) this->name_space_map_); + this->name_space_map_ = (ACE_Name_Space_Map *) ns_map; + } + ACE_DEBUG ((LM_DEBUG, "name_space_map_ = %d, ns_map = %d\n", + this->name_space_map_, ns_map)); + } + + return 0; +} + +template int +ACE_Local_Name_Space::list_names (ACE_PWSTRING_SET &set, + const ACE_WString &pattern) +{ + ACE_TRACE ("ACE_Local_Name_Space::list_names"); + ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + + MAP_ITERATOR map_iterator (*this->name_space_map_); + MAP_ENTRY *map_entry; + + int result = 1; + + for (map_entry = 0; + map_iterator.next (map_entry) != 0; + map_iterator.advance()) + { + if (map_entry->ext_id_.strstr (pattern) != -1) + { + ACE_WString entry (map_entry->ext_id_ ); + + if (set.insert (entry) == -1) + { + result = -1; + break; + } + else + result = 0; + } + } + + return result; +} + +template int +ACE_Local_Name_Space::list_values (ACE_PWSTRING_SET &set, + const ACE_WString &pattern) +{ + ACE_TRACE ("ACE_Local_Name_Space::list_values"); + ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + + MAP_ITERATOR map_iterator (*this->name_space_map_); + MAP_ENTRY *map_entry; + + int result = 1; + + for (map_entry = 0; + map_iterator.next (map_entry) != 0; + map_iterator.advance ()) + { + if (map_entry->int_id_.value ().strstr (pattern) != -1) + { + ACE_WString entry (map_entry->int_id_.value ()); + + if (set.insert (entry) == -1) + { + result = -1; + break; + } + else + result = 0; + } + } + + return result; +} + +template int +ACE_Local_Name_Space::list_types (ACE_PWSTRING_SET &set, + const ACE_WString &pattern) +{ + ACE_TRACE ("ACE_Local_Name_Space::list_types"); + ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + + MAP_ITERATOR map_iterator (*this->name_space_map_); + MAP_ENTRY *map_entry; + + char *compiled_regexp = 0; + + // Note that char_rep() allocates memory so we need to delete it + char *pattern_rep = pattern.char_rep (); + + // Check for wildcard case first. + if (ACE_OS::strcmp ("", pattern_rep) == 0) + compiled_regexp = ACE_OS::strdup (""); + else + // Compile the regular expression (the 0's cause ACE_OS::compile to allocate space). +#if defined (ACE_HAS_REGEX) + compiled_regexp = ACE_OS::compile (pattern_rep, 0, 0); +#else // If we don't have regular expressions just the pattern directly. + compiled_regexp = pattern_rep; +#endif /* ACE_HAS_REGEX */ + + int result = 1; + + for (map_entry = 0; + map_iterator.next (map_entry) != 0; + map_iterator.advance ()) + { + // Get the type + const char *type = map_entry->int_id_.type (); + + if (ACE_OS::strcmp ("", pattern_rep) == 0 // Everything matches the wildcard. +#if defined (ACE_HAS_REGEX) + || ACE_OS::step (type, compiled_regexp) != 0) +#else // If we don't have regular expressions just use strstr() for substring matching. + || ACE_OS::strstr (type, compiled_regexp) != 0) +#endif /* ACE_HAS_REGEX */ + + { + ACE_WString entry (type); + + if (set.insert (entry) == -1) + { + result = -1; + break; + } + else + result = 0; + } + } +#if defined (ACE_HAS_REGEX) + if (compiled_regexp) + ACE_OS::free ((void *) compiled_regexp); +#endif /* ACE_HAS_REGEX */ + delete [] pattern_rep; // delete pattern_rep; + return result; +} + +template int +ACE_Local_Name_Space ::list_name_entries (ACE_BINDING_SET &set, + const ACE_WString &pattern) +{ + ACE_TRACE ("ACE_Local_Name_Space::list_name_entries"); + ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + + MAP_ITERATOR map_iterator (*this->name_space_map_); + MAP_ENTRY *map_entry; + + for (map_entry = 0; + map_iterator.next (map_entry) != 0; + map_iterator.advance()) + { + if (map_entry->ext_id_.strstr (pattern) != -1) + { + ACE_Name_Binding entry (map_entry->ext_id_, + map_entry->int_id_.value (), + map_entry->int_id_.type ()); + + if (set.insert (entry) == -1) + return -1; + } + } + + return 0; +} + +template int +ACE_Local_Name_Space::list_value_entries (ACE_BINDING_SET &set, + const ACE_WString &pattern) +{ + ACE_TRACE ("ACE_Local_Name_Space::list_value_entries"); + ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + + MAP_ITERATOR map_iterator (*this->name_space_map_); + MAP_ENTRY *map_entry; + + for (map_entry = 0; + map_iterator.next (map_entry) != 0; + map_iterator.advance ()) + { + if (map_entry->int_id_.value ().strstr (pattern) != -1) + { + ACE_Name_Binding entry (map_entry->ext_id_, + map_entry->int_id_.value (), + map_entry->int_id_.type ()); + + if (set.insert (entry) == -1) + return -1; + } + } + return 0; +} + +template int +ACE_Local_Name_Space::list_type_entries (ACE_BINDING_SET &set, + const ACE_WString &pattern) +{ + ACE_TRACE ("ACE_Local_Name_Space::list_type_entries"); + ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1); + + MAP_ITERATOR map_iterator (*this->name_space_map_); + MAP_ENTRY *map_entry; + + char *compiled_regexp = 0; + // Note that char_rep() allocates memory so we need to delete it + char *pattern_rep = pattern.char_rep (); + + // Check for wildcard case first. + if (ACE_OS::strcmp ("", pattern_rep) == 0) + compiled_regexp = ACE_OS::strdup (""); + else + // Compile the regular expression (the 0's cause ACE_OS::compile to allocate space). +#if defined (ACE_HAS_REGEX) + compiled_regexp = ACE_OS::compile (pattern_rep, 0, 0); +#else // If we don't have regular expressions just the pattern directly. + compiled_regexp = pattern_rep; +#endif /* ACE_HAS_REGEX */ + + int result = 1; + + for (map_entry = 0; + map_iterator.next (map_entry) != 0; + map_iterator.advance ()) + { + // Get the type. + const char *type = map_entry->int_id_.type (); + + if (ACE_OS::strcmp ("", pattern_rep) == 0 // Everything matches the wildcard. +#if defined (ACE_HAS_REGEX) + || ACE_OS::step (type, compiled_regexp) != 0) +#else // If we don't have regular expressions just use strstr() for substring matching. + || ACE_OS::strstr (type, compiled_regexp) != 0) +#endif /* ACE_HAS_REGEX */ + { + ACE_Name_Binding entry (map_entry->ext_id_, + map_entry->int_id_.value (), + map_entry->int_id_.type ()); + + if (set.insert (entry) == -1) + return -1; + } + } +#if defined (ACE_HAS_REGEX) + if (compiled_regexp) + ACE_OS::free ((void *) compiled_regexp); +#endif /* ACE_HAS_REGEX */ + delete [] pattern_rep; // delete pattern_rep; + return 0; +} + + +template void +ACE_Local_Name_Space::dump (void) const +{ + ACE_TRACE ("ACE_Local_Name_Space::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + MAP_ITERATOR map_iterator (*this->name_space_map_); + MAP_ENTRY *map_entry; + + for (map_entry = 0; + map_iterator.next (map_entry) != 0; + map_iterator.advance()) + { + char *key = map_entry->ext_id_.char_rep (); + char *value = map_entry->int_id_.value ().char_rep (); + const char *type = map_entry->int_id_.type (); + + ACE_DEBUG ((LM_DEBUG, "key=%s\nvalue=%s\ntype=%s\n", + key, value, type)); + // We need to delete key and value since char_rep allocates memory for them + delete [] key; + delete [] value; + } + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +#endif /* ACE_LOCAL_NAME_SPACE_T_C */ diff --git a/ace/Local_Name_Space_T.h b/ace/Local_Name_Space_T.h new file mode 100644 index 00000000000..ada018f91c7 --- /dev/null +++ b/ace/Local_Name_Space_T.h @@ -0,0 +1,219 @@ +/* -*- C++ -*- */ +// $Id$ + +/*-*- C++ -*- */ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// ACE_Local_Name_Space_T.h +// +// = AUTHOR +// Prashant Jain (pjain@cs.wustl.edu), Irfan Pyarali +// (irfan@wuerl.wustl.edu), and Douglas C. Schmidt +// (schmidt@cs.wustl.edu). +// +// ============================================================================ + +#if !defined (ACE_LOCAL_NAME_SPACE_T_H) +#define ACE_LOCAL_NAME_SPACE_T_H + +#include "ace/Name_Space.h" +#include "ace/Naming_Context.h" +#include "ace/SString.h" +#include "ace/Local_Name_Space.h" + +// A short-hand name for our set of name/value/type tuples passed back +// to callers. +typedef ACE_Unbounded_Set ACE_WSTRING_SET; + +// Simplify later usage by defining typedefs. +typedef ACE_Map_Manager MAP_MANAGER; +typedef ACE_Map_Iterator MAP_ITERATOR; +typedef ACE_Map_Entry MAP_ENTRY; + +template +class ACE_Name_Space_Map : public MAP_MANAGER +{ + // = TITLE + // This class serves as a Proxy that ensures our process always + // has the appropriate allocator in place for every operation + // that accesses or updates the Map Manager. + // + // = DESCRIPTION + // We need this class because otherwise the SHARED_MALLOC + // pointer will be stored in the Map_Manager that resides within + // shared memory. Naturally, this will cause horrible problems + // since only the first process to set that pointer will be + // guaranteed the address of the SHARED_MALLOC allocator is + // meaningful! +public: + ACE_Name_Space_Map (ALLOCATOR *allocator); + // Constructor. + + // = The following methods are Proxies to the underlying methods + // provided by . When they are called, they + // acquire the lock, set the allocator to the one specific to this + // process, and then call down to perform the intended operation. + int bind (const ACE_NS_String &, + const ACE_NS_Internal &, + ALLOCATOR *allocator); + + int unbind (const ACE_NS_String &, + ACE_NS_Internal &, + ALLOCATOR *allocator); + + int rebind (const ACE_NS_String &, + const ACE_NS_Internal &, + ACE_NS_String &, + ACE_NS_Internal &, + ALLOCATOR *allocator); + + int find (const ACE_NS_String &, + ACE_NS_Internal &, + ALLOCATOR *allocator); + + int close (ALLOCATOR* allocator); + +private: +#if defined (ACE_WIN32) + int remap (EXCEPTION_POINTERS *ep, ALLOCATOR *allocator); + // Remap the backing store +#endif /* ACE_WIN32 */ +}; + +template +class ACE_Local_Name_Space : public ACE_Name_Space + // = TITLE + // Maintaining accesses Local Name Server Database. Allows to + // add NameBindings, change them, remove them and resolve + // NameBindings. + // + // = DESCRIPTION + // Manages a Naming Service for a local name space which includes + // bindings for node_local and host_local naming contexts. + // All strings are stored in wide character format. + // A Name Binding consists of a name (that's the key), a value + // string and an optional type string (no wide chars). +{ +public: + // = Initialization and termination methods. + ACE_Local_Name_Space (void); + // "Do-nothing" constructor. + + ACE_Local_Name_Space (ACE_Naming_Context::Context_Scope_Type scope_in, + ACE_Name_Options *name_options); + // Specifies the scope of this namespace, opens and memory-maps the + // associated file (if accessible) or contacts the dedicated name + // server process for NET_LOCAL namespace. + + int open (ACE_Naming_Context::Context_Scope_Type scope_in); + // Specifies the scope of this namespace, opens and memory-maps the + // associated file (if accessible) or contacts the dedicated name + // server process for NET_LOCAL namespace. + + ~ACE_Local_Name_Space (void); + // destructor, do some cleanup :TBD: last dtor should "compress" + // file + + virtual int bind (const ACE_WString &name, + const ACE_WString &value, + const char *type = ""); + // Bind a new name to a naming context (Wide character strings). + + virtual int rebind (const ACE_WString &name, + const ACE_WString &value, + const char *type = ""); + // Overwrite the value or type of an existing name in a + // ACE_Local_Name_Space or bind a new name to the context, if it + // didn't exist yet. (Wide charcter strings interface). + + virtual int unbind (const ACE_WString &name); + // Delete a name from a ACE_Local_Name_Space (Wide charcter strings + // Interface). + + virtual int resolve (const ACE_WString &name, + ACE_WString &value, + char *&type); + // Get value and type of a given name binding (Wide chars). The + // caller is responsible for deleting ! + + virtual int list_names (ACE_WSTRING_SET &set, + const ACE_WString &pattern); + // Get a set of names matching a specified pattern (wchars). Matching + // means the names must begin with the pattern string. + + virtual int list_values (ACE_WSTRING_SET &set, + const ACE_WString &pattern); + // Get a set of values matching a specified pattern (wchars). Matching + // means the values must begin with the pattern string. + + virtual int list_types (ACE_WSTRING_SET &set, + const ACE_WString &pattern); + // Get a set of types matching a specified pattern (wchars). Matching + // means the types must begin with the pattern string. + + virtual int list_name_entries (ACE_BINDING_SET &set, + const ACE_WString &pattern); + // Get a set of names matching a specified pattern (wchars). Matching + // means the names must begin with the pattern string. Returns the + // complete binding associated each pattern match. + + virtual int list_value_entries (ACE_BINDING_SET &set, + const ACE_WString &pattern); + // Get a set of values matching a specified pattern (wchars). Matching + // means the values must begin with the pattern string. Returns the + // complete binding associated each pattern match. + + virtual int list_type_entries (ACE_BINDING_SET &set, + const ACE_WString &pattern); + // Get a set of types matching a specified pattern (wchars). Matching + // means the types must begin with the pattern string. Returns the + // complete binding associated each pattern match. + + virtual void dump (void) const; + // Dump the state of the object + +private: + int shared_bind (const ACE_WString &name, const ACE_WString &value, + const char *type, int rebind); + // Factor out code from bind() and rebind(). + + int create_manager (void); + // Allocate the appropriate type of map manager that stores the + // key/value binding. + + // = I just know this is going to cause problems on some platform... + typedef ACE_Allocator_Adapter > ALLOCATOR; + + ALLOCATOR *allocator_; + // Pointer to the allocator + + ACE_Name_Space_Map *name_space_map_; + // Pointer to the allocated map manager. + + ACE_Naming_Context::Context_Scope_Type ns_scope_; + // Scope of this naming context (e.g., PROC_LOCAL, NODE_LOCAL, or NET_LOCAL). + + ACE_Name_Options *name_options_; + // Keep track of the options such as database name etc + + char context_file_[MAXNAMELEN]; + // Name of the file used as the backing store. + + LOCK lock_; + // Synchronization variable. +}; + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Local_Name_Space_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Local_Name_Space_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_LOCAL_NAME_SPACE_T_H */ diff --git a/ace/Local_Tokens.cpp b/ace/Local_Tokens.cpp new file mode 100644 index 00000000000..9b39c22f451 --- /dev/null +++ b/ace/Local_Tokens.cpp @@ -0,0 +1,1408 @@ +// Local_Tokens.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Thread.h" +#include "ace/Local_Tokens.h" +#include "ace/Token_Manager.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Local_Tokens.i" +#endif /* __ACE_INLINE__ */ + +void +ACE_Tokens::dump (void) const +{ + ACE_TRACE ("ACE_Tokens::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "ACE_Tokens::dump:\n" + " reference_cont_ = %d\n" + " token_name_ = %s\n", + reference_count_, token_name_)); + ACE_DEBUG ((LM_DEBUG, "waiters_\n")); + this->waiters_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Tokens::ACE_Tokens (void) + : reference_count_ (0), + visited_ (0) +{ + ACE_TRACE ("ACE_Tokens::ACE_Tokens"); +} + +void +ACE_Tokens::make_owner (ACE_TPQ_Entry *caller) +{ + this->waiters_.remove (caller); + this->waiters_.enqueue (caller, 0); +} + +// ************************************************************ +// ************************************************************ +// ************************************************************ + + +void +ACE_TPQ_Entry::dump (void) const +{ + ACE_TRACE ("ACE_TPQ_Entry::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, + "ACE_TPQ_Entry::dump:\n" + " nesting_level_ = %d\n" + " client_id_ = %s\n", + nesting_level_, + client_id_)); + + if (next_ != 0) + { + ACE_DEBUG ((LM_DEBUG, "next:.\n")); + next_->dump (); + } + + ACE_DEBUG ((LM_DEBUG, "ACE_TPQ_Entry::dump end.\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_TPQ_Entry::ACE_TPQ_Entry (const ACE_Token_Proxy *new_proxy, + const char *client_id) + : cond_var_ (lock_), + // This const typecast is safe. + proxy_ ((ACE_Token_Proxy *) new_proxy), + nesting_level_ (0), + sleep_hook_ (0), + next_ (0) +{ + ACE_TRACE ("ACE_TPQ_Entry::ACE_TPQ_Entry"); + + if (client_id != 0) + this->client_id (client_id); + else + { + // Just make sure we have enough space. + char host_name[MAXHOSTNAMELEN]; + char name[sizeof host_name + 256]; + ACE_OS::hostname (host_name, sizeof host_name); + + ACE_OS::sprintf (name, + "/%s/%u/%u", + host_name, + ACE_OS::getpid (), + ACE_Thread::self ()); + + this->client_id (name); + } +} + +ACE_TPQ_Entry::ACE_TPQ_Entry (void) + : proxy_ (0), + nesting_level_ (0), + sleep_hook_ (0), + cond_var_ (lock_) +{ + ACE_TRACE ("ACE_TPQ_Entry::ACE_TPQ_Entry null const."); +} + +ACE_TPQ_Entry::ACE_TPQ_Entry (const ACE_TPQ_Entry &rhs) +: cond_var_ (lock_) +{ + ACE_TRACE ("ACE_TPQ_Entry::ACE_TPQ_Entry copy const."); + *this = rhs; +} + +ACE_TPQ_Entry::~ACE_TPQ_Entry (void) +{ + ACE_TRACE ("ACE_TPQ_Entry::~ACE_TPQ_Entry"); +} + +void +ACE_TPQ_Entry::operator= (const ACE_TPQ_Entry& rhs) +{ + ACE_TRACE ("ACE_TPQ_Entry::operator="); + if (&rhs == this) + return; + this->proxy_ = rhs.proxy (); + this->nesting_level_ = rhs.nesting_level (); + this->client_id (rhs.client_id ()); + this->sleep_hook_ = rhs.sleep_hook (); +} + +void +ACE_TPQ_Entry::client_id (const char *id) +{ + ACE_TRACE ("ACE_TPQ_Entry::client_id"); + + if (id == 0) + return; + + int n = ACE_OS::strlen (id) + 1; + + if (n >= ACE_MAXCLIENTIDLEN) + n = ACE_MAXCLIENTIDLEN - 1; + + ACE_OS::strncpy (this->client_id_, (char *) id, n); + this->client_id_[ACE_MAXCLIENTIDLEN - 1] = '\0'; +} + +// ************************************************************ +// ************************************************************ +// ************************************************************ + +void +ACE_TSS_TPQ_Entry::dump (void) const +{ + ACE_TRACE ("ACE_TSS_TPQ_Entry::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "ACE_TSS_TPQ_Entry::dump:\n" + " client_id_ = %s\n", + client_id_ == 0 ? "0" : client_id_)); + ACE_DEBUG ((LM_DEBUG, "base:\n")); + ACE_TSS::dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_TSS_TPQ_Entry::ACE_TSS_TPQ_Entry (const ACE_Token_Proxy *proxy, + const char *client_id) +: proxy_ (proxy), + client_id_ (client_id) +{ + ACE_TRACE ("ACE_TSS_TPQ_Entry::ACE_TSS_TPQ_Entry"); +} + +ACE_TPQ_Entry * +ACE_TSS_TPQ_Entry::make_TSS_TYPE (void) const +{ + ACE_TRACE ("ACE_TSS_TPQ_Entry::make_TSS_TYPE"); + ACE_TPQ_Entry *temp; + + ACE_NEW_RETURN (temp, ACE_TPQ_Entry (this->proxy_, this->client_id_), 0); + return temp; +} + +ACE_TSS_TPQ_Entry::operator ACE_TPQ_Entry * (void) +{ + ACE_TRACE ("ACE_TSS_TPQ_Entry::operator"); + return (ACE_TPQ_Entry *) (*((ACE_TSS *) this)); +} + +// ************************************************************ +// ************************************************************ +// ************************************************************ + +ACE_TPQ_Iterator::ACE_TPQ_Iterator (ACE_Token_Proxy_Queue &q) +: current_ (q.head_) +{ + ACE_TRACE ("ACE_TPQ_Iterator::ACE_TPQ_Iterator"); +} + +int +ACE_TPQ_Iterator::next (ACE_TPQ_Entry *&next_item) +{ + ACE_TRACE ("ACE_TPQ_Iterator::next"); + + next_item = current_; + + if (current_ == 0) + return 0; + + return 1; +} + +void +ACE_TPQ_Iterator::advance (void) +{ + ACE_TRACE ("ACE_TPQ_Iterator::advance"); + if (current_ != 0) + current_ = current_->next_; +} + +void +ACE_TPQ_Iterator::dump (void) const +{ + ACE_TRACE ("ACE_TPQ_Iterator::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "ACE_TPQ_Iterator::dump:\n" + " current_ = %d\n", + (long) current_)); + ACE_DEBUG ((LM_DEBUG, "head_ and tail_\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// ************************************************************ +// ************************************************************ +// ************************************************************ + +void +ACE_Token_Proxy_Queue::dump (void) const +{ + ACE_TRACE ("ACE_Token_Proxy_Queue::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "ACE_Token_Proxy_Queue::dump:\n" + " size_ = %d\n", + size_)); + ACE_DEBUG ((LM_DEBUG, "head_ and tail_\n")); + if (this->head_ != 0) + this->head_->dump (); + + ACE_DEBUG ((LM_DEBUG, "ACE_Token_Proxy_Queue::dump end.\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Token_Proxy_Queue::ACE_Token_Proxy_Queue (void) + : head_ (0), + tail_ (0), + size_ (0) +{ + ACE_TRACE ("ACE_Token_Proxy_Queue::ACE_Token_Proxy_Queue"); +} + +void +ACE_Token_Proxy_Queue::enqueue (ACE_TPQ_Entry *tpq, + int position) +{ + ACE_TRACE ("ACE_Token_Proxy_Queue::enqueue"); + tpq->next_ = 0; + + ++this->size_; + + if (this->head_ == 0) + { + // make tpq the entire list + this->head_ = this->tail_ = tpq; + return; + } + + if (position == 0) + { + // make head of list + tpq->next_ = this->head_; + this->head_ = tpq; + return; + } + + if (position == -1) + { + // stick at back of list + this->tail_->next_ = tpq; + this->tail_ = tpq; + return; + } + + // walk through list to insertion point + ACE_TPQ_Entry *temp = head_; + + for (int x = position; x > 1; --x) + { + // end of queue? + if (temp->next_ == 0) + break; + // advance pointer + else + temp = temp->next_; + } + + // insert new tpq after temp + tpq->next_ = temp->next_; + temp->next_ = tpq; +} + +void +ACE_Token_Proxy_Queue::dequeue (void) +{ + ACE_TRACE ("ACE_Token_Proxy_Queue::dequeue"); + + if (head_ == 0) + return; + + ACE_TPQ_Entry *temp = this->head_; + + this->head_ = this->head_->next_; + + temp->next_ = 0; + + --this->size_; + + if (this->head_ == 0 && this->size_ != 0) + ACE_ERROR ((LM_ERROR, "incorrect size = %d\n", this->size_)); +} + +/* +int +ACE_Token_Proxy_Queue::member (const char *id) +{ + ACE_TRACE ("ACE_Token_Proxy_Queue::member"); + + for (ACE_TPQ_Entry *temp = this->head_; temp != 0; temp = temp->next_) + if (ACE_OS::strcmp (temp->client_id (), id) == 0) + // We found it! + return 1; + + // We didn't find it :-( + return 0; +} +*/ + +void +ACE_Token_Proxy_Queue::remove (const ACE_TPQ_Entry *remove_me) +{ + ACE_TRACE ("ACE_Token_Proxy_Queue::remove"); + // sanity + if ((remove_me == 0) || (this->head_ == 0)) + return; + + // is it the head? + if (this->head_ == remove_me) // pointer comparison. + { + this->head_ = this->head_->next_; + if (this->head_ == 0) + this->tail_ = 0; + + --this->size_; + return; + } + + ACE_TPQ_Entry *temp = this->head_; + ACE_TPQ_Entry *previous = 0; + + // is it in the middle or tail? + while (temp != 0) + { + if (temp == remove_me) + { + // previous should never be null since the first if + // conditional should always be false + previous->next_ = temp->next_; + // is it the tail? + if (this->tail_ == temp) + this->tail_ = previous; + + --this->size_; + return; + } + + previous = temp; + temp = temp->next_; + } + + // it wasn't in the list. + return; +} + +// ************************************************************ +// ************************************************************ +// ************************************************************ + +void +ACE_Mutex_Token::dump (void) const +{ + ACE_TRACE ("ACE_Mutex_Token::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "ACE_Mutex_Token::dump:\n")); + ACE_DEBUG ((LM_DEBUG, "lock_\n")); + lock_.dump (); + ACE_DEBUG ((LM_DEBUG, "base:\n")); + ACE_Tokens::dump (); + ACE_DEBUG ((LM_DEBUG, "ACE_Mutex_Token::dump end.\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Mutex_Token::ACE_Mutex_Token (const char *name) +{ + ACE_TRACE ("ACE_Mutex_Token::ACE_Mutex_Token"); + + int n = ACE_OS::strlen (name) + 1; // + 1 for \0 + + if (n > ACE_MAXTOKENNAMELEN) + n = ACE_MAXTOKENNAMELEN - 1; + + ACE_OS::strncpy (this->token_name_, name, n); + this->token_name_[ACE_MAXTOKENNAMELEN - 1] = '\0'; +} + +ACE_Mutex_Token::~ACE_Mutex_Token (void) +{ + ACE_TRACE ("ACE_Mutex_Token::~ACE_Mutex_Token"); +} + +int +ACE_Mutex_Token::acquire (ACE_TPQ_Entry *caller, + int ignore_deadlock, + int notify) +{ + ACE_TRACE ("ACE_Mutex_Token::acquire"); + // We need to acquire two locks. This one to ensure that only one + // thread uses this token at a time. + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1); + // This one to ensure an atomic transaction across all tokens. Note + // that this order is crucial too. It's resource coloring for other + // threads which may be calling this same token. + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1); + + // Does _anyone_ own the token? + if (this->owner () == 0) + { + // there are no waiters, so queue as the first waiter (the owner.) + this->waiters_.enqueue (caller, -1); + return 0; // success + } + + // Does the caller already own it? + if (this->is_owner (caller->client_id ())) + { + // Recursive acquisition. + caller->nesting_level (1); + return 0; // success + } + + // Check for deadlock. + if (!ignore_deadlock + && ACE_Token_Manager::instance ()->check_deadlock (caller->proxy ()) == 1) + { + errno = EDEADLK; + ACE_RETURN (-1); + } + + // Someone owns it. Sorry, you're getting queued up at the end of + // the waiter queue. + this->waiters_.enqueue (caller, -1); + + if (notify) + this->owner ()->call_sleep_hook (); + + errno = EWOULDBLOCK; + ACE_RETURN (-1); +} + +int +ACE_Mutex_Token::tryacquire (ACE_TPQ_Entry *caller) +{ + ACE_TRACE ("ACE_Mutex_Token::tryacquire"); + // We need to acquire two locks. This one to ensure that only one + // thread uses this token at a time. + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1); + // This one to ensure an atomic transaction across all tokens. Note + // that this order is crucial too. It's resource coloring for other + // threads which may be calling this same token. + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1); + + // Does _anyone_ own the token? + if (this->owner () == 0) + { + this->waiters_.enqueue (caller, -1); + return 0; // success + } + // Does the caller already own it? + if (this->is_owner (caller->client_id ())) + { + // recursive acquisition + caller->nesting_level (1); + return 0; // success + } + else + // Someone owns it. Fail. + { + errno = EWOULDBLOCK; + ACE_RETURN (-1); + } +} + +int +ACE_Mutex_Token::renew (ACE_TPQ_Entry *caller, + int requeue_position) +{ + ACE_TRACE ("ACE_Mutex_Token::renew"); + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1); + + // Verify that the caller is the owner. + if (this->is_owner (caller->client_id ()) == 0) + { + errno = EACCES; + ACE_RETURN (-1); + } + + // The caller is the owner, so check to see if there are any + // waiters. If not, we just keep the token. == 1 means that there + // is only the owner. + if (this->waiters_.size () == 1 || requeue_position == 0) + return 0; + + // Requeue the caller. + this->waiters_.dequeue (); + + this->waiters_.enqueue (caller, requeue_position); + + // Notify new owner. + if (this->owner () != 0) + this->owner ()->proxy ()->token_acquired (this->owner ()); + + // Tell the caller that the operation would block. + errno = EWOULDBLOCK; + ACE_RETURN (-1); +} + +// Release the current holder of the token (which had +// better be the caller's thread!). + +int +ACE_Mutex_Token::release (ACE_TPQ_Entry *caller) +{ + ACE_TRACE ("ACE_Mutex_Token::release"); + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1); + + // Does anyone own the token? + if (this->owner () == 0) + { + errno = EACCES; + ACE_RETURN (-1); + } + + // Is the caller the owner. + if (this->is_owner (caller->client_id ())) + { + // Check the nesting level. + if (caller->nesting_level () > 0) + caller->nesting_level (-1); + else + { + this->waiters_.dequeue (); + // Notify new owner. + if (this->owner () != 0) + this->owner ()->proxy ()->token_acquired (this->owner ()); + } + } + else + this->remove (caller); + + return 0; +} + +int +ACE_Mutex_Token::owners (OWNER_STACK &stack, + const char *id) +{ + ACE_TRACE ("ACE_Mutex_Token::owners"); + if (this->owner () != 0) + { + stack.push (this->owner ()); + // If an is specified, return whether it is the owner being + // returned. + if (id != 0) + return this->owner ()->equal_client_id (id); + } + + return 0; +} + +int +ACE_Mutex_Token::is_waiting_for (const char *id) +{ + ACE_TRACE ("ACE_Mutex_Token::is_waiting_for"); + // If there is no owner, or is the owner, return false. + if ((this->owner () == 0) || this->is_owner (id)) + return 0; + + // Step through each waiter looking for . + ACE_TPQ_Iterator iterator (waiters_); + iterator.advance (); + for (ACE_TPQ_Entry *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + if (temp->equal_client_id (id)) + return 1; + } + + return 0; +} + +int +ACE_Mutex_Token::is_owner (const char *id) +{ + ACE_TRACE ("ACE_Mutex_Token::is_owner"); + // If there is an owner, return whether it is . + if ((this->owner () != 0) && + this->owner ()->equal_client_id (id)) + return 1; + else + return 0; +} + +// ************************************************************ +// ************************************************************ +// ************************************************************ + +void +ACE_RW_Token::dump (void) const +{ + ACE_TRACE ("ACE_RW_Token::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "ACE_RW_Token::dump:\n" + "num_writers_ = %d\n", num_writers_)); + ACE_DEBUG ((LM_DEBUG, "lock_\n")); + this->lock_.dump (); + ACE_DEBUG ((LM_DEBUG, "base:\n")); + ACE_Tokens::dump (); + ACE_DEBUG ((LM_DEBUG, "ACE_RW_Token::dump end.\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_RW_Token::ACE_RW_Token (const char *name) +: num_writers_ (0) +{ + ACE_TRACE ("ACE_RW_Token::ACE_RW_Token"); + + int n = ACE_OS::strlen (name) + 1; // + 1 for \0 + + if (n > ACE_MAXTOKENNAMELEN) + n = ACE_MAXTOKENNAMELEN; + + ACE_OS::strncpy (this->token_name_, name, n); + this->token_name_[ACE_MAXTOKENNAMELEN - 1] = '\0'; +} + +ACE_RW_Token::~ACE_RW_Token (void) +{ + ACE_TRACE ("ACE_RW_Token::~ACE_RW_Token"); +} + +int +ACE_RW_Token::acquire (ACE_TPQ_Entry *caller, + int ignore_deadlock, + int notify) +{ + ACE_TRACE ("ACE_RW_Token::acquire"); + // We need to acquire two locks. This one to ensure that only one + // thread uses this token at a time. + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1); + // This one to ensure an atomic transaction across all tokens. Note + // that this order is crucial too. It's resource coloring for other + // threads which may be calling this same token. + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1); + + if (caller->proxy ()->type () == ACE_RW_Token::WRITER) + this->num_writers_++; + + // Does _anyone_ own the token? + if (this->owner () == 0) + { + // There are no waiters, so queue as the first waiter (the owner). + this->waiters_.enqueue (caller, -1); + return 0; + } + + // Check for recursive acquisition. + if (this->is_owner (caller->client_id ())) + { + caller->nesting_level (1); + return 0; // Success. + } + + // Reader. + if (caller->proxy ()->type () == ACE_RW_Token::READER) + { + // Are there any writers? + if (this->num_writers_ == 0) + { + // Queue the caller at the end of the queue. + this->waiters_.enqueue (caller, -1); + return 0; + } + // Else failure. + } + + // Failure code. + + // Check for deadlock. + if (!ignore_deadlock && + ACE_Token_Manager::instance ()->check_deadlock (caller->proxy ()) == 1) + { + if (caller->proxy ()->type () == ACE_RW_Token::WRITER) + this->num_writers_--; + errno = EDEADLK; + ACE_RETURN (-1); + } + + // Queue the caller at the end of the queue. + this->waiters_.enqueue (caller, -1); + + if (notify) + { + // If it's a writer, just notify it. + if (this->owner ()->proxy ()->type () == ACE_RW_Token::WRITER) + this->owner ()->call_sleep_hook (); + else + { + // Call back all reader owners. + ACE_TPQ_Entry *temp = this->owner (); + do + { + temp->call_sleep_hook (); + temp = temp->next_; + } + while (temp != 0 && + temp->proxy ()->type () == ACE_RW_Token::READER); + } + } + + errno = EWOULDBLOCK; + ACE_RETURN (-1); +} + + +int +ACE_RW_Token::tryacquire (ACE_TPQ_Entry *caller) +{ + ACE_TRACE ("ACE_RW_Token::tryacquire"); + // We need to acquire two locks. This one to ensure that only one + // thread uses this token at a time. + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1); + // This one to ensure an atomic transaction across all tokens. Note + // that this order is crucial too. It's resource coloring for other + // threads which may be calling this same token. + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1); + + if (caller->proxy ()->type () == ACE_RW_Token::WRITER) + { + this->num_writers_++; + } + + // Does _anyone_ own the token? + if (this->owner () == 0) + { + // There are no waiters, so queue as the first waiter (the owner). + this->waiters_.enqueue (caller, -1); + return 0; + } + + // Check for recursive acquisition. + if (this->is_owner (caller->client_id ())) + { + caller->nesting_level (1); + return 0; // Success. + } + + // Reader. + if (caller->proxy ()->type () == ACE_RW_Token::READER) + { + // Are there any writers? + if (this->num_writers_ == 0) + { + // queue the caller at the end of the queue. + this->waiters_.enqueue (caller, -1); + return 0; + } + // Else, fail. + } + else // Writer. + // We're going to fail, so decrement the num_writers. + { + this->num_writers_--; + } + + + errno = EWOULDBLOCK; + ACE_RETURN (-1); +} + +int +ACE_RW_Token::renew (ACE_TPQ_Entry *caller, + int requeue_position) +{ + ACE_TRACE ("ACE_RW_Token::renew"); + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1); + + // Werify that the caller is the owner + if (this->is_owner (caller->client_id ()) == 0) + { + errno = EACCES; + ACE_RETURN (-1); + } + + // The caller is the owner, so check to see if there are any + // waiters. If not, we just keep the token. + if (this->waiters_.size () == 1 || requeue_position == 0) + return 0; + + // There are waiters, so remove the caller. + this->remove (caller); + + // Requeue the caller. + this->waiters_.enqueue (caller, requeue_position); + + if (caller->proxy ()->type () == ACE_RW_Token::READER) + { + // If the caller got queued before any writers, the caller is + // still the owner. + if (this->is_owner (caller->client_id ())) + return 0; // success + // else fallthrough and return would block. + } + // Writers will always have to block since waiters_.size () == 1 or + // requeue_position == 0. + + // Get a new owner. + this->notify_new_owner (caller); + + // Tell the caller that the operation would block. + errno = EWOULDBLOCK; + ACE_RETURN (-1); +} + +int +ACE_RW_Token::release (ACE_TPQ_Entry *caller) +{ + ACE_TRACE ("ACE_RW_Token::release"); + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1); + + // Check for errors. + if ((this->owner () == 0) || + (this->is_owner (caller->client_id ()) == 0)) + { + errno = EACCES; + ACE_RETURN (-1); + } + + if (caller->proxy ()->type () == ACE_RW_Token::WRITER) + num_writers_--; + + // Recursive release. + if (caller->nesting_level () > 0) + { + caller->nesting_level (-1); + return 0; + } + + // Remove the caller and notify the new owner(s). + this->remove (caller); + this->notify_new_owner (caller); + + return 0; +} + +void +ACE_RW_Token::notify_new_owner (ACE_TPQ_Entry *old_owner) +{ + ACE_TRACE ("ACE_RW_Token::new_owner"); + + if (this->owner () == 0) + return; + + if (this->owner ()->proxy ()->type () == ACE_RW_Token::READER) + { + if (old_owner->proxy ()->type () == ACE_RW_Token::READER) + // the owners already know that they're owners + return; + + // The current owner is a reader and the previous owner was a + // writer, so notify all waiting readers up to the first writer. + // call back all reader owners. + ACE_TPQ_Iterator iterator (waiters_); + for (ACE_TPQ_Entry *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + if (temp->proxy ()->type () == WRITER) + // We've gone through all the readers. + break; + + temp->proxy ()->token_acquired (temp); + } + } + else // writer + this->owner ()->proxy ()->token_acquired (this->owner ()); +} + + +int +ACE_RW_Token::owners (OWNER_STACK &stack, + const char *id) +{ + ACE_TRACE ("ACE_RW_Token::owners"); + + if (this->owner () == 0) + return 0; + + int id_is_owner = 0; + + // The first waiter is a writer, so there is only one owner. + if (this->owner ()->proxy ()->type () == WRITER) + { + stack.push (this->owner ()); + // If an is specified, return whether it is the owner being + // returned. + if ((id != 0) && + (ACE_OS::strcmp (id, this->owner ()->client_id ()) == 0)) + id_is_owner = 1; + } + // The first waiter is a reader, so there can be multiple owning + // readers. + else + { + ACE_TPQ_Iterator iterator (waiters_); + for (ACE_TPQ_Entry *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + if (temp->proxy ()->type () == WRITER) + // We've gone through all the readers. + break; + + stack.push (temp); + + if (!id_is_owner && (id != 0) && + (ACE_OS::strcmp (id, temp->client_id ()) == 0)) + id_is_owner = 1; + } + } + + return id_is_owner; +} + +int +ACE_RW_Token::is_waiting_for (const char *id) +{ + ACE_TRACE ("ACE_RW_Token::is_waiting_for"); + // If there is no owner, or is the owner, return false. + if ((this->owner () == 0) || + this->is_owner (id)) + return 0; + + // Step through each waiter looking for . + ACE_TPQ_Iterator iterator (waiters_); + iterator.advance (); + for (ACE_TPQ_Entry *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + if (temp->equal_client_id (id)) + return 1; + } + + return 0; +} + +int +ACE_RW_Token::is_owner (const char *id) +{ + ACE_TRACE ("ACE_Mutex_Token::is_owner"); + // If there is no owner, return false. + if (this->owner () == 0) + return 0; + + // A writer owns us. + if (this->owner ()->proxy ()->type () == ACE_RW_Token::WRITER) + return this->owner ()->equal_client_id (id); + + // Readers own us. + // Step through each owning reader looking for . + ACE_TPQ_Iterator iterator (waiters_); + for (ACE_TPQ_Entry *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + if (temp->proxy ()->type () != ACE_RW_Token::READER) + break; + + if (temp->equal_client_id (id)) + return 1; + } + + return 0; +} + +// ************************************************************ +// ************************************************************ +// ************************************************************ +// 7.. + +void +ACE_Token_Proxy::dump (void) const +{ + ACE_TRACE ("ACE_Token_Proxy::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "ACE_Token_Proxy::dump:\n" + " type = %d\n" + " ignore_deadlock_ = %d\n" + " debug_ = %d\n", + (int) this->type (), ignore_deadlock_, debug_)); + ACE_DEBUG ((LM_DEBUG, "mutex_, and waiter_\n")); + + if (this->token_ != 0) + this->token_->dump (); + + this->waiter_.dump (); + ACE_DEBUG ((LM_DEBUG, "ACE_Token_Proxy::dump end.\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +const char* +ACE_Token_Proxy::client_id (void) const +{ + ACE_TRACE ("ACE_Token_Proxy::client_id"); + // Thread-specific. + const char *id = this->waiter_->client_id (); + + if (id == 0) + return "ERROR NO CLIENT ID"; + else + return id; +} + +void +ACE_Token_Proxy::client_id (const char *client_id) +{ + ACE_TRACE ("ACE_Token_Proxy::client_id"); + this->waiter_->client_id (client_id); +} + +const char * +ACE_Token_Proxy::owner_id (void) +{ + ACE_TRACE ("ACE_Token_Proxy::owner_id"); + return this->token_->owner_id (); +} + +const char * +ACE_Token_Proxy::name (void) const +{ + ACE_TRACE ("ACE_Token_Proxy::owner_id"); + return this->token_->name (); +} + +ACE_Token_Proxy::ACE_Token_Proxy (void) +: token_ (0), + waiter_ (this, 0) +{ + ACE_TRACE ("ACE_Token_Proxy::ACE_Token_Proxy"); +} + +// Notice the token_ (0). Do *not* copy the token pointer. This must +// be obtained through the token manager. Also, we don't copy any +// waiter info. A copied Proxy does *not* inherit client_id. +ACE_Token_Proxy::ACE_Token_Proxy (const ACE_Token_Proxy &p) +: token_ (0), + waiter_ (this, 0) +{ + ACE_TRACE ("ACE_Token_Proxy::ACE_Token_Proxy"); +} + +// @@ should I do a mutex_->release ()? +ACE_Token_Proxy::~ACE_Token_Proxy (void) +{ + ACE_TRACE ("ACE_Local_Mutex::~ACE_Local_Mutex"); + + if (token_ != 0) + // notify token manager that we are done with it so it can + // free it if necessary + ACE_Token_Manager::instance ()->release_token (token_); +} + +int +ACE_Token_Proxy::open (const char *token_name, + int ignore_deadlock, + int debug) +{ + ACE_TRACE ("ACE_Token_Proxy::open"); + + // Store some parameters. + this->ignore_deadlock_ = ignore_deadlock; + this->debug_ = debug; + + // Used in case a name was not specified. + char name[BUFSIZ]; + + // We must have a name. + if (token_name == 0) + { + ACE_OS::sprintf (name, "token %d", this); + token_name = name; + } + + // Get or create the underlying token. The Token Manager will call + // us back to set token_. + ACE_Token_Manager::instance ()->get_token (this, token_name); + + // Check for failed get or failed new. + if (this->token_ == 0) + { + errno = ENOMEM; + ACE_ERROR_RETURN ((LM_ERROR, "Can't allocate mutex"), -1); + } + + return 0; +} + +int +ACE_Token_Proxy::acquire (int notify, + void (*sleep_hook)(void *), + ACE_Synch_Options &options) +{ + ACE_TRACE ("ACE_Token_Proxy::acquire"); + if (this->token_ == 0) + { + errno = ENOENT; + ACE_ERROR_RETURN ((LM_ERROR, "Not open.\n"), -1); + } + + // Make sure no one calls our token_acquired until we have a chance + // to sleep first! If after we call an EWOULDBLOCK + // mutex_->acquire() below, but before we enter handle_options to + // wait on the cond_var, a thread tries to give take us off the + // waiter queue and signal us, IT WILL FIRST HAVE TO ACQUIRE THIS + // cond_var.mutex (). _This_ is why we acquire it. + this->waiter_->cond_var_.mutex ().acquire (); + + this->waiter_->sleep_hook (sleep_hook); + + if (this->token_->acquire (this->waiter_, this->ignore_deadlock_, notify) == -1) + // acquire failed + { + switch (errno) + { + case EDEADLK : + if (!ignore_deadlock_) + { + waiter_->cond_var_.mutex ().release (); + errno = EDEADLK; + ACE_RETURN (-1); + } + // Else, fallthrough and block! + + case EWOULDBLOCK : + if (this->debug_) + ACE_DEBUG ((LM_DEBUG, + "(%t) waiting for %s, owner is %s, " + "total waiters == %d\n", + this->name (), + this->token_->owner_id (), + token_->no_of_waiters ())); + + // no error, but would block, + // if error, return error (-1), otherwise, return whether we + // called the holder or not. + int return_value; + if (this->handle_options (options, waiter_->cond_var_) == -1) + return_value = -1; + else + return_value = notify == 1; + + errno = EWOULDBLOCK; + ACE_RETURN (return_value); + + default : + waiter_->cond_var_.mutex ().release (); + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n","Token Proxy acquire."), -1); + } + } + else + // we have the token + { + if (debug_) + ACE_DEBUG ((LM_DEBUG, "(%t) acquired %s\n", + this->name ())); + waiter_->cond_var_.mutex ().release (); + } + + return 0; +} + +int +ACE_Token_Proxy::tryacquire (void (*sleep_hook)(void *)) +{ + ACE_TRACE ("ACE_Token_Proxy::tryacquire"); + if (this->token_ == 0) + { + errno = ENOENT; + ACE_ERROR_RETURN ((LM_ERROR, "Not open.\n"), -1); + } + + this->waiter_->sleep_hook (sleep_hook); + + return this->token_->tryacquire (waiter_); +} + +int +ACE_Token_Proxy::renew (int requeue_position, + ACE_Synch_Options &options) +{ + ACE_TRACE ("ACE_Token_Proxy::renew"); + if (this->token_ == 0) + { + errno = ENOENT; + ACE_ERROR_RETURN ((LM_ERROR, "Not open.\n"), -1); + } + + // Make sure no one calls our token_acquired until we have a chance + // to sleep first! + this->waiter_->cond_var_.mutex ().acquire (); + + if (this->token_->renew (this->waiter_, requeue_position) == -1) + { + // check for error + if (errno != EWOULDBLOCK) + ACE_ERROR_RETURN ((LM_ERROR, + "%p renew failed\n", "ACE_Token_Proxy"), -1); + + if (this->debug_) + ACE_DEBUG ((LM_DEBUG, "(%t) renew blocking for %s, owner is %s\n", + this->name (), + token_->owner_id ())); + + // no error, but would block, so block or return + return this->handle_options (options, waiter_->cond_var_); + } + else + // we have the token + { + if (this->debug_) + ACE_DEBUG ((LM_DEBUG, "(%t) renewed %s\n", + this->name ())); + waiter_->cond_var_.mutex ().release (); + return 0; + } +} + +int +ACE_Token_Proxy::handle_options (ACE_Synch_Options &options, + ACE_TOKEN_CONST::COND_VAR &cv) +{ + // Some operation failed with EWOULDBLOCK. + ACE_TRACE ("ACE_Token_Proxy::handle_options"); + + if (options[ACE_Synch_Options::USE_REACTOR] == 1) + // Asynchronous. + { + int error = errno; + // if (options[ACE_Synch_Options::USE_TIMEOUT] == 1) + // ACE_ERROR_RETURN ((LM_ERROR, "Timeouts not yet supported" " + // with asynchronous operations."), -1); + cv.mutex ().release (); + errno = error; + ACE_RETURN (-1); + } + else + // Synchronous. + { + // Block on condition variable. + while (cv.wait ((ACE_Time_Value *) options.time_value ()) == -1) + { + // Note, this should obey whatever thread-specific + // interrupt policy is currently in place... + if (errno == EINTR) + continue; + // We come here if a timeout occurs or some serious + // ACE_Condition object error. + cv.mutex ().release (); + ACE_ERROR_RETURN ((LM_ERROR, "condition variable wait" + " bombed."), -1); + } + + if (this->debug_) + ACE_DEBUG ((LM_DEBUG, "(%t) unblocking.\n", + this->client_id ())); + cv.mutex ().release (); + return 0; // operation succeeded + } +} + +int +ACE_Token_Proxy::release (ACE_Synch_Options &options) +{ + ACE_TRACE ("ACE_Token_Proxy::release"); + if (this->token_ == 0) + { + errno = ENOENT; + if (debug_) + ACE_DEBUG ((LM_DEBUG, "Must open before releasing.\n")); + ACE_RETURN (-1); + } + + if (this->token_->release (waiter_) != 0) + { + // Release failed. + this->token_->remove (this->waiter_); + if (debug_) + ACE_DEBUG ((LM_DEBUG, "(%t) %p.\n", "release failed")); + return -1; + } + else + { + if (this->debug_) + ACE_DEBUG ((LM_DEBUG, "(%t) released %s, owner is %s\n", + this->name (), + token_->owner_id ())); + + return 0; + } +} + +int +ACE_Token_Proxy::remove (ACE_Synch_Options &) +{ + ACE_TRACE ("ACE_Token_Proxy::remove"); + return 0; +} + +void +ACE_Token_Proxy::sleep_hook (void) +{ + ACE_TRACE ("ACE_Token_Proxy::sleep_hook"); + // Somebody wants our token! (Let'em wait...) + return; +} + +void +ACE_Token_Proxy::token_acquired (ACE_TPQ_Entry *e) +{ + ACE_TRACE ("ACE_Token_Proxy::token_acquired"); + e->cond_var_.mutex ().acquire (); + // We've been taken off the waiters list and given the token! + // This implementation signals the internal condition + // variable. Thus, if asynchronous acquires are used, this must be + // overriden to do something more useful! + e->cond_var_.signal (); + e->cond_var_.mutex ().release (); + + return; +} + +// ************************************************************ + +ACE_Token_Name::ACE_Token_Name (const char *token_name) +{ + ACE_TRACE ("ACE_Token_Name::ACE_Token_Name"); + this->name (token_name); +} + +ACE_Token_Name::ACE_Token_Name (const ACE_Token_Name &rhs) +{ + ACE_TRACE ("ACE_Token_Name::ACE_Token_Name"); + this->name (rhs.name ()); +} + +ACE_Token_Name::~ACE_Token_Name () +{ + ACE_TRACE ("ACE_Token_Name::~ACE_Token_Name"); +} + +void +ACE_Token_Name::dump (void) const +{ + ACE_TRACE ("ACE_Token_Name::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "ACE_Token_Name::dump:\n" + " token_name_ = %s\n", + token_name_ == 0 ? "no name" : token_name_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +#if !defined (ACE_NO_TSS_TOKENS) +template class ACE_TSS ; +#endif /* ACE_NO_TSS_TOKENS */ +template class ACE_Unbounded_Stack ; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/ace/Local_Tokens.h b/ace/Local_Tokens.h new file mode 100644 index 00000000000..6d5786f2658 --- /dev/null +++ b/ace/Local_Tokens.h @@ -0,0 +1,974 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Local_Tokens +// +// = AUTHOR +// Karl-Heinz Dorn (kdorn@erlh.siemens.de) +// Douglas C. Schmidt (schmidt@cs.wustl.edu) +// Tim Harrison (harrison@cs.wustl.edu) +// +// = DESCRIPTION +// This file contains definitions for the following classes: +// +// public: +// 7. ACE_Token_Proxy +// 8. ACE_Null_Token : public ACE_Token_Proxy +// 9. ACE_Local_Mutex : public ACE_Token_Proxy +// *. ACE_Local_RLock : public ACE_Local_Mutex +// &. ACE_Local_WLock : public ACE_Local_Mutex +// private: +// 1. ACE_TOKEN_CONST +// 3. ACE_TPQ_Entry +// b. ACE_TSS_TPQ_Entry +// c. ACE_TPQ_Iterator +// 4. ACE_Token_Proxy_Queue +// 5. ACE_Tokens +// 6. ACE_Mutex_Token : public ACE_Tokens +// 12. ACE_RW_Token : public ACE_Tokens +// a. ACE_Token_Name +// +// ============================================================================ + +#if !defined (ACE_LOCAL_MUTEX_H) +#define ACE_LOCAL_MUTEX_H + +#include "ace/Synch.h" +#include "ace/Stack.h" +#include "ace/Synch_Options.h" +#include "ace/Map_Manager.h" + +// 1. +class ACE_Export ACE_TOKEN_CONST +{ + // = TITLE + // Not a public interface. + // + // = DESCRIPTION + // Constant definitions and typdefs for Token library. Mostly, + // this class is necessary to fight the compiler with order of + // declaration errors. +public: +#if defined (ACE_MT_SAFE) + // ACE platform supports some form of threading. + typedef ACE_Condition_Thread_Mutex COND_VAR; + typedef ACE_Thread_Mutex MUTEX; + typedef ACE_Thread_Mutex_Guard GUARD; +#else + typedef ACE_Null_Condition_Mutex COND_VAR; + typedef ACE_Null_Mutex MUTEX; + typedef ACE_Null_Mutex_Guard GUARD; +#endif /* ACE_HAS_THREADS */ +}; + +class ACE_Token_Proxy; + +// 3.. +class ACE_Export ACE_TPQ_Entry + // = TITLE + // Not a public interface. + // + // = DESCRIPTION + // Token Proxy Queue entry. + // Used in the ACE_Token_Proxy_Queue +{ +friend class ACE_Token_Manager; +public: + typedef void (*PTVF) (void *); + + ACE_TPQ_Entry (void); + // Null constructor. + + ACE_TPQ_Entry (const ACE_Token_Proxy *proxy, + const char *client_id); + // Construction. + + ACE_TPQ_Entry (const ACE_TPQ_Entry &rhs); + // Copy constructor. + + ~ACE_TPQ_Entry (void); + // Death. + + void operator= (const ACE_TPQ_Entry &rhs); + // Copy operator use by the queue. + + // = Set/get top of the queue. + ACE_Token_Proxy *proxy (void) const; + void proxy (ACE_Token_Proxy *); + + // = Delta/get nesting level of the entry. + int nesting_level (void) const; + void nesting_level (int delta); + + // = Set/get client_id of the entry. + const char *client_id (void) const; + void client_id (const char *); + + int equal_client_id (const char *id); + // Returns 1 if == client id. Does not check for == 0. + + void set (void (*sleep_hook)(void *)); + // One method for arg and sleep_hook. + + // = Set/get sleep hook of the entry. + void sleep_hook (void (*sh)(void *)); + PTVF sleep_hook (void) const; + + void call_sleep_hook (void); + // Call the sleep hook function or method passing arg. + + ACE_TPQ_Entry *next_; + // Pointer to next in list. + + void dump (void) const; + // Dump the state of the class. + + // = Used to block the thread if an acquire fails with EWOULDBLOCK. + ACE_TOKEN_CONST::MUTEX lock_; + ACE_TOKEN_CONST::COND_VAR cond_var_; + + // = Get/set whether this client is blocked waiting for a token. + int waiting (void) const; + void waiting (int w); + +private: + + int waiting_; + // This client is waiting for a token. + + ACE_Token_Proxy *proxy_; + // Proxy. + + int nesting_level_; + // Nesting level. + + void *arg_; + // Arg. + + char client_id_[ACE_MAXCLIENTIDLEN]; + // Client id. + + void (*sleep_hook_)(void *); + // Sleep hook. +}; + +// ************************************************************ + +// b.. +#if defined (ACE_NO_TSS_TOKENS) +typedef ACE_TPQ_Entry ACE_TPQ_ENTRY; +#else +typedef ACE_TSS ACE_TPQ_ENTRY; +#endif /* ACE_NO_TSS_TOKENS */ + +class ACE_Export ACE_TSS_TPQ_Entry : public ACE_TPQ_ENTRY + // = TITLE + // Not a public interface. + // = DESCRIPTION + // ACE_TSS_TPQ_Entry +{ +public: + ACE_TSS_TPQ_Entry (const ACE_Token_Proxy *proxy, + const char *client_id); + // These are passed to the constructor of ACE_TPQ_Entry in + // make_TSS_TYPE + + virtual ACE_TPQ_Entry *make_TSS_TYPE (void) const; + // Allows us to pass args to the construction of the TSS object. + + operator ACE_TPQ_Entry *(void); + // Operator overloading and inheritence don't mix. + + void dump (void) const; + // Dump the state of the class. + +#if defined (ACE_NO_TSS_TOKENS) + ACE_TSS_TPQ_Entry *operator-> (void) + { + return this; + } +#endif + +private: + // = These are passed to the constructor of ACE_TPQ_Entry in + // make_TSS_TYPE + const ACE_Token_Proxy *proxy_; + // Proxy. + const char *client_id_; + // Client_id. +}; + +// ************************************************************ + +class ACE_Token_Proxy_Queue; + +// c.. +class ACE_Export ACE_TPQ_Iterator + // = TITLE + // Not a public interface. + // + // = DESCRIPTION + // Iterates through ACE_Token_Proxy_Queues. +{ +public: + ACE_TPQ_Iterator (ACE_Token_Proxy_Queue &q); + // Construction. + + int next (ACE_TPQ_Entry *&next_item); + // Pass back the . Returns 0 when all items have been + // seen, else 1. + + void advance (void); + // Move forward by one element in the queue. + + void dump (void) const; + // Dump the state of an object. + +private: + ACE_TPQ_Entry *current_; +}; + +// 4.. +class ACE_Export ACE_Token_Proxy_Queue + // = TITLE + // Not a public interface. + // + // = DESCRIPTION + // Token waiter list. + // This queue holds all the token proxies waiting for ownership of + // a token. Along with the proxy reference, it also stores the + // nesting level, client id, and a magic cookie from the proxy. + // This queue stores the ACE_TPQ_Entries by pointer values. It + // DOES NOT make copies. Thus, the user is responsible to ensure + // that the TPQ's stick around. This is motivated by the need to + // reduce dynamic memory allocation. +{ + friend class ACE_TPQ_Iterator; +public: + ACE_Token_Proxy_Queue (void); + // Construction. + + void enqueue (ACE_TPQ_Entry* new_entry, + int position); + // Enqueue a proxy, nesting level, client_id, and a magic cookie at + // the given position in the list. If the position is -1, we + // enqueue at the end of the list (I think). + + const ACE_TPQ_Entry* head (void); + // Top of the queue. + +// int member (const char *id); + // Is this id in the waiter list? + + void dequeue (void); + // Remove the top waiter. + + void remove (const ACE_TPQ_Entry *remove_me); + // Remove the waiter whose proxy ref matches remove_me. + + int size (void); + // The number of waiters. + + void dump (void) const; + // Dump the state of the class. + +protected: + ACE_TPQ_Entry *head_; + // Head. + ACE_TPQ_Entry *tail_; + // Tail. + int size_; + // Size. +}; + +// 5.. +class ACE_Export ACE_Tokens + // = TITLE + // Not a public interface. + // + // = DESCRIPTION + // Abstract representation of ACE tokens. + // Currently, I don't see a reason for providing an abstract + // interface at this level of the library. As of yet, no one uses + // ACE_Tokens derivatives through this abstract interface except + // for Token_Manager. It only uses the statistical methods which + // are shared by all Tokens. For that reason, it still makes + // since to have a common base class. However, acquire, renew, + // and release do not need to have matching interfaces throughout + // all Tokens. + + // = EXTENDING TOKENS + // To add a new type of token (e.g. semaphore), this class must be + // subtyped to define the new semantics. See ACE_Token_Manager + // for details. +{ +public: + + ACE_Tokens (void); + // Null constructor. + + virtual int acquire (ACE_TPQ_Entry *caller, + int ignore_deadlock, + int notify) = 0; + // No implementation. + + virtual int tryacquire (ACE_TPQ_Entry *caller) = 0; + // No implementation. + + virtual int renew (ACE_TPQ_Entry *caller, + int requeue_position) = 0; + // No implementation. + + virtual int release (ACE_TPQ_Entry *caller) = 0; + // No implementation. + + void make_owner (ACE_TPQ_Entry *caller); + // Move the caller to the front of the waiter list. This is for use + // with remote mutexes and shadow mutexes. + + void remove (ACE_TPQ_Entry *caller); + // Remove the caller from the waiter list. + + // = Accessor methods. + + typedef ACE_Unbounded_Stack + OWNER_STACK; + // Stack of owners. + + virtual int owners (OWNER_STACK &o, const char *id) = 0; + // Returns a stack of the current owners. Returns -1 on error, 0 on + // success. If is non-zero, returns 1 if id is an owner. + + virtual int is_waiting_for (const char *id) = 0; + // Returns 1 if is waiting for this token. 0 otherwise. + + virtual int is_owner (const char *id) = 0; + // Returns 1 if is an owner of this token. 0 otherwise. + + virtual ACE_Token_Proxy_Queue *waiters (void); + // Return the queue of waiters. + + virtual int no_of_waiters (void); + // Return the number of proxies that are currently waiting to get + // the token. + + const char *owner_id (void); + // The current owner. + + const char* name (void); + // Token name. + + // = Reference counting. These are only called by the + // Token_Manager. + void inc_reference (void); + int dec_reference (void); + + void dump (void) const; + // Dump the state of the class. + + enum TOKEN_TYPES { MUTEX, RWLOCK }; + // These are the Token types supported by the library at ship time. + // There is no restriction on the number of Token types added by + // "3rd parties." These are only necessary for the Token Server. + + virtual int type (void) const = 0; + // Provides a manual RTTI mechanism. This method is used only by + // ACE_Token_Request so that the type of a token can be sent to a + // remote Token Server. + + // = The following methods allow the deadlock detection algorithm to + // check if this token has been visited. + + void visit (int v); + // Mark or unmark the token as visited. + + int visited (void); + // Check if the token has been visited. + + ACE_TPQ_Entry *owner (void); + // All the data of the current owner. + +protected: + + int visited_; + // For the deadlock detection algorithm. + + int reference_count_; + // Reference count. + + ACE_Token_Proxy_Queue waiters_; + // List of client's owning and waiting the token. + + char token_name_[ACE_MAXTOKENNAMELEN]; + // Name of token. +}; + +class ACE_Local_Mutex; + +// 6.. +class ACE_Export ACE_Mutex_Token : public ACE_Tokens + // = TITLE + // Not a public interface. + // + // = DESCRIPTION + // Class that acquires, renews, and releases a process-local + // synchronization token. + // This class is a more general-purpose synchronization mechanism + // than SunOS 5.x mutexes. For example, it implements "recursive + // mutex" semantics, where a thread that owns the token can + // reacquire it without deadlocking. In addition, threads that are + // blocked awaiting the token are serviced in strict FIFO order as + // other threads release the token (SunOS 5.x mutexes don't strictly + // enforce an acquisition order). +{ +public: + ACE_Mutex_Token (const char* name); + // life + + ~ACE_Mutex_Token (void); + // death + + // = Synchronization operations. + // With acquire, renew, and release, the caller must be specified so + // that multiple proxies (e.g. ACE_Local_Mutex) can use the same + // token. + + virtual int acquire (ACE_TPQ_Entry *caller, + int ignore_deadlock, + int notify); + // Returns 0 on success, -1 on failure with ACE_LOG_MSG->errnum() as + // the reason. If errnum == EWOULDBLOCK, and notify == 1, + // ACE_Token_Proxy::sleep_hook() has been called on the current owner + // of the token. If ignore_deadlock is passed as 1 and errnum == + // EDEADLK, then deadlock was detected via ace_token_manager. + + virtual int tryacquire (ACE_TPQ_Entry *caller); + // same as acquire, but fails if would block + + virtual int renew (ACE_TPQ_Entry *caller, + int requeue_position); + // An optimized method that efficiently reacquires the token if no + // other threads are waiting. This is useful for situations where + // you don't want to degrade the quality of service if there are + // other threads waiting to get the token. If == + // -1 and there are other threads waiting to obtain the token we are + // queued at the end of the list of waiters. If + // > -1 then it indicates how many entries to skip over before + // inserting our thread into the list of waiters (e.g., + // == 0 means "insert at front of the queue"). + // Renew has the rather odd semantics such that if there are other + // waiting threads it will give up the token even if the + // nesting_level_ > 1. I'm not sure if this is really the right + // thing to do (since it makes it possible for shared data to be + // changed unexpectedly) so use with caution... + // Returns 0 on success, -1 on failure with ACE_LOG_MSG->errnum() as + // the reason. If errnum == EWOULDBLOCK, and notify == 1, + // ACE_Token_Proxy::sleep_hook() has been called on the current owner + // of the token. + + virtual int release (ACE_TPQ_Entry *caller); + // Relinquish the token. If there are any waiters then the next one + // in line gets it. If the caller is not the owner, caller is + // removed from the waiter list. + + void dump (void) const; + // Dump the state of the class. + + virtual int type (void) const; + // Returns ACE_Tokens::MUTEX. + + virtual int owners (OWNER_STACK &o, const char *id); + // Returns a stack of the current owners. Returns -1 on error, 0 on + // success. If is non-zero, returns 1 if id is an owner. + + virtual int is_waiting_for (const char *id); + // Returns 1 if is waiting for this token. 0 otherwise. + + virtual int is_owner (const char *id); + // Returns 1 if is an owner of this token. 0 otherwise. + +private: + ACE_TOKEN_CONST::MUTEX lock_; + // ACE_Mutex_Token used to lock internal data structures. +}; + +// 12.. +class ACE_Export ACE_RW_Token : public ACE_Tokens + // = TITLE + // Not a public interface. + // + // = DESCRIPTION + // Class that acquires, renews, and releases a process-local + // synchronization token. + // This class is a more general-purpose synchronization mechanism + // than SunOS 5.x mutexes. For example, it implements "recursive + // mutex" semantics, where a thread that owns the token can + // reacquire it without deadlocking. In addition, threads that are + // blocked awaiting the token are serviced in strict FIFO order as + // other threads release the token (SunOS 5.x mutexes don't strictly + // enforce an acquisition order). +{ +public: + ACE_RW_Token (const char* name); + // Life. + + ~ACE_RW_Token (void); + // Death. + + // = Synchronization operations. + // With acquire, renew, and release, the caller must be specified so + // that multiple proxies (e.g. ACE_Local_Mutex) can use the same + // token. + + virtual int acquire (ACE_TPQ_Entry *caller, + int ignore_deadlock, + int notify); + // Returns 0 on success, -1 on failure with ACE_LOG_MSG->errnum() as + // the reason. If errnum == EWOULDBLOCK, and notify == 1, + // ACE_Token_Proxy::sleep_hook() has been called on the current owner + // of the token. If ignore_deadlock is passed as 1 and errnum == + // EDEADLK, then deadlock was detected via ace_token_manager. + + virtual int tryacquire (ACE_TPQ_Entry *caller); + // same as acquire except fails on would block + + virtual int renew (ACE_TPQ_Entry *caller, + int requeue_position); + // An optimized method that efficiently reacquires the token if no + // other threads are waiting. This is useful for situations where + // you don't want to degrade the quality of service if there are + // other threads waiting to get the token. If == + // -1 and there are other threads waiting to obtain the token we are + // queued at the end of the list of waiters. If + // > -1 then it indicates how many entries to skip over before + // inserting our thread into the list of waiters (e.g., + // == 0 means "insert at front of the queue"). + // Renew has the rather odd semantics such that if there are other + // waiting threads it will give up the token even if the + // nesting_level_ > 1. I'm not sure if this is really the right + // thing to do (since it makes it possible for shared data to be + // changed unexpectedly) so use with caution... + // Returns 0 on success, -1 on failure with ACE_LOG_MSG->errnum() as + // the reason. If errnum == EWOULDBLOCK, and notify == 1, + // ACE_Token_Proxy::sleep_hook() has been called on the current owner + // of the token. + + virtual int release (ACE_TPQ_Entry *caller); + // Relinquish the token. If there are any waiters then the next one + // in line gets it. If the caller is not the owner, caller is + // removed from the waiter list. + + void dump (void) const; + // Dump the state of the class. + + enum PROXY_TYPE { READER, WRITER }; + // These are the types that proxies can be. + + virtual int type (void) const; + // Returns READER or WRITER. + + virtual int owners (OWNER_STACK &o, const char *id); + // Returns a stack of the current owners. Returns -1 on error, 0 on + // success. If is non-zero, returns 1 if id is an owner. + + virtual int is_waiting_for (const char *id); + // Returns 1 if is waiting for this token. 0 otherwise. + + virtual int is_owner (const char *id); + // Returns 1 if is an owner of this token. 0 otherwise. + +protected: + int num_writers_; + // the number of waiting writers. + + ACE_TOKEN_CONST::MUTEX lock_; + // ACE_Mutex_Token used to lock internal data structures. + + void notify_new_owner (ACE_TPQ_Entry *caller); + // Sets the new owner. +}; + +// a.. +class ACE_Token_Name + // = TITLE + // Allows Token_Manger to identify tokens. + // + // = DESCRIPTION + // For now, this is just a string. We need a string class anyway + // to use in ACE_Map_Manager. Having this class (instead of + // SString) allows us to easily change if needed. For instance, + // we may choose to identify tokens by name and *type* in the + // future. +{ +public: + ACE_Token_Name (const char *token_name = 0); + // Construction. + + ACE_Token_Name (const ACE_Token_Name &rhs); + // Copy construction. + + ~ACE_Token_Name (void); + // Death. + + void operator= (const ACE_Token_Name &rhs); + // Copy. + + int operator== (const ACE_Token_Name &rhs) const; + // Comparison. + + const char *name (void) const; + // Token name. + + void name (const char *new_name); + // Token name. + + void dump (void) const; + // Dump the state of the class. + +private: + char token_name_[ACE_MAXTOKENNAMELEN]; + // Name of the token. +}; + + +// 7.. +class ACE_Export ACE_Token_Proxy + // = TITLE + // Abstract representation of ACE tokens. + // + // = DESCRIPTION + // Interface for all Tokens in ACE. This class implements the + // synchronization needed for tokens (condition variables etc.) + // The algorithms for the operations (acquire, release, etc.) + // operate on the generic ACE_Tokens interface. Thus, the _type_ + // of token (mutex, rwlock) can be set at construction of + // ACE_Token_Proxy. You can use all Tokens in ACE through the + // ACE_Token_Proxy by passing the proper values at construction. + // Alternatively, there are class definitions which "know" how to + // do this (ACE_Local_Mutex, ACE_Local_RLock, ACE_Local_WLock). + + // = EXTENDING TOKENS + // To add a new type of token (e.g. semaphore), this class is not + // changed. See ACE_Token_Manager for details. + + // = RESTRICTIONS + // Tokens (e.g. ACE_Mutex_Token) assume that it can always call + // ACE_Token_Proxy::token_acquired () on a new token owner. This + // is not a problem for synchronous use of token proxies (that is, + // when acquires block until successful.) However, for + // implementations of the Token Server, which may use asynch + // operations, the proxy can not go away after an acquire until + // the token is acquired. This is not really a problem, but + // should be understood. +{ +friend class ACE_Token_Manager; +friend class ACE_Token_Invariant_Manager; // For testing. +public: + + // Initialization and termination methods. + ACE_Token_Proxy (void); + // Construction. + + ~ACE_Token_Proxy (void); + // Death. + + virtual int open (const char *name, + int ignore_deadlock = 0, + int debug = 0); + // is the string uniquely identifying the token. + // can be 1 to disable deadlock notifications. + // prints debug messages. + + // = The following methods have implementations which are + // independent of the token semantics (mutex, rwlock, etc.) They + // forward operations to the underlying token and perform the + // necessary blocking semantics for operations (condition variables + // etc.) This allows reuse of the blocking code as well as having + // multiple proxies to the same token. + + virtual int acquire (int notify = 0, + void (*sleep_hook)(void *) = 0, + ACE_Synch_Options &options = + ACE_Synch_Options::defaults); + // Calls acquire on the token. Blocks the calling thread if would + // block. + + virtual int renew (int requeue_position = -1, + ACE_Synch_Options &options = + ACE_Synch_Options::defaults); + // Calls renew on the token. Blocks the calling thread if would + // block. + + virtual int tryacquire (void (*sleep_hook)(void *) = 0); + // Calls renew on the token. + + virtual int release (ACE_Synch_Options &options = + ACE_Synch_Options::defaults); + // Calls release on the token. + + virtual int remove (ACE_Synch_Options &options = + ACE_Synch_Options::defaults); + // Calls remove on the token. + + // = Utility methods. + + virtual const char *client_id (void) const; + // Get the client id of the proxy. This is implemented as + // thread-specific data. + + virtual void client_id (const char *client_id); + // Set the client_id for the calling thread. I strongly recommend + // that this not be used unless you really know what you're doing. + // I use this in the Token Server, and it caused many headaches. + + virtual const char *name (void) const; + // Return the name of the token. This is important for use within + // the token servers (local and remote) as well as with token + // collections. So, all derivations of ACE_Token_Proxy must be able to + // stringify some name. The name must uniquely identify a token. + // So, for instance, the token within the reactor should probably be + // called "Reactor Token." + + virtual void sleep_hook (void); + // This should really be called someone_waiting (). + // This is called by ACE_Token_xx's when another proxy enters the + // waiting list and requests that the current token holder be notified. + + virtual void token_acquired (ACE_TPQ_Entry *); + // This is called when a queued (waiting) proxy is removed from the + // waiters list and given the token. + + virtual const char *owner_id (void); + // the client id of the current token holder + + virtual ACE_Token_Proxy *clone (void) const = 0; + // Return a dynamically allocated clone of the derived class. + + void dump (void) const; + // Dump the state of the class. + + virtual int type (void) const; + // This method can be used be Tokens (e.g. Readers/Writer Tokens) to + // distinguish between Proxy types. For instance a Reader proxy + // should return a different type value than a Writer proxy. The + // default implementation returns 0. + +protected: + ACE_Token_Proxy (const ACE_Token_Proxy &); + // Duplication. + + int ignore_deadlock_; + // If this is set, we ignore deadlock. + + int debug_; + // Print a bunch of debug messages. + + ACE_Tokens *token_; + // Reference to the actual logical token. Many ACE_Local_Mutex + // proxies can reference the same ACE_Mutex_Token. + + int handle_options (ACE_Synch_Options &options, + ACE_TOKEN_CONST::COND_VAR &cv); + // Handles cond_var waits. + + ACE_TSS_TPQ_Entry waiter_; + // Waiter info used for asynchronous transactions. + + virtual ACE_Tokens *create_token (const char *name) = 0; + // Make the correct type of ACE_Tokens. This is called by the Token + // Manager. +}; + +// 8.. +class ACE_Export ACE_Null_Token : public ACE_Token_Proxy + // = TITLE + // No op class for nonthreaded platform protocols. +{ +public: + ACE_Null_Token (void) {}; + // Construction. + + virtual int acquire (int /* notify */ = 0, + void (* /* sleep_hook */ )(void *) = 0, + ACE_Synch_Options & /* options */ = + ACE_Synch_Options::defaults) { return 0; } + // Acquire. + + virtual int renew (int /* requeue_position */ = -1, + ACE_Synch_Options & /* options */ = + ACE_Synch_Options::defaults) { return 0; } + // Renew. + + virtual int tryacquire (void (* /* sleep_hook */)(void *) = 0) { return 0; } + // Try acquire. + + virtual int release (ACE_Synch_Options & /* options */ = + ACE_Synch_Options::defaults) { return 0; } + // Release. + + virtual int remove (ACE_Synch_Options & /* options */ = + ACE_Synch_Options::defaults) { return 0; } + // Remove. + + virtual ACE_Token_Proxy *clone (void) const { return new ACE_Null_Token; } + // Return a dynamically allocated clone of the derived class. + + void dump (void) const; + // Dump the state of the class. + + virtual ACE_Tokens *create_token (const char *) { return 0; } + // Do not allow the Token Manager to create us. +}; + +// 9.. +class ACE_Export ACE_Local_Mutex : public ACE_Token_Proxy + // = TITLE + // Class that acquires, renews, and releases a synchronization + // token local to the process. + // + // = DESCRIPTION + // This class is a more general-purpose synchronization mechanism + // than SunOS 5.x mutexes. For example, it implements "recursive + // mutex" semantics, where a thread that owns the token can + // reacquire it without deadlocking. In addition, threads that + // are blocked awaiting the token are serviced in strict FIFO + // order as other threads release the token (SunOS 5.x mutexes + // don't strictly enforce an acquisition order). Lastly, + // ACE_Local_Mutex performs deadlock detection on acquire calls. + // + // = Synchronization operations. + // The interfaces for acquire, tryacquire, renew, release, + // etc. are defined in ACE_Token_Proxy. The semantics for + // ACE_Local_Mutex are that of a mutex. +{ +public: + ACE_Local_Mutex (const char *token_name = 0, + int ignore_deadlock = 0, + int debug = 0); + // uniquely id's the token. + // will allow deadlock to occur (useful for + // testing). prints a bunch of messages. + + void dump (void) const; + // Dump the state of the class. + + virtual ACE_Token_Proxy *clone (void) const; + // Return deep copy. + +protected: + virtual ACE_Tokens *create_token (const char *name); + // Return a new ACE_Local_Mutex. +}; + +// *. +class ACE_Export ACE_Local_RLock : public ACE_Token_Proxy +// = TITLE +// Class that acquires, renews, and releases a readers lock that +// is local to the process. +// +// = DESCRIPTION +// This class implements the reader interface to canonical +// readers/writer locks. Multiple readers can hold the lock +// simultaneously when no writers have the lock. Alternatively, +// when a writer holds the lock, no other participants (readers or +// writers) may hold the lock. This class is a more +// general-purpose synchronization mechanism than SunOS 5.x RLocks. +// For example, it implements "recursive RLock" semantics, where a +// thread that owns the token can reacquire it without deadlocking. +// In addition, threads that are blocked awaiting the token are +// serviced in strict FIFO order as other threads release the token +// (SunOS 5.x RLockes don't strictly enforce an acquisition +// order). +// +// = Synchronization operations. +// The interfaces for acquire, tryacquire, renew, release, etc. are +// defined in ACE_Token_Proxy. The semantics for ACE_Local_RLock +// are that of a readers/writers lock. Acquire for this class +// implies a reader acquisition. That is, multiple clients may +// acquire a lock for read only. +{ +public: + // = Initialization and termination. + + ACE_Local_RLock (const char *token_name = 0, + int ignore_deadlock = 0, + int debug = 0); + // uniquely id's the token. + // will allow deadlock to occur (useful for + // testing). prints a bunch of messages. + + void dump (void) const; + // Dump the state of the class. + + virtual int type (void) const; + // Returns ACE_RW_Token::RLOCK. + + virtual ACE_Token_Proxy *clone (void) const; + // Return deep copy. + +protected: + virtual ACE_Tokens *create_token (const char *name); + // Return a new ACE_Local_Mutex. +}; + +// *. +class ACE_Export ACE_Local_WLock : public ACE_Token_Proxy +// = TITLE +// Class that acquires, renews, and releases a writer lock that +// is local to the process. +// +// = DESCRIPTION +// This class implements the writer interface to canonical +// readers/writer locks. Multiple readers can hold the lock +// simultaneously when no writers have the lock. Alternatively, +// when a writer holds the lock, no other participants (readers or +// writers) may hold the lock. This class is a more +// general-purpose synchronization mechanism than SunOS 5.x WLock. +// For example, it implements "recursive WLock" semantics, where a +// thread that owns the token can reacquire it without deadlocking. +// In addition, threads that are blocked awaiting the token are +// serviced in strict FIFO order as other threads release the token +// (SunOS 5.x WLocks don't strictly enforce an acquisition order). +// +// = Synchronization operations. +// The interfaces for acquire, tryacquire, renew, release, +// etc. are defined in ACE_Token_Proxy. The semantics for +// ACE_Local_WLock are that of a readers/writers lock. Acquire +// for this class implies a writer acquisition. That is, only one +// client may hold the lock for writing. +{ +public: + // = Initialization and termination. + + ACE_Local_WLock (const char *token_name = 0, + int ignore_deadlock = 0, + int debug = 0); + // uniquely id's the token. + // will allow deadlock to occur (useful for + // testing). prints a bunch of messages. + + void dump (void) const; + // Dump the state of the class. + + virtual int type (void) const; + // Returns ACE_RW_Token::WLOCK. + + virtual ACE_Token_Proxy *clone (void) const; + // Return deep copy. + +protected: + ACE_Tokens *create_token (const char *name); + // Return a new ACE_Local_Mutex. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Local_Tokens.i" +#endif /* __ACE_INLINE__ */ +#endif /* ACE_LOCAL_MUTEX_H */ diff --git a/ace/Local_Tokens.i b/ace/Local_Tokens.i new file mode 100644 index 00000000000..430c542bd85 --- /dev/null +++ b/ace/Local_Tokens.i @@ -0,0 +1,363 @@ +/* -*- C++ -*- */ +// $Id$ + +// Local_Tokens.i + +ACE_INLINE int +ACE_Token_Proxy::type (void) const +{ + ACE_TRACE ("ACE_Token_Proxy::type"); + return 0; +} + +ACE_INLINE int +ACE_Token_Proxy_Queue::size (void) +{ + ACE_TRACE ("ACE_Token_Proxy_Queue::size"); + return this->size_; +} + +// ************************************************************ + +ACE_INLINE int +ACE_TPQ_Entry::waiting (void) const +{ + ACE_TRACE ("ACE_TPQ_Entry::waiting"); + return waiting_; +} + +ACE_INLINE void +ACE_TPQ_Entry::waiting (int v) +{ + ACE_TRACE ("ACE_TPQ_Entry::waiting"); + waiting_ = v; +} + +ACE_INLINE const char * +ACE_TPQ_Entry::client_id (void) const +{ + ACE_TRACE ("ACE_TPQ_Entry::client_id"); + return this->client_id_; +} + +ACE_INLINE ACE_Token_Proxy * +ACE_TPQ_Entry::proxy (void) const +{ + ACE_TRACE ("ACE_TPQ_Entry::proxy"); + return this->proxy_; +} + +ACE_INLINE void +ACE_TPQ_Entry::proxy (ACE_Token_Proxy *proxy) +{ + ACE_TRACE ("ACE_TPQ_Entry::proxy"); + this->proxy_ = proxy; +} + +ACE_INLINE void +ACE_Tokens::remove (ACE_TPQ_Entry *caller) +{ + this->waiters_.remove (caller); +} + +ACE_INLINE int +ACE_Tokens::dec_reference (void) +{ + ACE_TRACE ("ACE_Tokens::dec_reference"); + if (this->reference_count_ == 0) + { + ACE_DEBUG ((LM_DEBUG, "dec_reference already zero")); + return 0; + } + + return --this->reference_count_; +} + +ACE_INLINE void +ACE_Tokens::inc_reference (void) +{ + ACE_TRACE ("ACE_Tokens::inc_reference"); + ++this->reference_count_; +} + +ACE_INLINE ACE_Token_Proxy_Queue * +ACE_Tokens::waiters () +{ + ACE_TRACE ("ACE_Tokens::waiters"); + return &this->waiters_; +} + +ACE_INLINE int +ACE_Tokens::no_of_waiters () +{ + ACE_TRACE ("ACE_Tokens::no_of_waiters"); + return this->waiters_.size (); +} + +ACE_INLINE const ACE_TPQ_Entry * +ACE_Token_Proxy_Queue::head (void) +{ + ACE_TRACE ("ACE_Token_Proxy_Queue::head"); + if (this->head_ == 0) + return 0; + else + return this->head_; +} + +// ************************************************** +// ************************************************** +// ************************************************** + +ACE_INLINE void +ACE_Tokens::visit (int v) +{ + ACE_TRACE ("ACE_Tokens::visit"); + visited_ = v; +} + +ACE_INLINE int +ACE_Tokens::visited (void) +{ + ACE_TRACE ("ACE_Tokens::visited"); + return visited_; +} + +ACE_INLINE ACE_TPQ_Entry * +ACE_Tokens::owner (void) +{ + ACE_TRACE ("ACE_Tokens::owner"); + return (ACE_TPQ_Entry *) this->waiters_.head (); +} + +ACE_INLINE const char* +ACE_Tokens::owner_id () +{ + ACE_TRACE ("ACE_Tokens::owner_id"); + if (this->owner () == 0) + return "no owner"; + else + return this->owner ()->client_id (); +} + +ACE_INLINE const char* +ACE_Tokens::name (void) +{ + ACE_TRACE ("ACE_Tokens::name"); + return this->token_name_; +} + +#if 0 +ACE_INLINE ACE_Token_Proxy * +ACE_Tokens::current_owner (void) +{ + ACE_TRACE ("ACE_Tokens::current_owner"); + // ACE_GUARD_RETURN ??? + + if (this->owner () == 0) + return 0; + else + return this->owner ()->proxy (); +} +#endif /* 0 */ + +// ************************************************************ + +ACE_INLINE int +ACE_Mutex_Token::type (void) const +{ + ACE_TRACE ("ACE_Mutex_Token::type"); + return (int) ACE_Tokens::MUTEX; +} + +// ************************************************************ + +ACE_INLINE int +ACE_RW_Token::type (void) const +{ + ACE_TRACE ("ACE_RW_Token::type"); + return (int) ACE_Tokens::RWLOCK; +} + +// ************************************************************ + +ACE_INLINE int +ACE_TPQ_Entry::nesting_level (void) const +{ + ACE_TRACE ("ACE_TPQ_Entry::nesting_level"); + return this->nesting_level_; +} + +ACE_INLINE void +ACE_TPQ_Entry::nesting_level (int delta) +{ + ACE_TRACE ("ACE_TPQ_Entry::nesting_level"); + this->nesting_level_ += delta; +} + +ACE_INLINE ACE_TPQ_Entry::PTVF +ACE_TPQ_Entry::sleep_hook (void) const +{ + ACE_TRACE ("ACE_TPQ_Entry::sleep_hook"); + return this->sleep_hook_; +} + +ACE_INLINE void +ACE_TPQ_Entry::sleep_hook (void (*sh)(void *)) +{ + ACE_TRACE ("ACE_TPQ_Entry::sleep_hook"); + this->sleep_hook_ = sh; +} + +ACE_INLINE void +ACE_TPQ_Entry::call_sleep_hook (void) +{ + ACE_TRACE ("ACE_TPQ_Entry::call_sleep_hook"); + + // if a function has been registered, call it. + if (this->sleep_hook () != 0) + this->sleep_hook () ((void *) this->proxy ()); + else + // otherwise, call back the sleep_hook method + this->proxy ()->sleep_hook (); +} + +ACE_INLINE int +ACE_TPQ_Entry::equal_client_id (const char *id) +{ + ACE_TRACE ("ACE_TPQ_Entry::equal_client_id"); + return (ACE_OS::strcmp (this->client_id (), id) == 0); +} + +// ************************************************************ +// ************************************************************ +// ************************************************************ + +ACE_INLINE +ACE_Local_Mutex::ACE_Local_Mutex (const char *token_name, + int ignore_deadlock, + int debug) +{ + ACE_TRACE ("ACE_Local_Mutex::ACE_Local_Mutex"); + this->open (token_name, ignore_deadlock, debug); +} + +ACE_INLINE void +ACE_Token_Name::name (const char *new_name) +{ + ACE_TRACE ("ACE_Token_Name::name"); + + if (new_name == 0) + new_name = "no name"; + + int n = ACE_OS::strlen (new_name) + 1; + + if (n >= ACE_MAXTOKENNAMELEN) + n = ACE_MAXTOKENNAMELEN - 1; + + ACE_OS::strncpy (this->token_name_, (char *) new_name, n); +} + +ACE_INLINE const char* +ACE_Token_Name::name (void) const +{ + ACE_TRACE ("ACE_Token_Name::name"); + return this->token_name_; +} + +ACE_INLINE ACE_Token_Proxy * +ACE_Local_Mutex::clone (void) const +{ + return new ACE_Local_Mutex (token_->name (), + ignore_deadlock_, + debug_); +} + +ACE_INLINE ACE_Tokens * +ACE_Local_Mutex::create_token (const char *name) +{ + return new ACE_Mutex_Token (name); +} + +// ************************************************************ + +ACE_INLINE +ACE_Local_RLock::ACE_Local_RLock (const char *token_name, + int ignore_deadlock, + int debug) +{ + ACE_TRACE ("ACE_Local_RLock::ACE_Local_RLock"); + this->open (token_name, ignore_deadlock, debug); +} + +ACE_INLINE ACE_Tokens * +ACE_Local_RLock::create_token (const char *name) +{ + return new ACE_RW_Token (name); +} + +ACE_INLINE int +ACE_Local_RLock::type (void) const +{ + return ACE_RW_Token::READER; +} + +ACE_INLINE ACE_Token_Proxy * +ACE_Local_RLock::clone (void) const +{ + return new ACE_Local_RLock (token_->name (), + ignore_deadlock_, + debug_); +} + +// ************************************************************ + +ACE_INLINE +ACE_Local_WLock::ACE_Local_WLock (const char *token_name, + int ignore_deadlock, + int debug) +{ + ACE_TRACE ("ACE_Local_WLock::ACE_Local_WLock"); + this->open (token_name, ignore_deadlock, debug); +} + +ACE_INLINE ACE_Tokens * +ACE_Local_WLock::create_token (const char *name) +{ + return new ACE_RW_Token (name); +} + +ACE_INLINE int +ACE_Local_WLock::type (void) const +{ + return ACE_RW_Token::WRITER; +} + +ACE_INLINE ACE_Token_Proxy * +ACE_Local_WLock::clone (void) const +{ + return new ACE_Local_WLock (token_->name (), + ignore_deadlock_, + debug_); +} + +// ************************************************************ + + +ACE_INLINE void +ACE_Token_Name::operator= (const ACE_Token_Name &rhs) +{ + ACE_TRACE ("ACE_Token_Name::operator="); + if (&rhs == this) + return; + else + this->name (rhs.name ()); +} + +ACE_INLINE int +ACE_Token_Name::operator== (const ACE_Token_Name &rhs) const +{ + ACE_TRACE ("ACE_Token_Name::operator=="); + + // the name and type must be the same + return (ACE_OS::strcmp (this->token_name_, rhs.name ()) == 0); +} diff --git a/ace/Local_Tokens_T.cpp b/ace/Local_Tokens_T.cpp new file mode 100644 index 00000000000..da978100488 --- /dev/null +++ b/ace/Local_Tokens_T.cpp @@ -0,0 +1,56 @@ +// Local_Tokens_T.cpp +// $Id$ + +#if !defined (ACE_LOCAL_TOKENS_T_C) +#define ACE_LOCAL_TOKENS_T_C + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Local_Tokens_T.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Local_Tokens_T.i" +#endif /* __ACE_INLINE__ */ + +template +ACE_Token_Name::ACE_Token_Name (void) +{ + ACE_TRACE ("ACE_Token_Name::ACE_Token_Name"); +} + +template +ACE_Token_Name::ACE_Token_Name (const char *token_name, + TYPE type) +{ + ACE_TRACE ("ACE_Token_Name::ACE_Token_Name"); + this->type (type); + this->name (token_name); +} + +template +ACE_Token_Name::ACE_Token_Name (const ACE_Token_Name &rhs) +{ + ACE_TRACE ("ACE_Token_Name::ACE_Token_Name"); + this->type (rhs.type ()); + this->name (rhs.name ()); +} + +template +ACE_Token_Name::~ACE_Token_Name () +{ + ACE_TRACE ("ACE_Token_Name::~ACE_Token_Name"); +} + +template void +ACE_Token_Name::dump (void) const +{ + ACE_TRACE ("ACE_Token_Name::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "ACE_Token_Name::dump:\n" + " token_name_ = %s\n" + " type_ = %d\n", + token_name_, (int) type_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +#endif /* ACE_LOCAL_TOKENS_T_C */ diff --git a/ace/Local_Tokens_T.h b/ace/Local_Tokens_T.h new file mode 100644 index 00000000000..c8a5f21db2a --- /dev/null +++ b/ace/Local_Tokens_T.h @@ -0,0 +1,95 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Local_Tokens_T +// +// = AUTHOR +// Tim Harrison (harrison@cs.wustl.edu) +// +// = DESCRIPTION +// This file contains definitions for the following classes: +// +// public: +// ACE_Token_Name +// +// ============================================================================ + +#if !defined (ACE_LOCAL_TOKENS_T_H) +#define ACE_LOCAL_TOKENS_T_H + +#include "ace/ACE.h" + +template +class ACE_Token_Name + // = TITLE + // Allows Token_Manger to identify tokens. + // + // = DESCRIPTION + // A 2-tuple of token name and token type. For now, we're going + // to use int's instead of ACE_Token_Manager::TOKEN_TYPE. This is + // because of the different ways the compilers are instantiating + // the templates in the token manager. +{ +public: + ACE_Token_Name (void); + // for map manager + + ACE_Token_Name (const char *token_name, + TYPE type); + // construction + + ACE_Token_Name (const ACE_Token_Name &rhs); + // copy construction + + ~ACE_Token_Name (void); + // death + + void operator= (const ACE_Token_Name &rhs); + // copy + + int operator== (const ACE_Token_Name &rhs) const; + // comparison + + const char *name (void) const; + // token name + + void name (const char *new_name); + // token name + + TYPE type (void) const; + // token type + + void type (TYPE type); + // token type + + void dump (void) const; + // Dump the state of the class. + +private: + char token_name_[ACE_MAXTOKENNAMELEN]; + // Name of the token. + + TYPE type_; + // Type of the token. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Local_Tokens_T.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Local_Tokens_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Local_Tokens_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_LOCAL_TOKENS_T_H */ diff --git a/ace/Local_Tokens_T.i b/ace/Local_Tokens_T.i new file mode 100644 index 00000000000..1eb8881a464 --- /dev/null +++ b/ace/Local_Tokens_T.i @@ -0,0 +1,65 @@ +/* -*- C++ -*- */ +// $Id$ + +// Local_Tokens_T.i + +template ACE_INLINE void +ACE_Token_Name::operator= (const ACE_Token_Name &rhs) +{ + ACE_TRACE ("ACE_Token_Name::operator="); + if (&rhs == this) + return; + else + { + this->type (rhs.type ()); + this->name (rhs.name ()); + } +} + +template ACE_INLINE int +ACE_Token_Name::operator== (const ACE_Token_Name &rhs) const +{ + ACE_TRACE ("ACE_Token_Name::operator=="); + + // the name and type must be the same + return (ACE_OS::strcmp (this->token_name_, rhs.name ()) == 0 + && rhs.type () == type_); +} + +template ACE_INLINE const char* +ACE_Token_Name::name (void) const +{ + ACE_TRACE ("ACE_Token_Name::name"); + return this->token_name_; +} + +template ACE_INLINE void +ACE_Token_Name::name (const char *new_name) +{ + ACE_TRACE ("ACE_Token_Name::name"); + + if (new_name == 0) + return; + + int n = ACE_OS::strlen (new_name) + 1; + + if (n > ACE_MAXTOKENNAMELEN) + n = ACE_MAXTOKENNAMELEN; + + ACE_OS::strncpy (this->token_name_, (char *) new_name, n); +} + +template ACE_INLINE TYPE +ACE_Token_Name::type (void) const +{ + ACE_TRACE ("ACE_Token_Name::type"); + return this->type_; +} + +template ACE_INLINE void +ACE_Token_Name::type (TYPE type) +{ + ACE_TRACE ("ACE_Token_Name::type"); + this->type_ = type; +} + diff --git a/ace/Log_Msg.cpp b/ace/Log_Msg.cpp new file mode 100644 index 00000000000..31015bddf5b --- /dev/null +++ b/ace/Log_Msg.cpp @@ -0,0 +1,895 @@ +// Log_Msg.cpp +// $Id$ + +#define ACE_BUILD_DLL +// We need this to get the status of ACE_NTRACE... +#include "ace/config.h" + +// Turn off tracing for the duration of this file. +#if defined (ACE_NTRACE) +#undef ACE_NTRACE +#endif /* ACE_NTRACE */ +#define ACE_NTRACE 1 + +// This must come first to avoid "order of include" problems... + +#if !defined (ACE_HAS_INLINED_OSCALLS) && !defined (ACE_WIN32) +#define ACE_HAS_INLINED_OSCALLS +#include "ace/ACE.h" +#undef ACE_HAS_INLINED_OSCALLS +#else +#include "ace/ACE.h" +#endif /* !ACE_HAS_INLINED_OSCALLS */ + +#include "ace/Thread.h" +#include "ace/Synch.h" + +#include "ace/Log_Msg.h" + +// IPC conduit between sender and client daemon. This should be +// included in the class, but due to "order of include" +// problems it can't be... +#if defined (ACE_WIN32) +#include "ace/SPIPE_Connector.h" +static ACE_SPIPE_Stream message_queue_; +#else +#include "ace/FIFO_Send_Msg.h" +static ACE_FIFO_Send_Msg message_queue_; +#endif /* ACE_WIN32 */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Log_Msg) + +#if defined (ACE_MT_SAFE) +// Synchronize output operations. +static ACE_Recursive_Thread_Mutex *lock_ = 0; + +static ACE_thread_key_t key_; + +/* static */ +void +ACE_TSS_cleanup (void *ptr) +{ + delete ptr; +} +#endif /* ACE_MT_SAFE */ + +ACE_Log_Msg * +ACE_Log_Msg::instance (void) +{ +#if defined (ACE_MT_SAFE) +#if !defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) +#error "Platform must support thread-specific storage if threads are used..." +#else + // TSS Singleton implementation. + + static int once_ = 0; + static int count_ = 0; + + if (once_ == 0) + { + // Synchronize Singleton creation (note that this may lose big + // if the compiler doesn't perform thread-safe initialization of + // local statics...). + static ACE_Thread_Mutex keylock_; + ACE_thread_mutex_t &lock = (ACE_thread_mutex_t &) keylock_.lock (); + + ACE_OS::thread_mutex_lock (&lock); + if (once_ == 0) + { + // Initialize the static recursive lock here. Note that we + // can't rely on the constructor being called at this point. + ACE_NEW_RETURN (lock_, ACE_Recursive_Thread_Mutex, 0); + + if (ACE_OS::thr_keycreate (&key_, + &ACE_TSS_cleanup) != 0) + { + ACE_OS::thread_mutex_unlock (&lock); + return 0; // Major problems, this should *never* happen! + } + once_ = 1; + } + ACE_OS::thread_mutex_unlock (&lock); + } + + ACE_Log_Msg *tss_log_msg = 0; + + // Get the tss_log_msg from thread-specific storage. Note that no locks + // are required here... + if (ACE_OS::thr_getspecific (key_, + (void **) &tss_log_msg) == -1) + return 0; // This should not happen! + + // Check to see if this is the first time in for this thread. + if (tss_log_msg == 0) + { + // Allocate memory off the heap and store it in a pointer in + // thread-specific storage (on the stack...). + + ACE_NEW_RETURN (tss_log_msg, ACE_Log_Msg, 0); + + // Store the dynamically allocated pointer in thread-specific + // storage. + if (ACE_OS::thr_setspecific (key_, + (void *) tss_log_msg) != 0) + return 0; // Major problems, this should *never* happen! + } + + return tss_log_msg; +#endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */ +#else + // Singleton implementation. + static ACE_Log_Msg log_msg; + + return &log_msg; +#endif /* defined (ACE_MT_SAFE) */ +} + +// Name of the local host. +const char *ACE_Log_Msg::local_host_ = 0; + +// Records the program name. +const char *ACE_Log_Msg::program_name_ = 0; + +// Default is to use stderr. +u_long ACE_Log_Msg::flags_ = ACE_Log_Msg::STDERR; + +// Process id of the current process. +pid_t ACE_Log_Msg::pid_ = -1; + +// Current offset of msg_[]. +int ACE_Log_Msg::msg_off_ = 0; + +// Call after a fork to resynchronize the PID and PROGRAM_NAME +// variables. + +void +ACE_Log_Msg::sync (const char *prog_name) +{ + ACE_TRACE ("ACE_Log_Msg::sync"); + if (prog_name) + { + ACE_OS::free ((void *) ACE_Log_Msg::program_name_); + ACE_Log_Msg::program_name_ = ACE_OS::strdup (prog_name); + } + ACE_Log_Msg::msg_off_ = 0; +} + +u_long +ACE_Log_Msg::flags (void) +{ + ACE_TRACE ("ACE_Log_Msg::flags"); + u_long result; + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, *lock_, 0)); + + result = ACE_Log_Msg::flags_; + return result; +} + +void +ACE_Log_Msg::set_flags (u_long flgs) +{ + ACE_TRACE ("ACE_Log_Msg::set_flags"); + ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, *lock_)); + + ACE_SET_BITS (ACE_Log_Msg::flags_, flgs); +} + +void +ACE_Log_Msg::clr_flags (u_long flgs) +{ + ACE_TRACE ("ACE_Log_Msg::clr_flags"); + ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, *lock_)); + + ACE_CLR_BITS (ACE_Log_Msg::flags_, flgs); +} + +int +ACE_Log_Msg::acquire (void) +{ + ACE_TRACE ("ACE_Log_Msg::acquire"); +#if defined (ACE_MT_SAFE) + return lock_->acquire (); +#else + return 0; +#endif /* ACE_MT_SAFE */ +} + +u_long +ACE_Log_Msg::priority_mask (u_long n_mask) +{ + u_long o_mask = this->priority_mask_; + this->priority_mask_ = n_mask; + return o_mask; +} + +u_long +ACE_Log_Msg::priority_mask (void) +{ + return this->priority_mask_; +} + +int +ACE_Log_Msg::release (void) +{ + ACE_TRACE ("ACE_Log_Msg::release"); + +#if defined (ACE_MT_SAFE) + return lock_->release (); +#else + return 0; +#endif /* ACE_MT_SAFE */ +} + +ACE_Log_Msg::ACE_Log_Msg (void) + : status_ (0), + errnum_ (0), + linenum_ (0), + ostream_ (0), + restart_ (1), // Restart by default... + thr_state_ (0), + trace_depth_ (0), + thr_handle_ (0), + trace_active_ (0), + tracing_enabled_ (0), // Off by default? + priority_mask_ (LM_SHUTDOWN // By default, all priorities are enabled. + | LM_TRACE + | LM_DEBUG + | LM_INFO + | LM_NOTICE + | LM_WARNING + | LM_STARTUP + | LM_ERROR + | LM_CRITICAL + | LM_ALERT + | LM_EMERGENCY) +{ + ACE_TRACE ("ACE_Log_Msg::ACE_Log_Msg"); +} + +// Open the sender-side of the Message ACE_Queue. + +int +ACE_Log_Msg::open (const char *prog_name, + u_long flags, + const char *logger_key) +{ + ACE_TRACE ("ACE_Log_Msg::open"); + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, *lock_, -1)); + + if (prog_name) + ACE_Log_Msg::program_name_ = ACE_OS::strdup (prog_name); + + int status = 0; + + // Note that if we fail to open the message queue the default action + // is to use stderr (set via static initialization in the + // ACE_Log_Msg.C file). + + if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::LOGGER)) + { + if (logger_key == 0) + status = -1; + else +#if defined (ACE_WIN32) + { + ACE_SPIPE_Connector con; + status = con.connect (message_queue_, ACE_SPIPE_Addr (logger_key)); + } +#else + status = message_queue_.open (logger_key); +#endif /* ACE_WIN32 */ + + if (status == -1) + ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::STDERR); + else + ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER); + } + + // Remember, ACE_Log_Msg::STDERR bit is on by default... + if (status != -1 + && ACE_BIT_ENABLED (flags, ACE_Log_Msg::STDERR) == 0) + ACE_CLR_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::STDERR); + + if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::VERBOSE)) + ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::VERBOSE); + + if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::OSTREAM)) + { + ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::OSTREAM); + ACE_LOG_MSG->msg_ostream (&cerr); + } + if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::SILENT)) + ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::SILENT); + + return status; +} + +// Valid Options (prefixed by '%', as in printf format strings) include: +// 'a': exit the program at this point (var-argument is the exit status!) +// 'c': print a character +// 'i', 'd': print a decimal number +// 'e', 'E', 'f', 'F', 'g', 'G': print a double +// 'l', print line number where an error occurred. +// 'N': print file name where the error occurred. +// 'n': print the name of the program (or "" if not set) +// 'o': print as an octal number +// 'P': format the current process id +// 'p': format the appropriate errno value from sys_errlist +// 'r': call the function pointed to by the corresponding argument +// 'R': print return status +// 'S': format the appropriate _sys_siglist entry corresponding to var-argument. +// 's': format a character string +// 'T': print timestamp in hour:minute:sec:usec format. +// 't': print thread id (1 if single-threaded) +// 'u': print as unsigned int +// 'X', 'x': print as a hex number +// '%': format a single percent sign, '%' + +ssize_t +ACE_Log_Msg::log (ACE_Log_Priority log_priority, + const char *format_str, ...) +{ + ACE_TRACE ("ACE_Log_Msg::log"); + + // Start of variable args section. + va_list argp; + + va_start (argp, format_str); + + int result = this->log (format_str, log_priority, argp); + + va_end (argp); + + return result; +} + +ssize_t +ACE_Log_Msg::log (const char *format_str, + ACE_Log_Priority log_priority, + va_list argp) +{ + ACE_TRACE ("ACE_Log_Msg::log"); + // External decls. + extern int sys_nerr; + typedef void (*PTF)(...); + + ACE_Log_Record log_record (log_priority, + ACE_OS::time ((time_t *) 0), + this->getpid ()); + char *bp = this->msg (); + int abort_prog = 0; + int exit_value = 0; + int result = 0; + char *format = ACE_OS::strdup (format_str); + char *save_p = format; // Remember pointer for ACE_OS::free() + + if (format == 0) + return -1; + + if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::VERBOSE)) + { + // Prepend the program name onto this message + + if (ACE_Log_Msg::program_name_ != 0) + { + for (const char *s = ACE_Log_Msg::program_name_; (*bp = *s) != '\0'; s++) + bp++; + + *bp++ = '|'; + } + } + + while (*format != '\0') + { + // Copy input to output until we encounter a %, however a + // % followed by another % is not a format specification. + + if (*format != '%') + *bp++ = *format++; + else if (format[1] == '%') // An "escaped" '%' (just print one '%'). + { + *bp++ = *format++; // Store first % + format++; // but skip second % + } + else + { + char c; // high use character + char *fp; // local format pointer + int wpc; // width/precision cnt + const int CONTINUE = 0; + const int SKIP_SPRINTF = -1; // We must skip the sprintf phase + const int SKIP_NUL_LOCATE = -2; // Skip locating the NUL character + int type = CONTINUE; // conversion type + int w[2]; // width/precision vals + + // % starts a format specification that ends with one of + // "arnPpSsdciouxXfFeEgG". An optional width and/or precision + // (indicated by an "*") may be encountered prior to the + // nend of the specification, each consumes an int arg. + // A call to sprintf() does the actual conversion. + + fp = format++; // Remember beginning of format. + wpc = 0; // Assume no width/precision seen. + + while (type == CONTINUE) + { + switch (*format++) + { + case 'a': // Abort program after handling all of format string. + type = SKIP_SPRINTF; + abort_prog = 1; + exit_value = va_arg (argp, int); + ACE_OS::sprintf (bp, ""); // Make sure to NUL-terminate this... + break; + case 'l': + ACE_OS::sprintf (bp, "%d", this->linenum ()); + type = SKIP_SPRINTF; + break; + case 'N': + { + const char *file = this->file (); + ACE_OS::sprintf (bp, "%s", file ? file : ""); + type = SKIP_SPRINTF; + break; + } + case 'n': // Print the name of the program. + type = SKIP_SPRINTF; + ACE_OS::strcpy (bp, ACE_Log_Msg::program_name_ ? + ACE_Log_Msg::program_name_ : ""); + break; + case 'P': // format the current process id + type = SKIP_SPRINTF; + ACE_OS::sprintf (bp, "%d", this->getpid ()); + break; + case 'p': // format the string assocated with the value of errno. + { + type = SKIP_SPRINTF; + errno = ACE::map_errno (errno); + if (errno >= 0 && errno < sys_nerr) + ACE_OS::sprintf (bp, "%s: %s", + va_arg (argp, char *), strerror (errno)); + else + ACE_OS::sprintf (bp, "%s: = %d", + va_arg (argp, char *), errno); + break; + } + case 'R': // format the return status of the operation. + this->op_status (va_arg (argp, int)); + ACE_OS::sprintf (bp, "%d", this->op_status ()); + break; + case 'r': // Run (invoke) this subroutine. + { + int osave = ACE_Log_Msg::msg_off_; + + if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::SILENT)) + *bp++ = '{'; + ACE_Log_Msg::msg_off_ = bp - this->msg_; + + type = SKIP_SPRINTF; + (*va_arg (argp, PTF))(); + + if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::SILENT)) + { + bp += ACE_OS::strlen (bp); + *bp++ = '}'; + } + *bp = '\0'; + + ACE_Log_Msg::msg_off_ = osave; + break; + } + case 'S': // format the string associated with this signal number. + { + int sig = va_arg (argp, int); + type = SKIP_SPRINTF; +#if defined (ACE_HAS_SYS_SIGLIST) + if (sig >= 0 && sig < NSIG) + ACE_OS::strcpy (bp, _sys_siglist[sig]); + else + ACE_OS::sprintf (bp, " %d", sig); +#else + ACE_OS::sprintf (bp, "signal %d", sig); +#endif /* ACE_HAS_SYS_SIGLIST */ + break; + } + case 'T': /* format the timestamp*/ + { + type = SKIP_SPRINTF; + char day_and_time[35]; + ACE_OS::sprintf (bp, "%s", + ACE::timestamp (day_and_time, + sizeof day_and_time)); + break; + } + case 't': // format thread id. + type = SKIP_SPRINTF; +#if defined (ACE_WIN32) + ACE_OS::sprintf (bp, "%u", ACE_Thread::self ()); +#else + ACE_hthread_t t_id; + ACE_Thread::self (t_id); + ACE_OS::sprintf (bp, "%u", t_id); +#endif /* ACE_WIN32 */ + break; + case 's': + type = 1 + wpc; // 1, 2, 3 + break; + case 'd': case 'c': case 'i': case 'o': + case 'u': case 'x': case 'X': + type = 4 + wpc; // 4, 5, 6 + break; + case 'F': case 'f': case 'e': case 'E': + case 'g': case 'G': + type = 7 + wpc; // 7, 8, 9 + break; + case '*': // consume width/precision + w[wpc++] = va_arg (argp, int); + break; + default: + // ? + break; + } + } + + if (type != SKIP_SPRINTF) + { + c = *format; // Remember char before we overwrite. + *format = 0; // Overwrite, terminating format. + + switch (type) + { + case 1: + ACE_OS::sprintf (bp, fp, va_arg (argp, char *)); + break; + case 2: + ACE_OS::sprintf (bp, fp, w[0], va_arg (argp, char *)); + bp += w[0]; + type = SKIP_NUL_LOCATE; + break; + case 3: + ACE_OS::sprintf (bp, fp, w[0], w[1], va_arg (argp, char *)); + bp += w[0]; + type = SKIP_NUL_LOCATE; + break; + case 4: + ACE_OS::sprintf (bp, fp, va_arg (argp, int)); + break; + case 5: + ACE_OS::sprintf (bp, fp, w[0], va_arg (argp, int)); + break; + case 6: + ACE_OS::sprintf (bp, fp, w[0], w[1], va_arg (argp, int)); + break; + case 7: + ACE_OS::sprintf (bp, fp, va_arg (argp, double)); + break; + case 8: + ACE_OS::sprintf (bp, fp, w[0], va_arg (argp, double)); + break; + case 9: + ACE_OS::sprintf (bp, fp, w[0], w[1], va_arg (argp, double)); + break; + } + *format = c; // Restore char we overwrote. + } + + if (type != SKIP_NUL_LOCATE) + while (*bp != '\0') // Locate end of bp. + bp++; + } + } + + *bp = '\0'; // Terminate bp, but don't auto-increment this! + + ACE_OS::free (ACE_MALLOC_T (save_p)); + + // Only print the message if "SILENT" mode is disabled and the + // hasn't been reset to exclude this logging + // priority. + if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::SILENT) == 0 + && ACE_BIT_ENABLED (this->priority_mask_, log_priority)) + { + // Copy the message from thread-specific storage into the + // transfer buffer (this can be optimized away by changing other + // code...). + log_record.msg_data (this->msg ()); + this->stop_tracing (); + + // Make sure that the lock is help during all this. + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, *lock_, -1)); + + if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::STDERR)) + log_record.print (ACE_Log_Msg::local_host_, + ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::VERBOSE), + stderr, + bp - this->msg ()); + if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER)) + { + ACE_Str_Buf log_msg ((void *) &log_record, + int (log_record.length ())); +#if defined (ACE_HAS_STREAM_PIPES) + result = message_queue_.send (int (log_record.type ()), + &log_msg); +#elif !defined (ACE_WIN32) + result = message_queue_.send (log_msg); +#else + result = message_queue_.send ((const ACE_Str_Buf *) &log_msg, + (const ACE_Str_Buf *) 0); +#endif /* ACE_HAS_STREAM_PIPES */ + } + // Format the message and print it to stderr and/or ship it + // off to the log_client daemon, and/or print it to the + // ostream. This must come last, after the other two print + // operations (see the ACE_Log_Record::print method for + // details). + + if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::OSTREAM) + && this->msg_ostream () != 0) + log_record.print (ACE_Log_Msg::local_host_, + ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::VERBOSE), + *this->msg_ostream (), + bp - this->msg ()); + this->start_tracing (); + } + + if (abort_prog) + ACE_OS::exit (exit_value); + + return result; +} + +// Calls log to do the actual print, but formats first. + +int +ACE_Log_Msg::log_hexdump (ACE_Log_Priority log_priority, + char *buffer, + int size) +{ + char buf[ACE_Log_Record::MAXLOGMSGLEN - ACE_Log_Record::VERBOSE_LEN - 58]; + // 58 for the HEXDUMP header; + + char msg_buf[80]; + + buf[0] = 0; // in case size = 0 + + int len = ACE::format_hexdump (buffer, size, buf, sizeof buf); + + int sz = ::sprintf (msg_buf, "HEXDUMP %d bytes", size); + if (len < size) + ::sprintf (msg_buf + sz, " (showing first %d bytes)", len); + + // Now print out the formatted buffer. + this->log (log_priority, "%s\n%s", msg_buf, buf); + return 0; +} + +void +ACE_Log_Msg::set (const char *filename, + int line, + int status, + int err, + int rs, + ostream *os) +{ + ACE_TRACE ("ACE_Log_Msg::set"); + this->file (filename); + this->linenum (line); + this->op_status (status); + this->errnum (err); + this->restart (rs); + this->msg_ostream (os); +} + +void +ACE_Log_Msg::dump (void) const +{ + ACE_TRACE ("ACE_Log_Msg::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "status_ = %d\n", this->status_)); + ACE_DEBUG ((LM_DEBUG, "\nerrnum_ = %d\n", this->errnum_)); + ACE_DEBUG ((LM_DEBUG, "\nlinenum_ = %d\n", this->linenum_)); + ACE_DEBUG ((LM_DEBUG, "\nfile_ = %s\n", this->file_)); + ACE_DEBUG ((LM_DEBUG, "\nmsg_ = %s\n", this->msg_)); + ACE_DEBUG ((LM_DEBUG, "\nrestart_ = %s\n", this->restart_)); + ACE_DEBUG ((LM_DEBUG, "\nostream_ = %x\n", this->ostream_)); + ACE_DEBUG ((LM_DEBUG, "\nprogram_name_ = %s\n", this->program_name_ ? this->program_name_ : "")); + ACE_DEBUG ((LM_DEBUG, "\nlocal_host_ = %s\n", this->local_host_ ? this->local_host_ : "")); + ACE_DEBUG ((LM_DEBUG, "\npid_ = %d\n", this->getpid ())); + ACE_DEBUG ((LM_DEBUG, "\nflags_ = %d\n", this->flags_)); + ACE_DEBUG ((LM_DEBUG, "\ntrace_depth_ = %d\n", this->trace_depth_)); + ACE_DEBUG ((LM_DEBUG, "\trace_active_ = %d\n", this->trace_active_)); + ACE_DEBUG ((LM_DEBUG, "\tracing_enabled_ = %d\n", this->tracing_enabled_)); + ACE_DEBUG ((LM_DEBUG, "\npriority_mask_ = %s\n", this->priority_mask_)); + if (this->thr_state_ != 0) + ACE_DEBUG ((LM_DEBUG, "\thr_state_ = %d\n", *this->thr_state_)); + ACE_DEBUG ((LM_DEBUG, "\nmsg_off_ = %d\n", this->msg_off_)); + message_queue_.dump (); +#if defined (ACE_MT_SAFE) + lock_->dump (); + // Synchronize output operations. +#endif /* ACE_MT_SAFE */ + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +void +ACE_Log_Msg::op_status (int status) +{ + this->status_ = status; +} + +int +ACE_Log_Msg::op_status (void) +{ + return this->status_; +} + +void +ACE_Log_Msg::restart (int r) +{ + this->restart_ = r; +} + +int +ACE_Log_Msg::restart (void) +{ + return this->restart_; +} + +int +ACE_Log_Msg::errnum (void) +{ + return this->errnum_; +} + +void +ACE_Log_Msg::errnum (int e) +{ + this->errnum_ = e; +} + +int +ACE_Log_Msg::linenum (void) +{ + return this->linenum_; +} + +void +ACE_Log_Msg::linenum (int l) +{ + this->linenum_ = l; +} + +int +ACE_Log_Msg::inc (void) +{ + return this->trace_depth_++; +} + +int +ACE_Log_Msg::dec (void) +{ + return --this->trace_depth_; +} + +int +ACE_Log_Msg::trace_active (void) +{ + return this->trace_active_; +} + +void +ACE_Log_Msg::trace_active (int value) +{ + this->trace_active_ = value; +} + +ACE_Thread_State * +ACE_Log_Msg::thr_state (void) +{ + return this->thr_state_; +} + +void +ACE_Log_Msg::thr_state (ACE_Thread_State *ts) +{ + this->thr_state_ = ts; +} + +ACE_hthread_t * +ACE_Log_Msg::thr_handle (void) +{ + return this->thr_handle_; +} + +void +ACE_Log_Msg::thr_handle (ACE_hthread_t *th) +{ + this->thr_handle_ = th; +} + +// Enable the tracing facility on a per-thread basis. + +void +ACE_Log_Msg::start_tracing (void) +{ + this->tracing_enabled_ = 1; +} + +// Disable the tracing facility on a per-thread basis. + +void +ACE_Log_Msg::stop_tracing (void) +{ + this->tracing_enabled_ = 0; +} + +int +ACE_Log_Msg::tracing_enabled (void) +{ + return this->tracing_enabled_; +} + +const char * +ACE_Log_Msg::file (void) +{ + return this->file_; +} + +void +ACE_Log_Msg::file (const char *s) +{ + ACE_OS::strncpy (this->file_, s, + sizeof this->file_); +} + +char * +ACE_Log_Msg::msg (void) +{ + return this->msg_ + ACE_Log_Msg::msg_off_; +} + +void +ACE_Log_Msg::msg (char *m) +{ + ACE_OS::strncpy (this->msg_, m, + sizeof this->msg_); +} + +ostream * +ACE_Log_Msg::msg_ostream (void) +{ + return this->ostream_; +} + +void +ACE_Log_Msg::msg_ostream (ostream *m) +{ + this->ostream_ = m; +} + +void +ACE_Log_Msg::local_host (const char *s) +{ + if (s) + { + ACE_OS::free ((void *) ACE_Log_Msg::local_host_); + ACE_Log_Msg::local_host_ = ACE_OS::strdup (s); + } +} + +const char * +ACE_Log_Msg::local_host (void) const +{ + return ACE_Log_Msg::local_host_; +} + +pid_t +ACE_Log_Msg::getpid (void) const +{ + if (ACE_Log_Msg::pid_ == -1) + ACE_Log_Msg::pid_ = ACE_OS::getpid (); + + return ACE_Log_Msg::pid_; +} + diff --git a/ace/Log_Msg.h b/ace/Log_Msg.h new file mode 100644 index 00000000000..724fe70dee3 --- /dev/null +++ b/ace/Log_Msg.h @@ -0,0 +1,359 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Log_Msg.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_LOG_MSG_H) +#define ACE_LOG_MSG_H + +// This stuff must come first to avoid problems with circular +// headers... + +// The following ASSERT macro is courtesy of Alexandre Karev +// . +#if defined (ACE_NDEBUG) +#define ACE_ASSERT(x) +#else +#define ACE_ASSERT(X) \ + do { if(!(X)) { int __ace_error = errno; ACE_Log_Msg *ace___ = ACE_Log_Msg::instance (); \ + ace___->set (__FILE__, __LINE__, -1, __ace_error, ace___->restart (), ace___->msg_ostream ()); \ + ace___->log (LM_ERROR, "ACE_ASSERT: file %N, line %l assertion failed for '%s'.%a\n", #X, -1); \ + } } while (0) +#endif /* ACE_NDEBUG */ + +#if defined (ACE_NLOGGING) +#define ACE_HEX_DUMP(X) +#define ACE_RETURN(ERROR, Y) do { errno = ERROR, return (Y); } while (0) +#define ACE_ERROR_RETURN(X, Y) return (Y) +#define ACE_ERROR(X) +#define ACE_DEBUG(X) +#define ACE_ERROR_INIT(VALUE, FLAGS) +#else +#define ACE_HEX_DUMP(X) \ + do { int __ace_error = errno; \ + ACE_Log_Msg *ace___ = ACE_Log_Msg::instance (); \ + ace___->set (__FILE__, __LINE__, 0, errno, ace___->restart (), \ + ace___->msg_ostream ()); \ + ace___->log_hexdump X; \ + } while (0) +#define ACE_RETURN(Y) \ + do { int __ace_error = errno; \ + ACE_Log_Msg::instance ()->set (__FILE__, __LINE__, Y, __ace_error); \ + return Y; \ + } while (0) +#define ACE_ERROR_RETURN(X, Y) \ + do { int __ace_error = errno; \ + ACE_Log_Msg *ace___ = ACE_Log_Msg::instance (); \ + ace___->set (__FILE__, __LINE__, Y, __ace_error, ace___->restart (), ace___->msg_ostream ()); \ + ace___->log X; \ + return Y; \ + } while (0) +#define ACE_ERROR(X) \ + do { int __ace_error = errno; \ + ACE_Log_Msg *ace___ = ACE_Log_Msg::instance (); \ + ace___->set (__FILE__, __LINE__, -1, __ace_error, ace___->restart (), ace___->msg_ostream ()); \ + ace___->log X; \ + } while (0) +#define ACE_DEBUG(X) \ + do { int __ace_error = errno; \ + ACE_Log_Msg *ace___ = ACE_Log_Msg::instance (); \ + ace___->set (__FILE__, __LINE__, 0, errno, ace___->restart (), ace___->msg_ostream ()); \ + ace___->log X; \ + } while (0) +#define ACE_ERROR_INIT(VALUE, FLAGS) \ + do { \ + ACE_Log_Msg *ace___ = ACE_Log_Msg::instance (); \ + ace___->set_flags (FLAGS); ace___->op_status (VALUE); \ + } while (0) +#endif /* ACE_NLOGGING */ + +#include "ace/Log_Record.h" + +#define ACE_LOG_MSG ACE_Log_Msg::instance () + +class ACE_Export ACE_Log_Msg + // = TITLE + // Provides a variable length argument message logging + // abstraction. + // + // = DESCRIPTION + // This class is very flexible since it allows formatted error + // messages to be printed in a thread-safe manner to stderr or a + // distributed logger. Moreover, the message is kept in a + // thread-specific storage location, which can be used to + // communicate errors between framework methods and callers. +{ +public: + enum /* Logger Flags */ + { + STDERR = 01, + // Write messages to stderr. + LOGGER = 02, + // Write messages to the local client logger deamon. + OSTREAM = 04, + // Write messages to the ostream * stored in thread-specific + // storage. + VERBOSE = 010, + // Display messages in a verbose manner + SILENT = 020 + // Do not print messages at all (just leave in thread-specific + // storage for later inspection). + }; + + // = Initialization and termination routines. + + static ACE_Log_Msg *instance (void); + // Returns a pointer to the Singleton. + + ACE_Log_Msg (void); + // Initialize logger. + + int open (const char *prog_name, + u_long options_flags = ACE_Log_Msg::STDERR, + const char *logger_key = 0); + // Initialize the ACE error handling facility. is the + // name of the executable program. are a bitwise-or of + // options flags passed to the Logger (see the enum above for the valid + // values). If the bit in is enabled then + // is the name of ACE_FIFO rendezvous point where the + // local client logger daemon is listening for logging messages. + + // = Set/get the options flags. + + void set_flags (u_long f); + // Enable the bits in the logger's options flags. + void clr_flags (u_long f); + // Disable the bits in the logger's options flags. + u_long flags (void); + // Return the bits in the logger's options flags. + + // = Operations that allow applications to acquire and release the + // synchronization lock used internally by the ACE_Log_Msg + // implementation. This allows applications to hold the lock + // atomically over a number of calls to ACE_Log_Msg. + int acquire (void); + // Acquire the internal lock. + int release (void); + // Release the internal lock. + + void sync (const char *program_name); + // Call after doing a fork() to resynchronize the PID and + // PROGRAM_NAME variables. + + // = Set/get methods. Note that these are non-static and thus will + // be thread-specific. + + void op_status (int status); + // Set the result of the operation status (by convention, -1 means error). + + int op_status (void); + // Get the result of the operation status (by convention, -1 means error). + + void errnum (int); + // Set the value of the errnum (by convention this corresponds to errno). + + int errnum (void); + // Get the value of the errnum (by convention this corresponds to errno). + + void linenum (int); + // Set the line number where an error occurred. + + int linenum (void); + // Get the line number where an error occurred. + + void file (const char *); + // Set the file name where an error occurred. + + const char *file (void); + // Get the file name where an error occurred. + + void msg (char *); + // Set the message that describes what type of error occurred. + + char *msg (void); + // Get the message that describes what type of error occurred. + + void restart (int); + // Set the field that indicates whether interrupted calls should be + // restarted. + + int restart (void); + // Get the field that indicates whether interrupted calls should be + // restarted. + + void msg_ostream (ostream *); + // Set the ostream that is used to print error messages. + + ostream *msg_ostream (void); + // Get the ostream that is used to print error messages. + + // = Nesting depth increment and decrement. + int inc (void); + int dec (void); + + // = Get/set trace active status. + int trace_active (void); + void trace_active (int value); + + // = Get/set the current thread state. + ACE_Thread_State *thr_state (void); + void thr_state (ACE_Thread_State *); + + // = Get/set the current thread ACE_hthread_t. + ACE_hthread_t *thr_handle (void); + void thr_handle (ACE_hthread_t *); + + // = Stop/start/query tracing status on a per-thread basis... + void stop_tracing (void); + void start_tracing (void); + int tracing_enabled (void); + + // = Get/set the priority mask. + u_long priority_mask (void); + // Get the current mask. + u_long priority_mask (u_long); + // Set the mask, returns original mask. + + pid_t getpid (void) const; + // Optimize reading of the pid (avoids a system call if the + // value is cached...). + + // = Set/get the name of the local host. + const char *local_host (void) const; + void local_host (const char *); + + void set (const char *file, + int line, + int op_status = -1, + int errnum = 0, + int restart = 1, + ostream *os = 0); + // Set the line number, file name, operational status, error number, + // restart flag, and ostream. This combines all the other set + // methods into a single method. + + ssize_t log (ACE_Log_Priority priority, const char *format, ...); + // Format a message to the thread-safe ACE logging mechanism. Valid + // options (prefixed by '%', as in printf format strings) include: + // 'a': exit the program at this point (var-argument is the exit status!) + // 'c': print a character + // 'i', 'd': print a decimal number + // 'e', 'E', 'f', 'F', 'g', 'G': print a double + // 'l', print line number where an error occurred. + // 'N': print file name where the error occurred. + // 'n': print the name of the program (or "" if not set) + // 'o': print as an octal number + // 'P': print out the current process id + // 'p': print out the appropriate errno value from sys_errlist + // 'r': call the function pointed to by the corresponding argument + // 'R': print return status + // 'S': print out the appropriate _sys_siglist entry corresponding to var-argument. + // 's': print out a character string + // 'T': print timestamp in hour:minute:sec:usec format. + // 't': print thread id (1 if single-threaded) + // 'u': print as unsigned int + // 'X', 'x': print as a hex number + // '%': print out a single percent sign, '%' + + ssize_t log (const char *format, ACE_Log_Priority priority, va_list argp); + // An alternative logging mechanism that makes it possible to + // integrate variable argument lists from other logging mechanisms + // into the ACE mechanism. + + int log_hexdump (ACE_Log_Priority log_priority, + char *buffer, + int size); + // Method to log hex dump. This is useful for debugging. Calls + // to do the actual print, but formats first to make the chars + // printable. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + int status_; + // Status of operation (-1 means failure, >= 0 means success). + + int errnum_; + // Type of error that occurred (see ). + + int linenum_; + // Line number where the error occurred. + + char file_[MAXNAMELEN]; + // File where the error occurred. + + char msg_[ACE_Log_Record::MAXLOGMSGLEN]; + // The error message. + + int restart_; + // Indicates whether we should restart system calls that are + // interrupted. + + ostream *ostream_; + // The ostream where logging messages can be written. + + int trace_depth_; + // Depth of the nesting for printing traces. + + int trace_active_; + // Are we already within an ACE_Trace constructor call? + + int tracing_enabled_; + // Are we allowing tracing in this thread? + + ACE_Thread_State *thr_state_; + // If we're running in the context of an this + // will point to the field in the + // . Threads can use this to rapidly + // determine if they've got a cancellation pending. + + ACE_hthread_t *thr_handle_; + // If we're running in the context of an this + // will point to the field in the + // . Threads can use this to rapidly + // determine their real ACE_hthread_t. + + u_long priority_mask_; + // Keeps track of all the values that are + // currently enabled. Default is for all logging priorities to be + // enabled. + + // = The following fields are *not* kept in thread-specific storage + // since we only want one instance for the entire process! + + static const char *program_name_; + // Records the program name. + + static const char *local_host_; + // Name of the local host (used when printing messages). + + static pid_t pid_; + // Process id of the current process. + + static u_long flags_; + // Options flags. + + static int msg_off_; + // Offset of msg_[]. +}; + +// #if defined (__ACE_INLINE__) +// #include "ace/Log_Msg.i" +// #endif /* __ACE_INLINE__ */ +#endif /* ACE_LOG_MSG_H */ diff --git a/ace/Log_Msg.i b/ace/Log_Msg.i new file mode 100644 index 00000000000..20edd3a6058 --- /dev/null +++ b/ace/Log_Msg.i @@ -0,0 +1,6 @@ +/* -*- C++ -*- */ +// $Id$ + +// Log_Msg.i + + diff --git a/ace/Log_Priority.h b/ace/Log_Priority.h new file mode 100644 index 00000000000..26b2a5f64d6 --- /dev/null +++ b/ace/Log_Priority.h @@ -0,0 +1,73 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Log_Priority.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_LM_PRIORITY_H) +#define ACE_LM_PRIORITY_H + +enum ACE_Log_Priority + // = TITLE + // This data type indicates the relative priorities of the + // logging messages, from lowest to highest priority. + // + // = DESCRIPTION + // These values are defined using powers of two so that it's + // possible to form a mask to turn the on or off dynamically. +{ + // = Note, this first argument *must* start at 1! + + LM_SHUTDOWN = 01, + // Shutdown the logger (decimal 1). + + LM_TRACE = 02, + // Messages indicating function-calling sequence (decimal 2). + + LM_DEBUG = 04, + // Messages that contain information normally of use only when + // debugging a program (decimal 4). + + LM_INFO = 010, + // Informational messages (decimal 8). + + LM_NOTICE = 020, + // Conditions that are not error conditions, but that may require + // special handling (decimal 16). + + LM_WARNING = 040, + // Warning messages (decimal 32). + + LM_STARTUP = 0100, + // Initialize the logger (decimal 64). + + LM_ERROR = 0200, + // Error messages (decimal 128). + + LM_CRITICAL = 0400, + // Critical conditions, such as hard device errors (decimal 256). + + LM_ALERT = 01000, + // A condition that should be corrected immediately, such as a + // corrupted system database (decimal 512). + + LM_EMERGENCY = 02000, + // A panic condition. This is normally broadcast to all users + // (decimal 1024). + + LM_MAX = LM_EMERGENCY + // The maximum logging priority. +}; + +#endif /* ACE_LM_PRIORITY_H */ diff --git a/ace/Log_Record.cpp b/ace/Log_Record.cpp new file mode 100644 index 00000000000..cee731cb0da --- /dev/null +++ b/ace/Log_Record.cpp @@ -0,0 +1,136 @@ +// Log_Record.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Log_Record.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_Log_Record) + +void +ACE_Log_Record::dump (void) const +{ + // ACE_TRACE ("ACE_Log_Record::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "type_ = %d\n", this->type_)); + ACE_DEBUG ((LM_DEBUG, "\nlength_ = %d\n", this->length_)); + ACE_DEBUG ((LM_DEBUG, "\nlength_ = %d\n", this->time_stamp_)); + ACE_DEBUG ((LM_DEBUG, "\ntime_stamp_ = %s\n", this->pid_)); + ACE_DEBUG ((LM_DEBUG, "\nmsg_data_ = %s\n", this->msg_data_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +void +ACE_Log_Record::msg_data (const char *data) +{ + // ACE_TRACE ("ACE_Log_Record::msg_data"); + ACE_OS::strncpy (this->msg_data_, data, ACE_Log_Record::MAXLOGMSGLEN); + this->round_up (); +} + +ACE_Log_Record::ACE_Log_Record (ACE_Log_Priority lp, + long ts, + long p) + : type_ (long (lp)), + length_ (0), + time_stamp_ (ts), + pid_ (p) +{ + // ACE_TRACE ("ACE_Log_Record::ACE_Log_Record"); +} + +void +ACE_Log_Record::round_up (void) +{ + // ACE_TRACE ("ACE_Log_Record::round_up"); + // Determine the length of the payload. + int len = (sizeof *this - MAXLOGMSGLEN) + + (ACE_OS::strlen (this->msg_data_) + 1); + + // Round up to the alignment. + this->length_ = 1 + ((len + ACE_Log_Record::ALIGN_WORDB - 1) + & ~(ACE_Log_Record::ALIGN_WORDB - 1)); +} + +ACE_Log_Record::ACE_Log_Record (void) + : type_ (0), + length_ (0), + time_stamp_ (0), + pid_ (0) +{ + // ACE_TRACE ("ACE_Log_Record::ACE_Log_Record"); +} + +// Print out the record on the stderr stream with the appropriate +// format. + +int +ACE_Log_Record::print (const char host_name[], + int verbose, + FILE *fp, + size_t len) +{ + // ACE_TRACE ("ACE_Log_Record::print"); + + if (verbose) + { + time_t now = this->time_stamp_; + char ctp[26]; // 26 is a magic number... + + if (ACE_OS::ctime_r (&now, ctp, sizeof ctp) == 0) + return -1; + + /* 01234567890123456789012345 */ + /* Wed Oct 18 14:25:36 1989n0 */ + + ctp[24] = '\0'; + + if (host_name == 0) + host_name = ""; + + return ACE_OS::fprintf (fp, "%s@%s@%d@%d@%s", + ctp + 4, host_name, this->pid_, + this->type_, this->msg_data_); + } + else + return ACE_OS::fprintf (fp, "%s", this->msg_data_); +} + +int +ACE_Log_Record::print (const char host_name[], + int verbose, + ostream &s, + size_t len) +{ + // ACE_TRACE ("ACE_Log_Record::print"); + + if (verbose) + { + time_t now = this->time_stamp_; + char ctp[26]; // 26 is a magic number... + if (ACE_OS::ctime_r (&now, ctp, sizeof ctp) == 0) + return -1; + + /* 01234567890123456789012345 */ + /* Wed Oct 18 14:25:36 1989n0 */ + + ctp[24] = '\0'; + + if (host_name == 0) + host_name = ""; + + s << (ctp + 4) + << '@' + << host_name + << '@' + << this->pid_ + << '@' + << this->type_ + << '@'; + } + + s << this->msg_data_; + s.flush (); + return 0; +} diff --git a/ace/Log_Record.h b/ace/Log_Record.h new file mode 100644 index 00000000000..273e185c3c6 --- /dev/null +++ b/ace/Log_Record.h @@ -0,0 +1,135 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Log_Record.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_LM_RECORD_H) +#define ACE_LM_RECORD_H + +#include "ace/ACE.h" +#include "ace/Log_Priority.h" + +class ACE_Export ACE_Log_Record +{ + // = TITLE + // Defines the structure of an ACE logging record. +public: +friend ostream &operator << (ostream &, ACE_Log_Record &); + enum + { + MAXLOGMSGLEN = BUFSIZ * 4, + // Maximum size of a logging message. + + ALIGN_WORDB = 8, + // Most restrictive alignment. + + VERBOSE_LEN = 128 + // Size used by verbose mode. + // 20 (date) + 15 (host_name) + 10 (pid) + 10 (type) + 4 (@) ... + + // ? (progname) + }; + + // = Initialization + ACE_Log_Record (void); + ACE_Log_Record (ACE_Log_Priority lp, + long time_stamp, + long pid); + // Create a and set its priority, time stamp, and + // process id. + + int print (const char host_name[], + int verbose = 1, + FILE *fp = stderr, + size_t msg_data_len = 0); + // Write the contents of the logging record to the appropriate + // . + + int print (const char host_name[], + int verbose, + ostream &stream, + size_t msg_data_len = 0); + // Write the contents of the logging record to the appropriate + // . + + // = Marshall/demarshall + void encode (void); + // Encode the for transmission on the network. + + void decode (void); + // Decode the received from the network. + + // = Set/get methods + + long type (void) const; + // Get the type of the . + + void type (long); + // Set the type of the . + + long length (void) const; + // Get the length of the . + + void length (long); + // Set the length of the . + + long time_stamp (void) const; + // Get the time stamp of the . + + void time_stamp (long); + // Set the time stamp of the . + + long pid (void) const; + // Get the process id of the . + + void pid (long); + // Set the process id of the . + + char *msg_data (void); + // Get the message data of the . + + void msg_data (const char *data); + // Set the message data of the . + + void msg_data_len (size_t len); + // Set the size of the message data of the . + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + void round_up (void); + // Round up to the alignment restrictions. + + long type_; + // Type of logging record + + long length_; + // length of the logging record + + long time_stamp_; + // Time logging record generated + + long pid_; + // Id of process that generated the record + + char msg_data_[MAXLOGMSGLEN]; + // Logging record data +}; + +#include "ace/Log_Record.i" +#endif /* ACE_LM_Record_H */ diff --git a/ace/Log_Record.i b/ace/Log_Record.i new file mode 100644 index 00000000000..8ddba60122d --- /dev/null +++ b/ace/Log_Record.i @@ -0,0 +1,88 @@ +/* -*- C++ -*- */ +// $Id$ + +// Log_Record.i + +inline void +ACE_Log_Record::encode (void) +{ + ACE_TRACE ("ACE_Log_Record::encode"); + this->type_ = htonl (this->type_); + this->length_ = htonl (this->length_); + this->time_stamp_ = htonl (this->time_stamp_); + this->pid_ = htonl (this->pid_); +} + +inline void +ACE_Log_Record::decode (void) +{ + ACE_TRACE ("ACE_Log_Record::decode"); + this->type_ = ntohl (this->type_); + this->time_stamp_ = ntohl (this->time_stamp_); + this->pid_ = ntohl (this->pid_); + this->length_ = ntohl (this->length_); +} + +inline long +ACE_Log_Record::type (void) const +{ + ACE_TRACE ("ACE_Log_Record::type"); + return this->type_; +} + +inline void +ACE_Log_Record::type (long t) +{ + ACE_TRACE ("ACE_Log_Record::type"); + this->type_ = t; +} + +inline long +ACE_Log_Record::length (void) const +{ + ACE_TRACE ("ACE_Log_Record::length"); + return this->length_; +} + +inline void +ACE_Log_Record::length (long l) +{ + ACE_TRACE ("ACE_Log_Record::length"); + this->length_ = l; +} + +inline long +ACE_Log_Record::time_stamp (void) const +{ + ACE_TRACE ("ACE_Log_Record::time_stamp"); + return this->time_stamp_; +} + +inline void +ACE_Log_Record::time_stamp (long ts) +{ + ACE_TRACE ("ACE_Log_Record::time_stamp"); + this->time_stamp_ = ts; +} + +inline long +ACE_Log_Record::pid (void) const +{ + ACE_TRACE ("ACE_Log_Record::pid"); + return this->pid_; +} + +inline void +ACE_Log_Record::pid (long p) +{ + ACE_TRACE ("ACE_Log_Record::pid"); + this->pid_ = p; +} + +inline char * +ACE_Log_Record::msg_data (void) +{ + ACE_TRACE ("ACE_Log_Record::msg_data"); + return this->msg_data_; +} + diff --git a/ace/Makefile b/ace/Makefile new file mode 100644 index 00000000000..36abc2e2f0e --- /dev/null +++ b/ace/Makefile @@ -0,0 +1,2107 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the entire ACE release +#---------------------------------------------------------------------------- + +MAKEFILE = Makefile +LIB = libACE.a +SHLIB = libACE.so + +FILES = ACE \ + Activation_Queue \ + Addr \ + ARGV \ + CORBA_Handler \ + CORBA_Ref \ + DEV \ + DEV_Addr \ + DEV_Connector \ + DEV_IO \ + Dump \ + Dynamic \ + Event_Handler \ + FIFO \ + FIFO_Recv \ + FIFO_Recv_Msg \ + FIFO_Send \ + FIFO_Send_Msg \ + FILE \ + FILE_Addr \ + FILE_Connector \ + FILE_IO \ + Get_Opt \ + Handle_Set \ + High_Res_Timer \ + INET_Addr \ + IO_Cntl_Msg \ + IO_SAP \ + IPC_SAP \ + Local_Name_Space \ + Local_Tokens \ + LSOCK \ + LSOCK_Acceptor \ + LSOCK_CODgram \ + LSOCK_Connector \ + LSOCK_Dgram \ + LSOCK_Stream \ + Log_Msg \ + Log_Record \ + Malloc \ + Mem_Map \ + Memory_Pool \ + Message_Block \ + Method_Object \ + Name_Proxy \ + Name_Request_Reply \ + Name_Space \ + Naming_Context \ + Obstack \ + OS \ + Parse_Node \ + Pipe \ + Proactor \ + Process \ + Process_Manager \ + Profile_Timer \ + Reactor \ + ReactorEx \ + Read_Buffer \ + Remote_Name_Space \ + Remote_Tokens \ + SOCK \ + SOCK_Acceptor \ + SOCK_CODgram \ + SOCK_Connector \ + SOCK_Dgram \ + SOCK_Dgram_Bcast \ + SOCK_IO \ + SOCK_Dgram_Mcast \ + SOCK_Stream \ + SPIPE \ + SPIPE_Acceptor \ + SPIPE_Addr \ + SPIPE_Connector \ + SPIPE_Stream \ + SString \ + Service_Config \ + Service_Manager \ + Service_Object \ + Service_Record \ + Service_Repository \ + Shared_Memory_MM \ + Shared_Memory_SV \ + Shared_Object \ + Signal \ + SV_Message \ + SV_Message_Queue \ + SV_Semaphore_Complex \ + SV_Semaphore_Simple \ + SV_Shared_Memory \ + Synch \ + Synch_Options \ + System_Time \ + TLI \ + TLI_Acceptor \ + TLI_Connector \ + TLI_Stream \ + Thread \ + Thread_Manager \ + Time_Request_Reply \ + Time_Value \ + Timer_Queue \ + Token \ + Token_Collection \ + Token_Invariants \ + Token_Manager \ + Token_Request_Reply \ + Trace \ + TTY_IO \ + UNIX_Addr \ + UPIPE_Acceptor \ + UPIPE_Connector \ + UPIPE_Stream \ + XtReactor + +TEMPLATE_FILES = \ + Acceptor \ + Auto_Ptr \ + Connector \ + Dump_T \ + Dynamic_Service \ + Event_Handler_T \ + Future \ + Local_Name_Space_T \ + Local_Tokens_T \ + Malloc_T \ + Map_Manager \ + Message_Queue \ + Module \ + Set \ + Singleton \ + Stack \ + Strategies \ + Stream \ + Stream_Modules \ + Svc_Handler \ + Synch_T \ + Task \ + Typed_SV_Message \ + Typed_SV_Message_Queue + +DEFS = $(addsuffix .h,$(FILES)) Svc_Conf_Tokens.h +DEFS += $(addsuffix .i,$(FILES)) +LSRC = $(addsuffix .cpp,$(FILES)) \ + Svc_Conf_l.cpp Svc_Conf_y.cpp +LSRC2 = $(addsuffix .cpp,$(TEMPLATE_FILES)) + +BUILD = $(VLIB) $(VSHLIB) $(SHLIBA) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +Svc_Conf_y.cpp: Svc_Conf.y + $(YACC) -d Svc_Conf.y + sed -e "s/char *getenv/char *ace_foo/g" -e "s/= getenv/= ACE_OS::getenv/g" -e "s/yyerrlab://g" -e "s/yynewerror://g" -e "s/yy/ace_yy/g" < y.tab.c > /tmp/$@ + cp /tmp/$@ $@ + $(RM) -f /tmp/$@ + sed -e "s/yy/ace_yy/g" < y.tab.h >> /tmp/$@ + cp /tmp/$@ Svc_Conf_Tokens.h + $(RM) -f /tmp/$@ + +Svc_Conf_l.cpp: Svc_Conf.l + $(LEX) -t -I Svc_Conf.l > $@ + sed -e "s/unistd/stdio/g" -e "s/yy/ace_yy/g" -e "s/free( ptr );/free( ACE_MALLOC_T (ptr) );/g" -e "s/realloc( ptr, size );/realloc( ACE_MALLOC_T (ptr), size );/g" < $@ > /tmp/$@ + cp /tmp/$@ $@ + $(RM) -f /tmp/$@ + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/ACE.o .shobj/ACE.so: ACE.cpp \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i +.obj/Activation_Queue.o .shobj/Activation_Queue.so: Activation_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Activation_Queue.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Method_Object.h +.obj/Addr.o .shobj/Addr.so: Addr.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.i +.obj/ARGV.o .shobj/ARGV.so: ARGV.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/ARGV.h \ + $(WRAPPER_ROOT)/ace/ARGV.i +.obj/CORBA_Handler.o .shobj/CORBA_Handler.so: CORBA_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/CORBA_Handler.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/CORBA_Handler.i +.obj/CORBA_Ref.o .shobj/CORBA_Ref.so: CORBA_Ref.cpp \ + $(WRAPPER_ROOT)/ace/CORBA_Ref.h \ + $(WRAPPER_ROOT)/ace/CORBA_Ref.i +.obj/DEV.o .shobj/DEV.so: DEV.cpp \ + $(WRAPPER_ROOT)/ace/DEV.h \ + $(WRAPPER_ROOT)/ace/IO_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IO_SAP.i \ + $(WRAPPER_ROOT)/ace/DEV_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/DEV.i +.obj/DEV_Addr.o .shobj/DEV_Addr.so: DEV_Addr.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/DEV_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/DEV_Addr.i +.obj/DEV_Connector.o .shobj/DEV_Connector.so: DEV_Connector.cpp \ + $(WRAPPER_ROOT)/ace/DEV_Connector.h \ + $(WRAPPER_ROOT)/ace/DEV_IO.h \ + $(WRAPPER_ROOT)/ace/DEV.h \ + $(WRAPPER_ROOT)/ace/IO_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IO_SAP.i \ + $(WRAPPER_ROOT)/ace/DEV_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/DEV.i \ + $(WRAPPER_ROOT)/ace/DEV_IO.i \ + $(WRAPPER_ROOT)/ace/DEV_Connector.i +.obj/DEV_IO.o .shobj/DEV_IO.so: DEV_IO.cpp \ + $(WRAPPER_ROOT)/ace/DEV_IO.h \ + $(WRAPPER_ROOT)/ace/DEV.h \ + $(WRAPPER_ROOT)/ace/IO_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IO_SAP.i \ + $(WRAPPER_ROOT)/ace/DEV_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/DEV.i \ + $(WRAPPER_ROOT)/ace/DEV_IO.i +.obj/Dump.o .shobj/Dump.so: Dump.cpp \ + $(WRAPPER_ROOT)/ace/Dump.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Dump_T.h \ + $(WRAPPER_ROOT)/ace/Dump_T.cpp +.obj/Dynamic.o .shobj/Dynamic.so: Dynamic.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Dynamic.i +.obj/Event_Handler.o .shobj/Event_Handler.so: Event_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.i +.obj/FIFO.o .shobj/FIFO.so: FIFO.cpp \ + $(WRAPPER_ROOT)/ace/FIFO.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/FIFO.i +.obj/FIFO_Recv.o .shobj/FIFO_Recv.so: FIFO_Recv.cpp \ + $(WRAPPER_ROOT)/ace/FIFO_Recv.h \ + $(WRAPPER_ROOT)/ace/FIFO.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/FIFO_Recv.i +.obj/FIFO_Recv_Msg.o .shobj/FIFO_Recv_Msg.so: FIFO_Recv_Msg.cpp \ + $(WRAPPER_ROOT)/ace/FIFO_Recv_Msg.h \ + $(WRAPPER_ROOT)/ace/FIFO_Recv.h \ + $(WRAPPER_ROOT)/ace/FIFO.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/FIFO_Recv.i \ + $(WRAPPER_ROOT)/ace/FIFO_Recv_Msg.i +.obj/FIFO_Send.o .shobj/FIFO_Send.so: FIFO_Send.cpp \ + $(WRAPPER_ROOT)/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/ace/FIFO.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/FIFO_Send.i +.obj/FIFO_Send_Msg.o .shobj/FIFO_Send_Msg.so: FIFO_Send_Msg.cpp \ + $(WRAPPER_ROOT)/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/ace/FIFO.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/ace/FIFO_Send_Msg.i +.obj/FILE.o .shobj/FILE.so: FILE.cpp \ + $(WRAPPER_ROOT)/ace/FILE.h \ + $(WRAPPER_ROOT)/ace/IO_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IO_SAP.i \ + $(WRAPPER_ROOT)/ace/FILE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/FILE.i +.obj/FILE_Addr.o .shobj/FILE_Addr.so: FILE_Addr.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/FILE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/FILE_Addr.i +.obj/FILE_Connector.o .shobj/FILE_Connector.so: FILE_Connector.cpp \ + $(WRAPPER_ROOT)/ace/FILE_Connector.h \ + $(WRAPPER_ROOT)/ace/FILE_IO.h \ + $(WRAPPER_ROOT)/ace/FILE.h \ + $(WRAPPER_ROOT)/ace/IO_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IO_SAP.i \ + $(WRAPPER_ROOT)/ace/FILE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/FILE.i \ + $(WRAPPER_ROOT)/ace/FILE_IO.i \ + $(WRAPPER_ROOT)/ace/FILE_Connector.i +.obj/FILE_IO.o .shobj/FILE_IO.so: FILE_IO.cpp \ + $(WRAPPER_ROOT)/ace/FILE_IO.h \ + $(WRAPPER_ROOT)/ace/FILE.h \ + $(WRAPPER_ROOT)/ace/IO_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IO_SAP.i \ + $(WRAPPER_ROOT)/ace/FILE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/FILE.i \ + $(WRAPPER_ROOT)/ace/FILE_IO.i +.obj/Get_Opt.o .shobj/Get_Opt.so: Get_Opt.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Get_Opt.i +.obj/Handle_Set.o .shobj/Handle_Set.so: Handle_Set.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.i +.obj/High_Res_Timer.o .shobj/High_Res_Timer.so: High_Res_Timer.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/High_Res_Timer.h \ + $(WRAPPER_ROOT)/ace/High_Res_Timer.i +.obj/INET_Addr.o .shobj/INET_Addr.so: INET_Addr.cpp \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.i +.obj/IO_Cntl_Msg.o .shobj/IO_Cntl_Msg.so: IO_Cntl_Msg.cpp +.obj/IO_SAP.o .shobj/IO_SAP.so: IO_SAP.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IO_SAP.h \ + $(WRAPPER_ROOT)/ace/IO_SAP.i +.obj/IPC_SAP.o .shobj/IPC_SAP.so: IPC_SAP.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i +.obj/Local_Name_Space.o .shobj/Local_Name_Space.so: Local_Name_Space.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Local_Name_Space.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/Local_Name_Space_T.h \ + $(WRAPPER_ROOT)/ace/Name_Space.h \ + $(WRAPPER_ROOT)/ace/Name_Proxy.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Name_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Naming_Context.h \ + $(WRAPPER_ROOT)/ace/Local_Name_Space_T.cpp +.obj/Local_Tokens.o .shobj/Local_Tokens.so: Local_Tokens.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Stack.h \ + $(WRAPPER_ROOT)/ace/Stack.cpp \ + $(WRAPPER_ROOT)/ace/Stack.i \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + $(WRAPPER_ROOT)/ace/Token_Manager.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens.i +.obj/LSOCK.o .shobj/LSOCK.so: LSOCK.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/LSOCK.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/LSOCK.i +.obj/LSOCK_Acceptor.o .shobj/LSOCK_Acceptor.so: LSOCK_Acceptor.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/UNIX_Addr.h \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/LSOCK.h \ + $(WRAPPER_ROOT)/ace/LSOCK.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Acceptor.i +.obj/LSOCK_CODgram.o .shobj/LSOCK_CODgram.so: LSOCK_CODgram.cpp \ + $(WRAPPER_ROOT)/ace/LSOCK_CODgram.h \ + $(WRAPPER_ROOT)/ace/LSOCK.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/LSOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_CODgram.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_CODgram.i \ + $(WRAPPER_ROOT)/ace/LSOCK_CODgram.i +.obj/LSOCK_Connector.o .shobj/LSOCK_Connector.so: LSOCK_Connector.cpp \ + $(WRAPPER_ROOT)/ace/LSOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/LSOCK.h \ + $(WRAPPER_ROOT)/ace/LSOCK.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/UNIX_Addr.h \ + $(WRAPPER_ROOT)/ace/LSOCK_Connector.i +.obj/LSOCK_Dgram.o .shobj/LSOCK_Dgram.so: LSOCK_Dgram.cpp \ + $(WRAPPER_ROOT)/ace/LSOCK_Dgram.h \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.i \ + $(WRAPPER_ROOT)/ace/LSOCK.h \ + $(WRAPPER_ROOT)/ace/LSOCK.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Dgram.i +.obj/LSOCK_Stream.o .shobj/LSOCK_Stream.so: LSOCK_Stream.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/LSOCK.h \ + $(WRAPPER_ROOT)/ace/LSOCK.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.i +.obj/Log_Msg.o .shobj/Log_Msg.so: Log_Msg.cpp \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/OS.i \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/ace/FIFO.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/ace/FIFO_Send_Msg.i +.obj/Log_Record.o .shobj/Log_Record.so: Log_Record.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i +.obj/Malloc.o .shobj/Malloc.so: Malloc.cpp \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Malloc.i +.obj/Mem_Map.o .shobj/Mem_Map.so: Mem_Map.cpp \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.i +.obj/Memory_Pool.o .shobj/Memory_Pool.so: Memory_Pool.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.i +.obj/Message_Block.o .shobj/Message_Block.so: Message_Block.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Message_Block.i +.obj/Method_Object.o .shobj/Method_Object.so: Method_Object.cpp \ + $(WRAPPER_ROOT)/ace/Method_Object.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h +.obj/Name_Proxy.o .shobj/Name_Proxy.so: Name_Proxy.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Name_Proxy.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Name_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/SString.h +.obj/Name_Request_Reply.o .shobj/Name_Request_Reply.so: Name_Request_Reply.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Name_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/SString.h +.obj/Name_Space.o .shobj/Name_Space.so: Name_Space.cpp \ + $(WRAPPER_ROOT)/ace/Name_Space.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Name_Proxy.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Name_Request_Reply.h +.obj/Naming_Context.o .shobj/Naming_Context.so: Naming_Context.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Naming_Context.h \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Name_Proxy.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Name_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Name_Space.h \ + $(WRAPPER_ROOT)/ace/Remote_Name_Space.h \ + $(WRAPPER_ROOT)/ace/Local_Name_Space.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + $(WRAPPER_ROOT)/ace/Local_Name_Space_T.h \ + $(WRAPPER_ROOT)/ace/Local_Name_Space_T.cpp +.obj/Obstack.o .shobj/Obstack.so: Obstack.cpp \ + $(WRAPPER_ROOT)/ace/Obstack.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i +.obj/OS.o .shobj/OS.so: OS.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/ARGV.h \ + $(WRAPPER_ROOT)/ace/OS.i +.obj/Parse_Node.o .shobj/Parse_Node.so: Parse_Node.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Repository.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + $(WRAPPER_ROOT)/ace/Parse_Node.h \ + $(WRAPPER_ROOT)/ace/Parse_Node.i +.obj/Pipe.o .shobj/Pipe.so: Pipe.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i +.obj/Proactor.o .shobj/Proactor.so: Proactor.cpp \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Proactor.i +.obj/Process.o .shobj/Process.so: Process.cpp \ + $(WRAPPER_ROOT)/ace/Process.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ARGV.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/Acceptor.cpp \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/Process.i +.obj/Process_Manager.o .shobj/Process_Manager.so: Process_Manager.cpp +.obj/Profile_Timer.o .shobj/Profile_Timer.so: Profile_Timer.cpp \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Profile_Timer.i +.obj/Reactor.o .shobj/Reactor.so: Reactor.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i +.obj/ReactorEx.o .shobj/ReactorEx.so: ReactorEx.cpp \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Token.h +.obj/Read_Buffer.o .shobj/Read_Buffer.so: Read_Buffer.cpp \ + $(WRAPPER_ROOT)/ace/Read_Buffer.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Read_Buffer.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h +.obj/Remote_Name_Space.o .shobj/Remote_Name_Space.so: Remote_Name_Space.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Remote_Name_Space.h \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Name_Proxy.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Name_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Name_Space.h +.obj/Remote_Tokens.o .shobj/Remote_Tokens.so: Remote_Tokens.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Remote_Tokens.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Stack.h \ + $(WRAPPER_ROOT)/ace/Stack.cpp \ + $(WRAPPER_ROOT)/ace/Stack.i \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + $(WRAPPER_ROOT)/ace/Token_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Singleton.h \ + $(WRAPPER_ROOT)/ace/Singleton.cpp \ + $(WRAPPER_ROOT)/ace/Singleton.i \ + $(WRAPPER_ROOT)/ace/Remote_Tokens.i +.obj/SOCK.o .shobj/SOCK.so: SOCK.cpp \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i +.obj/SOCK_Acceptor.o .shobj/SOCK_Acceptor.so: SOCK_Acceptor.cpp \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.i +.obj/SOCK_CODgram.o .shobj/SOCK_CODgram.so: SOCK_CODgram.cpp \ + $(WRAPPER_ROOT)/ace/SOCK_CODgram.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_CODgram.i +.obj/SOCK_Connector.o .shobj/SOCK_Connector.so: SOCK_Connector.cpp \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Handle_Set.h +.obj/SOCK_Dgram.o .shobj/SOCK_Dgram.so: SOCK_Dgram.cpp \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.i +.obj/SOCK_Dgram_Bcast.o .shobj/SOCK_Dgram_Bcast.so: SOCK_Dgram_Bcast.cpp \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram_Bcast.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.i \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram_Bcast.i +.obj/SOCK_IO.o .shobj/SOCK_IO.so: SOCK_IO.cpp \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i +.obj/SOCK_Dgram_Mcast.o .shobj/SOCK_Dgram_Mcast.so: SOCK_Dgram_Mcast.cpp \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram_Mcast.h \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram_Mcast.i +.obj/SOCK_Stream.o .shobj/SOCK_Stream.so: SOCK_Stream.cpp \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/Typed_SV_Message.i +.obj/Typed_SV_Message_Queue.o .shobj/Typed_SV_Message_Queue.so: Typed_SV_Message_Queue.cpp \ +.obj/Typed_SV_Message_Queue.o .shobj/Typed_SV_Message_Queue.so: Typed_SV_Message_Queue.cpp \ + $(ACE_ROOT)/ace/Typed_SV_Message.cpp + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/iosfwd.h \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS.i $(ACE_ROOT)/ace/Trace.h \ + $(ACE_ROOT)/ace/Log_Record.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Version.h \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Typed_SV_Message.i \ + $(ACE_ROOT)/ace/Typed_SV_Message.i \ + $(ACE_ROOT)/ace/Typed_SV_Message.cpp \ + $(ACE_ROOT)/ace/Typed_SV_Message_Queue.h \ + $(ACE_ROOT)/ace/SV_Message.i \ + $(ACE_ROOT)/ace/Typed_SV_Message_Queue.i + $(ACE_ROOT)/ace/Typed_SV_Message_Queue.i + $(ACE_ROOT)/ace/Typed_SV_Message_Queue.i \ + $(ACE_ROOT)/ace/Typed_SV_Message_Queue.cpp diff --git a/ace/Malloc.cpp b/ace/Malloc.cpp new file mode 100644 index 00000000000..734827dc9b6 --- /dev/null +++ b/ace/Malloc.cpp @@ -0,0 +1,81 @@ +// Malloc.cpp +// $Id$ + +#if !defined (ACE_MALLOC_C) +#define ACE_MALLOC_C + +#define ACE_BUILD_DLL +#include "ace/Malloc.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Malloc.i" +#endif /* __ACE_INLINE__ */ + +void +ACE_Control_Block::dump (void) const +{ + ACE_TRACE ("ACE_Control_Block::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->name_head_->dump (); + ACE_DEBUG ((LM_DEBUG, "freep_ = %x", this->freep_)); + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Name_Node::ACE_Name_Node (void) +{ + ACE_TRACE ("ACE_Name_Node::ACE_Name_Node"); +} + +ACE_Name_Node::ACE_Name_Node (const char *name, + void *ptr, + ACE_Name_Node *next) + : pointer_ (ptr), + next_ (next) +{ + ACE_TRACE ("ACE_Name_Node::ACE_Name_Node"); + ACE_OS::strcpy (this->name_, name); +} + +void +ACE_Name_Node::dump (void) const +{ + ACE_TRACE ("ACE_Name_Node"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "pointer = %x", this->pointer_)); + ACE_DEBUG ((LM_DEBUG, "\nnext_ = %x", this->next_)); + ACE_DEBUG ((LM_DEBUG, "\nname_ = %s", this->name_)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +#if defined (ACE_MALLOC_STATS) +ACE_Malloc_Stats::ACE_Malloc_Stats (void) + : nblocks_ (0), + nchunks_ (0), + ninuse_ (0) +{ + ACE_TRACE ("ACE_Malloc_Stats::ACE_Malloc_Stats"); +} + +void +ACE_Malloc_Stats::dump (void) const +{ + ACE_TRACE ("ACE_Malloc_Stats::print"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + int nblocks = this->nblocks_; + int ninuse = this->ninuse_; + int nchunks = this->nchunks_; + + ACE_DEBUG ((LM_DEBUG, "nblocks = %d", nblocks)); + ACE_DEBUG ((LM_DEBUG, "\nninuse = %d", ninuse)); + ACE_DEBUG ((LM_DEBUG, "\nnchunks = %d", nchunks)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +#endif /* ACE_MALLOC_STATS */ +#endif /* ACE_MALLOC_C */ diff --git a/ace/Malloc.h b/ace/Malloc.h new file mode 100644 index 00000000000..fe67fca2150 --- /dev/null +++ b/ace/Malloc.h @@ -0,0 +1,217 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Malloc.h +// +// = AUTHOR +// Doug Schmidt and Irfan Pyarali +// +// ============================================================================ + +#if !defined (ACE_MALLOC_H) +#define ACE_MALLOC_H + +#include "ace/ACE.h" + +class ACE_Export ACE_Allocator + // = TITLE + // Interface for a dynamic memory allocator that uses inheritance + // and dynamic binding to provide extensible mechanisms for + // allocating and deallocating memory. +{ +public: + // = Memory Management + + virtual void *malloc (size_t nbytes) = 0; + // Allocate , but don't give them any initial value. + + virtual void *calloc (size_t nbytes, char initial_value = '\0') = 0; + // Allocate , giving them . + + virtual void free (void *ptr) = 0; + // Free (must have been allocated by ). + + virtual int remove (void) = 0; + // Remove any resources associated with this memory manager. + + // = Map manager like functions + + virtual int bind (const char *name, void *pointer, int duplicates = 0) = 0; + // Associate with . If == 0 then do + // not allow duplicate / associations, else if + // != 0 then allow duplicate / + // assocations. Returns 0 if successfully binds (1) a previously + // unbound or (2) != 0, returns 1 if trying to + // bind a previously bound and == 0, else + // returns -1 if a resource failure occurs. + + virtual int trybind (const char *name, void *&pointer) = 0; + // Associate with . Does not allow duplicate + // / associations. Returns 0 if successfully binds + // (1) a previously unbound , 1 if trying to bind a previously + // bound , or returns -1 if a resource failure occurs. When + // this call returns 's value will always reference the + // void * that is associated with. Thus, if the caller needs + // to use (e.g., to free it) a copy must be maintained by + // the caller. + + virtual int find (const char *name, void *&pointer) = 0; + // Locate and pass out parameter via pointer. If found, + // return 0, Returns -1 if failure occurs. + + virtual int find (const char *name) = 0; + // returns 0 if the name is in the mapping. -1, otherwise. + + virtual int unbind (const char *name) = 0; + // Unbind (remove) the name from the map. Don't return the pointer + // to the caller + + virtual int unbind (const char *name, void *&pointer) = 0; + // Break any association of name. Returns the value of pointer in + // case the caller needs to deallocate memory. + + // = Protection and "sync" (i.e., flushing memory to persistent + // backing store). + + virtual int sync (ssize_t len = -1, int flags = MS_SYNC) = 0; + // Sync bytes of the memory region to the backing store + // starting at base_addr_>. If == -1 then sync the + // whole region. + + virtual int sync (void *addr, size_t len, int flags = MS_SYNC) = 0; + // Sync bytes of the memory region to the backing store + // starting at . + + virtual int protect (ssize_t len = -1, int prot = PROT_RDWR) = 0; + // Change the protection of the pages of the mapped region to + // starting at base_addr_> up to bytes. If == -1 + // then change protection of all pages in the mapped region. + + virtual int protect (void *addr, size_t len, int prot = PROT_RDWR) = 0; + // Change the protection of the pages of the mapped region to + // starting at up to bytes. + + virtual void dump (void) const = 0; + // Dump the state of the object. +}; + +typedef long ACE_Malloc_Align; +// For alignment to long boundary + +union ACE_Export ACE_Malloc_Header +// TITLE +// This is a block header. +{ + struct ACE_Malloc_Control_Block + { + ACE_Malloc_Header *next_block_; + // Points to next block if on free list. + size_t size_; + // Size of this block. + } s_; + + ACE_Malloc_Align x_; + // Force alignment. +}; + +class ACE_Export ACE_Name_Node + // = TITLE + // This is stored as a linked list within the Memory_Pool + // to allow "named memory chunks." +{ +public: + // = Initialization methods. + ACE_Name_Node (const char *name, void *, ACE_Name_Node *); + ACE_Name_Node (void); + + char *name_; + // Name of the Node. + + void *pointer_; + // Pointer to the contents. + + ACE_Name_Node *next_; + // Pointer to the next node in the chain. + + void dump (void) const; + // Dump the state of the object. +}; + +class ACE_Export ACE_Control_Block + // = TITLE + // This information is stored in memory allocated by the MEMORY_POOL. + // + // = DESCRIPTION + // This class should be local to class ACE_Malloc, but cfront and + // G++ don't like nested classes in templates... +{ +public: + ACE_Name_Node *name_head_; + // Head of the linked list of Name Nodes. + + ACE_Malloc_Header *freep_; + // Current head of the freelist. + + char lock_name_[MAXNAMELEN]; + // Name of lock thats ensures mutual exclusion. + +#if defined (ACE_MALLOC_STATS) + // Keep statistics about ACE_Malloc state and performance. + ACE_Malloc_Stats malloc_stats_; +#endif /* ACE_MALLOC_STATS */ + + ACE_Malloc_Header base_; + // Dummy node used to anchor the freelist. + + void dump (void) const; + // Dump the state of the object. +}; + +#if defined (ACE_MALLOC_STATS) +#include "ace/Sync_T.h" +#if defined (ACE_HAS_THREADS) +#define ACE_PROCESS_MUTEX ACE_Process_Mutex +#else +#include "ace/SV_Semaphore_Simple.h" +#define ACE_PROCESS_MUTEX ACE_SV_Semaphore_Simple +#endif /* ACE_HAS_THREADS */ + +typedef ACE_Atomic_Op ACE_INT; + +struct ACE_Export ACE_Malloc_Stats +// TITLE +// This keeps stats on the usage of the memory manager. +{ + ACE_Malloc_Stats (void); + void dump (void) const; + + ACE_INT nchunks_; + // Coarse-grained unit of allocation. + + ACE_INT nblocks_; + // Fine-grained unit of allocation. + + ACE_INT ninuse_; + // Number of blocks in use +}; +#define AMS(X) X +#else +#define AMS(X) +#endif /* ACE_MALLOC_STATS */ + +#if defined (__ACE_INLINE__) +#include "ace/Malloc.i" +#endif /* __ACE_INLINE__ */ + +// Include the ACE_Malloc templates and ACE_Memory_Pool stuff at this point. +#include "ace/Malloc_T.h" +#include "ace/Memory_Pool.h" + +#endif /* ACE_MALLOC_H */ diff --git a/ace/Malloc.i b/ace/Malloc.i new file mode 100644 index 00000000000..ae0bc8064d4 --- /dev/null +++ b/ace/Malloc.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// $Id$ + +// Malloc.i diff --git a/ace/Malloc_T.cpp b/ace/Malloc_T.cpp new file mode 100644 index 00000000000..52390601baa --- /dev/null +++ b/ace/Malloc_T.cpp @@ -0,0 +1,574 @@ +// Malloc_T.cpp +// $Id$ + +#if !defined (ACE_MALLOC_T_C) +#define ACE_MALLOC_T_C + +#define ACE_BUILD_DLL +#include "ace/Malloc_T.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Malloc_T.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Malloc) + +template +ACE_Allocator_Adapter::ACE_Allocator_Adapter (const char *pool_name, + const char *lock_name) + : allocator_ (pool_name, lock_name) +{ + ACE_TRACE ("ACE_Allocator_Adapter::ACE_Allocator_Adapter"); +} + +template +ACE_Allocator_Adapter::ACE_Allocator_Adapter (const char *pool_name) + : allocator_ (pool_name) +{ + ACE_TRACE ("ACE_Allocator_Adapter::ACE_Allocator_Adapter"); +} + +template void +ACE_Allocator_Adapter::dump (void) const +{ + ACE_TRACE ("ACE_Malloc::dump"); + this->allocator_.dump (); +} + +template void +ACE_Malloc::dump (void) const +{ + ACE_TRACE ("ACE_Malloc::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->memory_pool_.dump (); + ACE_DEBUG ((LM_DEBUG, "cb_ptr_ = %x", this->cb_ptr_)); + ACE_DEBUG ((LM_DEBUG, "\n")); +#if defined (ACE_MALLOC_STATS) + this->malloc_stats_.dump (); +#endif /* ACE_MALLOC_STATS */ + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +#if defined (ACE_MALLOC_STATS) + +template void +ACE_Malloc::print_stats (void) +{ + ACE_TRACE ("ACE_Malloc::print_stats"); + ACE_GUARD (LOCK, ace_mon, this->lock_); + + this->cb_ptr_->malloc_stats_.print (); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) contents of freelist:\n")); + + for (ACE_Malloc_Header *currp = this->cb_ptr_->freep_->s_.next_block_; + ; + currp = currp->s_.next_block_) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) ptr = %u, ACE_Malloc_Header units = %d, byte units = %d\n", + currp, currp->s_.size_, + currp->s_.size_ * sizeof (ACE_Malloc_Header))); + if (currp == this->cb_ptr_->freep_) + break; + } +} +#endif /* ACE_MALLOC_STATS */ + +// Put block AP in the free list (locked version). + +template void +ACE_Malloc::free (void *ap) +{ + ACE_TRACE ("ACE_Malloc::free"); + ACE_GUARD (LOCK, ace_mon, this->lock_); + + this->shared_free (ap); +} + +// This function is called by the ACE_Malloc constructor to initialize +// the memory pool. The first time in it allocates room for the +// control block (as well as a chunk of memory, depending on +// rounding...). Depending on the type of (i.e., shared +// vs. local) subsequent calls from other processes will only +// initialize the control block pointer. + +template int +ACE_Malloc::open (void) +{ + ACE_TRACE ("ACE_Malloc::open"); + ACE_GUARD_RETURN (LOCK, ace_mon, this->lock_, -1); + + size_t rounded_bytes = 0; + int first_time = 0; + + this->cb_ptr_ = (ACE_Control_Block *) + this->memory_pool_.init_acquire (sizeof *this->cb_ptr_, + rounded_bytes, + first_time); + if (this->cb_ptr_ == 0) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "init_acquire failed"), -1); + else if (first_time) + { + // ACE_DEBUG ((LM_DEBUG, "(%P|%t) first time in, control block = %u\n", this->cb_ptr_)); + +#if defined (ACE_MALLOC_STATS) + // Call the constructor on the LOCK, using the placement + // operator! + new ((void *) &this->cb_ptr_->malloc_stats_) ACE_Malloc_Stats; +#endif /* ACE_MALLOC_STATS */ + + // Initialize the freelist pointer to point to the dummy + // ACE_Malloc_Header. + this->cb_ptr_->freep_ = &this->cb_ptr_->base_; + + // Initialize the dummy ACE_Malloc_Header to point to itself. + this->cb_ptr_->freep_->s_.size_ = 0; + this->cb_ptr_->freep_->s_.next_block_ = this->cb_ptr_->freep_; + + // initialize the name list to 0 + this->cb_ptr_->name_head_ = 0; + + + if (rounded_bytes > (sizeof *this->cb_ptr_ + sizeof (ACE_Malloc_Header))) + { + // If we've got any extra space at the end of the control + // block, then skip past the dummy ACE_Malloc_Header to + // point at the first free block. + ACE_Malloc_Header *p = this->cb_ptr_->freep_ + 1; + p->s_.size_ = (rounded_bytes - sizeof *this->cb_ptr_) + / sizeof (ACE_Malloc_Header); + + AMS (++this->cb_ptr_->malloc_stats_.nchunks_); + AMS (++this->cb_ptr_->malloc_stats_.nblocks_); + AMS (++this->cb_ptr_->malloc_stats_.ninuse_); + + // Insert the newly allocated chunk of memory into the free + // list. + this->shared_free ((void *) (p + 1)); + } + } + return 0; +} + +template +ACE_Malloc::ACE_Malloc (const char *pool_name) + : memory_pool_ (pool_name), + lock_ (pool_name == 0 ? 0 : ACE::basename (pool_name, + ACE_DIRECTORY_SEPARATOR_CHAR)) +{ + ACE_TRACE ("ACE_Malloc::ACE_Malloc"); + + this->open (); +} + +template +ACE_Malloc::ACE_Malloc (const char *pool_name, + const char *lock_name) + : memory_pool_ (pool_name), + lock_ (lock_name) +{ + ACE_TRACE ("ACE_Malloc::ACE_Malloc"); + + this->open (); +} + +// Clean up the resources allocated by ACE_Malloc. + +template int +ACE_Malloc::remove (void) +{ + ACE_TRACE ("ACE_Malloc::remove"); + // ACE_DEBUG ((LM_DEBUG, "(%P|%t) destroying ACE_Malloc\n")); + int result = 0; + +#if defined (ACE_MALLOC_STATS) + this->print_stats (); +#endif /* ACE_MALLOC_STATS */ + + // Remove the LOCK. + this->lock_.remove (); + + // Give the memory pool a chance to release its resources. + result = this->memory_pool_.release (); + + return result; +} + +// General-purpose memory allocator. Assumes caller holds the locks. + +template void * +ACE_Malloc::shared_malloc (size_t nbytes) +{ + ACE_TRACE ("ACE_Malloc::shared_malloc"); + + // Round up request to a multiple of the ACE_Malloc_Header size. + size_t nunits = (nbytes + sizeof (ACE_Malloc_Header) - 1) + / sizeof (ACE_Malloc_Header) + 1; + + // Begin the search starting at the place in the freelist + // where the last block was found. + ACE_Malloc_Header *prevp = this->cb_ptr_->freep_; + ACE_Malloc_Header *currp = prevp->s_.next_block_; + + // Search the freelist to locate a block of the appropriate size. + + for (int i = 0; ; i++, prevp = currp, currp = currp->s_.next_block_) + { + if (currp->s_.size_ >= nunits) // Big enough + { + AMS (++this->cb_ptr_->malloc_stats_.ninuse_); + if (currp->s_.size_ == nunits) + // Exact size, just update the pointers. + prevp->s_.next_block_ = currp->s_.next_block_; + else + { + // Remaining chunk is larger than requested block, so + // allocate at tail end. + AMS (++this->cb_ptr_->malloc_stats_.nblocks_); + currp->s_.size_ -= nunits; + currp += currp->s_.size_; + currp->s_.size_ = nunits; + } + this->cb_ptr_->freep_ = prevp; + // Skip over the ACE_Malloc_Header when returning pointer. + return (void *) (currp + 1); + } + else if (currp == this->cb_ptr_->freep_) + { + // We've wrapped around freelist without finding a block. + // Therefore, we need to ask the memory pool for a new chunk + // of bytes. + + size_t chunk_bytes = 0; + + if ((currp = (ACE_Malloc_Header *) + this->memory_pool_.acquire (nunits * sizeof (ACE_Malloc_Header), + chunk_bytes)) != 0) + { + AMS (++this->cb_ptr_->malloc_stats_.nblocks_); + AMS (++this->cb_ptr_->malloc_stats_.nchunks_); + AMS (++this->cb_ptr_->malloc_stats_.ninuse_); + + // Compute the chunk size in ACE_Malloc_Header units. + currp->s_.size_ = chunk_bytes / sizeof (ACE_Malloc_Header); + + // Insert the new chunk into the freelist. + this->shared_free ((void *) (currp + 1)); + currp = this->cb_ptr_->freep_; + } + else + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "malloc"), 0); + } + } +} + +// General-purpose memory allocator. + +template void * +ACE_Malloc::malloc (size_t nbytes) +{ + ACE_TRACE ("ACE_Malloc::malloc"); + ACE_GUARD_RETURN (LOCK, ace_mon, this->lock_, 0); + + return this->shared_malloc (nbytes); +} + +// General-purpose memory allocator. + +template void * +ACE_Malloc::calloc (size_t nbytes, + char initial_value) +{ + ACE_TRACE ("ACE_Malloc::calloc"); + void *ptr = this->malloc (nbytes); + + if (ptr != 0) + ACE_OS::memset (ptr, initial_value, nbytes); + + return ptr; +} + +// Put block AP in the free list (must be called with locks held!) + +template void +ACE_Malloc::shared_free (void *ap) +{ + ACE_TRACE ("ACE_Malloc::shared_free"); + + if (ap == 0) + return; + + ACE_Malloc_Header *blockp; // Points to the block ACE_Malloc_Header. + ACE_Malloc_Header *currp; + + // Adjust AP to point to the block ACE_Malloc_Header + blockp = (ACE_Malloc_Header *) ap - 1; + + // Search until we find the location where the blocks belongs. Note + // that addresses are kept in sorted order. + + for (currp = this->cb_ptr_->freep_; + blockp <= currp || blockp >= currp->s_.next_block_; + currp = currp->s_.next_block_) + { + if (currp >= currp->s_.next_block_ + && (blockp > currp || blockp < currp->s_.next_block_)) + // Freed block at the start or the end of the memory pool + break; + } + + // Join to upper neighbor + if (blockp + blockp->s_.size_ == currp->s_.next_block_) + { + AMS (--this->cb_ptr_->malloc_stats_.nblocks_); + blockp->s_.size_ += currp->s_.next_block_->s_.size_; + blockp->s_.next_block_ = currp->s_.next_block_->s_.next_block_; + } + else + blockp->s_.next_block_ = currp->s_.next_block_; + + if (currp + currp->s_.size_ == blockp) // Join to lower neighbor + { + AMS (--this->cb_ptr_->malloc_stats_.nblocks_); + currp->s_.size_ += blockp->s_.size_; + currp->s_.next_block_ = blockp->s_.next_block_; + } + else + currp->s_.next_block_ = blockp; + + AMS (--this->cb_ptr_->malloc_stats_.ninuse_); + this->cb_ptr_->freep_ = currp; +} + +// No locks held here, caller must acquire/release lock. + +template ACE_Name_Node * +ACE_Malloc::shared_find (const char *name) +{ + ACE_TRACE ("ACE_Malloc::shared_find"); + + for (ACE_Name_Node *node = this->cb_ptr_->name_head_; + node != 0; + node = node->next_) + if (ACE_OS::strcmp (node->name_, name) == 0) + return node; + + return 0; +} + +template int +ACE_Malloc::shared_bind (const char *name, + void *pointer) +{ + // Combine the two allocations into one to avoid overhead... + ACE_Name_Node *new_node = (ACE_Name_Node *) + this->shared_malloc (sizeof (ACE_Name_Node) + ACE_OS::strlen (name) + 1); + + if (new_node == 0) + return -1; + + // This is a sleezy trick ;-) + new_node->name_ = (char *) (new_node + 1); + + // Insert new node at the head of the list. Note that (new_node) is + // *not* a cast! + ACE_NEW_RETURN (this->cb_ptr_->name_head_, + (new_node) ACE_Name_Node (name, pointer, + this->cb_ptr_->name_head_), + -1); + return 0; +} + +template int +ACE_Malloc::trybind (const char *name, + void *&pointer) +{ + ACE_TRACE ("ACE_Malloc::trybind"); + ACE_Write_Guard mon (this->lock_); + + ACE_Name_Node *node = this->shared_find (name); + if (node == 0) + // Didn't find it, so insert it. + return this->shared_bind (name, pointer); + else + { + // Found it, so return a copy of the current entry. + pointer = node->pointer_; + return 1; + } +} + +template int +ACE_Malloc::bind (const char *name, + void *pointer, + int duplicates) +{ + ACE_TRACE ("ACE_Malloc::bind"); + ACE_Write_Guard mon (this->lock_); + + if (duplicates == 0 && this->shared_find (name) != 0) + // If we're not allowing duplicates, then if the name is already + // present, return 1. + return 1; + else + // If we get this far, either we're allowing duplicates or we didn't + // find the name yet. + + return this->shared_bind (name, pointer); +} + +template int +ACE_Malloc::find (const char *name, void *&pointer) +{ + ACE_TRACE ("ACE_Malloc::find"); + + ACE_Read_Guard mon (this->lock_); + + ACE_Name_Node *node = this->shared_find (name); + + if (node == 0) + return -1; + else + { + pointer = node->pointer_; + return 0; + } +} + +template int +ACE_Malloc::find (const char *name) +{ + ACE_TRACE ("ACE_Malloc::find"); + + ACE_Read_Guard mon (this->lock_); + return this->shared_find (name) == 0 ? -1 : 0; +} + +template int +ACE_Malloc::unbind (const char *name, void *&pointer) +{ + ACE_TRACE ("ACE_Malloc::unbind"); + + ACE_Write_Guard mon (this->lock_); + ACE_Name_Node *prev = 0; + + for (ACE_Name_Node *curr = this->cb_ptr_->name_head_; + curr != 0; + curr = curr->next_) + { + if (ACE_OS::strcmp (curr->name_, name) == 0) + { + pointer = curr->pointer_; + + if (prev == 0) + this->cb_ptr_->name_head_ = curr->next_; + else + prev->next_ = curr->next_; + + // This will free up both the node and the name due to our + // sleezy trick in bind()! + this->shared_free (curr); + return 0; + } + prev = curr; + } + + // Didn't find it, so fail. + return -1; +} + +template int +ACE_Malloc::unbind (const char *name) +{ + ACE_TRACE ("ACE_Malloc::unbind"); + void *temp = 0; + return this->unbind (name, temp); +} + + +template void +ACE_Malloc_Iterator::dump (void) const +{ + ACE_TRACE ("ACE_Malloc_Iterator::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->curr_->dump (); + this->guard_.dump (); + ACE_DEBUG ((LM_DEBUG, "name_ = %s", this->name_)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +template +ACE_Malloc_Iterator::ACE_Malloc_Iterator (ACE_Malloc &malloc, + const char *name) + : malloc_ (malloc), + guard_ (malloc_.lock_), + curr_ (0), + name_ (name != 0 ? ACE_OS::strdup (name) : 0) +{ + ACE_TRACE ("ACE_Malloc_Iterator::ACE_Malloc_Iterator"); + // Cheap trick to make code simple. + ACE_Name_Node temp; + this->curr_ = &temp; + this->curr_->next_ = malloc_.cb_ptr_->name_head_; + + this->advance(); +} + +template +ACE_Malloc_Iterator::~ACE_Malloc_Iterator (void) +{ + ACE_OS::free ((void *) this->name_); +} + +template int +ACE_Malloc_Iterator::next (void *&next_entry, + char *&name) +{ + ACE_TRACE ("ACE_Malloc_Iterator::next"); + + if (curr_ != 0) + { + next_entry = curr_->pointer_; + name = curr_->name_; + return 1; + } + else + return 0; +} + +template int +ACE_Malloc_Iterator::next (void *&next_entry) +{ + ACE_TRACE ("ACE_Malloc_Iterator::next"); + + if (curr_ != 0) + { + next_entry = curr_->pointer_; + return 1; + } + else + return 0; +} + +template int +ACE_Malloc_Iterator::advance (void) +{ + ACE_TRACE ("ACE_Malloc_Iterator::advance"); + + this->curr_ = this->curr_->next_; + + if (this->name_ == 0) + return 1; + + for (; + this->curr_ != 0 && + ACE_OS::strcmp (this->name_, this->curr_->name_) != 0; + this->curr_ = this->curr_->next_) + continue; + return 1; +} + +#endif /* ACE_MALLOC_T_C */ diff --git a/ace/Malloc_T.h b/ace/Malloc_T.h new file mode 100644 index 00000000000..89434879f31 --- /dev/null +++ b/ace/Malloc_T.h @@ -0,0 +1,337 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Malloc_T.h +// +// = AUTHOR +// Doug Schmidt and Irfan Pyarali +// +// ============================================================================ + +#if !defined (ACE_MALLOC_T_H) +#define ACE_MALLOC_T_H + +#include "ace/ACE.h" +#include "ace/Log_Msg.h" +#include "ace/Synch.h" +#include "ace/Malloc.h" + +template +class ACE_Allocator_Adapter : public ACE_Allocator + // = TITLE + // This class is an Adapter that allows the to + // use the class below. +{ +public: + // Trait. + typedef MALLOC ALLOCATOR; + + // = Initialization. + ACE_Allocator_Adapter (const char *pool_name = ACE_DEFAULT_MUTEX); + ACE_Allocator_Adapter (const char *pool_name, + const char *lock_name); + // Constructor. + + // = Memory Management + + virtual void *malloc (size_t nbytes); + // Allocate , but don't give them any initial value. + + virtual void *calloc (size_t nbytes, char initial_value = '\0'); + // Allocate , giving them all an . + + virtual void free (void *ptr); + // Free (must have been allocated by ). + + virtual int remove (void); + // Remove any resources associated with this memory manager. + + // = Map manager like functions + + int bind (const char *name, void *pointer, int duplicates = 0); + // Associate with . If == 0 then do + // not allow duplicate / associations, else if + // != 0 then allow duplicate / + // assocations. Returns 0 if successfully binds (1) a previously + // unbound or (2) != 0, returns 1 if trying to + // bind a previously bound and == 0, else + // returns -1 if a resource failure occurs. + + int trybind (const char *name, void *&pointer); + // Associate with . Does not allow duplicate + // / associations. Returns 0 if successfully binds + // (1) a previously unbound , 1 if trying to bind a previously + // bound , or returns -1 if a resource failure occurs. When + // this call returns 's value will always reference the + // void * that is associated with. Thus, if the caller needs + // to use (e.g., to free it) a copy must be maintained by + // the caller. + + int find (const char *name, void *&pointer); + // Locate and pass out parameter via pointer. If found, + // return 0, Returns -1 if failure occurs. + + int find (const char *name); + // returns 0 if the name is in the mapping. -1, otherwise. + + int unbind (const char *name); + // Unbind (remove) the name from the map. Don't return the pointer + // to the caller + + int unbind (const char *name, void *&pointer); + // Break any association of name. Returns the value of pointer in + // case the caller needs to deallocate memory. + + // = Protection and "sync" (i.e., flushing data to backing store). + + int sync (ssize_t len = -1, int flags = MS_SYNC); + // Sync bytes of the memory region to the backing store + // starting at base_addr_>. If == -1 then sync the + // whole region. + + int sync (void *addr, size_t len, int flags = MS_SYNC); + // Sync bytes of the memory region to the backing store + // starting at . + + int protect (ssize_t len = -1, int prot = PROT_RDWR); + // Change the protection of the pages of the mapped region to + // starting at base_addr_> up to bytes. If == -1 + // then change protection of all pages in the mapped region. + + int protect (void *addr, size_t len, int prot = PROT_RDWR); + // Change the protection of the pages of the mapped region to + // starting at up to bytes. + + ALLOCATOR &allocator (void); + // Returns the underlying allocator. + + virtual void dump (void) const; + // Dump the state of the object. + +private: + ALLOCATOR allocator_; + // ALLOCATOR instance. +}; + +// Forward declaration. +template +class ACE_Malloc_Iterator; + +template +class ACE_Malloc + // = TITLE + // Define a C++ class that uses parameterized types to provide + // an extensible mechanism for encapsulating various of dynamic + // memory management strategies. + // + // = DESCRIPTION + // This class can be configured flexibly with different + // MEMORY_POOL strategies and different types of LOCK + // strategies. +{ +friend class ACE_Malloc_Iterator; +public: + typedef MEM_POOL MEMORY_POOL; + + // = Initialization and termination methods. + ACE_Malloc (const char *pool_name = 0); + // Initialize ACE_Malloc. This constructor passes to + // initialize the memory pool, and uses to + // automatically extract out the name used for the underlying lock + // name (if necessary). + + ACE_Malloc (const char *pool_name, + const char *lock_name); + // Initialize ACE_Malloc. This constructor passes to + // initialize the memory pool, and uses to automatically + // extract out the name used for the underlying lock name (if + // necessary). + + int remove (void); + // Releases resources allocated by ACE_Malloc. + + // = Memory management + + void *malloc (size_t nbytes); + // Allocate , but don't give them any initial value. + + void *calloc (size_t nbytes, char initial_value = '\0'); + // Allocate , giving them . + + void free (void *ptr); + // Deallocate memory pointed to by , which must have been + // allocated previously by malloc>. + + MEMORY_POOL &memory_pool (void); + // Returns a reference to the underlying memory pool. + + // = Map manager like functions + + int bind (const char *name, void *pointer, int duplicates = 0); + // Associate with . If == 0 then do + // not allow duplicate / associations, else if + // != 0 then allow duplicate / + // assocations. Returns 0 if successfully binds (1) a previously + // unbound or (2) != 0, returns 1 if trying to + // bind a previously bound and == 0, else + // returns -1 if a resource failure occurs. + + int trybind (const char *name, void *&pointer); + // Associate with . Does not allow duplicate + // / associations. Returns 0 if successfully binds + // (1) a previously unbound , 1 if trying to bind a previously + // bound , or returns -1 if a resource failure occurs. When + // this call returns 's value will always reference the + // void * that is associated with. Thus, if the caller needs + // to use (e.g., to free it) a copy must be maintained by + // the caller. + + int find (const char *name, void *&pointer); + // Locate and pass out parameter via . If found, + // return 0, returns -1 if failure occurs. + + int find (const char *name); + // Returns 0 if is in the mapping. -1, otherwise. + + int unbind (const char *name); + // Unbind (remove) the name from the map. Don't return the pointer + // to the caller. If you want to remove all occurrences of + // you'll need to call this method multiple times until it fails... + + int unbind (const char *name, void *&pointer); + // Unbind (remove) one association of to . Returns + // the value of pointer in case the caller needs to deallocate + // memory. If you want to remove all occurrences of you'll + // need to call this method multiple times until it fails... + + // = Protection and "sync" (i.e., flushing data to backing store). + + int sync (ssize_t len = -1, int flags = MS_SYNC); + // Sync bytes of the memory region to the backing store + // starting at base_addr_>. If == -1 then sync the + // whole region. + + int sync (void *addr, size_t len, int flags = MS_SYNC); + // Sync bytes of the memory region to the backing store + // starting at . + + int protect (ssize_t len = -1, int prot = PROT_RDWR); + // Change the protection of the pages of the mapped region to + // starting at base_addr_> up to bytes. If == -1 + // then change protection of all pages in the mapped region. + + int protect (void *addr, size_t len, int prot = PROT_RDWR); + // Change the protection of the pages of the mapped region to + // starting at up to bytes. + +#if defined (ACE_MALLOC_STATS) + void print_stats (void); + // Dump statistics of how malloc is behaving. +#endif /* ACE_MALLOC_STATS */ + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + int open (void); + // Initialize the Malloc pool. + + int shared_bind (const char *name, void *pointer); + // Associate with . Assumes that locks are held by + // callers. + + ACE_Name_Node *shared_find (const char *name); + // Try to locate . If found, return the associated + // , else returns 0 if can't find the . + // Assumes that locks are held by callers. + + void *shared_malloc (size_t nbytes); + // Allocate memory. Assumes that locks are held by callers. + + void shared_free (void *ptr); + // Deallocate memory. Assumes that locks are held by callers. + + MEMORY_POOL memory_pool_; + // Pool of memory used by ACE_Malloc + + ACE_Control_Block *cb_ptr_; + // Pointer to the control block (stored in memory controlled by + // MEMORY_POOL). + + LOCK lock_; + // Local that ensures mutual exclusion. +}; + +template +class ACE_Malloc_Iterator + // = TITLE + // Iterator for names stored in Malloc'd memory. + // + // = DESCRIPTION + // Does not allows deletions while iteration is occurring. +{ +public: + // = Initialization method. + ACE_Malloc_Iterator (ACE_Malloc &malloc, const char *name = 0); + // if = 0 it will iterate through everything else only + // through those entries whose match + + ~ACE_Malloc_Iterator (void); + + // = Iteration methods. + + int next (void *&next_entry); + // Pass back the next in the set that hasn't yet been + // visited. Returns 0 when all items have been seen, else 1. + + int next (void *&next_entry, char *&name); + // Pass back the next (and the associated with it) in + // the set that hasn't yet been visited. Returns 0 when all items + // have been seen, else 1. + + int advance (void); + // Move forward by one element in the set. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Malloc &malloc_; + // Malloc we are iterating over. + + ACE_Name_Node *curr_; + // Keeps track of how far we've advanced... + + ACE_Read_Guard guard_; + // Lock Malloc for the lifetime of the iterator. + + const char *name_; + // Name that we are searching for. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Malloc_T.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Malloc_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Malloc_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_MALLOC_H */ diff --git a/ace/Malloc_T.i b/ace/Malloc_T.i new file mode 100644 index 00000000000..a66cb7ef7fd --- /dev/null +++ b/ace/Malloc_T.i @@ -0,0 +1,150 @@ +/* -*- C++ -*- */ +// $Id$ + +// Malloc_T.i + +template ACE_INLINE void * +ACE_Allocator_Adapter::malloc (size_t nbytes) +{ + ACE_TRACE ("ACE_Allocator_Adapter::malloc"); + return this->allocator_.malloc (nbytes); +} + +template ACE_INLINE void * +ACE_Allocator_Adapter::calloc (size_t nbytes, + char initial_value) +{ + ACE_TRACE ("ACE_Allocator_Adapter::malloc"); + return this->allocator_.calloc (nbytes, initial_value); +} + +template ACE_INLINE MALLOC & +ACE_Allocator_Adapter::allocator (void) +{ + ACE_TRACE ("ACE_Allocator_Adapter::allocator"); + return this->allocator_; +} + +template ACE_INLINE void +ACE_Allocator_Adapter::free (void *ptr) +{ + ACE_TRACE ("ACE_Allocator_Adapter::free"); + this->allocator_.free (ptr); +} + +template ACE_INLINE int +ACE_Allocator_Adapter::remove (void) +{ + ACE_TRACE ("ACE_Allocator_Adapter::remove"); + return this->allocator_.remove (); +} + +template ACE_INLINE int +ACE_Allocator_Adapter::trybind (const char *name, + void *&pointer) +{ + ACE_TRACE ("ACE_Allocator_Adapter::trybind"); + return this->allocator_.trybind (name, pointer); +} + +template ACE_INLINE int +ACE_Allocator_Adapter::bind (const char *name, + void *pointer, + int duplicates) +{ + ACE_TRACE ("ACE_Allocator_Adapter::bind"); + return this->allocator_.bind (name, pointer, duplicates); +} + +template ACE_INLINE int +ACE_Allocator_Adapter::find (const char *name, + void *&pointer) +{ + ACE_TRACE ("ACE_Allocator_Adapter::find"); + return this->allocator_.find (name, pointer); +} + +template ACE_INLINE int +ACE_Allocator_Adapter::find (const char *name) +{ + ACE_TRACE ("ACE_Allocator_Adapter::find"); + return this->allocator_.find (name); +} + +template ACE_INLINE int +ACE_Allocator_Adapter::unbind (const char *name, void *&pointer) +{ + ACE_TRACE ("ACE_Allocator_Adapter::unbind"); + return this->allocator_.unbind (name, pointer); +} + +template ACE_INLINE int +ACE_Allocator_Adapter::unbind (const char *name) +{ + ACE_TRACE ("ACE_Allocator_Adapter::unbind"); + return this->allocator_.unbind (name); +} + +template ACE_INLINE int +ACE_Allocator_Adapter::sync (ssize_t len, int flags) +{ + ACE_TRACE ("ACE_Malloc::sync"); + return this->allocator_.sync (len, flags); +} + +template ACE_INLINE int +ACE_Allocator_Adapter::sync (void *addr, size_t len, int flags) +{ + ACE_TRACE ("ACE_Malloc::sync"); + return this->allocator_.sync (addr, len, flags); +} + +template ACE_INLINE int +ACE_Allocator_Adapter::protect (ssize_t len, int flags) +{ + ACE_TRACE ("ACE_Malloc::protect"); + return this->allocator_.protect (len, flags); +} + +template ACE_INLINE int +ACE_Allocator_Adapter::protect (void *addr, size_t len, int flags) +{ + ACE_TRACE ("ACE_Malloc::protect"); + return this->allocator_.protect (addr, len, flags); +} + +template MEM_POOL & +ACE_Malloc::memory_pool (void) +{ + ACE_TRACE ("ACE_Malloc::memory_pool"); + return this->memory_pool_; +} + +template int +ACE_Malloc::sync (ssize_t len, int flags) +{ + ACE_TRACE ("ACE_Malloc::sync"); + return this->memory_pool_.sync (len, flags); +} + +template int +ACE_Malloc::sync (void *addr, size_t len, int flags) +{ + ACE_TRACE ("ACE_Malloc::sync"); + return this->memory_pool_.sync (addr, len, flags); +} + +template int +ACE_Malloc::protect (ssize_t len, int flags) +{ + ACE_TRACE ("ACE_Malloc::protect"); + return this->memory_pool_.protect (len, flags); +} + +template int +ACE_Malloc::protect (void *addr, size_t len, int flags) +{ + ACE_TRACE ("ACE_Malloc::protect"); + return this->memory_pool_.protect (addr, len, flags); +} + diff --git a/ace/Map_Manager.cpp b/ace/Map_Manager.cpp new file mode 100644 index 00000000000..8a7794346bd --- /dev/null +++ b/ace/Map_Manager.cpp @@ -0,0 +1,575 @@ +// Map_Manager.cpp +// $Id$ + +#if !defined (ACE_MAP_MANAGER_C) +#define ACE_MAP_MANAGER_C + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Synch.h" +#include "ace/Malloc.h" +#include "ace/Service_Config.h" +#include "ace/Map_Manager.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Map_Manager.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Map_Entry) + +template void +ACE_Map_Entry::dump (void) const +{ + ACE_TRACE ("ACE_Map_Entry::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "is_free_ = %d", this->is_free_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Map_Manager) + +template void +ACE_Map_Manager::dump (void) const +{ + ACE_TRACE ("ACE_Map_Manager::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "max_size_ = %d", this->max_size_)); + ACE_DEBUG ((LM_DEBUG, "\ncur_size_ = %d", this->cur_size_)); + this->allocator_->dump (); + this->lock_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +template +ACE_Map_Manager::ACE_Map_Manager (size_t size, + ACE_Allocator *allocator) + : allocator_ (0), + max_size_ (0), + cur_size_ (0), + search_structure_ (0) +{ + ACE_TRACE ("ACE_Map_Manager::ACE_Map_Manager"); + + if (this->open (size, allocator) == -1) + ACE_ERROR ((LM_ERROR, "ACE_Map_Manager\n")); +} + +template +ACE_Map_Manager::ACE_Map_Manager (ACE_Allocator *allocator) + : allocator_ (0), + max_size_ (0), + cur_size_ (0), + search_structure_ (0) +{ + ACE_TRACE ("ACE_Map_Manager::ACE_Map_Manager"); + if (this->open (DEFAULT_SIZE, allocator) == -1) + ACE_ERROR ((LM_ERROR, "ACE_Map_Manager\n")); +} + +template int +ACE_Map_Manager::close_i (void) +{ + ACE_TRACE ("ACE_Map_Manager::close_i"); + + if (this->search_structure_ != 0) + { + this->allocator_->free (this->search_structure_); + this->search_structure_ = 0; + } + return 0; +} + +template int +ACE_Map_Manager::close (void) +{ + ACE_TRACE ("ACE_Map_Manager::close"); + ACE_Write_Guard m (this->lock_); + + return this->close_i (); +} + +template +ACE_Map_Manager::~ACE_Map_Manager (void) +{ + ACE_TRACE ("ACE_Map_Manager::~ACE_Map_Manager"); + this->close (); +} + +// Create a new search_structure of size SIZE. + +template int +ACE_Map_Manager::open (size_t size, + ACE_Allocator *allocator) +{ + ACE_TRACE ("ACE_Map_Manager::open"); + ACE_Write_Guard m (this->lock_); + + if (allocator == 0) + allocator = ACE_Service_Config::allocator (); + + this->allocator_ = allocator; + + // If we need to grow buffer, then remove the existing buffer. + if (this->max_size_ < size) + return this->resize_i (size); + return 0; +} + +template int +ACE_Map_Manager::resize_i (size_t size) +{ + ACE_TRACE ("ACE_Map_Manager::resize_i"); + + // If we need to grow buffer, then remove the existing buffer. + void *ptr = this->allocator_->malloc (size * sizeof (ACE_Map_Entry)); + + if (ptr == 0) + { + errno = ENOMEM; + return -1; + } + + size_t i; + + ACE_Map_Entry *temp = (ACE_Map_Entry *) ptr; + ACE_Map_Entry *foo; + + // Copy over the currently active elements. + for (i = 0; i < this->cur_size_; i++) + { + temp[i] = this->search_structure_[i]; // Structure assignment. + } + + this->max_size_ = size; + + // Mark the newly allocated elements as being "free". + + for (i = this->cur_size_; i < this->max_size_; i++) + { + // call the constructor for each element in the array + foo = new (&(temp[i])) ACE_Map_Entry; + temp[i].is_free_ = 1; + } + + this->allocator_->free (this->search_structure_); + + this->search_structure_ = temp; + return 0; +} + +template int +ACE_Map_Manager::shared_find (const EXT_ID &ext_id, + int &first_free) +{ + // See if the entry is already there, keeping track of the first + // free slot. + + for (size_t i = 0; i < this->cur_size_; i++) + { + ACE_Map_Entry &ss = this->search_structure_[i]; + + if (ss.is_free_ == 0) + { + if (ss.ext_id_ == ext_id) + return i; + } + else if (first_free == -1) + first_free = int (i); + } + + errno = ENOENT; + return -1; +} + +// Find the corresponding to the . + +template int +ACE_Map_Manager::shared_find (const EXT_ID &ext_id) +{ + ACE_TRACE ("ACE_Map_Manager::shared_find"); + + for (size_t i = 0; i < this->cur_size_; i++) + { + const ACE_Map_Entry &ss + = this->search_structure_[i]; + + if (ss.is_free_ == 0 && ss.ext_id_ == ext_id) + // We found it! + return i; + } + + // not found + errno = ENOENT; + return -1; +} + +template int +ACE_Map_Manager::shared_bind (const EXT_ID &ext_id, + const INT_ID &int_id, + int first_free) +{ + if (first_free > -1) + { + // We found a free spot, let's reuse it. + + ACE_Map_Entry &ss = this->search_structure_[first_free]; + + ss.ext_id_ = ext_id; + ss.int_id_ = int_id; + ss.is_free_ = 0; + this->allocator_->sync ((void *) &this->search_structure_[first_free], sizeof ss); + return 0; + } + + // Check if we have reached max_size_ + else if (this->cur_size_ == this->max_size_) + // We are out of room so grow the map + if (this->resize_i (this->max_size_ + DEFAULT_SIZE) == -1) + { + // Out of memory + errno = ENOMEM; + return -1; + } + + // Insert at the end of the active portion. + + ACE_Map_Entry &ss = this->search_structure_[this->cur_size_]; + + ss.int_id_ = int_id; + ss.ext_id_ = ext_id; + ss.is_free_ = 0; + this->allocator_->sync ((void *) &this->search_structure_[this->cur_size_], sizeof ss); + this->cur_size_++; + this->allocator_->sync ((void *) &this->cur_size_, sizeof this->cur_size_); + return 0; +} + +template int +ACE_Map_Manager::trybind_i (const EXT_ID &ext_id, + INT_ID &int_id) +{ + ACE_TRACE ("ACE_Map_Manager::trybind_i"); + int first_free = -1; + int index = this->shared_find (ext_id, first_free); + + if (index >= 0) + { + // There was already something there, so make a copy, but + // *don't* update anything in the map! + + int_id = this->search_structure_[index].int_id_; + return 1; + } + else + // We didn't find it, so let's bind it! + return this->shared_bind (ext_id, int_id, first_free); +} + +template int +ACE_Map_Manager::trybind (const EXT_ID &ext_id, + INT_ID &int_id) +{ + ACE_TRACE ("ACE_Map_Manager::trybind"); + ACE_Write_Guard m (this->lock_); + + return this->trybind_i (ext_id, int_id); +} + +template int +ACE_Map_Manager::find_i (const EXT_ID &ext_id) +{ + ACE_TRACE ("ACE_Map_Manager::find_i"); + return this->shared_find (ext_id); +} + +// Find the INT_ID corresponding to the EXT_ID. + +template int +ACE_Map_Manager::find (const EXT_ID &ext_id) +{ + ACE_TRACE ("ACE_Map_Manager::find"); + ACE_Read_Guard m (this->lock_); + + return this->find_i (ext_id); +} + +// Unbind (remove) the EXT_ID from the map and return it via an out +// parameter. Note that this method does *not* free up the INT_ID +// structure. Thus, if there is dynamic memory associated with this, +// the caller is responsible for freeing this memory. + +template int +ACE_Map_Manager::unbind_i (const EXT_ID &ext_id, + INT_ID &int_id) +{ + ACE_TRACE ("ACE_Map_Manager::unbind_i"); + + ssize_t index = this->shared_unbind (ext_id); + + if (index == -1) + return -1; + else + { + int_id = this->search_structure_[index].int_id_; + return 0; + } +} + +// Associate with . If is already in the +// map then the is not changed. Returns 0 if a new +// entry is bound successfully, returns 1 if an attempt is made to +// bind an existing entry, and returns -1 if failures occur. + +template int +ACE_Map_Manager::bind_i (const EXT_ID &ext_id, + const INT_ID &int_id) +{ + ACE_TRACE ("ACE_Map_Manager::bind_i"); + + int first_free = -1; + int index = this->shared_find (ext_id, first_free); + + if (index >= 0) + // It was already bound, so return 1. + return 1; + + else + // We didn't find it, so let's bind it! + return this->shared_bind (ext_id, int_id, first_free); +} + +// Associate with . If is not in the +// map then behaves just like . Otherwise, store the old +// values of and into the "out" parameters and +// rebind the new parameters. This is very useful if you need to +// have an atomic way of updating and you also need +// full control over memory allocation. Returns 0 if a new entry is +// bound successfully, returns 1 if an existing entry was rebound, +// and returns -1 if failures occur. + +template int +ACE_Map_Manager::rebind_i (const EXT_ID &ext_id, + const INT_ID &int_id, + EXT_ID &old_ext_id, + INT_ID &old_int_id) +{ + ACE_TRACE ("ACE_Map_Manager::rebind_i"); + + int first_free = -1; + int index = this->shared_find (ext_id, first_free); + + if (index >= 0) + { + // We found it, so make copies of the old entries and rebind + // current entries. + + ACE_Map_Entry &ss = this->search_structure_[index]; + + old_ext_id = ss.ext_id_; + old_int_id = ss.int_id_; + ss.ext_id_ = ext_id; + ss.int_id_ = int_id; + this->allocator_->sync ((void *) &this->search_structure_[index], sizeof ss); + return 1; + } + else + // We didn't find it, so let's bind it! + return this->shared_bind (ext_id, int_id, first_free); +} + +// Find the INT_ID corresponding to the EXT_ID. + +template int +ACE_Map_Manager::find_i (const EXT_ID &ext_id, + INT_ID &int_id) +{ + ACE_TRACE ("ACE_Map_Manager::find_i"); + + int index = this->shared_find (ext_id); + + if (index == -1) + // Didn't find it. + return -1; + else + { + // Found it, so assign a copy. + int_id = this->search_structure_[index].int_id_; + return 0; + } +} + +// Unbind (remove) the EXT_ID from the map. Keeps track of where +// the EXT_ID was found so that this->unbind (EXT_ID, INT_ID) +// can return it to the caller. + +template int +ACE_Map_Manager::shared_unbind (const EXT_ID &ext_id) +{ + ACE_TRACE ("ACE_Map_Manager::shared_unbind"); + for (size_t i = 0; i < this->cur_size_; i++) + { + ACE_Map_Entry &ss = this->search_structure_[i]; + + if (ss.is_free_ == 0 && ss.ext_id_ == ext_id) + { + size_t index = i; + + // Mark this entry as being free. + ss.is_free_ = 1; + + this->allocator_->sync ((void *) &ss.is_free_, + sizeof ss.is_free_); + + // If we just unbound the highest active entry, then we need + // to figure out where the next highest active entry is. + + if (i + 1 == this->cur_size_) + { + while (i > 0 && this->search_structure_[--i].is_free_) + continue; + + if (i == 0 && this->search_structure_[i].is_free_) + this->cur_size_ = 0; + else + this->cur_size_ = i + 1; + this->allocator_->sync ((void *) &this->cur_size_, + sizeof this->cur_size_); + } + return index; + } + } + errno = ENOENT; + return -1; +} + +template int +ACE_Map_Manager::unbind (const EXT_ID &ext_id, + INT_ID &int_id) +{ + ACE_TRACE ("ACE_Map_Manager::unbind"); + ACE_Write_Guard m (this->lock_); + + return this->unbind_i (ext_id, int_id); +} + +template int +ACE_Map_Manager::bind (const EXT_ID &ext_id, + const INT_ID &int_id) +{ + ACE_TRACE ("ACE_Map_Manager::bind"); + ACE_Write_Guard m (this->lock_); + + return this->bind_i (ext_id, int_id); +} + +template int +ACE_Map_Manager::rebind (const EXT_ID &ext_id, + const INT_ID &int_id, + EXT_ID &old_ext_id, + INT_ID &old_int_id) +{ + ACE_TRACE ("ACE_Map_Manager::rebind"); + ACE_Write_Guard m (this->lock_); + + return this->rebind_i (ext_id, int_id, old_ext_id, old_int_id); +} + +template int +ACE_Map_Manager::find (const EXT_ID &ext_id, + INT_ID &int_id) +{ + ACE_TRACE ("ACE_Map_Manager::find"); + ACE_Read_Guard m (this->lock_); + + return this->find_i (ext_id, int_id); +} + +// Unbind (remove) the EXT_ID from the map. Don't return the INT_ID +// to the caller (this is useful for collections where the INT_IDs are +// *not* dynamically allocated...) + +template int +ACE_Map_Manager::unbind_i (const EXT_ID &ext_id) +{ + ACE_TRACE ("ACE_Map_Manager::unbind_i"); + return this->shared_unbind (ext_id) == -1 ? -1 : 0; +} + +template int +ACE_Map_Manager::unbind (const EXT_ID &ext_id) +{ + ACE_TRACE ("ACE_Map_Manager::unbind"); + ACE_Write_Guard m (this->lock_); + return this->unbind_i (ext_id) == -1 ? -1 : 0; +} + +template int +ACE_Map_Manager::current_size (void) +{ + ACE_TRACE ("ACE_Map_Manager::current_size"); + ACE_Write_Guard m (this->lock_); + return this->cur_size_; +} + +template int +ACE_Map_Manager::total_size (void) +{ + ACE_TRACE ("ACE_Map_Manager::total_size"); + ACE_Write_Guard m (this->lock_); + return this->max_size_; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Map_Iterator) + +template void +ACE_Map_Iterator::dump (void) const +{ + ACE_TRACE ("ACE_Map_Iterator::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "next_ = %d", this->next_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +template +ACE_Map_Iterator::ACE_Map_Iterator (ACE_Map_Manager &mm) + : map_man_ (mm), + next_ (-1) +{ + ACE_TRACE ("ACE_Map_Iterator::ACE_Map_Iterator"); + this->advance (); +} + +template int +ACE_Map_Iterator::next (ACE_Map_Entry *&mm) +{ + ACE_TRACE ("ACE_Map_Iterator::next"); + ACE_Read_Guard m (this->map_man_.lock_); + + // Note that this->next_ is never negative at this point... + if (size_t (this->next_) < this->map_man_.cur_size_) + { + mm = &this->map_man_.search_structure_[this->next_]; + return 1; + } + else + return 0; +} + +template int +ACE_Map_Iterator::advance (void) +{ + ACE_TRACE ("ACE_Map_Iterator::advance"); + ACE_Read_Guard m (this->map_man_.lock_); + + for (++this->next_; + size_t (this->next_) < this->map_man_.cur_size_ + && this->map_man_.search_structure_[this->next_].is_free_; + this->next_++) + continue; + return this->next_; +} + +#endif /* ACE_MAP_MANAGER_C */ diff --git a/ace/Map_Manager.h b/ace/Map_Manager.h new file mode 100644 index 00000000000..74f142ffcef --- /dev/null +++ b/ace/Map_Manager.h @@ -0,0 +1,262 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Map_Manager.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_MAP_MANAGER_H) +#define ACE_MAP_MANAGER_H + +#include "ace/ACE.h" + +// Forward declaration. +class ACE_Allocator; + +template +struct ACE_Map_Entry + // = TITLE + // An entry in the Map. +{ + EXT_ID ext_id_; + // Key used to look up an entry. + + INT_ID int_id_; + // The contents of the entry itself. + + int is_free_; + // Keeps track whether entry is free or not. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +// Forward decl. +template +class ACE_Map_Iterator; + +template +class ACE_Map_Manager + // = TITLE + // Define a map abstraction (useful for managing connections and + // sessions). + // + // = DESCRIPTION + // This implementation of a map uses an array. It should + // be enhanced to use a hash table... + // This class uses an ACE_Allocator to allocate memory + // The user can make this a persistant class by providing an + // ACE_Allocator with a persistable memory pool +{ +friend class ACE_Map_Iterator; +public: + enum {DEFAULT_SIZE = ACE_DEFAULT_MAP_SIZE}; + + // = Initialization and termination methods. + ACE_Map_Manager (ACE_Allocator *allocator = 0); + // Initialize a with the . + + ACE_Map_Manager (size_t size, ACE_Allocator *allocator = 0); + // Initialize a with entries. + + int open (size_t length = DEFAULT_SIZE, + ACE_Allocator *allocator = 0); + // Initialize a with size . + + int close (void); + // Close down a and release dynamically allocated + // resources. + + ~ACE_Map_Manager (void); + // Close down a and release dynamically allocated + // resources. + + int trybind (const EXT_ID &ext_id, INT_ID &int_id); + // Associate with if and only if is not + // in the map. If is already in the map then the + // parameter is overwritten with the existing value in the map + // Returns 0 if a new entry is bound successfully, returns 1 if an + // attempt is made to bind an existing entry, and returns -1 if + // failures occur. + + int bind (const EXT_ID &ext_id, const INT_ID &int_id); + // Associate with . If is already in the + // map then the is not changed. Returns 0 if a new + // entry is bound successfully, returns 1 if an attempt is made to + // bind an existing entry, and returns -1 if failures occur. + + int rebind (const EXT_ID &ext_id, const INT_ID &int_id, + EXT_ID &old_ext_id, INT_ID &old_int_id); + // Associate with . If is not in the + // map then behaves just like . Otherwise, store the old + // values of and into the "out" parameters and + // rebind the new parameters. This is very useful if you need to + // have an atomic way of updating and you also need + // full control over memory allocation. Returns 0 if a new entry is + // bound successfully, returns 1 if an existing entry was rebound, + // and returns -1 if failures occur. + + int find (const EXT_ID &ext_id, INT_ID &int_id); + // Locate and pass out parameter via . If found, + // return 0, returns -1 if failure occurs. + + int find (const EXT_ID &ext_id); + // Returns 0 if the is in the mapping, otherwise -1. + + int unbind (const EXT_ID &ext_id, INT_ID &int_id); + // Break any association of . Returns the value of in + // case the caller needs to deallocate memory. + + int unbind (const EXT_ID &ext_id); + // Unbind (remove) the from the map. Don't return the + // to the caller (this is useful for collections where the s + // are *not* dynamically allocated...) + + int current_size (void); + // Return the current size of the map. + + int total_size (void); + // Return the total size of the map. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + + ACE_Map_Entry *search_structure_; + // Implementation of the Map (should use hashing instead of + // array...). + + // = The following methods do the actual work and assume that + // the locks are held by the private methods. + + int bind_i (const EXT_ID &ext_id, const INT_ID &int_id); + // Performs the binding of to . Must be + // called with locks held. + + int rebind_i (const EXT_ID &ext_id, const INT_ID &int_id, + EXT_ID &old_ext_id, INT_ID &old_int_id); + // Performs a rebinding of to . Must be called + // with locks held. + + int find_i (const EXT_ID &ext_id, INT_ID &int_id); + // Performs a find of using as the key. Must be + // called with locks held. + + int find_i (const EXT_ID &ext_id); + // Performs a find using as the key. Must be called with + // locks held. + + int unbind_i (const EXT_ID &ext_id, INT_ID &int_id); + // Performs an unbind of using as the key. Must + // be called with locks held. + + int unbind_i (const EXT_ID &ext_id); + // Performs an unbind using as the key. Must be called + // with locks held. + + int trybind_i (const EXT_ID &ext_id, INT_ID &int_id); + // Performs a conditional bind of using as the + // key. Must be called with locks held. + + int resize_i (size_t size); + // Resize the map. Must be called with locks held. + + int close_i (void); + // Close down a . Must be called with + // locks held. + + ACE_Allocator *allocator_; + // Pointer to a memory allocator. + + LOCK lock_; + // Synchronization variable for the MT_SAFE ACE_Map_Manager. + +private: + + int shared_find (const EXT_ID &ext_id, int &first_free); + // Locate an entry, keeping track of the first free slot. Must be + // called with locks held. + + int shared_find (const EXT_ID &ext_id); + // Locate an entry. Must be called with locks held. + + int shared_bind (const EXT_ID &ext_id, const INT_ID &int_id, int first_free); + // Bind an entry. Must be called with locks held. + + int shared_unbind (const EXT_ID &ext_id); + // Unbind (remove) the from the map. Keeps track of where + // the was found so that this->unbind (, ) + // can return it to the caller. Must be called with locks held. + + size_t max_size_; + // Total number of elements in this->search_structure_. + + size_t cur_size_; + // Index of highest active elementin this->search_structure_. +}; + +template +class ACE_Map_Iterator + // = TITLE + // Iterator for the ACE_Map_Manager. + // + // = DESCRIPTION + // Allows deletions while iteration is occurring. +{ +public: + // = Initialization method. + ACE_Map_Iterator (ACE_Map_Manager &mm); + + // = Iteration methods. + + int next (ACE_Map_Entry *&next_entry); + // Pass back the that hasn't been seen in the Set. + // Returns 0 when all items have been seen, else 1. + + int advance (void); + // Move forward by one element in the set. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Map_Manager &map_man_; + // Map we are iterating over. + + ssize_t next_; + // Keeps track of how far we've advanced... +}; + +#if defined (__ACE_INLINE__) +#include "ace/Map_Manager.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Map_Manager.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Map_Manager.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_MAP_MANAGER_H */ diff --git a/ace/Map_Manager.i b/ace/Map_Manager.i new file mode 100644 index 00000000000..7e1703cd066 --- /dev/null +++ b/ace/Map_Manager.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// $Id$ + +// Map_Manager.i diff --git a/ace/Mem_Map.cpp b/ace/Mem_Map.cpp new file mode 100644 index 00000000000..9f392f85f15 --- /dev/null +++ b/ace/Mem_Map.cpp @@ -0,0 +1,218 @@ +// Mem_Map.cpp +// $Id$ + +// Defines the member functions for the memory mapping facility. + +#define ACE_BUILD_DLL +#include "ace/Mem_Map.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Mem_Map.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Mem_Map) + +void +ACE_Mem_Map::dump (void) const +{ + ACE_TRACE ("ACE_Mem_Map::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "base_addr_ = %x", this->base_addr_)); + ACE_DEBUG ((LM_DEBUG, "\nfilename_ = %s", this->filename_)); + ACE_DEBUG ((LM_DEBUG, "\nlength_ = %d", this->length_)); + ACE_DEBUG ((LM_DEBUG, "\nhandle_ = %d", this->handle_)); + ACE_DEBUG ((LM_DEBUG, "\nfile_mapping_ = %d", this->file_mapping_)); + ACE_DEBUG ((LM_DEBUG, "\nclose_handle_ = %d", this->close_handle_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +int +ACE_Mem_Map::close (void) +{ + ACE_TRACE ("ACE_Mem_Map::close"); + + this->unmap (); + + if (this->file_mapping_ != this->handle_) + ACE_OS::close (this->file_mapping_); + + if (this->close_handle_) + return ACE_OS::close (this->handle_); + + return 0; +} + +ACE_Mem_Map::~ACE_Mem_Map (void) +{ + ACE_TRACE ("ACE_Mem_Map::~ACE_Mem_Map"); + + this->close (); +} + +// This function does the dirty work of actually calling ACE_OS::mmap +// to map the file into memory. + +int +ACE_Mem_Map::map_it (ACE_HANDLE handle, + int len_request, + int prot, + int share, + void *addr, + off_t pos) +{ + ACE_TRACE ("ACE_Mem_Map::map_it"); + this->base_addr_ = addr; + this->handle_ = handle; + + long file_len = ACE_OS::filesize (this->handle_); + + if (file_len == -1) + return -1; + + if (this->length_ < size_t (file_len)) + { + // If the length of the mapped region is less than the length of + // the file then we force a complete new remapping by setting + // the descriptor to ACE_INVALID_HANDLE (closing down the + // descriptor if necessary). + if (this->file_mapping_ != this->handle_) + ACE_OS::close (this->file_mapping_); + this->file_mapping_ = ACE_INVALID_HANDLE; + } + + // At this point we know is not negative... + this->length_ = size_t (file_len); + + if (len_request == -1) + len_request = 0; + + if ((this->length_ == 0 && len_request > 0) + || this->length_ < size_t (len_request)) + { + this->length_ = len_request; + + // Extend the backing store. + if (ACE_OS::lseek (this->handle_, + len_request > 0 ? len_request - 1 : 0, + SEEK_SET) == -1 + || ACE_OS::write (this->handle_, "", 1) == -1 + || ACE_OS::lseek (this->handle_, 0, SEEK_SET) == -1) + return -1; + } + + this->base_addr_ = ACE_OS::mmap (this->base_addr_, + this->length_, + prot, + share, + this->handle_, + off_t (ACE::round_to_pagesize (pos)), + &this->file_mapping_); + + return this->base_addr_ == MAP_FAILED ? -1 : 0; +} + +int +ACE_Mem_Map::open (LPCTSTR file_name, + int flags, + int mode) +{ + ACE_TRACE ("ACE_Mem_Map::open"); + + ACE_OS::strncpy (this->filename_, file_name, MAXPATHLEN); + + this->handle_ = ACE_OS::open (file_name, flags, mode); + + if (this->handle_ == ACE_INVALID_HANDLE) + return -1; + else + { + this->close_handle_ = 1; + return 0; + } +} + +int +ACE_Mem_Map::map (const char file_name[], + int len, + int flags, + int mode, + int prot, + int share, + void *addr, + off_t pos) +{ + ACE_TRACE ("ACE_Mem_Map::map"); + this->length_ = 0; + + if (this->open (file_name, flags, mode) == -1) + return -1; + else + return this->map_it (this->handle (), len, prot, share, addr, pos); +} + +ACE_Mem_Map::ACE_Mem_Map (void) + : length_ (0), + base_addr_ (0), + handle_ (ACE_INVALID_HANDLE), + file_mapping_ (ACE_INVALID_HANDLE), + close_handle_ (0) +{ + ACE_TRACE ("ACE_Mem_Map::ACE_Mem_Map"); + ACE_OS::memset (this->filename_, 0, sizeof this->filename_); +} + +// Map a file specified by FILE_NAME. + +ACE_Mem_Map::ACE_Mem_Map (const char file_name[], + int len, + int flags, + int mode, + int prot, + int share, + void *addr, + off_t pos) + : base_addr_ (0), + close_handle_ (0), + file_mapping_ (ACE_INVALID_HANDLE) +{ + ACE_TRACE ("ACE_Mem_Map::ACE_Mem_Map"); + if (this->map (file_name, len, flags, mode, prot, share, addr, pos) < 0) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Mem_Map::ACE_Mem_Map")); +} + +// Map a file from an open file descriptor HANDLE. This function will +// lookup the length of the file if it is not given. + +ACE_Mem_Map::ACE_Mem_Map (ACE_HANDLE handle, + int len, + int prot, + int share, + void *addr, + off_t pos) + : close_handle_ (0), + file_mapping_ (ACE_INVALID_HANDLE) +{ + ACE_TRACE ("ACE_Mem_Map::ACE_Mem_Map"); + + ACE_OS::memset (this->filename_, 0, sizeof this->filename_); + + if (this->map (handle, len, prot, share, addr, pos) < 0) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Mem_Map::ACE_Mem_Map")); +} + +// Close down and remove the file from the file system. + +int +ACE_Mem_Map::remove (void) +{ + ACE_TRACE ("ACE_Mem_Map::remove"); + + ACE_OS::ftruncate (this->handle_, 0); + this->close (); + + if (this->filename_[0] != '\0') + return ACE_OS::unlink (this->filename_); + else + return 0; +} diff --git a/ace/Mem_Map.h b/ace/Mem_Map.h new file mode 100644 index 00000000000..ee439b1e5a5 --- /dev/null +++ b/ace/Mem_Map.h @@ -0,0 +1,179 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Mem_Map.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_MEM_MAP_H) +#define ACE_MEM_MAP_H + +#include "ace/ACE.h" + +class ACE_Export ACE_Mem_Map + // = TITLE + // C++ interface to the mmap(2) UNIX system call. +{ +public: + // = Initialization and termination methods. + + ACE_Mem_Map (void); + // Default constructor. + + ACE_Mem_Map (ACE_HANDLE handle, + int length = -1, + int prot = PROT_RDWR, + int share = MAP_PRIVATE, + void *addr = 0, + off_t pos = 0); + // Map a file from an open file descriptor . This function + // will lookup the length of the file if it is not given. + + ACE_Mem_Map (LPCTSTR filename, + int len = -1, + int flags = O_RDWR | O_CREAT, + int mode = ACE_DEFAULT_PERMS, + int prot = PROT_RDWR, + int share = MAP_PRIVATE, + void *addr = 0, + off_t pos = 0); + // Map a file specified by . + + int map (ACE_HANDLE handle, + int length = -1, + int prot = PROT_RDWR, + int share = MAP_PRIVATE, + void *addr = 0, + off_t pos = 0); + // Map a file from an open file descriptor . This function + // will lookup the length of the file if it is not given. + + int map (int length = -1, + int prot = PROT_RDWR, + int share = MAP_PRIVATE, + void *addr = 0, + off_t pos = 0); + // Remap the file associated with . + + int map (LPCTSTR filename, + int len = -1, + int flags = O_RDWR | O_CREAT, + int mode = ACE_DEFAULT_PERMS, + int prot = PROT_RDWR, + int share = MAP_PRIVATE, + void *addr = 0, + off_t pos = 0); + // Map a file specified by . + + ~ACE_Mem_Map (void); + // Destructor. + + int open (LPCTSTR filename, + int flags = O_RDWR | O_CREAT, + int mode = ACE_DEFAULT_PERMS); + // Open the file without mapping it. + + int close (void); + // Close down the if necessary. + + int operator () (void *&addr); + // This operator passes back the starting address of the mapped + // file. + + void *addr (void) const; + // Return the base address. + + size_t size (void) const; + // This function returns the number of bytes currently mapped in the + // file. + + int unmap (int len = -1); + // Unmap the region starting at . + + int unmap (void *addr, int len); + // Unmap the region starting at . + + int sync (ssize_t len = -1, int flags = MS_SYNC); + // Sync bytes of the memory region to the backing store + // starting at . If == -1 then sync the whole + // region. + + int sync (void *addr, size_t len, int flags = MS_SYNC); + // Sync bytes of the memory region to the backing store + // starting at . + + int protect (ssize_t len = -1, int prot = PROT_RDWR); + // Change the protection of the pages of the mapped region to + // starting at up to bytes. If == -1 then + // change protection of all pages in the mapped region. + + int protect (void *addr, size_t len, int prot = PROT_RDWR); + // Change the protection of the pages of the mapped region to + // starting at up to bytes. + + int remove (void); + // Close down and remove the file from the file system. + + int advise (int behavior, int len = -1); + // Hook into the underlying VM system. + + ACE_HANDLE handle (void) const; + // Return the underlying . + + const TCHAR *filename (void) const; + // Return the name of file that is mapped (if any). + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + void *base_addr_; + // Base address of the memory-mapped file. + + TCHAR filename_[MAXPATHLEN + 1]; + // Name of the file that is mapped. + + size_t length_; + // Length of the mapping. + + ACE_HANDLE handle_; + // HANDLE for the open file. + + ACE_HANDLE file_mapping_; + // HANDLE for the open mapping. + + int close_handle_; + // Keeps track of whether we need to close the handle. This is set + // if we opened the file. + + int map_it (ACE_HANDLE handle, + int len = -1, + int prot = PROT_RDWR, + int share = MAP_SHARED, + void *addr = 0, + off_t pos = 0); + // This method does the dirty work of actually calling ::mmap to map + // the file into memory. + + ACE_Mem_Map (const ACE_Mem_Map &) {} + void operator = (const ACE_Mem_Map &) {} +}; + +#if defined (__ACE_INLINE__) +#include "ace/Mem_Map.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_MEM_MAP_H */ diff --git a/ace/Mem_Map.i b/ace/Mem_Map.i new file mode 100644 index 00000000000..ecba43e127d --- /dev/null +++ b/ace/Mem_Map.i @@ -0,0 +1,166 @@ +/* -*- C++ -*- */ +// $Id$ + +// Mem_Map.i + +#include "ace/Log_Msg.h" + +ACE_INLINE ACE_HANDLE +ACE_Mem_Map::handle (void) const +{ + ACE_TRACE ("ACE_Mem_Map::handle"); + return this->handle_; +} + +// Return the name of file that is mapped (if any). + +ACE_INLINE const TCHAR * +ACE_Mem_Map::filename (void) const +{ + return this->filename_; +} + +ACE_INLINE int +ACE_Mem_Map::map (ACE_HANDLE handle, + int len, + int prot, + int share, + void *addr, + off_t pos) +{ + ACE_TRACE ("ACE_Mem_Map::map"); + return this->map_it (handle, len, prot, share, addr, pos); +} + +// Remap the file associated with handle_>. + +ACE_INLINE int +ACE_Mem_Map::map (int len, + int prot, + int share, + void *addr, + off_t pos) +{ + ACE_TRACE ("ACE_Mem_Map::map"); + return this->map_it (this->handle (), len, prot, + share, addr, pos); +} + +// This operator passes back the starting address of the mapped file. + +ACE_INLINE int +ACE_Mem_Map::operator () (void *&addr) +{ + ACE_TRACE ("ACE_Mem_Map::operator"); + + if (this->base_addr_ == MAP_FAILED) + return -1; + else + { + addr = this->base_addr_; + return 0; + } +} + +// Return the base address. + +ACE_INLINE void * +ACE_Mem_Map::addr (void) const +{ + ACE_TRACE ("ACE_Mem_Map::addr"); + + return this->base_addr_; +} + +// This function returns the number of bytes currently mapped in the +// file. + +ACE_INLINE size_t +ACE_Mem_Map::size (void) const +{ + ACE_TRACE ("ACE_Mem_Map::size"); + return this->length_; +} + +// Unmap the region starting at base_addr_>. + +ACE_INLINE int +ACE_Mem_Map::unmap (int len) +{ + ACE_TRACE ("ACE_Mem_Map::unmap"); + if (this->file_mapping_ != this->handle_) + ACE_OS::close (this->file_mapping_); + + this->file_mapping_ = ACE_INVALID_HANDLE; + + return ACE_OS::munmap (this->base_addr_, len < 0 ? this->length_ : len); +} + +// Unmap the region starting at . + +ACE_INLINE int +ACE_Mem_Map::unmap (void *addr, int len) +{ + ACE_TRACE ("ACE_Mem_Map::unmap"); + if (this->file_mapping_ != this->handle_) + ACE_OS::close (this->file_mapping_); + + this->file_mapping_ = ACE_INVALID_HANDLE; + + return ACE_OS::munmap (addr, len < 0 ? this->length_ : len); +} + +// Sync bytes of the memory region to the backing store starting +// at base_addr_>. If == -1 then sync the whole mapped +// region. + +ACE_INLINE int +ACE_Mem_Map::sync (ssize_t len, int flags) +{ + ACE_TRACE ("ACE_Mem_Map::sync"); + return ACE_OS::msync (this->base_addr_, len < 0 ? this->length_ : len, flags); +} + +// Sync bytes of the memory region to the backing store starting +// at . + +ACE_INLINE int +ACE_Mem_Map::sync (void *addr, size_t len, int flags) +{ + ACE_TRACE ("ACE_Mem_Map::sync"); + return ACE_OS::msync (addr, len, flags); +} + +// Change the protection of the pages of the mapped region to +// starting at base_addr_> up to bytes. If == -1 +// then change protection of all pages in the mapped region. + +ACE_INLINE int +ACE_Mem_Map::protect (ssize_t len, int prot) +{ + ACE_TRACE ("ACE_Mem_Map::protect"); + if (len < 0) + len = this->length_; + return ACE_OS::mprotect (this->base_addr_, len, prot); +} + +// Change the protection of the pages of the mapped region to +// starting at up to bytes. + +ACE_INLINE int +ACE_Mem_Map::protect (void *addr, size_t len, int prot) +{ + ACE_TRACE ("ACE_Mem_Map::protect"); + return ACE_OS::mprotect (addr, len, prot); +} + +// Hook into the underlying VM system. + +ACE_INLINE int +ACE_Mem_Map::advise (int behavior, int len) +{ + ACE_TRACE ("ACE_Mem_Map::advise"); + if (len < 0) + len = this->length_; + return ACE_OS::madvise ((caddr_t) this->base_addr_, len, behavior); +} diff --git a/ace/Memory_Pool.cpp b/ace/Memory_Pool.cpp new file mode 100644 index 00000000000..2ec2b76c6a9 --- /dev/null +++ b/ace/Memory_Pool.cpp @@ -0,0 +1,587 @@ + +// $Id$ + +// Memory_Pool.cpp +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Memory_Pool.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Memory_Pool.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Local_Memory_Pool) + +void +ACE_Local_Memory_Pool::dump (void) const +{ + ACE_TRACE ("ACE_Local_Memory_Pool::dump"); +} + +ACE_Local_Memory_Pool::ACE_Local_Memory_Pool (const char *) +{ + ACE_TRACE ("ACE_Local_Memory_Pool::ACE_Local_Memory_Pool"); +} + +void * +ACE_Local_Memory_Pool::acquire (size_t nbytes, + size_t &rounded_bytes) +{ + ACE_TRACE ("ACE_Local_Memory_Pool::acquire"); + rounded_bytes = this->round_up (nbytes); + // ACE_DEBUG ((LM_DEBUG, "(%P|%t) acquiring more chunks, nbytes = %d, rounded_bytes = %d\n", nbytes, rounded_bytes)); + + void *cp = (void *) new char[rounded_bytes]; + + if (cp == 0) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %u\n", cp), 0); + else + // ACE_DEBUG ((LM_DEBUG, "(%P|%t) acquired more chunks, nbytes = %d, rounded_bytes = %d, new break = %d\n", nbytes, rounded_bytes, cp)); + return cp; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_MMAP_Memory_Pool) + +void +ACE_MMAP_Memory_Pool::dump (void) const +{ + ACE_TRACE ("ACE_MMAP_Memory_Pool::dump"); +} + +int +ACE_MMAP_Memory_Pool::release (void) +{ + ACE_TRACE ("ACE_MMAP_Memory_Pool::release"); + this->mmap_.remove (); + return 0; +} + +int +ACE_MMAP_Memory_Pool::sync (ssize_t len, int flags) +{ + ACE_TRACE ("ACE_MMAP_Memory_Pool::sync"); + + if (len < 0) + len = ACE_OS::lseek (this->mmap_.handle (), 0, SEEK_END); + + return this->mmap_.sync (len, flags); +} + +// Sync bytes of the memory region to the backing store starting +// at . + +int +ACE_MMAP_Memory_Pool::sync (void *addr, size_t len, int flags) +{ + ACE_TRACE ("ACE_MMAP_Memory_Pool::sync"); + return ACE_OS::msync (addr, len, flags); +} + +// Change the protection of the pages of the mapped region to +// starting at base_addr_> up to bytes. If == -1 +// then change protection of all pages in the mapped region. + +int +ACE_MMAP_Memory_Pool::protect (ssize_t len, int prot) +{ + ACE_TRACE ("ACE_MMAP_Memory_Pool::protect"); + + if (len < 0) + len = ACE_OS::lseek (this->mmap_.handle (), 0, SEEK_END); + + return this->mmap_.protect (len, prot); +} + +// Change the protection of the pages of the mapped region to +// starting at up to bytes. + +int +ACE_MMAP_Memory_Pool::protect (void *addr, size_t len, int prot) +{ + ACE_TRACE ("ACE_MMAP_Memory_Pool::protect"); + return ACE_OS::mprotect (addr, len, prot); +} + +ACE_MMAP_Memory_Pool::ACE_MMAP_Memory_Pool (const char *pool_name, + int use_fixed_addr, + int write_each_page, + char *base_addr) + : base_addr_ (use_fixed_addr ? base_addr : 0), + flags_ (MAP_SHARED | (use_fixed_addr ? MAP_FIXED : 0)), + write_each_page_ (write_each_page) +{ + ACE_TRACE ("ACE_MMAP_Memory_Pool::ACE_MMAP_Memory_Pool"); + + if (pool_name == 0) + // Only create a new unique filename for the backing store file + // if the user didn't supply one... + pool_name = ACE_DEFAULT_BACKING_STORE; // from "ace/OS.h" + + ACE_OS::strncpy (this->backing_store_, pool_name, + sizeof this->backing_store_); + + if (this->signal_handler_.register_handler (SIGSEGV, this) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", this->backing_store_)); +} + +// Compute the new file_offset of the backing store and commit the +// memory. + +int +ACE_MMAP_Memory_Pool::commit_backing_store (size_t rounded_bytes, + off_t &file_offset) +{ + ACE_TRACE ("ACE_MMAP_Memory_Pool::commit_backing_store"); + + size_t seek_len; + + if (this->write_each_page_) + // Write to the end of every block to ensure that we have enough + // space in the backing store. + seek_len = this->round_up (1); // round_up(1) is one page. + else + // We're willing to risk it all in the name of efficiency... + seek_len = rounded_bytes; + + // The following loop will execute multiple times (if + // this->write_each_page == 1) or just once (if + // this->write_each_page == 0). + + for (size_t cur_block = 0; + cur_block < rounded_bytes; + cur_block += seek_len) + { + file_offset = ACE_OS::lseek (this->mmap_.handle () , seek_len - 1, SEEK_END); + + if (file_offset == -1 || ACE_OS::write (this->mmap_.handle (), "", 1) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", this->backing_store_), -1); + } + + // Increment by one to put us at the beginning of the next chunk... + file_offset++; + return 0; +} + +// Memory map the file up to bytes. + +int +ACE_MMAP_Memory_Pool::map_file (off_t file_offset) +{ + ACE_TRACE ("ACE_MMAP_Memory_Pool::map_file"); + + // Unmap the existing mapping. + this->mmap_.unmap (); + + // Remap the file. + if (this->mmap_.map (file_offset, PROT_RDWR, + this->flags_, this->base_addr_, 0) == -1 + || this->base_addr_ != 0 && this->mmap_.addr () != this->base_addr_) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) base_addr = %u, addr = %u, file_offset = %u, %p\n", + this->mmap_.addr (), this->base_addr_, + file_offset, this->backing_store_), -1); + + return 0; +} + +// Ask operating system for more shared memory, increasing the mapping +// accordingly. Note that this routine assumes that the appropriate +// locks are held when it is called. + +void * +ACE_MMAP_Memory_Pool::acquire (size_t nbytes, + size_t &rounded_bytes) +{ + ACE_TRACE ("ACE_MMAP_Memory_Pool::acquire"); + rounded_bytes = this->round_up (nbytes); + + // ACE_DEBUG ((LM_DEBUG, "(%P|%t) acquiring more chunks, nbytes = + // %d, rounded_bytes = %d\n", nbytes, rounded_bytes)); + + off_t file_offset; + + if (this->commit_backing_store (rounded_bytes, file_offset) == -1) + return 0; + + if (this->map_file (file_offset) == -1) + return 0; + + // ACE_DEBUG ((LM_DEBUG, "(%P|%t) acquired more chunks, nbytes = %d, + // rounded_bytes = %d, file_offset = %d\n", nbytes, rounded_bytes, + // file_offset)); + + return (void *) ((char *) this->mmap_.addr () + (this->mmap_.size () - rounded_bytes)); +} + +// Ask system for initial chunk of shared memory. + +void * +ACE_MMAP_Memory_Pool::init_acquire (size_t nbytes, + size_t &rounded_bytes, + int &first_time) +{ + ACE_TRACE ("ACE_MMAP_Memory_Pool::init_acquire"); + + first_time = 0; + + if (this->mmap_.open (this->backing_store_, + O_RDWR | O_CREAT | O_TRUNC | O_EXCL, + ACE_DEFAULT_PERMS) != -1) + { + // First time in, so need to acquire memory. + first_time = 1; + return this->acquire (nbytes, rounded_bytes); + } + else if (errno == EEXIST) + { + // Reopen file *without* using O_EXCL... + if (this->mmap_.map (this->backing_store_, + -1, + O_RDWR, + ACE_DEFAULT_PERMS, + PROT_RDWR, + this->flags_, + this->base_addr_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), 0); + + return this->mmap_.addr (); + } + else + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), 0); +} + +int +ACE_MMAP_Memory_Pool::remap (void *addr) +{ + ACE_TRACE ("ACE_MMAP_Memory_Pool::remap"); + ACE_DEBUG ((LM_DEBUG, "Remapping with fault address at: %X\n", addr)); + off_t current_file_offset = ACE_OS::filesize (this->mmap_.handle ()); + // ACE_OS::lseek (this->mmap_.handle (), 0, SEEK_END); + + if (addr != 0 + && !(addr < (void *) ((char *) this->mmap_.addr () + current_file_offset) + && addr >= this->mmap_.addr ())) + return -1; + + // Extend the mapping to cover the size of the backing store. + return this->map_file (current_file_offset); +} + +// Handle SIGSEGV and SIGBUS signals to remap memory properly. When a +// process reads or writes to non-mapped memory a signal (SIGBUS or +// SIGSEGV) will be triggered. At that point, the ACE_Sig_Handler +// (which is part of the ACE_Reactor) will catch the signal and +// dispatch the handle_signal() method defined here. If the SIGSEGV +// signal occurred due to the fact that the mapping wasn't uptodate +// with respect to the backing store, the handler method below will +// update the mapping accordingly. When the signal handler returns, +// the instruction should be restarted and the operation should work. + +int +ACE_MMAP_Memory_Pool::handle_signal (int signum, siginfo_t *siginfo, ucontext_t *) +{ + ACE_TRACE ("ACE_MMAP_Memory_Pool::handle_signal"); + + if (signum != SIGSEGV) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) ignoring signal %S\n", + signum), -1); + else + ; // ACE_DEBUG ((LM_DEBUG, "(%P|%t) received %S\n", signum)); + + // ACE_DEBUG ((LM_DEBUG, "(%P|%t) new mapping address = %u\n", (char *) this->base_addr_ + current_file_offset)); + +#if defined (ACE_HAS_SIGINFO_T) && !defined (ACE_LACKS_SI_ADDR) + // Make sure that the pointer causing the problem is within the + // range of the backing store. + + if (siginfo != 0) + { + // ACE_DEBUG ((LM_DEBUG, "(%P|%t) si_signo = %d, si_code = %d, addr = %u\n", siginfo->si_signo, siginfo->si_code, siginfo->si_addr)); + if (this->remap ((void *) siginfo->si_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) address %u out of range\n", + siginfo->si_addr), -1); + return 0; + } +#endif /* ACE_HAS_SIGINFO_T && !defined ACE_LACKS_SI_ADDR */ + // This is total desperation since we don't know what the faulting + // address is in this case! + this->remap (0); + return 0; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Lite_MMAP_Memory_Pool) + +ACE_Lite_MMAP_Memory_Pool::ACE_Lite_MMAP_Memory_Pool (const char *pool_name, + int use_fixed_addr, + int write_each_page, + char *base_addr) + : ACE_MMAP_Memory_Pool (pool_name, use_fixed_addr, write_each_page, base_addr) +{ + ACE_TRACE ("ACE_Lite_MMAP_Memory_Pool::ACE_Lite_MMAP_Memory_Pool"); +} + +int +ACE_Lite_MMAP_Memory_Pool::sync (ssize_t len, int flags) +{ + ACE_TRACE ("ACE_Lite_MMAP_Memory_Pool::sync"); + return 0; +} + +int +ACE_Lite_MMAP_Memory_Pool::sync (void *addr, size_t len, int flags) +{ + ACE_TRACE ("ACE_Lite_MMAP_Memory_Pool::sync"); + return 0; +} + +#if !defined (ACE_LACKS_SBRK) +ACE_ALLOC_HOOK_DEFINE(ACE_Sbrk_Memory_Pool) + +// Ask system for more local memory via sbrk(2). + +void * +ACE_Sbrk_Memory_Pool::acquire (size_t nbytes, + size_t &rounded_bytes) +{ + ACE_TRACE ("ACE_Sbrk_Memory_Pool::acquire"); + rounded_bytes = this->round_up (nbytes); + // ACE_DEBUG ((LM_DEBUG, "(%P|%t) acquiring more chunks, nbytes = %d, rounded_bytes = %d\n", nbytes, rounded_bytes)); + void *cp = ACE_OS::sbrk (rounded_bytes); + + if (cp == MAP_FAILED) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) cp = %u\n", cp), 0); + else + // ACE_DEBUG ((LM_DEBUG, "(%P|%t) acquired more chunks, nbytes = %d, rounded_bytes = %d, new break = %u\n", nbytes, rounded_bytes, cp)); + return cp; +} + +void +ACE_Sbrk_Memory_Pool::dump (void) const +{ + ACE_TRACE ("ACE_Sbrk_Memory_Pool::dump"); +} + +ACE_Sbrk_Memory_Pool::ACE_Sbrk_Memory_Pool (const char *) +{ + ACE_TRACE ("ACE_Sbrk_Memory_Pool::ACE_Sbrk_Memory_Pool"); +} +#endif /* !ACE_LACKS_SBRK */ + +#if !defined (ACE_LACKS_SYSV_SHMEM) +ACE_ALLOC_HOOK_DEFINE(ACE_Shared_Memory_Pool) + +void +ACE_Shared_Memory_Pool::dump (void) const +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::dump"); +} + +int +ACE_Shared_Memory_Pool::in_use (off_t &offset, + int &counter) +{ + offset = 0; + SHM_TABLE *st = (SHM_TABLE *) ACE_DEFAULT_BASE_ADDR; + shmid_ds buf; + + for (counter = 0; + counter < ACE_DEFAULT_MAX_SEGMENTS + && st[counter].used == 1; + counter++) + { + if (ACE_OS::shmctl (st[counter].shmid, IPC_STAT, &buf) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "shmctl"), -1); + offset += buf.shm_segsz; + // ACE_DEBUG ((LM_DEBUG, "(%P|%t) segment size = %d, offset = %d\n", buf.shm_segsz, offset)); + } + + return 0; +} + +int +ACE_Shared_Memory_Pool::commit_backing_store (size_t rounded_bytes, + off_t &offset) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::update"); + int counter; + SHM_TABLE *st = (SHM_TABLE *) ACE_DEFAULT_BASE_ADDR; + + if (this->in_use (offset, counter) == -1) + return -1; + + if (counter == ACE_DEFAULT_MAX_SEGMENTS) + ACE_ERROR_RETURN ((LM_ERROR, + "exceeded max number of segments = %d, base = %u, offset = %u\n", + counter, ACE_DEFAULT_BASE_ADDR, offset), -1); + else + { + int shmid = ACE_OS::shmget (st[counter].key, + rounded_bytes, + ACE_DEFAULT_PERMS | IPC_CREAT | IPC_EXCL); + if (shmid == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "shmget"), 0); + + st[counter].shmid = shmid; + st[counter].used = 1; + + void *address = (void *) (ACE_DEFAULT_BASE_ADDR + offset); + void *shmem = ACE_OS::shmat (st[counter].shmid, (char *) address, 0); + + if (shmem != address) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p, shmem = %u, address = %u\n", + "shmat", shmem, address), 0); + } + + return 0; +} + +// Handle SIGSEGV and SIGBUS signals to remap shared memory properly. + +int +ACE_Shared_Memory_Pool::handle_signal (int , siginfo_t *siginfo, ucontext_t *) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::handle_signal"); + // ACE_DEBUG ((LM_DEBUG, "signal %S occurred\n", signum)); + off_t offset; + +#if defined (ACE_HAS_SIGINFO_T) && !defined (ACE_LACKS_SI_ADDR) + // Make sure that the pointer causing the problem is within the + // range of the backing store. + + if (siginfo != 0) + { + // ACE_DEBUG ((LM_DEBUG, "(%P|%t) si_signo = %d, si_code = %d, addr = %u\n", siginfo->si_signo, siginfo->si_code, siginfo->si_addr)); + int counter; + if (this->in_use (offset, counter) == -1) + ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "in_use")); + else if (!(siginfo->si_code == SEGV_MAPERR + && siginfo->si_addr < (((char *) ACE_DEFAULT_BASE_ADDR) + offset) + && siginfo->si_addr >= ((char *) ACE_DEFAULT_BASE_ADDR))) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) address %u out of range\n", + siginfo->si_addr), -1); + } +#endif /* ACE_HAS_SIGINFO_T && !defined (ACE_LACKS_SI_ADDR) */ + this->commit_backing_store (this->round_up (ACE_DEFAULT_SEGMENT_SIZE), + offset); + return 0; +} + +ACE_Shared_Memory_Pool::ACE_Shared_Memory_Pool (const char *pool_name) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::ACE_Shared_Memory_Pool"); + + if (this->signal_handler_.register_handler (SIGSEGV, this) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Sig_Handler::register_handler")); +} + +// Ask system for more shared memory. + +void * +ACE_Shared_Memory_Pool::acquire (size_t nbytes, + size_t &rounded_bytes) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::acquire"); + + rounded_bytes = this->round_up (nbytes); + + // ACE_DEBUG ((LM_DEBUG, "(%P|%t) acquiring more chunks, nbytes = %d, rounded_bytes = %d\n", nbytes, rounded_bytes)); + + off_t offset; + + if (this->commit_backing_store (rounded_bytes, offset) == -1) + return 0; + + SHM_TABLE *st = (SHM_TABLE *) ACE_DEFAULT_BASE_ADDR; + void *new_memory = ((char *) ACE_DEFAULT_BASE_ADDR) + offset; + + // ACE_DEBUG ((LM_DEBUG, "(%P|%t) acquired more chunks, nbytes = %d, rounded_bytes = %d\n", nbytes, rounded_bytes)); + return new_memory; +} + +// Ask system for initial chunk of shared memory. + +void * +ACE_Shared_Memory_Pool::init_acquire (size_t nbytes, + size_t &rounded_bytes, + int &first_time) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::init_acquire"); + + int counter; + void *base_addr = (void *) ACE_DEFAULT_BASE_ADDR; + off_t shm_table_offset = ACE::round_to_pagesize (sizeof (SHM_TABLE)); + rounded_bytes = this->round_up (nbytes); + + // Acquire the semaphore to serialize initialization and prevent + // race conditions. + + int shmid = ACE_OS::shmget (ACE_DEFAULT_SHM_KEY, + rounded_bytes + shm_table_offset, + ACE_DEFAULT_PERMS | IPC_CREAT | IPC_EXCL); + if (shmid == -1) + { + if (errno != EEXIST) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "shmget"), 0); + + first_time = 0; + + shmid = ACE_OS::shmget (ACE_DEFAULT_SHM_KEY, 0, 0); + + if (shmid == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "shmget"), 0); + + void *shmem = ACE_OS::shmat (shmid, (char *) base_addr, 0); + + if (shmem != base_addr) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p, shmem = %u, base_addr = %u\n", + "shmat", shmem, base_addr), 0); + } + else + { + first_time = 1; + + void *shmem = ACE_OS::shmat (shmid, (char *) base_addr, 0); + + if (shmem != base_addr) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p, shmem = %u, base_addr = %u\n", + "shmat", shmem, base_addr), 0); + + SHM_TABLE *st = (SHM_TABLE *) base_addr; + + st[0].key = ACE_DEFAULT_SHM_KEY; + st[0].shmid = shmid; + st[0].used = 1; + + for (counter = 1; // Skip over the first entry... + counter < ACE_DEFAULT_MAX_SEGMENTS; + counter++) + { + st[counter].key = ACE_DEFAULT_SHM_KEY + counter; + st[counter].shmid = 0; + st[counter].used = 0; + } + } + + return (void *) (((char *) base_addr) + shm_table_offset); +} + +// Instruct the memory pool to release all of its resources. + +int +ACE_Shared_Memory_Pool::release (void) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::release"); + + int result = 0; + SHM_TABLE *st = (SHM_TABLE *) ACE_DEFAULT_BASE_ADDR; + + for (int counter = 0; + counter < ACE_DEFAULT_MAX_SEGMENTS && st[counter].used == 1; + counter++) + if (ACE_OS::shmctl (st[counter].shmid, IPC_RMID, NULL) == -1) + result = -1; + + return result; +} +#endif /* !ACE_LACKS_SYSV_SHMEM */ diff --git a/ace/Memory_Pool.h b/ace/Memory_Pool.h new file mode 100644 index 00000000000..de4c69126f8 --- /dev/null +++ b/ace/Memory_Pool.h @@ -0,0 +1,352 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// ACE_Memory_Pool.h +// +// = AUTHOR +// Doug Schmidt and Prashant Jain +// +// ============================================================================ + +#if !defined (ACE_MEMORY_POOL_H) +#define ACE_MEMORY_POOL_H + +#include "ace/ACE.h" +#include "ace/Event_Handler.h" +#include "ace/Signal.h" +#include "ace/Mem_Map.h" +#if !defined (ACE_WIN32) +#include "ace/SV_Semaphore_Complex.h" +#endif /* !ACE_WIN32 */ + +#if !defined (ACE_LACKS_SBRK) +class ACE_Export ACE_Sbrk_Memory_Pool + // = TITLE + // Make a memory pool that is based on . +{ +public: + ACE_Sbrk_Memory_Pool (const char *pool_name = 0); + // Initialization constructor. + + // = Implementor operations. + virtual void *init_acquire (size_t nbytes, + size_t &rounded_bytes, + int &first_time); + // Ask system for initial chunk of local memory. + + virtual void *acquire (size_t nbytes, + size_t &rounded_bytes); + // Acquire at least NBYTES from the memory pool. ROUNDED_BYTES is + // the actual number of bytes allocated. + + virtual int release (void); + // Instruct the memory pool to release all of its resources. + + virtual int sync (ssize_t len = -1, int flags = MS_SYNC); + // Sync bytes of the memory region to the backing store + // starting at base_addr_>. If == -1 then sync the + // whole region. + + virtual int sync (void *addr, size_t len, int flags = MS_SYNC); + // Sync bytes of the memory region to the backing store + // starting at . + + virtual int protect (ssize_t len = -1, int prot = PROT_RDWR); + // Change the protection of the pages of the mapped region to + // starting at base_addr_> up to bytes. If == -1 + // then change protection of all pages in the mapped region. + + virtual int protect (void *addr, size_t len, int prot = PROT_RDWR); + // Change the protection of the pages of the mapped region to + // starting at up to bytes. + + virtual void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + virtual size_t round_up (size_t nbytes); + // Implement the algorithm for rounding up the request to an + // appropriate chunksize. +}; +#endif /* !ACE_LACKS_SBRK */ + +#if !defined (ACE_LACKS_SYSV_SHMEM) +class ACE_Export ACE_Shared_Memory_Pool : public ACE_Event_Handler + // = TITLE + // Make a memory pool that is based on System V shared memory + // (shmget(2) etc.). This implementation allows memory to be + // shared between processes. +{ +public: + ACE_Shared_Memory_Pool (const char *pool_name = ACE_ITOA (ACE_DEFAULT_SHM_KEY)); + // Initialization constructor. + + virtual void *init_acquire (size_t nbytes, + size_t &rounded_bytes, + int &first_time); + // Ask system for initial chunk of local memory. + + virtual void *acquire (size_t nbytes, + size_t &rounded_bytes); + // Acquire at least NBYTES from the memory pool. ROUNDED_BYTES is + // the actual number of bytes allocated. Also acquires an internal + // semaphore that ensures proper serialization of Memory_Pool + // initialization across processes. + + virtual int release (void); + // Instruct the memory pool to release all of its resources. + + virtual int sync (ssize_t len = -1, int flags = MS_SYNC); + // Sync the memory region to the backing store starting at + // base_addr_>. + + virtual int sync (void *addr, size_t len, int flags = MS_SYNC); + // Sync the memory region to the backing store starting at . + + virtual int protect (ssize_t len = -1, int prot = PROT_RDWR); + // Change the protection of the pages of the mapped region to + // starting at base_addr_> up to bytes. If == -1 + // then change protection of all pages in the mapped region. + + virtual int protect (void *addr, size_t len, int prot = PROT_RDWR); + // Change the protection of the pages of the mapped region to + // starting at up to bytes. + + virtual void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + virtual size_t round_up (size_t nbytes); + // Implement the algorithm for rounding up the request to an + // appropriate chunksize. + + virtual int commit_backing_store (size_t rounded_bytes, + off_t &offset); + // Commits a new shared memory segment if necessary after an + // acquire() or a signal. is set to the new offset into + // the backing store. + + struct SHM_TABLE + { + key_t key; + int shmid; + int used; + }; + + virtual int in_use (off_t &offset, int &counter); + // Determine how much memory is currently in use. + + ACE_Sig_Handler signal_handler_; + // Handles SIGSEGV. + + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + // Handle SIGSEGV and SIGBUS signals to remap shared memory + // properly. + + ACE_SV_Semaphore_Complex init_finished_; + // Used to serialize initialization of the Memory_Pool and Malloc. +}; +#endif /* !ACE_LACKS_SYSV_SHMEM */ + +class ACE_Export ACE_Local_Memory_Pool + // = TITLE + // Make a memory pool that is based on C++ new/delete. This is + // useful for integrating existing components that use new/delete + // into the ACE Malloc scheme... +{ +public: + ACE_Local_Memory_Pool (const char *pool_name = 0); + // Initialization constructor. + + virtual void *init_acquire (size_t nbytes, + size_t &rounded_bytes, + int &first_time); + // Ask system for initial chunk of local memory. + + virtual void *acquire (size_t nbytes, + size_t &rounded_bytes); + // Acquire at least NBYTES from the memory pool. ROUNDED_BYTES is + // the actual number of bytes allocated. + + virtual int release (void); + // Instruct the memory pool to release all of its resources. + + virtual int sync (ssize_t len = -1, int flags = MS_SYNC); + // Sync bytes of the memory region to the backing store + // starting at base_addr_>. If == -1 then sync the + // whole region. + + virtual int sync (void *addr, size_t len, int flags = MS_SYNC); + // Sync bytes of the memory region to the backing store + // starting at . + + virtual int protect (ssize_t len = -1, int prot = PROT_RDWR); + // Change the protection of the pages of the mapped region to + // starting at base_addr_> up to bytes. If == -1 + // then change protection of all pages in the mapped region. + + virtual int protect (void *addr, size_t len, int prot = PROT_RDWR); + // Change the protection of the pages of the mapped region to + // starting at up to bytes. + + virtual void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + virtual size_t round_up (size_t nbytes); + + // Implement the algorithm for rounding up the request to an + // appropriate chunksize. +}; + +class ACE_Export ACE_MMAP_Memory_Pool : public ACE_Event_Handler + // = TITLE + // Make a memory pool that is based on . This + // implementation allows memory to be shared between processes. +{ +public: + // = Initialization and termination methods. + ACE_MMAP_Memory_Pool (const char *pool_name = 0, + int use_fixed_addr = 1, + int write_each_page = 1, + char *base_addr = ACE_DEFAULT_BASE_ADDR); + // Initialize the pool. + + virtual void *init_acquire (size_t nbytes, + size_t &rounded_bytes, + int &first_time); + // Ask system for initial chunk of shared memory. + + virtual void *acquire (size_t nbytes, + size_t &rounded_bytes); + // Acquire at least from the memory pool. + // is the actual number of bytes allocated. Also acquires an + // internal semaphore that ensures proper serialization of + // initialization across processes. + + virtual int release (void); + // Instruct the memory pool to release all of its resources. + + virtual int sync (ssize_t len = -1, int flags = MS_SYNC); + // Sync the memory region to the backing store starting at + // base_addr_>. + + virtual int sync (void *addr, size_t len, int flags = MS_SYNC); + // Sync the memory region to the backing store starting at . + + virtual int protect (ssize_t len = -1, int prot = PROT_RDWR); + // Change the protection of the pages of the mapped region to + // starting at base_addr_> up to bytes. If == -1 + // then change protection of all pages in the mapped region. + + virtual int protect (void *addr, size_t len, int prot = PROT_RDWR); + // Change the protection of the pages of the mapped region to + // starting at up to bytes. + + virtual int remap (void *addr); + // Try to extend the virtual address space so that is now + // covered by the address mapping. The method succeeds and returns + // 0 if the backing store has adequate memory to cover this address. + // Otherwise, it returns -1. This method is typically called by a + // UNIX signal handler for SIGSEGV or a Win32 structured exception + // when another process has grown the backing store (and its + // mapping) and our process now incurs a fault because our mapping + // isn't in range (yet). + + virtual void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + // = Implement the algorithm for rounding up the request to an + // appropriate chunksize. + + virtual size_t round_up (size_t nbytes); + + virtual int commit_backing_store (size_t rounded_bytes, off_t &file_offset); + // Compute the new file_offset of the backing store and commit the + // memory. + + virtual int map_file (off_t file_offset); + // Memory map the file up to bytes. + + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + // Handle SIGSEGV and SIGBUS signals to remap shared memory + // properly. + + ACE_Sig_Handler signal_handler_; + // Handles SIGSEGV. + + ACE_Mem_Map mmap_; + // Memory-mapping object. + + void *base_addr_; + // Base of mapped region. If this has the value of 0 then the OS is + // free to select any address to map the file, otherwise this value + // is what the OS must try to use to mmap the file. + + int flags_; + // Flags passed into . + + const int write_each_page_; + // Should we write a byte to each page to forceably allocate memory + // for this backing store? + + char backing_store_[MAXPATHLEN]; + // Name of the backing store where the shared memory is kept. +}; + +class ACE_Export ACE_Lite_MMAP_Memory_Pool : public ACE_MMAP_Memory_Pool + // = TITLE + // Make a ``lighter-weight'' memory pool based . + // + // = DESCRIPTION + // This implementation allows memory to be shared between + // processes. However, unlike the + // the sync() methods are no-ops, which means that we don't pay + // for the price of flushing the memory to the backing store on + // every update. Naturally, this trades off increased + // performance for less reliability if the machine crashes. +{ +public: + // = Initialization and termination methods. + ACE_Lite_MMAP_Memory_Pool (const char *pool_name = 0, + int use_fixed_addr = 1, + int write_each_page = 1, + char *base_addr = ACE_DEFAULT_BASE_ADDR); + // Initialize the pool. + + int sync (ssize_t len = -1, int flags = MS_SYNC); + // Overwrite the default sync behavior with no-op + + int sync (void *addr, size_t len, int flags = MS_SYNC); + // Overwrite the default sync behavior with no-op +}; + +#if defined (__ACE_INLINE__) +#include "ace/Memory_Pool.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_MEMORY_POOL_H */ + + + + diff --git a/ace/Memory_Pool.i b/ace/Memory_Pool.i new file mode 100644 index 00000000000..cd7ce978ab7 --- /dev/null +++ b/ace/Memory_Pool.i @@ -0,0 +1,181 @@ +/* -*- C++ -*- */ +// $Id$ + +// Memory_Pool.i + +ACE_INLINE int +ACE_Local_Memory_Pool::sync (ssize_t, int) +{ + ACE_TRACE ("ACE_Local_Memory_Pool::sync"); + return 0; +} + +ACE_INLINE int +ACE_Local_Memory_Pool::sync (void *, size_t, int) +{ + ACE_TRACE ("ACE_Local_Memory_Pool::sync"); + return 0; +} + +ACE_INLINE int +ACE_Local_Memory_Pool::protect (ssize_t, int) +{ + ACE_TRACE ("ACE_Local_Memory_Pool::protect"); + return 0; +} + +ACE_INLINE int +ACE_Local_Memory_Pool::protect (void *, size_t, int) +{ + ACE_TRACE ("ACE_Local_Memory_Pool::protect"); + return 0; +} + +ACE_INLINE size_t +ACE_MMAP_Memory_Pool::round_up (size_t nbytes) +{ + ACE_TRACE ("ACE_MMAP_Memory_Pool::round_up"); + return ACE::round_to_pagesize (nbytes); +} + +// Ask system for initial chunk of local memory. + +ACE_INLINE void * +ACE_Local_Memory_Pool::init_acquire (size_t nbytes, + size_t &rounded_bytes, + int &first_time) +{ + ACE_TRACE ("ACE_Local_Memory_Pool::init_acquire"); + // Note that we assume that when ACE_Local_Memory_Pool is used, + // ACE_Malloc's constructor will only get called once. If this + // assumption doesn't hold, we are in deep trouble! + + first_time = 1; + return this->acquire (nbytes, rounded_bytes); +} + +// Let the underlying new operator figure out the alignment... + +ACE_INLINE size_t +ACE_Local_Memory_Pool::round_up (size_t nbytes) +{ + ACE_TRACE ("ACE_Local_Memory_Pool::round_up"); + return ACE::round_to_pagesize (nbytes); +} + +// No-op for now... + +ACE_INLINE int +ACE_Local_Memory_Pool::release (void) +{ + ACE_TRACE ("ACE_Local_Memory_Pool::release"); + return 0; +} + +#if !defined (ACE_LACKS_SYSV_SHMEM) +// Implement the algorithm for rounding up the request to an +// appropriate chunksize. + +ACE_INLINE size_t +ACE_Shared_Memory_Pool::round_up (size_t nbytes) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::round_up"); + if (nbytes < ACE_DEFAULT_SEGMENT_SIZE) + nbytes = ACE_DEFAULT_SEGMENT_SIZE; + + return ACE::round_to_pagesize (nbytes); +} + +ACE_INLINE int +ACE_Shared_Memory_Pool::sync (ssize_t, int) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::sync"); + return 0; +} + +ACE_INLINE int +ACE_Shared_Memory_Pool::sync (void *, size_t, int) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::sync"); + return 0; +} + +ACE_INLINE int +ACE_Shared_Memory_Pool::protect (ssize_t, int) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::protect"); + return 0; +} + +ACE_INLINE int +ACE_Shared_Memory_Pool::protect (void *, size_t, int) +{ + ACE_TRACE ("ACE_Shared_Memory_Pool::protect"); + return 0; +} +#endif /* !ACE_LACKS_SYSV_SHMEM */ + +#if !defined (ACE_LACKS_SBRK) + +// Ask system for initial chunk of local memory. + +ACE_INLINE void * +ACE_Sbrk_Memory_Pool::init_acquire (size_t nbytes, + size_t &rounded_bytes, + int &first_time) +{ + ACE_TRACE ("ACE_Sbrk_Memory_Pool::init_acquire"); + // Note that we assume that when ACE_Sbrk_Memory_Pool is used, + // ACE_Malloc's constructor will only get called once. If this + // assumption doesn't hold, we are in deep trouble! + + first_time = 1; + return this->acquire (nbytes, rounded_bytes); +} + +// Round up the request to a multiple of the page size. + +ACE_INLINE size_t +ACE_Sbrk_Memory_Pool::round_up (size_t nbytes) +{ + ACE_TRACE ("ACE_Sbrk_Memory_Pool::round_up"); + return ACE::round_to_pagesize (nbytes); +} + +/* No-op for now... */ + +ACE_INLINE int +ACE_Sbrk_Memory_Pool::release (void) +{ + ACE_TRACE ("ACE_Sbrk_Memory_Pool::release"); + return 0; +} + +ACE_INLINE int +ACE_Sbrk_Memory_Pool::sync (ssize_t, int) +{ + ACE_TRACE ("ACE_Sbrk_Memory_Pool::sync"); + return 0; +} + +ACE_INLINE int +ACE_Sbrk_Memory_Pool::sync (void *, size_t, int) +{ + ACE_TRACE ("ACE_Sbrk_Memory_Pool::sync"); + return 0; +} + +ACE_INLINE int +ACE_Sbrk_Memory_Pool::protect (ssize_t, int) +{ + ACE_TRACE ("ACE_Sbrk_Memory_Pool::protect"); + return 0; +} + +ACE_INLINE int +ACE_Sbrk_Memory_Pool::protect (void *, size_t, int) +{ + ACE_TRACE ("ACE_Sbrk_Memory_Pool::protect"); + return 0; +} +#endif /* !ACE_LACKS_SBRK */ diff --git a/ace/Message_Block.cpp b/ace/Message_Block.cpp new file mode 100644 index 00000000000..c8266dae728 --- /dev/null +++ b/ace/Message_Block.cpp @@ -0,0 +1,249 @@ +// Message_Block.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Message_Block.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Message_Block.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Message_Block) + +int +ACE_Message_Block::copy (const char *buf, size_t n) +{ + ACE_TRACE ("ACE_Message_Block::copy"); + // Note that for this to work correct, end() *must* be >= wr_ptr(). + size_t len = size_t (this->end () - this->wr_ptr ()); + + if (len < n) + return -1; + else + { + (void) ACE_OS::memcpy (this->wr_ptr (), buf, n); + this->wr_ptr (n); + return 0; + } +} + +void +ACE_Message_Block::dump (void) const +{ + ACE_TRACE ("ACE_Message_Block::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, + "-----( Message Block )-----\n" + "type = %d\n" + "priority = %d\n" + "max_size = %d\n" + "cur_size = %d\n" + "flag = %x\n" + "next = %u\n" + "base = %u\n" + "rd_ptr = %u\n" + "wr_ptr = %u\n" + "---------------------------\n", + this->type_, this->priority_, this->max_size_, this->cur_size_, + this->flags_, this->next_, this->base_, this->rd_ptr_, + this->wr_ptr_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Message_Block::ACE_Message_Block (void) + : flags_ (0), + base_ (0), + cur_size_ (0), + max_size_ (0), + rd_ptr_ (0), + wr_ptr_ (0), + type_ (MB_NORMAL), + priority_ (0), + cont_ (0), + next_ (0), + prev_ (0), + allocator_ (0) +{ + ACE_TRACE ("ACE_Message_Block::ACE_Message_Block"); +} + +ACE_Message_Block::ACE_Message_Block (size_t sz, + ACE_Message_Type msg_type, + ACE_Message_Block *msg_cont, + const char *msg_data, + ACE_Allocator *alloc) +{ + ACE_TRACE ("ACE_Message_Block::ACE_Message_Block"); + if (this->init (sz, msg_type, msg_cont, msg_data, alloc) == -1) + ACE_ERROR ((LM_ERROR, "ACE_Message_Block")); +} + +ACE_Message_Block::~ACE_Message_Block (void) +{ + ACE_TRACE ("ACE_Message_Block::~ACE_Message_Block"); + if (ACE_BIT_DISABLED (this->flags_, ACE_Message_Block::DONT_DELETE)) + { + if (this->allocator_) + this->allocator_->free ((void *) this->base_); + else + delete [] this->base_; + } + if (this->cont_) + delete this->cont_; + this->prev_ = 0; + this->next_ = 0; +} + +ACE_Message_Block::ACE_Message_Block (const char *data, + size_t size) + : flags_ (ACE_Message_Block::DONT_DELETE), + base_ ((char *) data), + cur_size_ (size), + max_size_ (size), + rd_ptr_ (0), + wr_ptr_ (0), + type_ (MB_NORMAL), + priority_ (0), + cont_ (0), + next_ (0), + prev_ (0), + allocator_ (0) +{ + ACE_TRACE ("ACE_Message_Block::ACE_Message_Block"); +} + +int +ACE_Message_Block::size (size_t length) +{ + ACE_TRACE ("ACE_Message_Block::size"); + if (length < this->max_size_) + this->cur_size_ = length; + else + { + int r_delta, w_delta; + char *buf; + + if (this->allocator_ == 0) + ACE_NEW_RETURN (buf, char[length], -1); + else // Use the allocator! + { + buf = (char *) this->allocator_->malloc (length); + if (buf == 0) + { + errno = ENOMEM; + return -1; + } + } + + if (ACE_BIT_DISABLED (this->flags_, ACE_Message_Block::DONT_DELETE)) + { + if (this->allocator_) + this->allocator_->free ((void *) this->base_); + else + delete [] this->base_; + } + else + // We now assume ownership. + ACE_CLR_BITS (this->flags_, ACE_Message_Block::DONT_DELETE); + + ACE_OS::memcpy (buf, this->base_, this->cur_size_); + r_delta = this->rd_ptr_ - this->base_; + w_delta = this->wr_ptr_ - this->base_; + this->max_size_ = length; + this->cur_size_ = length; + + this->base_ = buf; + + this->rd_ptr_ = this->base_ + r_delta; + this->wr_ptr_ = this->base_ + w_delta; + } + return 0; +} + +int +ACE_Message_Block::init (const char *data, + size_t size) +{ + ACE_TRACE ("ACE_Message_Block::init"); + this->base_ = (char *) data; + this->cur_size_ = size; + this->max_size_ = size; + ACE_SET_BITS (this->flags_, ACE_Message_Block::DONT_DELETE); + return 0; +} + +int +ACE_Message_Block::init (size_t sz, + ACE_Message_Type msg_type, + ACE_Message_Block *msg_cont, + const char *msg_data, + ACE_Allocator *allocator) +{ + ACE_TRACE ("ACE_Message_Block::init"); + this->flags_ = 0; + + if (msg_data == 0) + { + if (allocator == 0) + { + this->allocator_ = 0; + ACE_NEW_RETURN (this->base_, char[sz], -1); + } + else // Use the allocator! + { + this->allocator_ = allocator; + this->base_ = (char *) allocator->malloc (sz); + if (this->base_ == 0) + { + errno = ENOMEM; + return -1; + } + } + } + else + { + this->base_ = (char *) msg_data; + ACE_SET_BITS (this->flags_, ACE_Message_Block::DONT_DELETE); + } + + this->cur_size_ = sz; + this->max_size_ = sz; + this->rd_ptr_ = this->base_; + this->wr_ptr_ = this->base_; + this->priority_ = 0; + this->type_ = msg_type; + this->cont_ = msg_cont; + this->next_ = 0; + this->prev_ = 0; + return 0; +} + +ACE_Message_Block * +ACE_Message_Block::clone (Message_Flags mask) const +{ + // You always want to clear this one to prevent memory leaks but you + // might add some others later. + const Message_Flags always_clear = ACE_Message_Block::DONT_DELETE; + + ACE_TRACE ("ACE_Message_Block::clone"); + ACE_Message_Block *nb; + + ACE_NEW_RETURN (nb, + ACE_Message_Block (this->max_size_, this->type_, + 0, 0, this->allocator_), + 0); + + ACE_OS::memcpy (nb->base_, this->base_, this->max_size_); + + nb->rd_ptr (this->rd_ptr_ - this->base_); + nb->wr_ptr (this->wr_ptr_ - this->base_); + + // Set new flags minus the mask... + nb->set_flags (this->flags ()); + nb->clr_flags (mask | always_clear); + + if (this->cont_ != 0) + nb->cont_ = this->cont_->clone (mask); + return nb; +} diff --git a/ace/Message_Block.h b/ace/Message_Block.h new file mode 100644 index 00000000000..c94fbfffc81 --- /dev/null +++ b/ace/Message_Block.h @@ -0,0 +1,268 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Message_Block.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#include "ace/ACE.h" + +#if !defined (ACE_MESSAGE_BLOCK_H) +#define ACE_MESSAGE_BLOCK_H + +#include "ace/Malloc.h" + +class ACE_Export ACE_Message_Block + // = TITLE + // Object used to store messages in the ASX framework. + // + // = DESCRIPTION + // An ACE_Message_Block is modeled after the message data + // structures used in System V STREAMS. A Message_Block is + // composed of one or more Message_Blocks that are linked + // together by PREV and NEXT pointers. In addition, a + // ACE_Message_Block may also be linked to a chain of other + // Message_Blocks. This structure enables efficient + // manipulation of arbitrarily-large messages *without* + // incurring memory copying overhead. +{ +public: + enum ACE_Message_Type + { + // = Data and protocol messages (regular and priority) + MB_DATA = 0x01, // regular data + MB_PROTO = 0x02, // protocol control + + // = Control messages (regular and priority) + MB_BREAK = 0x03, // line break + MB_PASSFP = 0x04, // pass file pointer + MB_EVENT = 0x05, // post an event to an event queue + MB_SIG = 0x06, // generate process signal + MB_IOCTL = 0x07, // ioctl; set/get params + MB_SETOPTS = 0x08, // set various stream head options + + // = Control messages (high priority; go to head of queue) + MB_IOCACK = 0x81, // acknowledge ioctl + MB_IOCNAK = 0x82, // negative ioctl acknowledge + MB_PCPROTO = 0x83, // priority proto message + MB_PCSIG = 0x84, // generate process signal + MB_READ = 0x85, // generate read notification + MB_FLUSH = 0x86, // flush your queues + MB_STOP = 0x87, // stop transmission immediately + MB_START = 0x88, // restart transmission after stop + MB_HANGUP = 0x89, // line disconnect + MB_ERROR = 0x8a, // fatal error used to set u.u_error + MB_PCEVENT = 0x8b, // post an event to an event queue + + // Message class masks + MB_NORMAL = 0x00, // Normal priority messages + MB_PRIORITY = 0x80, // High priority control messages + MB_USER = 0x200 // User-defined control messages + }; + + typedef u_long Message_Flags; + + enum + { + DONT_DELETE = 01, // Don't delete the data on exit since we don't own it. + USER_FLAGS = 0x1000 // user defined flags start here + }; + + // = Initialization and termination. + ACE_Message_Block (void); + // Create an empty message. + + ACE_Message_Block (const char *data, + size_t size = 0); + // Create a Message Block that assumes ownership of without + // copying it (i.e., we don't delete it since we don't malloc it!). + + ACE_Message_Block (size_t size, + ACE_Message_Type type = MB_DATA, + ACE_Message_Block *cont = 0, + const char *data = 0, + ACE_Allocator *allocator = 0); + // Create an initialized message of type containing + // bytes. The argument initializes the continuation field in + // the . If == 0 then we create and own the + // , using to get the data if it's non-0. If + // != 0 we assume ownership of the (and don't delete + // it). + + int init (const char *data, + size_t size = 0); + // Create a Message Block that assumes ownership of (i.e., + // doesn't delete it since it didn't malloc it!). + + int init (size_t size, + ACE_Message_Type type = MB_DATA, + ACE_Message_Block *cont = 0, + const char *data = 0, + ACE_Allocator *allocator = 0); + // Create an initialized message of type containing + // bytes. The argument initializes the continuation field in + // the . If == 0 then we create and own the + // , using to get the data if it's non-0. If + // != 0 we assume ownership of the (and don't delete + // it). + + ~ACE_Message_Block (void); + // Delete all the resources held in the message. + + int is_data_msg (void) const; + // Find out what type of message this is. + + ACE_Message_Type msg_class (void) const; + // Find out what class of message this is (there are two classes, + // messages and messages). + + ACE_Message_Type msg_type (void) const; + // Get type of the message. + + // = Set/Unset/Inspect the message flags. + Message_Flags set_flags (Message_Flags more_flags); + Message_Flags clr_flags (Message_Flags less_flags); + Message_Flags flags (void) const; + + void msg_type (ACE_Message_Type type); + // Set type of the message. + + u_long msg_priority (void) const; + // Get priority of the message. + + void msg_priority (u_long priority); + // Set priority of the message. + + ACE_Message_Block *clone (Message_Flags mask = ACE_Message_Block::DONT_DELETE) const; + // Return an exact "deep copy" of the message. + + // = Operations on Message data + + int copy (const char *buf, size_t n); + // Copies bytes from into the Message_Block starting at + // the wr_ptr() offset. Return 0 if succeeds and -1 if the size of + // the message is too small... + + char *base (void) const; + // Get message data. + + void base (char *data, size_t size, Message_Flags = DONT_DELETE); + // Set message data. + + char *end (void) const; + // Return a pointer to 1 past the end of the data in a message. + + char *rd_ptr (void); + // Get the read pointer. + void rd_ptr (char *ptr); + // Set the read pointer to . + void rd_ptr (size_t n); + // Set the read pointer ahead bytes. + + char *wr_ptr (void); + // Get the write pointer. + void wr_ptr (char *ptr); + // Set the write pointer to . + void wr_ptr (size_t n); + // Set the write pointer ahead bytes. + + // = The length of a message is computed as the length between the + // wr_ptr() - rd_ptr ()). + size_t length (void) const; + // Get the length of the message + void length (size_t n); + // Set the length of the message + + // = The size of the allocated buffer is the total amount of space + // alloted. + size_t size (void) const; + // Get the total amount of space in the message. + int size (size_t length); + // Set the total amount of space in the message. Returns 0 if + // successful, else -1. + + // = The coninuation field is used to chain together composite + // messages. + ACE_Message_Block *cont (void) const; + // Get the continuation field. + void cont (ACE_Message_Block *); + // Set the continuation field. + + // = The pointer points to the directly ahead + // in the Message_Queue. + ACE_Message_Block *next (void) const; + // Get link to next message. + void next (ACE_Message_Block *); + // Set link to next message. + + // = The pointer points to the directly + // ahead in the Message_Queue. + ACE_Message_Block *prev (void) const; + // Get link to prev message. + void prev (ACE_Message_Block *); + // Set link to prev message. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + Message_Flags flags_; + // Misc flags. + + char *base_; + // Pointer to beginning of message block. + + size_t cur_size_; + // Current size of message block. + + size_t max_size_; + // Total size of buffer. + + char *rd_ptr_; + // Pointer to beginning of next read. + + char *wr_ptr_; + // Pointer to beginning of next write. + + ACE_Message_Type type_; + // Type of message. + + u_long priority_; + // Priority of message. + + // = Links to other ACE_Message_Block *s. + ACE_Message_Block *cont_; + // Pointer to next message block in the chain. + + ACE_Message_Block *next_; + // Pointer to next message in the list. + + ACE_Message_Block *prev_; + // Pointer to previous message in the list. + + ACE_Allocator *allocator_; + // Pointer to the allocator defined for this message block. + + // = Disallow these operations for now (use instead). + ACE_Message_Block &operator= (const ACE_Message_Block &); + ACE_Message_Block (const ACE_Message_Block &); +}; + +#if defined (__ACE_INLINE__) +#include "ace/Message_Block.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_MESSAGE_BLOCK_H */ diff --git a/ace/Message_Block.i b/ace/Message_Block.i new file mode 100644 index 00000000000..ee7f50939b8 --- /dev/null +++ b/ace/Message_Block.i @@ -0,0 +1,234 @@ +/* -*- C++ -*- */ +// $Id$ + +// Message_Block.i + +#include "ace/Log_Msg.h" + +ACE_INLINE ACE_Message_Block::Message_Flags +ACE_Message_Block::set_flags (ACE_Message_Block::Message_Flags more_flags) +{ + ACE_TRACE ("ACE_Message_Block::set_flags"); + // Later we might mask more_glags so that user can't change internal + // ones: more_flags &= ~(USER_FLAGS -1). + return ACE_SET_BITS (this->flags_, more_flags); +} + +ACE_INLINE ACE_Message_Block::Message_Flags +ACE_Message_Block::clr_flags (ACE_Message_Block::Message_Flags less_flags) +{ + ACE_TRACE ("ACE_Message_Block::clr_flags"); + // Later we might mask more_flags so that user can't change internal + // ones: less_flags &= ~(USER_FLAGS -1). + return ACE_CLR_BITS (this->flags_, less_flags); +} + +ACE_INLINE ACE_Message_Block::Message_Flags +ACE_Message_Block::flags (void) const +{ + ACE_TRACE ("ACE_Message_Block::flags"); + return this->flags_; +} + +/* Return the length of the "active" portion of the message */ + +ACE_INLINE size_t +ACE_Message_Block::length (void) const +{ + ACE_TRACE ("ACE_Message_Block::length"); + return this->wr_ptr_ - this->rd_ptr_; +} + +// Sets the length of the "active" portion of the message. This is +// defined as the offset from RD_PTR to WR_PTR. + +ACE_INLINE void +ACE_Message_Block::length (size_t len) +{ + ACE_TRACE ("ACE_Message_Block::length"); + this->wr_ptr_ = this->rd_ptr_ + len; +} + +// Return the length of the potential size of the message. + +ACE_INLINE size_t +ACE_Message_Block::size (void) const +{ + ACE_TRACE ("ACE_Message_Block::size"); + return this->cur_size_; +} + +ACE_INLINE ACE_Message_Block & +ACE_Message_Block::operator= (const ACE_Message_Block &) +{ + ACE_TRACE ("ACE_Message_Block::operator="); + return *this; +} + +ACE_INLINE ACE_Message_Block::ACE_Message_Type +ACE_Message_Block::msg_type (void) const +{ + ACE_TRACE ("ACE_Message_Block::msg_type"); + return this->type_; +} + +ACE_INLINE void +ACE_Message_Block::msg_type (ACE_Message_Block::ACE_Message_Type t) +{ + ACE_TRACE ("ACE_Message_Block::msg_type"); + this->type_ = t; +} + +ACE_INLINE ACE_Message_Block::ACE_Message_Type +ACE_Message_Block::msg_class (void) const +{ + ACE_TRACE ("ACE_Message_Block::msg_class"); + + if (this->msg_type () < ACE_Message_Block::MB_PRIORITY) + return ACE_Message_Block::MB_NORMAL; + else if (this->msg_type () < ACE_Message_Block::MB_USER) + return ACE_Message_Block::MB_PRIORITY; + else + return ACE_Message_Block::MB_USER; +} + +ACE_INLINE int +ACE_Message_Block::is_data_msg (void) const +{ + ACE_TRACE ("ACE_Message_Block::is_data_msg"); + ACE_Message_Type mt = this->msg_type (); + return + mt == ACE_Message_Block::MB_DATA + || mt == ACE_Message_Block::MB_PROTO + || mt == ACE_Message_Block::MB_PCPROTO; +} + +ACE_INLINE u_long +ACE_Message_Block::msg_priority (void) const +{ + ACE_TRACE ("ACE_Message_Block::msg_priority"); + return this->priority_; +} + +ACE_INLINE void +ACE_Message_Block::msg_priority (u_long pri) +{ + ACE_TRACE ("ACE_Message_Block::msg_priority"); + this->priority_ = pri; +} + +ACE_INLINE void +ACE_Message_Block::base (char *msg_data, + size_t msg_length, + Message_Flags msg_flags) +{ + ACE_TRACE ("ACE_Message_Block::base"); + this->max_size_ = msg_length; + this->cur_size_ = msg_length; + this->rd_ptr_ = msg_data; + this->wr_ptr_ = msg_data; + this->base_ = msg_data; + this->flags_ = msg_flags; +} + +ACE_INLINE char * +ACE_Message_Block::rd_ptr (void) +{ + ACE_TRACE ("ACE_Message_Block::rd_ptr"); + return this->rd_ptr_; +} + +ACE_INLINE void +ACE_Message_Block::wr_ptr (char *new_ptr) +{ + ACE_TRACE ("ACE_Message_Block::wr_ptr"); + this->wr_ptr_ = new_ptr; +} + +ACE_INLINE char * +ACE_Message_Block::base (void) const +{ + ACE_TRACE ("ACE_Message_Block::base"); + return this->base_; +} + +// Return a pointer to 1 past the end of the data buffer. + +ACE_INLINE char * +ACE_Message_Block::end (void) const +{ + ACE_TRACE ("ACE_Message_Block::end"); + return this->base_ + this->max_size_; +} + + +ACE_INLINE void +ACE_Message_Block::rd_ptr (char *new_ptr) +{ + ACE_TRACE ("ACE_Message_Block::rd_ptr"); + this->rd_ptr_ = new_ptr; +} + +ACE_INLINE void +ACE_Message_Block::rd_ptr (size_t n) +{ + ACE_TRACE ("ACE_Message_Block::rd_ptr"); + this->rd_ptr_ += n; +} + +ACE_INLINE char * +ACE_Message_Block::wr_ptr (void) +{ + ACE_TRACE ("ACE_Message_Block::wr_ptr"); + return this->wr_ptr_; +} + +ACE_INLINE void +ACE_Message_Block::wr_ptr (size_t n) +{ + ACE_TRACE ("ACE_Message_Block::wr_ptr"); + this->wr_ptr_ += n; +} + +ACE_INLINE void +ACE_Message_Block::cont (ACE_Message_Block *next_block) +{ + ACE_TRACE ("ACE_Message_Block::cont"); + this->cont_ = next_block; +} + +ACE_INLINE ACE_Message_Block * +ACE_Message_Block::cont (void) const +{ + ACE_TRACE ("ACE_Message_Block::cont"); + return this->cont_; +} + +ACE_INLINE void +ACE_Message_Block::next (ACE_Message_Block *next_block) +{ + ACE_TRACE ("ACE_Message_Block::next"); + this->next_ = next_block; +} + +ACE_INLINE ACE_Message_Block * +ACE_Message_Block::next (void) const +{ + ACE_TRACE ("ACE_Message_Block::next"); + return this->next_; +} + +ACE_INLINE void +ACE_Message_Block::prev (ACE_Message_Block *next_block) +{ + ACE_TRACE ("ACE_Message_Block::prev"); + this->prev_ = next_block; +} + +ACE_INLINE ACE_Message_Block * +ACE_Message_Block::prev (void) const +{ + ACE_TRACE ("ACE_Message_Block::prev"); + return this->prev_; +} + diff --git a/ace/Message_Queue.cpp b/ace/Message_Queue.cpp new file mode 100644 index 00000000000..30b8a77abaa --- /dev/null +++ b/ace/Message_Queue.cpp @@ -0,0 +1,508 @@ +// Message_Queue.cpp +// $Id$ + +#if !defined (ACE_MESSAGE_QUEUE_C) +#define ACE_MESSAGE_QUEUE_C + +#define ACE_BUILD_DLL +#include "ace/Message_Queue.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Message_Queue.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Message_Queue) + +template void +ACE_Message_Queue::dump (void) const +{ + ACE_TRACE ("ACE_Message_Queue::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, + "deactivated = %d\n" + "low_water_mark = %d\n" + "high_water_mark = %d\n" + "cur_bytes = %d\n" + "cur_count = %d\n", + this->deactivated_, + this->low_water_mark_, + this->high_water_mark_, + this->cur_bytes_, + this->cur_count_)); + ACE_DEBUG ((LM_DEBUG,"notfull_cond: \n")); + notfull_cond_.dump(); + ACE_DEBUG ((LM_DEBUG,"notempty_cond: \n")); + notempty_cond_.dump(); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +template +ACE_Message_Queue::ACE_Message_Queue (size_t hwm, + size_t lwm) + : notfull_cond_ (this->lock_), + notempty_cond_ (this->lock_) +{ + ACE_TRACE ("ACE_Message_Queue::ACE_Message_Queue"); + if (this->open (hwm, lwm) == -1) + ACE_ERROR ((LM_ERROR, "open")); +} + +template +ACE_Message_Queue::~ACE_Message_Queue (void) +{ + ACE_TRACE ("ACE_Message_Queue::~ACE_Message_Queue"); + if (this->head_ != 0) + if (this->close () == -1) + ACE_ERROR ((LM_ERROR, "close")); +} + +// Don't bother locking since if someone calls this function more than +// once for the same queue, we're in bigger trouble than just +// concurrency control! + +template int +ACE_Message_Queue::open (size_t hwm, size_t lwm) +{ + ACE_TRACE ("ACE_Message_Queue::open"); + this->high_water_mark_ = hwm; + this->low_water_mark_ = lwm; + this->deactivated_ = 0; + this->cur_bytes_ = 0; + this->cur_count_ = 0; + this->tail_ = 0; + this->head_ = 0; + return 0; +} + +// Implementation of the public deactivate() method +// (assumes locks are held). + +template int +ACE_Message_Queue::deactivate_i (void) +{ + ACE_TRACE ("ACE_Message_Queue::deactivate_i"); + int current_status = + this->deactivated_ ? WAS_INACTIVE : WAS_ACTIVE; + + // Wakeup all waiters. + this->notempty_cond_.broadcast (); + this->notfull_cond_.broadcast (); + + this->deactivated_ = 1; + return current_status; +} + +template int +ACE_Message_Queue::activate_i (void) +{ + ACE_TRACE ("ACE_Message_Queue::activate_i"); + int current_status = + this->deactivated_ ? WAS_INACTIVE : WAS_ACTIVE; + this->deactivated_ = 0; + return current_status; +} + +// Clean up the queue if we have not already done so! + +template int +ACE_Message_Queue::close (void) +{ + ACE_TRACE ("ACE_Message_Queue::close"); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); + + int res = this->deactivate_i (); + + // Free up the remaining message on the list + + for (this->tail_ = 0; this->head_ != 0; ) + { + ACE_Message_Block *temp; + + // Make sure we decrement all the counts. + for (temp = this->head_; + temp != 0; + temp = temp->cont ()) + this->cur_bytes_ -= temp->size (); + + this->cur_count_--; + + this->head_ = this->head_->next (); + delete temp; + } + + return res; +} + +// Actually put the node at the end (no locking so must be called with +// locks held). + +template int +ACE_Message_Queue::enqueue_tail_i (ACE_Message_Block *new_item) +{ + ACE_TRACE ("ACE_Message_Queue::enqueue_tail_i"); + + if (new_item == 0) + return -1; + + // List was empty, so build a new one. + if (this->tail_ == 0) + { + this->head_ = new_item; + this->tail_ = new_item; + new_item->next (0); + new_item->prev (0); + } + // Link at the end. + else + { + + new_item->next (0); + this->tail_->next (new_item); + new_item->prev (this->tail_); + this->tail_ = new_item; + } + + // Make sure to count *all* the bytes in a composite message!!! + + for (ACE_Message_Block *temp = new_item; + temp != 0; + temp = temp->cont ()) + this->cur_bytes_ += temp->size (); + + this->cur_count_++; + + // Tell any blocked threads that the queue has a new item! + if (this->notempty_cond_.signal () != 0) + return -1; + else + return this->cur_count_; +} + +// Actually put the node at the head (no locking) + +template int +ACE_Message_Queue::enqueue_head_i (ACE_Message_Block *new_item) +{ + ACE_TRACE ("ACE_Message_Queue::enqueue_head_i"); + + if (new_item == 0) + return -1; + + new_item->prev (0); + new_item->next (this->head_); + + if (this->head_ != 0) + this->head_->prev (new_item); + else + this->tail_ = new_item; + + this->head_ = new_item; + + // Make sure to count *all* the bytes in a composite message!!! + + for (ACE_Message_Block *temp = new_item; + temp != 0; + temp = temp->cont ()) + this->cur_bytes_ += temp->size (); + + this->cur_count_++; + + // Tell any blocked threads that the queue has a new item! + if (this->notempty_cond_.signal () != 0) + return -1; + else + return this->cur_count_; +} + +// Actually put the node at its proper position relative to its +// priority. + +template int +ACE_Message_Queue::enqueue_i (ACE_Message_Block *new_item) +{ + ACE_TRACE ("ACE_Message_Queue::enqueue_i"); + + if (new_item == 0) + return -1; + + if (this->head_ == 0) + // Check for simple case of an empty queue, where all we need to + // do is insert into the head. + return this->enqueue_head_i (new_item); + else + { + ACE_Message_Block *temp; + + // Figure out where the new item goes relative to its priority. + // We start looking from the highest priority to the lowest + // priority. + + for (temp = this->tail_; + temp != 0; + temp = temp->prev ()) + { + if (temp->msg_priority () >= new_item->msg_priority ()) + // Break out when we've located an item that has higher + // priority that . + break; + } + + if (temp == 0) + // Check for simple case of inserting at the head of the queue, + // where all we need to do is insert before the + // current head. + return this->enqueue_head_i (new_item); + else if (temp->next () == 0) + // Check for simple case of inserting at the end of the + // queue, where all we need to do is insert after + // the current tail. + return this->enqueue_tail_i (new_item); + else + { + // Insert the message right before the item of equal or + // higher priority. This ensures that FIFO order is + // maintained when messages of the same priority are + // inserted consecutively. + new_item->prev (temp); + new_item->next (temp->next ()); + temp->next ()->prev (new_item); + temp->next (new_item); + } + } + + // Make sure to count *all* the bytes in a composite message!!! + + for (ACE_Message_Block *temp = new_item; + temp != 0; + temp = temp->cont ()) + this->cur_bytes_ += temp->size (); + + this->cur_count_++; + + // Tell any blocked threads that the queue has a new item! + if (this->notempty_cond_.signal () != 0) + return -1; + else + return this->cur_count_; +} + +// Actually get the first ACE_Message_Block (no locking, so must be called +// with locks held). This method assumes that the queue has at least +// one item in it when it is called. + +template int +ACE_Message_Queue::dequeue_head_i (ACE_Message_Block *&first_item) +{ + ACE_TRACE ("ACE_Message_Queue::dequeue_head_i"); + first_item = this->head_; + this->head_ = this->head_->next (); + + if (this->head_ == 0) + this->tail_ = 0; + else + // The prev pointer of the first message block has to point to + // NULL... + this->head_->prev (0); + + // Make sure to subtract off all of the bytes associated with this + // message. + for (ACE_Message_Block *temp = first_item; + temp != 0; + temp = temp->cont ()) + this->cur_bytes_ -= temp->size (); + + this->cur_count_--; + +#if 0 + if (this->cur_bytes_ <= this->low_water_mark_) + // If queue is no longer full signal any waiting threads. +#endif /* 0 */ + + if (this->notfull_cond_.signal () != 0) + return -1; + else + return this->cur_count_; +} + +// Take a look at the first item without removing it. + +template int +ACE_Message_Queue::peek_dequeue_head (ACE_Message_Block *&first_item, + ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Message_Queue::peek_dequeue_head"); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); + + if (this->deactivated_) + { + errno = ESHUTDOWN; + return -1; + } + + // Wait for at least one item to become available + + while (this->is_empty_i ()) + { + if (this->notempty_cond_.wait (tv) == -1) + { + if (errno == ETIME) + errno = EWOULDBLOCK; + return -1; + } + if (this->deactivated_) + { + errno = ESHUTDOWN; + return -1; + } + } + + first_item = this->head_; + return this->cur_count_; +} + +// Block indefinitely waiting for an item to arrive, +// does not ignore alerts (e.g., signals). + +template int +ACE_Message_Queue::enqueue_head (ACE_Message_Block *new_item, + ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Message_Queue::enqueue_head"); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); + + if (this->deactivated_) + { + errno = ESHUTDOWN; + return -1; + } + + // Wait while the queue is full + + while (this->is_full_i ()) + { + if (this->notfull_cond_.wait (tv) == -1) + { + if (errno == ETIME) + errno = EWOULDBLOCK; + return -1; + } + if (this->deactivated_) + { + errno = ESHUTDOWN; + return -1; + } + } + return this->enqueue_head_i (new_item); +} + +// Enqueue an into the in +// accordance with its (0 is lowest priority). Returns +// -1 on failure, else the number of items still on the queue. + +template int +ACE_Message_Queue::enqueue (ACE_Message_Block *new_item, + ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Message_Queue::enqueue"); + + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); + + if (this->deactivated_) + { + errno = ESHUTDOWN; + return -1; + } + + // Wait while the queue is full + + while (this->is_full_i ()) + { + if (this->notfull_cond_.wait (tv) == -1) + { + if (errno == ETIME) + errno = EWOULDBLOCK; + return -1; + } + if (this->deactivated_) + { + errno = ESHUTDOWN; + return -1; + } + } + + return this->enqueue_i (new_item); +} + +// Block indefinitely waiting for an item to arrive, +// does not ignore alerts (e.g., signals). + +template int +ACE_Message_Queue::enqueue_tail (ACE_Message_Block *new_item, + ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Message_Queue::enqueue_tail"); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); + + if (this->deactivated_) + { + errno = ESHUTDOWN; + return -1; + } + + // Wait while the queue is full + + while (this->is_full_i ()) + { + if (this->notfull_cond_.wait (tv) == -1) + { + if (errno == ETIME) + errno = EWOULDBLOCK; + return -1; + } + if (this->deactivated_) + { + errno = ESHUTDOWN; + return -1; + } + } + return this->enqueue_tail_i (new_item); +} + +// Remove an item from the front of the queue. If TV == 0 block +// indefinitely (or until an alert occurs). Otherwise, block for upto +// the amount of time specified by TV. + +template int +ACE_Message_Queue::dequeue_head (ACE_Message_Block *&first_item, + ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Message_Queue::dequeue_head"); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); + + if (this->deactivated_) + { + errno = ESHUTDOWN; + return -1; + } + + // Wait while the queue is empty. + + while (this->is_empty_i ()) + { + if (this->notempty_cond_.wait (tv) == -1) + { + if (errno == ETIME) + errno = EWOULDBLOCK; + return -1; + } + if (this->deactivated_) + { + errno = ESHUTDOWN; + return -1; + } + } + + return this->dequeue_head_i (first_item); +} + +#endif /* ACE_MESSAGE_QUEUE_C */ diff --git a/ace/Message_Queue.h b/ace/Message_Queue.h new file mode 100644 index 00000000000..1caac7f3d0a --- /dev/null +++ b/ace/Message_Queue.h @@ -0,0 +1,217 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Message_Queue.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_MESSAGE_LIST_H) +#define ACE_MESSAGE_LIST_H + +#include "ace/Message_Block.h" +#include "ace/Time_Value.h" +#include "ace/IO_Cntl_Msg.h" + +template +class ACE_Message_Queue + // = TITLE + // A thread-safe message queueing facility, modeled after the + // queueing facilities in System V StreamS. + // + // = DESCRIPTION + // A ACE_Message_Queue is the central queueing facility for + // messages in the ASX framework. If is + // ACE_MT_SYNCH then all operations are thread-safe. Otherwise, + // if it's then there's no locking overhead. +{ +public: + // = Default high and low water marks. + enum + { + DEFAULT_LWM = 0, + // Default low watermark. + DEFAULT_HWM = 16 * 1024, + // Default high watermark (16 K). + WAS_ACTIVE = 1, + // Message queue was active before activate() or deactivate(). + WAS_INACTIVE = 2 + // Message queue was inactive before activate() or deactivate(). + }; + + // = Initialization and termination methods. + ACE_Message_Queue (size_t hwm = DEFAULT_HWM, + size_t lwm = DEFAULT_LWM); + // Create a message queue with all the defaults. + int open (size_t hwm = DEFAULT_HWM, size_t lwm = DEFAULT_LWM); + // Create a message queue with all the defaults. + + int close (void); + // Close down the message queue and release all resources. + + ~ACE_Message_Queue (void); + // Close down the message queue and release all resources. + + int peek_dequeue_head (ACE_Message_Block *&first_item, + ACE_Time_Value *tv = 0); + // Retrieve the first ACE_Message_Block without removing it. + // Returns -1 on failure, else the number of items still on the + // queue. + + // = For all the following three routines if tv == 0, the caller + // will block until action is possible, else will wait for amount of + // time in *tv). Calls will return, however, when queue is closed, + // deactivated, when a signal occurs, or if the time specified in tv + // elapses, (in which case errno = EWOULDBLOCK). + + int enqueue (ACE_Message_Block *new_item, ACE_Time_Value *tv = 0); + // Enqueue an into the in + // accordance with its (0 is lowest priority). FIFO + // order is maintained when messages of the same priority are + // inserted consecutively. Returns -1 on failure, else the number + // of items still on the queue. + + int enqueue_tail (ACE_Message_Block *new_item, ACE_Time_Value *tv = 0); + // Enqueue an at the end of the queue. + // Returns -1 on failure, else the number of items still on the + // queue. + + int enqueue_head (ACE_Message_Block *new_item, ACE_Time_Value *tv = 0); + // Enqueue an at the head of the queue. + // Returns -1 on failure, else the number of items still on the + // queue. + + int dequeue_head (ACE_Message_Block *&first_item, ACE_Time_Value *tv = 0); + // Dequeue and return the at the head of the + // queue. Returns -1 on failure, else the number of items still on + // the queue. + + // = Checks if queue is full/empty. + int is_full (void); + // True if queue is full, else false. + int is_empty (void); + // True if queue is empty, else false. + + size_t message_bytes (void); + // Number of total bytes on the queue. + + size_t message_count (void); + // Number of total messages on the queue. + + // = Flow control routines + + size_t high_water_mark (void); + // Get high watermark. + void high_water_mark (size_t hwm); + // Set high watermark. + size_t low_water_mark (void); + // Get low watermark. + void low_water_mark (size_t lwm); + // Set low watermark. + + // = Activation control methods. + + int deactivate (void); + // Deactivate the queue and wakeup all threads waiting on the queue + // so they can continue. No messages are removed from the queue, + // however. Any other operations called until the queue is + // activated again will immediately return -1 with == + // ESHUTDOWN. Returns WAS_INACTIVE if queue was inactive before the + // call and WAS_ACTIVE if queue was active before the call. + + int activate (void); + // Reactivate the queue so that threads can enqueue and dequeue + // messages again. Returns WAS_INACTIVE if queue was inactive + // before the call and WAS_ACTIVE if queue was active before the + // call. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + // = Routines that actually do the enqueueing and dequeueing (these + // assume that locks are held by the corresponding public methods). + + int enqueue_i (ACE_Message_Block *new_item); + // Enqueue an in accordance with its priority. + + int enqueue_tail_i (ACE_Message_Block *new_item); + // Enqueue an at the end of the queue. + + int enqueue_head_i (ACE_Message_Block *new_item); + // Enqueue an at the head of the queue. + + int dequeue_head_i (ACE_Message_Block *&first_item); + // Dequeue and return the at the head of the + // queue. + + // = Check the boundary conditions (assumes locks are held). + int is_full_i (void); + // True if queue is full, else false. + int is_empty_i (void); + // True if queue is empty, else false. + + // = Implementation of the public activate() and deactivate() + // methods above (assumes locks are held). + int deactivate_i (void); + // Deactivate the queue. + int activate_i (void); + // Activate the queue. + + ACE_Message_Block *head_; + // Pointer to head of ACE_Message_Block list. + + ACE_Message_Block *tail_; + // Pointer to tail of ACE_Message_Block list. + + int low_water_mark_; + // Lowest number before unblocking occurs. + + int high_water_mark_; + // Greatest number of bytes before blocking. + + int cur_bytes_; + // Current number of bytes in the queue. + + int cur_count_; + // Current number of messages in the queue. + + int deactivated_; + // Indicates that the queue is inactive. + + // = Synchronization primitives for controlling concurrent access. + ACE_SYNCH_MUTEX lock_; + // Protect queue from concurrent access. + + ACE_SYNCH_CONDITION notempty_cond_; + // Used to make threads sleep until the queue is no longer empty. + + ACE_SYNCH_CONDITION notfull_cond_; + // Used to make threads sleep until the queue is no longer full. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Message_Queue.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Message_Queue.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Message_Queue.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_MESSAGE_LIST_H */ diff --git a/ace/Message_Queue.i b/ace/Message_Queue.i new file mode 100644 index 00000000000..980fa487677 --- /dev/null +++ b/ace/Message_Queue.i @@ -0,0 +1,122 @@ +/* -*- C++ -*- */ +// $Id$ + +// Message_Queue.i + +#include "ace/Log_Msg.h" + +// Check if queue is empty (does not hold locks). + +template ACE_INLINE int +ACE_Message_Queue::is_empty_i (void) +{ + ACE_TRACE ("ACE_Message_Queue::is_empty_i"); + return this->cur_bytes_ <= 0 && this->cur_count_ <= 0; +} + +// Check if queue is full (does not hold locks). + +template ACE_INLINE int +ACE_Message_Queue::is_full_i (void) +{ + ACE_TRACE ("ACE_Message_Queue::is_full_i"); + return this->cur_bytes_ > this->high_water_mark_; +} + +// Check if queue is empty (holds locks). + +template ACE_INLINE int +ACE_Message_Queue::is_empty (void) +{ + ACE_TRACE ("ACE_Message_Queue::is_empty"); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); + + return this->is_empty_i (); +} + +// Check if queue is full (holds locks). + +template ACE_INLINE int +ACE_Message_Queue::is_full (void) +{ + ACE_TRACE ("ACE_Message_Queue::is_full"); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); + + return this->is_full_i (); +} + +template ACE_INLINE size_t +ACE_Message_Queue::high_water_mark (void) +{ + ACE_TRACE ("ACE_Message_Queue::high_water_mark"); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0); + + return this->high_water_mark_; +} + +template ACE_INLINE void +ACE_Message_Queue::high_water_mark (size_t hwm) +{ + ACE_TRACE ("ACE_Message_Queue::high_water_mark"); + ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->lock_); + + this->high_water_mark_ = hwm; +} + +template ACE_INLINE size_t +ACE_Message_Queue::low_water_mark (void) +{ + ACE_TRACE ("ACE_Message_Queue::low_water_mark"); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0); + + return this->low_water_mark_; +} + +template ACE_INLINE void +ACE_Message_Queue::low_water_mark (size_t lwm) +{ + ACE_TRACE ("ACE_Message_Queue::low_water_mark"); + ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->lock_); + + this->low_water_mark_ = lwm; +} + +// Return the current number of bytes in the queue. + +template ACE_INLINE size_t +ACE_Message_Queue::message_bytes (void) +{ + ACE_TRACE ("ACE_Message_Queue::message_bytes"); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0); + + return this->cur_bytes_; +} + +// Return the current number of messages in the queue. + +template ACE_INLINE size_t +ACE_Message_Queue::message_count (void) +{ + ACE_TRACE ("ACE_Message_Queue::message_count"); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0); + + return this->cur_count_; +} + +template int +ACE_Message_Queue::activate (void) +{ + ACE_TRACE ("ACE_Message_Queue::activate"); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); + + return this->activate_i (); +} + +template int +ACE_Message_Queue::deactivate (void) +{ + ACE_TRACE ("ACE_Message_Queue::deactivate"); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); + + return this->deactivate_i (); +} diff --git a/ace/Method_Object.cpp b/ace/Method_Object.cpp new file mode 100644 index 00000000000..86fffea0812 --- /dev/null +++ b/ace/Method_Object.cpp @@ -0,0 +1,14 @@ +// Method_Object.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Method_Object.h" + +ACE_Method_Object::ACE_Method_Object (void) +{ +} + +ACE_Method_Object::~ACE_Method_Object (void) +{ +} + diff --git a/ace/Method_Object.h b/ace/Method_Object.h new file mode 100644 index 00000000000..49daaff39d5 --- /dev/null +++ b/ace/Method_Object.h @@ -0,0 +1,43 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Method_Object.h +// +// = AUTHOR +// Andres Kruse and Douglas C. Schmidt +// +// +// ============================================================================ + +#if !defined (ACE_METHOD_OBJECT_H) +#define ACE_METHOD_OBJECT_H + +#include "ace/OS.h" + +class ACE_Export ACE_Method_Object + // = TITLE + // Reifies a method into an object. Subclasses typically + // represent necessary state and behavior. + // + // = DESCRIPTION + // A is inserted in the , where + // it is subsequently removed by the and invoked. +{ +public: + // = Initialization and termination methods. + ACE_Method_Object (void); + virtual ~ACE_Method_Object (void); + + // = Invocation method + virtual int call (void) = 0; + // Invoked when the is scheduled to run. +}; + +#endif /* ACE_METHOD_OBJECT_H */ diff --git a/ace/Module.cpp b/ace/Module.cpp new file mode 100644 index 00000000000..46f6ae1ea76 --- /dev/null +++ b/ace/Module.cpp @@ -0,0 +1,168 @@ +// Module.cpp +// $Id$ + +#if !defined (ACE_MODULE_C) +#define ACE_MODULE_C + +#define ACE_BUILD_DLL +#include "ace/Module.h" +#include "ace/Stream_Modules.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Module.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Module) + +template void +ACE_Module::dump (void) const +{ + ACE_TRACE ("ACE_Module::dump"); +} + +template void +ACE_Module::writer (ACE_Task *q) +{ + ACE_TRACE ("ACE_Module::writer"); + this->q_pair_[1] = q; + if (q != 0) + ACE_CLR_BITS (q->flags_, ACE_Task_Flags::ACE_READER); +} + +template void +ACE_Module::reader (ACE_Task *q) +{ + ACE_TRACE ("ACE_Module::reader"); + this->q_pair_[0] = q; + if (q != 0) + ACE_SET_BITS (q->flags_, ACE_Task_Flags::ACE_READER); +} + +// Link this ACE_Module on top of ACE_Module M. + +template void +ACE_Module::link (ACE_Module *m) +{ + ACE_TRACE ("ACE_Module::link"); + this->next (m); + this->writer ()->next (m->writer ()); + m->reader ()->next (this->reader ()); +} + +template int +ACE_Module::open (char *mod_name, + ACE_Task *writer_q, + ACE_Task *reader_q, + void *arg) +{ + ACE_TRACE ("ACE_Module::open"); + this->name (mod_name); + this->arg_ = arg; + + if (writer_q == 0) + writer_q = new ACE_Thru_Task; + if (reader_q == 0) + reader_q = new ACE_Thru_Task; + + // Make sure that the memory is allocated before proceding. + if (writer_q == 0 || reader_q == 0) + { + delete writer_q; + delete reader_q; + errno = ENOMEM; + return -1; + } + + this->reader (reader_q); + this->writer (writer_q); + + // Setup back pointers. + reader_q->mod_ = this; + writer_q->mod_ = this; + return 0; +} + +// Set and get pointer to sibling ACE_Task in ACE_Module. + +template ACE_Task * +ACE_Module::sibling (ACE_Task *orig) +{ + ACE_TRACE ("ACE_Module::sibling"); + if (this->q_pair_[0] == orig) + return this->q_pair_[1]; + else if (this->q_pair_[1] == orig) + return this->q_pair_[0]; + else + return 0; +} + +template ACE_INLINE +ACE_Module::ACE_Module (void) +{ + ACE_TRACE ("ACE_Module::ACE_Module"); + this->name (""); + // Do nothing... +} + +// Should never be called... +template ACE_INLINE +ACE_Module::~ACE_Module (void) +{ + ACE_TRACE ("ACE_Module::~ACE_Module"); + ACE_ERROR ((LM_ERROR, "destructor for %s should never be called!\n", + this->name ())); +} + +template ACE_INLINE +ACE_Module::ACE_Module (char *mod_name, + ACE_Task *writer_q, + ACE_Task *reader_q, + void *flags) +{ + ACE_TRACE ("ACE_Module::ACE_Module"); + if (this->open (mod_name, writer_q, reader_q, flags) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Module")); +} + +template int +ACE_Module::close (u_long flags) +{ + ACE_TRACE ("ACE_Module::close"); + ACE_Task *reader_q = this->reader (); + ACE_Task *writer_q = this->writer (); + int result = 0; + + if (reader_q != 0) + { + if (reader_q->close () == -1) + result = -1; + reader_q->flush (); + reader_q->next (0); + } + + if (writer_q != 0) + { + if (writer_q->close () == -1) + result = -1; + writer_q->flush (); + writer_q->next (0); + } + + if (ACE_BIT_ENABLED (flags, ACE_Module::M_DELETE)) + { + // Only delete the Tasks if there aren't any more threads + // running in them. + if (reader_q->thr_count () == 0) + delete reader_q; + this->reader (0); + + if (writer_q->thr_count () == 0) + delete writer_q; + this->writer (0); + + delete (void *) this; // Darn well better be allocated dynamically!!! + } + return result; +} + +#endif /* ACE_MODULE_C */ diff --git a/ace/Module.h b/ace/Module.h new file mode 100644 index 00000000000..b9983852a37 --- /dev/null +++ b/ace/Module.h @@ -0,0 +1,139 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Module.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_MODULE_H) +#define ACE_MODULE_H + +#include "ace/ACE.h" +#include "ace/Task.h" + +// Forward decl. +// template class ACE_Task; + +template +class ACE_Module + // = TITLE + // An abstraction for managing a bi-directional flow of messages. + // + // = DESCRIPTION + // This is based on the Module concept in System V Streams, + // which contains a pair of Tasks, one for handling upstream + // processing, one for handling downstream processing. +{ + friend class ACE_Shutup_GPlusPlus; // Turn off g++ warning +public: + enum + { + M_DELETE = 1 + // Indicates that close() deletes the Tasks. Don't change this + // value without updating the same enum in class ACE_Stream... + }; + + // = Initialization and termination methods. + ACE_Module (void); + // Create an empty Module. + + ACE_Module (char *module_name, + ACE_Task *writer = 0, + ACE_Task *reader = 0, void *a = 0); + // Create an initialized module with as its identity + // and and as its tasks. + + int open (char *module_name, + ACE_Task *writer = 0, + ACE_Task *reader = 0, void *a = 0); + // Create an initialized module with as its identity + // and and as its tasks. + + int close (u_long flags = M_DELETE); + // Close down the Module and its Tasks. If the argument + // is given then delete all the memory too. + + // = ACE_Task manipulation routines + ACE_Task *writer (void); + // Get the writer task. + void writer (ACE_Task *q); + // Set the writer task. + + ACE_Task *reader (void); + // Get the reader task. + void reader (ACE_Task *q); + // Set the reader task. + + ACE_Task *sibling (ACE_Task *orig); + // Set and get pointer to sibling ACE_Task in ACE_Module + + // = Identify the module + const char *name (void) const; + // Get the module name. + void name (char *); + // Set the module name. + + // = Argument to the Tasks. + void *arg (void) const; + // Get the argument passed to the tasks. + + void arg (void *); + // Set the argument passed to the tasks. + + void link (ACE_Module *m); + // Link to other modules in the ustream stack + + ACE_Module *next (void); + // Get the next pointer to the module above in the stream. + + void next (ACE_Module *m); + // Set the next pointer to the module above in the stream. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ~ACE_Module (void); + // *Must* use dynamic allocation. + + ACE_Task *q_pair_[2]; + // Pair of Tasks that form the "read-side" and "write-side" of the + // ACE_Module partitioning. + + char name_[MAXNAMLEN + 1]; + // Name of the ACE_Module. + + ACE_Module *next_; + // Next ACE_Module in the stack. + + void *arg_; + // Argument passed through to the reader and writer task when they + // are opened. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Module.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Module.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Module.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_MODULE_H */ diff --git a/ace/Module.i b/ace/Module.i new file mode 100644 index 00000000000..affc11f568c --- /dev/null +++ b/ace/Module.i @@ -0,0 +1,62 @@ +/* -*- C++ -*- */ +// $Id$ + +// Module.i + +template ACE_INLINE void * +ACE_Module::arg (void) const +{ + ACE_TRACE ("ACE_Module::arg"); + return this->arg_; +} + +template ACE_INLINE void +ACE_Module::arg (void *a) +{ + ACE_TRACE ("ACE_Module::arg"); + this->arg_ = a; +} + +template ACE_INLINE const char * +ACE_Module::name (void) const +{ + ACE_TRACE ("ACE_Module::name"); + return this->name_; +} + +template ACE_INLINE void +ACE_Module::name (char *n) +{ + ACE_TRACE ("ACE_Module::name"); + ACE_OS::strncpy (this->name_, n, MAXNAMLEN); +} + +template ACE_INLINE ACE_Task * +ACE_Module::writer (void) +{ + ACE_TRACE ("ACE_Module::writer"); + return this->q_pair_[1]; +} + +template ACE_INLINE ACE_Task * +ACE_Module::reader (void) +{ + ACE_TRACE ("ACE_Module::reader"); + return this->q_pair_[0]; +} + +template ACE_INLINE ACE_Module * +ACE_Module::next (void) +{ + ACE_TRACE ("ACE_Module::next"); + return this->next_; +} + +template ACE_INLINE void +ACE_Module::next (ACE_Module *m) +{ + ACE_TRACE ("ACE_Module::next"); + this->next_ = m; +} + + diff --git a/ace/Multiplexor.cpp b/ace/Multiplexor.cpp new file mode 100644 index 00000000000..42b5eb753a6 --- /dev/null +++ b/ace/Multiplexor.cpp @@ -0,0 +1,13 @@ +// Multiplexor.cpp +// $Id$ + +#if defined (ACE_HAS_THREADS) + +#define ACE_BUILD_DLL +#include "ace/Multiplexor.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Multiplexor.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_THREADS */ diff --git a/ace/Multiplexor.h b/ace/Multiplexor.h new file mode 100644 index 00000000000..960d67e371e --- /dev/null +++ b/ace/Multiplexor.h @@ -0,0 +1,76 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Multiplexor.h +// +// Define the Driver and ACE_Multiplexor container classes. +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + + +#if !defined (ACE_MULTIPLEXOR_H) +#define ACE_MULTIPLEXOR_H + +#include "ace/Module.h" +#include "ace/Map_Manager.h" + +#if defined (ACE_HAS_THREADS) + +#if 0 +class Driver + // = TITLE + // + // + // = DESCRIPTION + // +{ +public: + Driver (void); + ~Driver (void); + + virtual int link_from_below (ACE_Module *mod); + virtual ACE_Module *alloc_module (Driver *) = 0; + virtual int unlink_from_below (ACE_Module *); +}; + +class ACE_Export ACE_Multiplexor + // = TITLE + // + // + // = DESCRIPTION + // +{ +public: + // = Constructors and destructors + ACE_Multiplexor (void); + ~ACE_Multiplexor (void); + + virtual int link_from_above (Driver &ld); + virtual int link_from_above (ACE_Multiplexor &lm); + virtual int link_from_below (ACE_Module *mod); + virtual ACE_Module *alloc_lower_module (ACE_Multiplexor *) = 0; + virtual ACE_Module *alloc_upper_module (ACE_Multiplexor *) = 0; + + virtual int unlink_from_above (Driver &ld); + virtual int unlink_from_above (ACE_Multiplexor &lm); + virtual int unlink_from_below (ACE_Module *mod); +}; + +#if defined (__ACE_INLINE__) +#include "ace/Multiplexor.i" +#endif /* __ACE_INLINE__ */ + +#endif /* 0 */ + +#endif /* ACE_HAS_THREADS */ +#endif /* ACE_MULTIPLEXOR_H */ diff --git a/ace/Multiplexor.i b/ace/Multiplexor.i new file mode 100644 index 00000000000..1763c13ab4c --- /dev/null +++ b/ace/Multiplexor.i @@ -0,0 +1,88 @@ +/* -*- C++ -*- */ +// $Id$ + +// Multiplexor.i + +int +Driver::link_from_below (ACE_Module *stream_head) +{ + ACE_TRACE ("Driver::link_from_below"); + ACE_Module *stream_tail = this->alloc_module (this); + + stream_head->link (stream_tail); + if (stream_tail->reader ()->open () == -1 + || stream_tail->writer ()->open () == -1) + { + stream_tail->close (); + return -1; + } + return 0; +} + +int +Driver::unlink_from_below (ACE_Module *) +{ + ACE_TRACE ("Driver::unlink_from_below"); + return -1; +} + +ACE_Multiplexor::ACE_Multiplexor (void) +{ + ACE_TRACE ("ACE_Multiplexor::ACE_Multiplexor"); +} + +ACE_Multiplexor::~ACE_Multiplexor (void) +{ + ACE_TRACE ("ACE_Multiplexor::~ACE_Multiplexor"); +} + +int +ACE_Multiplexor::link_from_above (Driver &ld) +{ + ACE_TRACE ("ACE_Multiplexor::link_from_above"); + return ld.link_from_below (this->alloc_lower_module (this)); +} + +int +ACE_Multiplexor::link_from_above (ACE_Multiplexor &lm) +{ + ACE_TRACE ("ACE_Multiplexor::link_from_above"); + return lm.link_from_below (this->alloc_lower_module (this)); +} + +int +ACE_Multiplexor::link_from_below (ACE_Module *stream_head) +{ + ACE_TRACE ("ACE_Multiplexor::link_from_below"); + ACE_Module *stream_tail = this->alloc_upper_module (this); + + stream_head->link (stream_tail); + if (stream_tail->reader ()->open () == -1 + || stream_tail->writer ()->open () == -1) + { + stream_tail->close (); + return -1; + } + return 0; +} + +int +ACE_Multiplexor::unlink_from_above (Driver &) +{ + ACE_TRACE ("ACE_Multiplexor::unlink_from_above"); + return -1; +} + +int +ACE_Multiplexor::unlink_from_above (ACE_Multiplexor &) +{ + ACE_TRACE ("ACE_Multiplexor::unlink_from_above"); + return -1; +} + +int +ACE_Multiplexor::unlink_from_below (ACE_Module *) +{ + ACE_TRACE ("ACE_Multiplexor::unlink_from_below"); + return -1; +} diff --git a/ace/Name_Proxy.cpp b/ace/Name_Proxy.cpp new file mode 100644 index 00000000000..dadc2580b76 --- /dev/null +++ b/ace/Name_Proxy.cpp @@ -0,0 +1,175 @@ +// Name_Proxy.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Name_Proxy.h" + +void +ACE_Name_Proxy::dump (void) const +{ + ACE_TRACE ("ACE_Name_Proxy::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->connector_.dump (); + this->peer_.dump (); + ACE_DEBUG ((LM_DEBUG, "reactor_ = %x", this->reactor_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// Default constructor. + +ACE_Name_Proxy::ACE_Name_Proxy (void) + : reactor_ (0) +{ + ACE_TRACE ("ACE_Name_Proxy::ACE_Name_Proxy"); +} + +// Establish binding with the ACE_Name Server at remote_addr. + +int +ACE_Name_Proxy::open (const ACE_INET_Addr &remote_addr, + ACE_Synch_Options& options) +{ + ACE_TRACE ("ACE_Name_Proxy::open"); + ACE_Time_Value *timeout = 0; + + if (options[ACE_Synch_Options::USE_TIMEOUT]) + timeout = (ACE_Time_Value *) &ACE_Time_Value::zero; + else + timeout = (ACE_Time_Value *) options.time_value (); + + // Initiate the connection. + return this->connector_.connect (this->peer_, remote_addr, timeout); +} + +// Establish binding with the ACE_Name Server at remote_addr. + +ACE_Name_Proxy::ACE_Name_Proxy (const ACE_INET_Addr &remote_addr, + ACE_Synch_Options& options) +{ + ACE_TRACE ("ACE_Name_Proxy::ACE_Name_Proxy"); + if (this->open (remote_addr, options) == -1 + && options[ACE_Synch_Options::USE_TIMEOUT] && errno != EWOULDBLOCK) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Name_Proxy::ACE_Name_Proxy")); +} + +// Obtain underlying handle. + +/* VIRTUAL */ ACE_HANDLE +ACE_Name_Proxy::get_handle (void) const +{ + ACE_TRACE ("ACE_Name_Proxy::get_handle"); + return this->peer_.get_handle (); +} + +int +ACE_Name_Proxy::request_reply (ACE_Name_Request &request) +{ + ACE_TRACE ("ACE_Name_Proxy::request_reply"); + void *buffer; + ssize_t length; + + if ((length = request.encode (buffer)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "encode failed"), -1); + + // Transmit request via a blocking send. + + if (this->peer_.send_n (buffer, length) != length) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send_n failed"), -1); + else + { + ACE_Name_Reply reply; + + // Receive reply via blocking read. + + if (this->peer_.recv (&reply, sizeof reply) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv failed"), -1); + + else if (reply.decode () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "decode failed"), -1); + + errno = int (reply.errnum ()); + return reply.status (); + } +} + +int +ACE_Name_Proxy::send_request (ACE_Name_Request &request) +{ + ACE_TRACE ("ACE_Name_Proxy::send_request"); + void *buffer; + ssize_t length; + + if ((length = request.encode (buffer)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "encode failed"), -1); + + // Transmit request via a blocking send. + + else if (this->peer_.send_n (buffer, length) != length) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send_n failed"), -1); + + return 0; +} + +int +ACE_Name_Proxy::recv_reply (ACE_Name_Request &reply) +{ + ACE_TRACE ("ACE_Name_Proxy::recv_reply"); + // Read the first 4 bytes to get the length of the message + // This implementation assumes that the first 4 bytes are + // the length of the message. + ssize_t n = this->peer_.recv ((void *) &reply, sizeof (ACE_UINT32)); + + switch (n) + { + case -1: + // FALLTHROUGH + ACE_DEBUG ((LM_DEBUG, "****************** recv_reply returned -1\n")); + default: + ACE_ERROR ((LM_ERROR, "%p got %d bytes, expected %d bytes\n", + "recv failed", n, sizeof (ACE_UINT32))); + // FALLTHROUGH + case 0: + // We've shutdown unexpectedly + return -1; + // NOTREACHED + case sizeof (ACE_UINT32): + { + // Transform the length into host byte order. + ssize_t length = ntohl (reply.length ()); + + // Receive the rest of the request message. + // @@ beware of blocking read!!!. + n = this->peer_.recv ((void *) (((char *) &reply) + + sizeof (ACE_UINT32)), + length - sizeof (ACE_UINT32)); + + // Subtract off the size of the part we skipped over... + if (n != ssize_t (length - sizeof (ACE_UINT32))) + { + ACE_ERROR ((LM_ERROR, "%p expected %d, got %d\n", + "invalid length", length, n)); + return -1; + } + + // Decode the request into host byte order. + if (reply.decode () == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "decode failed")); + return -1; + } + } + } + return 0; +} + +// Close down the connection to the server. + +ACE_Name_Proxy::~ACE_Name_Proxy (void) +{ + ACE_TRACE ("ACE_Name_Proxy::~ACE_Name_Proxy"); + this->peer_.close (); +} + + diff --git a/ace/Name_Proxy.h b/ace/Name_Proxy.h new file mode 100644 index 00000000000..f99fff09d9d --- /dev/null +++ b/ace/Name_Proxy.h @@ -0,0 +1,82 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// ACE_Name_Proxy.h +// +// = DESCRIPTION +// Proxy for dealing with remote server process managing NET_LOCAL +// Name_Bindings. +// +// = AUTHOR +// Gerhard Lenzer, Douglas C. Schmidt, and Prashant Jain +// +// ============================================================================ + +#if !defined (ACE_NAME_PROXY_H) +#define ACE_NAME_PROXY_H + +#include "ace/INET_Addr.h" +#include "ace/SOCK_Connector.h" +#include "ace/SOCK_Stream.h" +#include "ace/Service_Config.h" +#include "ace/Synch_Options.h" +#include "ace/Name_Request_Reply.h" + +class ACE_Export ACE_Name_Proxy : public ACE_Event_Handler + // = TITLE + // Proxy for dealing with remote server process managing NET_LOCAL NameBindings + // + // = DESCRIPTION + // Shields applications from details of interacting with the ACE_Name Server. +{ +public: + ACE_Name_Proxy (void); + // Default constructor. + + // = Establish a binding with the ACE_Name Server. + ACE_Name_Proxy (const ACE_INET_Addr &remote_addr, // Address of ACE_Name Server. + ACE_Synch_Options& options = + ACE_Synch_Options::defaults); + + int open (const ACE_INET_Addr &remote_addr, // Address of ACE_Name Server. + ACE_Synch_Options& options = + ACE_Synch_Options::defaults); + + int request_reply (ACE_Name_Request &request); + // Perform the request and wait for the reply. + + int send_request (ACE_Name_Request &request); + // Perform the request. + + int recv_reply (ACE_Name_Request &reply); + // Receive the reply. + + virtual ACE_HANDLE get_handle (void) const; + // Obtain underlying handle. + + virtual ~ACE_Name_Proxy (void); + // Close down the connection to the server. + + void dump (void) const; + // Dump the state of the object; + +private: + + ACE_SOCK_Connector connector_; + // ACE_Connector factory used to establish connections actively. + + ACE_SOCK_Stream peer_; + // Connection to ACE_Name Server peer. + + ACE_Reactor *reactor_; + // Pointer to ACE_Reactor (used if we are run in "reactive-mode"). +}; + +#endif /* ACE_NAME_PROXY_H */ diff --git a/ace/Name_Request_Reply.cpp b/ace/Name_Request_Reply.cpp new file mode 100644 index 00000000000..804ae6ce89d --- /dev/null +++ b/ace/Name_Request_Reply.cpp @@ -0,0 +1,491 @@ +// Name_Request_Reply.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Name_Request_Reply.h" + +// Default "do nothing" constructor. + +ACE_Name_Request::ACE_Name_Request (void) +{ + ACE_TRACE ("ACE_Name_Request::ACE_Name_Request"); +} + +// Create a ACE_Name_Request message. + +ACE_Name_Request::ACE_Name_Request (ACE_UINT32 t, // Type of request. + const ACE_USHORT16 name[], // Name + const size_t name_length, // size in bytes + const ACE_USHORT16 value[], // + const size_t value_length, // size in bytes + const char type[], // + const size_t type_length, // size in bytes + ACE_Time_Value *timeout) // Max time waiting for request. +{ + ACE_TRACE ("ACE_Name_Request::ACE_Name_Request"); + this->msg_type (t); + this->name_len (name_length); + this->value_len (value_length); + this->type_len (type_length); + + // If timeout is a NULL pointer, then block forever... + if (timeout == 0) + { + this->transfer_.block_forever_ = 1; + this->transfer_.sec_timeout_ = 0; + this->transfer_.usec_timeout_ = 0; + } + else // Do a "timed wait." + { + this->block_forever (0); + // Keep track of how long client is willing to wait. + this->transfer_.sec_timeout_ = timeout->sec (); + this->transfer_.usec_timeout_ = timeout->usec (); + } + + // Set up pointers and copy name value and type into request. + this->name_ = this->transfer_.data_; + this->value_ = &this->name_[name_length / sizeof (ACE_USHORT16) ]; + this->type_ = (char *)(&this->value_[value_length / sizeof (ACE_USHORT16)]); // + + (void) ACE_OS::memcpy (this->name_, name, name_length); + (void) ACE_OS::memcpy (this->value_, value, value_length); + (void) ACE_OS::memcpy (this->type_, type, type_length); + + // Compute size of the fixed portion of the message... + size_t len = sizeof this->transfer_ - sizeof this->transfer_.data_; + + // ... then add in the amount of the variable-sized portion. + len += name_length + value_length + type_length ; + + this->length (len); +} + +// Initialize length_ in order to avoid problems with byte-ordering +void +ACE_Name_Request::init (void) +{ + ACE_TRACE ("ACE_Name_Request::init"); + this->length (sizeof this->transfer_); +} + +// = Set/get the length of the encoded/decoded message. +ACE_UINT32 +ACE_Name_Request::length (void) const +{ + ACE_TRACE ("ACE_Name_Request::length"); + return this->transfer_.length_; +} + +void +ACE_Name_Request::length (ACE_UINT32 l) +{ + ACE_TRACE ("ACE_Name_Request::length"); + this->transfer_.length_ = l; +} + +// = Set/get the type of the message. +ACE_UINT32 +ACE_Name_Request::msg_type (void) const +{ + ACE_TRACE ("ACE_Name_Request::msg_type"); + return this->transfer_.msg_type_; +} + +void +ACE_Name_Request::msg_type (ACE_UINT32 t) +{ + ACE_TRACE ("ACE_Name_Request::msg_type"); + this->transfer_.msg_type_ = t; +} + +// = Set/get the len of the name +ACE_UINT32 +ACE_Name_Request::name_len (void) const +{ + ACE_TRACE ("ACE_Name_Request::name_len"); + return this->transfer_.name_len_; +} + +void +ACE_Name_Request::name_len (ACE_UINT32 t) +{ + ACE_TRACE ("ACE_Name_Request::name_len"); + this->transfer_.name_len_ = t; +} + +// = Set/get the len of the value +ACE_UINT32 +ACE_Name_Request::value_len (void) const +{ + ACE_TRACE ("ACE_Name_Request::value_len"); + return this->transfer_.value_len_; +} + +void +ACE_Name_Request::value_len (ACE_UINT32 t) +{ + ACE_TRACE ("ACE_Name_Request::value_len"); + this->transfer_.value_len_ = t; +} + +// = Set/get the len of the type +ACE_UINT32 +ACE_Name_Request::type_len (void) const +{ + ACE_TRACE ("ACE_Name_Request::type_len"); + return this->transfer_.type_len_; +} + +void +ACE_Name_Request::type_len (ACE_UINT32 t) +{ + ACE_TRACE ("ACE_Name_Request::type_len"); + this->transfer_.type_len_ = t; +} + +// = Set/get the blocking semantics. +ACE_UINT32 +ACE_Name_Request::block_forever (void) const +{ + ACE_TRACE ("ACE_Name_Request::block_forever"); + return this->transfer_.block_forever_; +} + +void +ACE_Name_Request::block_forever (ACE_UINT32 bs) +{ + ACE_TRACE ("ACE_Name_Request::block_forever"); + this->transfer_.block_forever_ = bs; +} + +// = Set/get the timeout. +ACE_Time_Value +ACE_Name_Request::timeout (void) const +{ + ACE_TRACE ("ACE_Name_Request::timeout"); + return ACE_Time_Value (this->transfer_.sec_timeout_, this->transfer_.usec_timeout_); +} + +void +ACE_Name_Request::timeout (const ACE_Time_Value timeout) +{ + ACE_TRACE ("ACE_Name_Request::timeout"); + this->transfer_.sec_timeout_ = timeout.sec (); + this->transfer_.usec_timeout_ = timeout.usec (); +} + +// = Set/get the name +const ACE_USHORT16 * +ACE_Name_Request::name (void) const +{ + ACE_TRACE ("ACE_Name_Request::name"); + return this->name_; +} + +void +ACE_Name_Request::name (const ACE_USHORT16 *t) +{ + ACE_TRACE ("ACE_Name_Request::name"); + (void) ACE_OS::memcpy (this->name_, t, this->name_len()); +} + +// = Set/get the value +const ACE_USHORT16 * +ACE_Name_Request::value (void) const +{ + ACE_TRACE ("ACE_Name_Request::value"); + return this->value_; +} + +void +ACE_Name_Request::value (const ACE_USHORT16 *c) +{ + ACE_TRACE ("ACE_Name_Request::value"); + (void) ACE_OS::memcpy (this->value_, c, this->value_len()); +} + +// = Set/get the type +const char * +ACE_Name_Request::type (void) const +{ + ACE_TRACE ("ACE_Name_Request::type"); + return this->type_; +} + +void +ACE_Name_Request::type (const char *c) +{ + ACE_TRACE ("ACE_Name_Request::type"); + (void) ::strncpy (this->type_, c, MAXPATHLEN + 1); +} + +// Encode the transfer buffer into network byte order +// so that it can be sent to the server. + +int +ACE_Name_Request::encode (void *&buf) +{ + ACE_TRACE ("ACE_Name_Request::encode"); + // Compute the length *before* doing the marshaling. + ssize_t len = this->length (); + size_t nv_data_len = + (this->transfer_.name_len_ + this->transfer_.value_len_) / sizeof (ACE_USHORT16); + + for (size_t i = 0; i < nv_data_len; i++) + this->transfer_.data_[i] = htons (this->transfer_.data_[i]); + + buf = (void *) &this->transfer_; + this->transfer_.block_forever_ = htonl (this->transfer_.block_forever_); + this->transfer_.usec_timeout_ = htonl (this->transfer_.usec_timeout_); + this->transfer_.sec_timeout_ = htonl (this->transfer_.sec_timeout_); + this->transfer_.length_ = htonl (this->transfer_.length_); + this->transfer_.msg_type_ = htonl (this->transfer_.msg_type_); + this->transfer_.name_len_ = htonl (this->transfer_.name_len_); + this->transfer_.value_len_ = htonl (this->transfer_.value_len_); + this->transfer_.type_len_ = htonl (this->transfer_.type_len_); + + return len; +} + +// Decode the transfer buffer into host byte byte order +// so that it can be used by the server. + +int +ACE_Name_Request::decode (void) +{ + ACE_TRACE ("ACE_Name_Request::decode"); + // Decode the fixed-sized portion first. + this->transfer_.block_forever_ = ntohl (this->transfer_.block_forever_); + this->transfer_.usec_timeout_ = ntohl (this->transfer_.usec_timeout_); + this->transfer_.sec_timeout_ = ntohl (this->transfer_.sec_timeout_); + this->transfer_.length_ = ntohl (this->transfer_.length_); + this->transfer_.msg_type_ = ntohl (this->transfer_.msg_type_); + this->transfer_.name_len_ = ntohl (this->transfer_.name_len_); + this->transfer_.value_len_ = ntohl (this->transfer_.value_len_); + this->transfer_.type_len_ = ntohl (this->transfer_.type_len_); + + size_t nv_data_len = + (this->transfer_.name_len_ + this->transfer_.value_len_) / sizeof (ACE_USHORT16); + + for (size_t i = 0; i < nv_data_len; i++) + this->transfer_.data_[i] = ntohs (this->transfer_.data_[i]); + + this->name_ = this->transfer_.data_; + this->value_ = &this->name_[this->transfer_.name_len_ / sizeof (ACE_USHORT16)]; + this->type_ = (char *)(&this->value_[this->transfer_.value_len_ / sizeof (ACE_USHORT16)]); + this->type_[this->transfer_.type_len_] = '\0'; + + // Decode the variable-sized portion. + return 0; +} + +// Print out the current values of the ACE_Name_Request. + +void +ACE_Name_Request::dump (void) const +{ + ACE_TRACE ("ACE_Name_Request::dump"); + ACE_DEBUG ((LM_DEBUG, "*******\nlength = %d\n", + this->length ())); + ACE_DEBUG ((LM_DEBUG, "message-type = ")); + + switch (this->msg_type ()) + { + case ACE_Name_Request::BIND: + ACE_DEBUG ((LM_DEBUG, "BIND\n")); + break; + case ACE_Name_Request::REBIND: + ACE_DEBUG ((LM_DEBUG, "REBIND\n")); + break; + case ACE_Name_Request::RESOLVE: + ACE_DEBUG ((LM_DEBUG, "RESOLVE\n")); + break; + case ACE_Name_Request::UNBIND: + ACE_DEBUG ((LM_DEBUG, "UNBIND\n")); + break; + case ACE_Name_Request::LIST_NAMES: + ACE_DEBUG ((LM_DEBUG, "LIST_NAMES\n")); + break; + case ACE_Name_Request::LIST_VALUES: + ACE_DEBUG ((LM_DEBUG, "LIST_VALUES\n")); + break; + case ACE_Name_Request::LIST_TYPES: + ACE_DEBUG ((LM_DEBUG, "LIST_TYPES\n")); + break; + case ACE_Name_Request::LIST_NAME_ENTRIES: + ACE_DEBUG ((LM_DEBUG, "LIST_NAME_ENTRIES\n")); + break; + case ACE_Name_Request::LIST_VALUE_ENTRIES: + ACE_DEBUG ((LM_DEBUG, "LIST_VALUE_ENTRIES\n")); + break; + case ACE_Name_Request::LIST_TYPE_ENTRIES: + ACE_DEBUG ((LM_DEBUG, "LIST_TYPE_ENTRIES\n")); + break; + default: + ACE_DEBUG ((LM_DEBUG, " = %d\n", this->msg_type ())); + break; + } + + if (this->block_forever ()) + ACE_DEBUG ((LM_DEBUG, "blocking forever\n")); + else + { + ACE_Time_Value tv = this->timeout (); + ACE_DEBUG ((LM_DEBUG, "waiting for %ld secs and %ld usecs\n", + tv.sec (), tv.usec ())); + } + ACE_DEBUG ((LM_DEBUG, "*******\nname_len = %d\n", + this->name_len ())); + ACE_DEBUG ((LM_DEBUG, "*******\nvalue_len = %d\n", + this->value_len ())); +#if 0 + cout << "Name = " << ACE_WString (this->name(), this->name_len() / sizeof (ACE_USHORT16)) << endl; + cout << "value = " << ACE_WString (this->value(), this->value_len() / sizeof (ACE_USHORT16)) << endl; + cout << "type = " << this->type () << endl; +#endif + ACE_DEBUG ((LM_DEBUG, "+++++++\n")); +} + +// Default constructor. + +ACE_Name_Reply::ACE_Name_Reply (void) +{ + ACE_TRACE ("ACE_Name_Reply::ACE_Name_Reply"); + // Initialize to a known quantity. + this->msg_type (0); + this->errnum (0); + this->length (sizeof this->transfer_); +} + +// Create a ACE_Name_Reply message. + +ACE_Name_Reply::ACE_Name_Reply (ACE_UINT32 t, ACE_UINT32 err) // Type of reply. +{ + ACE_TRACE ("ACE_Name_Reply::ACE_Name_Reply"); + this->msg_type (t); + this->errnum (err); + this->length (sizeof this->transfer_); +} + +// Initialize length_ in order to avoid problems with byte-ordering +void +ACE_Name_Reply::init (void) +{ + ACE_TRACE ("ACE_Name_Reply::init"); + this->length (sizeof this->transfer_); +} + +// = Set/get the length of the encoded/decoded message. +ACE_UINT32 +ACE_Name_Reply::length (void) const +{ + ACE_TRACE ("ACE_Name_Reply::length"); + return this->transfer_.length_; +} + +void +ACE_Name_Reply::length (ACE_UINT32 l) +{ + ACE_TRACE ("ACE_Name_Reply::length"); + this->transfer_.length_ = l; +} + +// = Set/get the type of the message. +ACE_UINT32 +ACE_Name_Reply::msg_type (void) const +{ + ACE_TRACE ("ACE_Name_Reply::msg_type"); + return this->transfer_.type_; +} + +void +ACE_Name_Reply::msg_type (ACE_UINT32 t) +{ + ACE_TRACE ("ACE_Name_Reply::msg_type"); + this->transfer_.type_ = t; +} + +// = Set/get the status of the reply (0 == success, -1 == failure). +ACE_UINT32 +ACE_Name_Reply::status (void) const +{ + ACE_TRACE ("ACE_Name_Reply::status"); + return this->transfer_.type_ == ACE_Name_Reply::SUCCESS ? 0 : -1; +} + +void +ACE_Name_Reply::status (ACE_UINT32 s) +{ + ACE_TRACE ("ACE_Name_Reply::status"); + this->transfer_.type_ = s == (ACE_UINT32) -1 ? ACE_Name_Reply::FAILURE : ACE_Name_Reply::SUCCESS; +} + +// = Set/get the errno of a failed reply. +ACE_UINT32 +ACE_Name_Reply::errnum (void) const +{ + ACE_TRACE ("ACE_Name_Reply::errnum"); + return this->transfer_.errno_; +} + +void +ACE_Name_Reply::errnum (ACE_UINT32 e) +{ + ACE_TRACE ("ACE_Name_Reply::errnum"); + this->transfer_.errno_ = e; +} + +// Encode the transfer buffer into network byte order +// so that it can be sent to the client. + +int +ACE_Name_Reply::encode (void *&buf) +{ + ACE_TRACE ("ACE_Name_Reply::encode"); + int len = this->length (); // Get length *before* marshaling. + + this->transfer_.length_ = htonl (this->transfer_.length_); + this->transfer_.type_ = htonl (this->transfer_.type_); + this->transfer_.errno_ = htonl (this->transfer_.errno_); + buf = (void *) &this->transfer_; + return len; +} + +// Decode the transfer buffer into host byte order +// so that it can be used by the client. + +int +ACE_Name_Reply::decode (void) +{ + ACE_TRACE ("ACE_Name_Reply::decode"); + this->transfer_.length_ = ntohl (this->transfer_.length_); + this->transfer_.type_ = ntohl (this->transfer_.type_); + this->transfer_.errno_ = ntohl (this->transfer_.errno_); + return 0; +} + +// Print out current values of the ACE_Name_Reply object. + +void +ACE_Name_Reply::dump (void) const +{ + ACE_TRACE ("ACE_Name_Reply::dump"); + ACE_DEBUG ((LM_DEBUG, "*******\nlength = %d\nerrnum = %d", + this->length (), this->errnum ())); + ACE_DEBUG ((LM_DEBUG, "type = ")); + + switch (this->msg_type ()) + { + case ACE_Name_Reply::SUCCESS: + ACE_DEBUG ((LM_DEBUG, "SUCCESS\n")); + break; + case ACE_Name_Reply::FAILURE: + ACE_DEBUG ((LM_DEBUG, "FAILURE\n")); + break; + default: + ACE_DEBUG ((LM_DEBUG, " = %d\n", this->msg_type ())); + break; + } +} diff --git a/ace/Name_Request_Reply.h b/ace/Name_Request_Reply.h new file mode 100644 index 00000000000..dfc9cb5deed --- /dev/null +++ b/ace/Name_Request_Reply.h @@ -0,0 +1,253 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// ACE_Name_Request_Reply.h +// +// = DESCRIPTION +// Define the format used to exchange messages between the +// ACE_Name Server and its clients. +// +// = AUTHOR +// Gerhard Lenzer, Douglas C. Schmidt, and Prashant Jain +// +// ============================================================================ + +#if !defined (ACE_NAME_REQUEST_REPLY_H) +#define ACE_NAME_REQUEST_REPLY_H + +#include "ace/Time_Value.h" +#include "ace/SString.h" + +class ACE_Export ACE_Name_Request + // = TITLE + // Message format for delivering requests to the ACE_Name Server. + // + // = DESCRIPTION + // This class is implemented to minimize data copying. + // In particular, all marshaling is done in situ... +{ +public: + enum Constants + { + /* Request message types. */ + BIND = 01, + REBIND = 02, + RESOLVE = 03, + UNBIND = 04, + LIST_NAMES = 05, + LIST_VALUES = 015, + LIST_TYPES = 025, + LIST_NAME_ENTRIES = 06, + LIST_VALUE_ENTRIES = 016, + LIST_TYPE_ENTRIES = 026, + MAX_ENUM = 11, + MAX_LIST = 3, + + // Mask for bitwise operation used for table lookup + OP_TABLE_MASK = 07, // Mask for lookup of operation + LIST_OP_MASK = 030, // Mask for lookup of list_operation + + /* Class-specific constant values. */ + MAX_NAME_LEN = MAXPATHLEN + 1 + }; + + ACE_Name_Request (void); + // Default constructor. + + ACE_Name_Request (ACE_UINT32 msg_type, // Type of request. + const ACE_USHORT16 name[], // + const size_t name_length, + const ACE_USHORT16 value[], + const size_t value_length, + const char type[], + const size_t type_length, + ACE_Time_Value *timeout = 0); // Max time willing to wait for request. + // Create a message. + + void init (void); + // Initialize length_ in order to ensure correct byte ordering + // before a request is sent. + + // = Set/get the length of the encoded/decoded message. + ACE_UINT32 length (void) const; + void length (ACE_UINT32); + + // = Set/get the type of the message. + ACE_UINT32 msg_type (void) const; + void msg_type (ACE_UINT32); + + // = Set/get the blocking semantics. + ACE_UINT32 block_forever (void) const; + void block_forever (ACE_UINT32); + + // = Set/get the timeout. + ACE_Time_Value timeout (void) const; + void timeout (const ACE_Time_Value timeout); + + // = Set/get the name + const ACE_USHORT16 *name (void) const; + void name (const ACE_USHORT16 *); + + // = Set/get the value + const ACE_USHORT16 *value (void) const; + void value (const ACE_USHORT16 *); + + // = Set/get the type + const char *type (void) const; + void type (const char *); + + // = Set/get the len of name + ACE_UINT32 name_len (void) const; + void name_len (ACE_UINT32); + + // = Set/get the len of value + ACE_UINT32 value_len (void) const; + void value_len (ACE_UINT32); + + // = Set/get the len of type + ACE_UINT32 type_len (void) const; + void type_len (ACE_UINT32); + + int encode (void *&); + // Encode the message before transmission. + + int decode (void); + // Decode message after reception. + + void dump (void) const; + // Print out the values of the message for debugging purposes. + +private: + // = The 5 fields in the struct are transmitted to the server. + // The remaining 2 fields are not tranferred -- they are used only on + // the server-side to simplify lookups. + + struct Transfer + { + ACE_UINT32 length_; + // Length of entire request. + + ACE_UINT32 msg_type_; + // Type of the request (i.e., , , , and ). + + ACE_UINT32 block_forever_; + // Indicates if we should block forever. If 0, then + // and indicates how long we should wait. + + ACE_UINT32 sec_timeout_; + // Max seconds willing to wait for name if not blocking forever. + + ACE_UINT32 usec_timeout_; + // Max micro seconds to wait for name if not blocking forever. + + ACE_UINT32 name_len_; + // Len of name in bytes + + ACE_UINT32 value_len_; + // Len of value in bytes + + ACE_UINT32 type_len_; + // Len of type in bytes + + ACE_USHORT16 data_[MAX_NAME_LEN + MAXPATHLEN + MAXPATHLEN + 2]; + // The data portion contains the + // followed by the + // followed by the . + }; + + Transfer transfer_; + // Transfer buffer. + + ACE_USHORT16 *name_; + // Pointer to the beginning of the name in this->data_. + + ACE_USHORT16 *value_; + // Pointer to the beginning of the value in this->data_; + + char *type_; + // Pointer to the beginning of the type in this->data_; +}; + +class ACE_Export ACE_Name_Reply + // = TITLE + // Message format for delivering replies from the ACE_Name Server. + // + // = DESCRIPTION + // This class is implemented to minimize data copying. + // In particular, all marshaling is done in situ... +{ +public: + enum Constants + { + /* Reply message types. */ + SUCCESS = 1, // Reply for successful operation. + FAILURE = 2, // Reply for failed operation. + + /* Class-specific constant values. */ + MAX_NAME_LEN = MAXPATHLEN + 1 + }; + + ACE_Name_Reply (void); + // Default constructor. + + ACE_Name_Reply (ACE_UINT32 type, ACE_UINT32 err); // Type of reply. + // Create a message. + + void init (void); + // Initialize length_ in order to ensure correct byte ordering + // before a reply is sent. + + // = Set/get the length of the encoded/decoded message. + ACE_UINT32 length (void) const; + void length (ACE_UINT32); + + // = Set/get the type of the message. + ACE_UINT32 msg_type (void) const; + void msg_type (ACE_UINT32); + + // = Set/get the status of the reply (0 == success, -1 == failure). + ACE_UINT32 status (void) const; + void status (ACE_UINT32); + + // = Set/get the errno of a failed reply. + ACE_UINT32 errnum (void) const; + void errnum (ACE_UINT32); + + int encode (void *&); + // Encode the message before transfer. + + int decode (void); + // Decode a message after reception. + + void dump (void) const; + // Print out the values of the message for debugging purposes. + +private: + // = The 3 fields in the struct are transmitted to the server. + + struct Transfer + { + ACE_UINT32 length_; + // Length of entire reply. + + ACE_UINT32 type_; + // Type of the reply (i.e., or ). + + ACE_UINT32 errno_; + // Indicates why error occurred if type_> == . + // Typical reasons include: + // (if the client timed out after waiting for the name). + }; + + Transfer transfer_; + // Transfer buffer. +}; + +#endif /* ACE_NAME_REQUEST_REPLY_H */ diff --git a/ace/Name_Space.cpp b/ace/Name_Space.cpp new file mode 100644 index 00000000000..e684003509b --- /dev/null +++ b/ace/Name_Space.cpp @@ -0,0 +1,60 @@ +// Name_Space.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Name_Space.h" + +ACE_Name_Binding::ACE_Name_Binding (void) + : type_ (ACE_OS::strdup ("")) +{ + ACE_TRACE ("ACE_Name_Binding::ACE_Name_Binding"); +} + + +ACE_Name_Binding::~ACE_Name_Binding (void) +{ + ACE_TRACE ("ACE_Name_Binding::~ACE_Name_Binding"); + ACE_OS::free ((void *) this->type_); +} + +ACE_Name_Binding::ACE_Name_Binding (const ACE_WString &name, + const ACE_WString &value, + const char *type) + : name_ (name), + value_ (value), + type_ (type == 0 ? ACE_OS::strdup ("") : ACE_OS::strdup (type)) +{ + ACE_TRACE ("ACE_Name_Binding::ACE_Name_Binding"); +} + +ACE_Name_Binding::ACE_Name_Binding (const ACE_Name_Binding &s) + : name_ (s.name_), + value_ (s.value_), + type_ (ACE_OS::strdup (s.type_)) +{ + ACE_TRACE ("ACE_Name_Binding::ACE_Name_Binding"); +} + +void +ACE_Name_Binding::operator = (const ACE_Name_Binding &s) +{ + ACE_TRACE ("ACE_Name_Binding::operator ="); + + this->name_ = s.name_; + this->value_ = s.value_; + this->type_ = ACE_OS::strdup (s.type_); +} + +int +ACE_Name_Binding::operator == (const ACE_Name_Binding &s) const +{ + ACE_TRACE ("ACE_Name_Binding::operator =="); + return this->name_ == s.name_ + && this->value_ == s.value_ + && ACE_OS::strcmp (this->type_, s.type_) == 0; +} + +ACE_Name_Space::~ACE_Name_Space (void) +{ + ACE_TRACE ("ACE_Name_Space::~ACE_Name_Space"); +} diff --git a/ace/Name_Space.h b/ace/Name_Space.h new file mode 100644 index 00000000000..78a274e86b5 --- /dev/null +++ b/ace/Name_Space.h @@ -0,0 +1,145 @@ +/* -*- C++ -*- */ +// $Id$ + +/*-*- C++ -*- */ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// ACE_Name_Space +// +// = AUTHOR +// Prashant Jain +// +// ============================================================================ + +#if !defined (ACE_NAME_SPACE_H) +#define ACE_NAME_SPACE_H + +#include "ace/ACE.h" +#include "ace/SString.h" +#include "ace/Set.h" +#include "ace/Name_Proxy.h" + +typedef ACE_Unbounded_Set ACE_WSTRING_SET; + +class ACE_Export ACE_Name_Binding +{ +public: + // = Initialization and termination. + ACE_Name_Binding (const ACE_WString &n, + const ACE_WString &v, + const char *t); + // Main constructor that initializes all the fields. + + ACE_Name_Binding (void); + // Default constructor. + + ACE_Name_Binding (const ACE_Name_Binding &); + // Copy constructor. + + void operator= (const ACE_Name_Binding &); + // Assignment operator. + + ~ACE_Name_Binding (void); + // Destructor. + + int operator == (const ACE_Name_Binding &s) const; + // Test for equality. + + ACE_WString name_; + // Name of the binding. + + ACE_WString value_; + // Value of the binding. + + char *type_; + // Type of the binding. +}; + +typedef ACE_Unbounded_Set ACE_BINDING_SET; +typedef ACE_Unbounded_Set_Iterator ACE_BINDING_ITERATOR; + +typedef ACE_Unbounded_Set ACE_PWSTRING_SET; +typedef ACE_Unbounded_Set_Iterator ACE_PWSTRING_ITERATOR; + +class ACE_Export ACE_Name_Space + // = TITLE + // Abstract base class that provides an abstract interface to + // the database without exposing any implemenation details. + // + // = DESCRIPTION + // Manages a Naming Service Name Space. Provides the basic + // methods -- bind, unbind, rebind, find, and listnames. +{ +public: + + virtual ~ACE_Name_Space (void); + // virtual destructor to ensure destructors of subclasses get + // called. + + virtual int bind (const ACE_WString &name_in, + const ACE_WString &value_in, + const char *type_in = "") = 0; + // Bind a new name to a naming context (Wide character strings). + + + virtual int rebind (const ACE_WString &name_in, + const ACE_WString &value_in, + const char *type_in = "") = 0; + // Overwrite the value or type of an existing name in a + // ACE_Name_Space or bind a new name to the context, if it didn't + // exist yet. (Wide charcter strings interface). + + virtual int unbind (const ACE_WString &name_in) = 0; + // Delete a name from a ACE_Name_Space (Wide charcter strings + // Interface). + + virtual int resolve (const ACE_WString &name_in, + ACE_WString &value_out, + char *&type_out) = 0; + // Get value and type of a given name binding (Wide chars). The + // caller is responsible for deleting both and ! + + virtual int list_names (ACE_WSTRING_SET &set_out, + const ACE_WString &pattern_in) = 0; + // Get a set of names matching a specified pattern (wchars). Matching + // means the names must begin with the pattern string. + + virtual int list_values (ACE_WSTRING_SET &set_out, + const ACE_WString &pattern_in) = 0; + // Get a set of values matching a specified pattern (wchars). Matching + // means the values must begin with the pattern string. + + virtual int list_types (ACE_WSTRING_SET &set_out, + const ACE_WString &pattern_in) = 0; + // Get a set of types matching a specified pattern (wchars). Matching + // means the types must begin with the pattern string. + + virtual int list_name_entries (ACE_BINDING_SET &set, + const ACE_WString &pattern) = 0; + // Get a set of names matching a specified pattern (wchars). Matching + // means the names must begin with the pattern string. Returns the + // complete binding associated each pattern match. + + virtual int list_value_entries (ACE_BINDING_SET &set, + const ACE_WString &pattern) = 0; + // Get a set of values matching a specified pattern (wchars). Matching + // means the values must begin with the pattern string. Returns the + // complete binding associated each pattern match. + + virtual int list_type_entries (ACE_BINDING_SET &set, + const ACE_WString &pattern) = 0; + // Get a set of types matching a specified pattern (wchars). Matching + // means the types must begin with the pattern string. Returns the + // complete binding associated each pattern match. + + virtual void dump (void) const = 0; + // Dump the state of the object +}; + +#endif /* ACE_NAME_SPACE_H */ + diff --git a/ace/Naming_Context.cpp b/ace/Naming_Context.cpp new file mode 100644 index 00000000000..11f775a1498 --- /dev/null +++ b/ace/Naming_Context.cpp @@ -0,0 +1,531 @@ +// Naming_Context.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/Naming_Context.h" +#include "ace/Remote_Name_Space.h" +#include "ace/Local_Name_Space.h" + +// Make life easier later on... + +typedef ACE_Local_Name_Space LOCAL_NAME_SPACE; +typedef ACE_Local_Name_Space LIGHT_LOCAL_NAME_SPACE; + +// The following Factory is used by the ACE_Service_Config and +// svc.conf file to dynamically initialize the state of the Name +// Server client. + +ACE_SVC_FACTORY_DEFINE (ACE_Naming_Context) + +// Define the object that describes the service statically. +ACE_STATIC_SVC_DEFINE (ACE_Naming_Context, + "ACE_Naming_Context", ACE_SVC_OBJ_T, &ACE_SVC_NAME (ACE_Naming_Context), + ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ, 0) + +ACE_STATIC_SVC_REQUIRE (ACE_Naming_Context) + +int +ACE_Naming_Context::info (char **strp, + size_t length) const +{ + ACE_TRACE ("ACE_Naming_Context::info"); + char buf[BUFSIZ]; + + ACE_OS::sprintf (buf, "%s\t#%s\n", + "ACE_Naming_Context", + "Proxy for making calls to a Name Server"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +int +ACE_Naming_Context::local (void) +{ + ACE_TRACE ("ACE_Naming_Context::local"); + return ACE_OS::strcmp (this->netnameserver_host_, "localhost") == 0 + || ACE_OS::strcmp (this->netnameserver_host_, this->hostname_) == 0; +} + +int +ACE_Naming_Context::open (Context_Scope_Type scope_in, int light) +{ + ACE_TRACE ("ACE_Naming_Context::open"); + ACE_OS::hostname (this->hostname_, sizeof this->hostname_); + + this->netnameserver_host_ = this->name_options_->nameserver_host (); + this->netnameserver_port_ = this->name_options_->nameserver_port (); + + // Perform factory operation to select appropriate type of + // Name_Space subclass. + + if (scope_in == ACE_Naming_Context::NET_LOCAL && this->local () == 0) + // Use NET_LOCAL name space, set up connection with remote server. + ACE_NEW_RETURN (this->name_space_, + ACE_Remote_Name_Space (this->netnameserver_host_, + this->netnameserver_port_), + -1); + else // Use NODE_LOCAL or PROC_LOCAL name space. + { + if (light) + ACE_NEW_RETURN (this->name_space_, LIGHT_LOCAL_NAME_SPACE (scope_in, this->name_options_), -1); + else + ACE_NEW_RETURN (this->name_space_, LOCAL_NAME_SPACE (scope_in, this->name_options_), -1); + } + return 0; +} + +int +ACE_Naming_Context::close (void) +{ + ACE_TRACE ("ACE_Naming_Context::close"); + + delete this->name_space_; + + return 0; +} + +ACE_Naming_Context::ACE_Naming_Context (void) +{ + ACE_TRACE ("ACE_Naming_Context::ACE_Naming_Context"); + ACE_NEW (this->name_options_, ACE_Name_Options); +} + +ACE_Naming_Context::ACE_Naming_Context (Context_Scope_Type scope_in, + int light) +{ + ACE_TRACE ("ACE_Naming_Context::ACE_Naming_Context"); + + ACE_NEW (this->name_options_, ACE_Name_Options); + + // Initialize. + if (this->open (scope_in, light) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Naming_Context::ACE_Naming_Context")); +} + +ACE_Name_Options * +ACE_Naming_Context::name_options (void) +{ + return this->name_options_; +} + +int +ACE_Naming_Context::bind (const ACE_WString &name_in, + const ACE_WString &value_in, + const char *type_in) +{ + ACE_TRACE ("ACE_Naming_Context::bind"); + return this->name_space_->bind (name_in, value_in, type_in); +} + +int +ACE_Naming_Context::bind (const char *name_in, + const char *value_in, + const char *type_in) +{ + ACE_TRACE ("ACE_Naming_Context::bind"); + return this->bind (ACE_WString (name_in), ACE_WString (value_in), type_in); +} + +int +ACE_Naming_Context::rebind (const ACE_WString &name_in, + const ACE_WString &value_in, + const char *type_in) +{ + ACE_TRACE ("ACE_Naming_Context::rebind"); + return this->name_space_->rebind (name_in, value_in, type_in); +} + +int +ACE_Naming_Context::rebind (const char *name_in, + const char *value_in, + const char *type_in) +{ + ACE_TRACE ("ACE_Naming_Context::rebind"); + return rebind (ACE_WString (name_in), ACE_WString (value_in), type_in); +} + +int +ACE_Naming_Context::resolve (const ACE_WString &name_in, + ACE_WString &value_out, + char *&type_out) +{ + ACE_TRACE ("ACE_Naming_Context::resolve"); + return this->name_space_->resolve (name_in, value_out, type_out); +} + +int +ACE_Naming_Context::resolve (const char *name_in, + ACE_WString &value_out, + char *&type_out) +{ + ACE_TRACE ("ACE_Naming_Context::resolve"); + return this->resolve (ACE_WString (name_in), value_out, type_out); +} + +int +ACE_Naming_Context::resolve (const char *name_in, + char *&value_out, + char *&type_out) +{ + ACE_TRACE ("ACE_Naming_Context::resolve"); + ACE_WString val_str; + + if (this->resolve (ACE_WString (name_in), val_str, type_out) == -1) + return -1; + + // Note that char_rep() *allocates* the memory! Thus, caller is + // responsible for deleting it! + value_out = val_str.char_rep (); + + return value_out == 0 ? -1 : 0; +} + +int +ACE_Naming_Context::unbind (const ACE_WString &name_in) +{ + ACE_TRACE ("ACE_Naming_Context::unbind"); + return this->name_space_->unbind (name_in); +} + +int +ACE_Naming_Context::unbind (const char *name_in) +{ + ACE_TRACE ("ACE_Naming_Context::unbind"); + return this->unbind (ACE_WString (name_in)); +} + +int +ACE_Naming_Context::list_names (ACE_PWSTRING_SET &set_out, + const ACE_WString &pattern_in) +{ + ACE_TRACE ("ACE_Naming_Context::list_names"); + return this->name_space_->list_names (set_out, pattern_in); +} + +int +ACE_Naming_Context::list_names (ACE_PWSTRING_SET &set_out, + const char *pattern_in) +{ + ACE_TRACE ("ACE_Naming_Context::list_names"); + return this->list_names (set_out, ACE_WString (pattern_in)); +} + +int +ACE_Naming_Context::list_values (ACE_PWSTRING_SET &set_out, + const ACE_WString &pattern_in) +{ + ACE_TRACE ("ACE_Naming_Context::list_values"); + return this->name_space_->list_values (set_out, pattern_in); +} + +int +ACE_Naming_Context::list_values (ACE_PWSTRING_SET &set_out, + const char *pattern_in) +{ + ACE_TRACE ("ACE_Naming_Context::list_values"); + return this->list_values (set_out, ACE_WString (pattern_in)); +} + +int +ACE_Naming_Context::list_types (ACE_PWSTRING_SET &set_out, + const ACE_WString &pattern_in) +{ + ACE_TRACE ("ACE_Naming_Context::list_types"); + return this->name_space_->list_types (set_out, pattern_in); +} + +int +ACE_Naming_Context::list_types (ACE_PWSTRING_SET &set_out, + const char *pattern_in) +{ + ACE_TRACE ("ACE_Naming_Context::list_types"); + return this->list_types (set_out, ACE_WString (pattern_in)); +} + +int +ACE_Naming_Context::list_name_entries (ACE_BINDING_SET &set_out, + const ACE_WString &pattern_in) +{ + ACE_TRACE ("ACE_Naming_Context::list_name_entries"); + return this->name_space_->list_name_entries (set_out, pattern_in); +} + +int +ACE_Naming_Context::list_name_entries (ACE_BINDING_SET &set_out, + const char *pattern_in) +{ + ACE_TRACE ("ACE_Naming_Context::list_name_entries"); + return this->list_name_entries (set_out, ACE_WString (pattern_in)); +} + +int +ACE_Naming_Context::list_value_entries (ACE_BINDING_SET &set_out, + const ACE_WString &pattern_in) +{ + ACE_TRACE ("ACE_Naming_Context::list_value_entries"); + return this->name_space_->list_value_entries (set_out, pattern_in); +} + +int +ACE_Naming_Context::list_value_entries (ACE_BINDING_SET &set_out, + const char *pattern_in) +{ + ACE_TRACE ("ACE_Naming_Context::list_value_entries"); + return this->list_value_entries (set_out, ACE_WString (pattern_in)); +} + +int +ACE_Naming_Context::list_type_entries (ACE_BINDING_SET &set_out, + const ACE_WString &pattern_in) +{ + ACE_TRACE ("ACE_Naming_Context::list_type_entries"); + return this->name_space_->list_type_entries (set_out, pattern_in); +} + +int +ACE_Naming_Context::list_type_entries (ACE_BINDING_SET &set_out, + const char *pattern_in) +{ + ACE_TRACE ("ACE_Naming_Context::list_type_entries"); + return this->list_type_entries (set_out, ACE_WString (pattern_in)); +} + + +ACE_Naming_Context::~ACE_Naming_Context (void) +{ + ACE_TRACE ("ACE_Naming_Context::~ACE_Naming_Context"); + delete this->name_space_; +} + +void +ACE_Naming_Context::dump () +{ + ACE_TRACE ("ACE_Naming_Context::dump"); + this->name_space_->dump(); +} + +int +ACE_Naming_Context::init (int argc, char *argv[]) +{ + ACE_DEBUG ((LM_DEBUG, "ACE_Naming_Context::init\n")); + this->name_options_->parse_args (argc, argv); + return this->open (this->name_options_->context ()); +} + +int +ACE_Naming_Context::fini (void) +{ + ACE_DEBUG ((LM_DEBUG, "ACE_Naming_Context::fini\n")); + delete this->name_options_; + return 0; +} + +ACE_Name_Options::ACE_Name_Options (void) + : debugging_ (0), + verbosity_ (0), + nameserver_port_ (ACE_DEFAULT_SERVER_PORT), + nameserver_host_ (ACE_OS::strdup (ACE_DEFAULT_SERVER_HOST)), + namespace_dir_ (ACE_OS::strdup (ACE_DEFAULT_NAMESPACE_DIR)), + process_name_ (0), + database_ (0) +{ + ACE_TRACE ("ACE_Name_Options::ACE_Name_Options"); +} + +ACE_Name_Options::~ACE_Name_Options (void) +{ + ACE_TRACE ("ACE_Name_Options::~ACE_Name_Options"); + + ACE_OS::free ((void *) this->nameserver_host_); + ACE_OS::free ((void *) this->namespace_dir_ ); + ACE_OS::free ((void *) this->process_name_ ); + ACE_OS::free ((void *) this->database_ ); +} + +void +ACE_Name_Options::nameserver_port (int port) +{ + ACE_TRACE ("ACE_Name_Options::nameserver_port"); + this->nameserver_port_ = port; +} + +int +ACE_Name_Options::nameserver_port (void) +{ + ACE_TRACE ("ACE_Name_Options::nameserver_port"); + return this->nameserver_port_; +} + +void +ACE_Name_Options::namespace_dir (const char *dir) +{ + ACE_TRACE ("ACE_Name_Options::namespace_dir"); + this->namespace_dir_ = ACE_OS::strdup (dir); +} + +void +ACE_Name_Options::process_name (const char *pname) +{ + ACE_TRACE ("ACE_Name_Options::process_name"); + const char *t = ACE::basename (pname, ACE_DIRECTORY_SEPARATOR_CHAR); + this->process_name_ = ACE_OS::strdup (t); +} + +void +ACE_Name_Options::nameserver_host (const char *host) +{ + ACE_TRACE ("ACE_Name_Options::nameserver_host"); + this->nameserver_host_ = ACE_OS::strdup (host); +} + +const char * +ACE_Name_Options::nameserver_host (void) +{ + ACE_TRACE ("ACE_Name_Options::nameserver_host"); + return this->nameserver_host_; +} + +const char * +ACE_Name_Options::database (void) +{ + ACE_TRACE ("ACE_Name_Options::database"); + return this->database_; +} + +void +ACE_Name_Options::database (const char *db) +{ + ACE_TRACE ("ACE_Name_Options::database"); + if (this->database_ != 0) + ACE_OS::free ((void *) this->database_); + this->database_ = ACE_OS::strdup (db); +} + +ACE_Naming_Context::Context_Scope_Type +ACE_Name_Options::context (void) +{ + ACE_TRACE ("ACE_Name_Options::context"); + return this->context_; +} + +void +ACE_Name_Options::context (ACE_Naming_Context::Context_Scope_Type context) +{ + ACE_TRACE ("ACE_Name_Options::context"); + this->context_ = context; +} + +const char * +ACE_Name_Options::process_name (void) +{ + ACE_TRACE ("ACE_Name_Options::process_name"); + return this->process_name_; +} + +const char * +ACE_Name_Options::namespace_dir (void) +{ + ACE_TRACE ("ACE_Name_Options::namespace_dir"); + return this->namespace_dir_; +} + +int +ACE_Name_Options::debug (void) +{ + ACE_TRACE ("ACE_Name_Options::debug"); + return this->debugging_; +} + +int +ACE_Name_Options::verbose (void) +{ + ACE_TRACE ("ACE_Name_Options::verbose"); + return this->verbosity_; +} + +void +ACE_Name_Options::parse_args (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_Name_Options::parse_args"); + ACE_LOG_MSG->open (argv[0]); + this->process_name (argv[0]); + + // Default is to use the PROC_LOCAL context... + this->context (ACE_Naming_Context::PROC_LOCAL); + + // Make the database name the same as the process name by default + // (note that this makes a copy of the process_name_ so that we can + // clean it up in the destructor). + this->database (this->process_name ()); + + ACE_Get_Opt get_opt (argc, argv, "c:dh:l:P:p:s:T:v"); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'c': + { + if (ACE_OS::strcmp (get_opt.optarg, "PROC_LOCAL")) + this->context (ACE_Naming_Context::PROC_LOCAL); + else if (ACE_OS::strcmp (get_opt.optarg, "NODE_LOCAL")) + this->context (ACE_Naming_Context::NODE_LOCAL); + else if (ACE_OS::strcmp (get_opt.optarg, "NET_LOCAL")) + this->context (ACE_Naming_Context::NET_LOCAL); + } + break; + case 'd': + this->debugging_ = 1; + break; + case 'h': + this->nameserver_host (get_opt.optarg); + break; + case 'l': + this->namespace_dir (get_opt.optarg); + break; + case 'P': + this->process_name (get_opt.optarg); + break; + case 'p': + this->nameserver_port (ACE_OS::atoi (get_opt.optarg)); + break; + case 's': + this->database (get_opt.optarg); + break; + case 'T': + if (ACE_OS::strcasecmp (get_opt.optarg, "ON") == 0) + ACE_Trace::start_tracing (); + else if (ACE_OS::strcasecmp (get_opt.optarg, "OFF") == 0) + ACE_Trace::stop_tracing (); + break; + case 'v': + this->verbosity_ = 1; + break; + default: + ACE_OS::fprintf (stderr, "%s\n" + "\t[-d] (enable debugging)\n" + "\t[-h nameserver host]\n" + "\t[-l namespace directory]\n" + "\t[-P processname]\n" + "\t[-p nameserver port]\n" + "\t[-s database name]\n" + "\t[-v] (verbose) \n", + argv[0]); + /* NOTREACHED */ + break; + } +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Local_Name_Space ; +template class ACE_Local_Name_Space ; +template class ACE_Allocator_Adapter >; +template class ACE_Allocator_Adapter >; +ACE_Name_Space_Map > >; +ACE_Name_Space_Map > >; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/ace/Naming_Context.h b/ace/Naming_Context.h new file mode 100644 index 00000000000..a1c483e855f --- /dev/null +++ b/ace/Naming_Context.h @@ -0,0 +1,312 @@ +/* -*- C++ -*- */ +// $Id$ + +/*-*- C++ -*- */ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// ACE_Naming_Context.h +// +// = AUTHOR +// Gerhard Lenzer, Douglas C. Schmidt, and Prashant Jain +// +// ============================================================================ + +#if !defined (ACE_NAMING_CONTEXT_H) +#define ACE_NAMING_CONTEXT_H + +#include "ace/ACE.h" +#include "ace/SString.h" +#include "ace/Set.h" +#include "ace/Service_Object.h" +#include "ace/Name_Proxy.h" +#include "ace/Name_Space.h" + +// Forward decl +class ACE_Name_Options; + +class ACE_Export ACE_Naming_Context : public ACE_Service_Object + // = TITLE + // Maintaining accesses Name Server Databases. Allows to add + // NameBindings, change them, remove them and resolve + // NameBindings + // + // = DESCRIPTION + // Manages a Naming Service . That represents a persistent + // string to string mapping for different scopes. The scope of a + // ACE_Naming_Context may be either local for the calling + // process (Note : A process is hereby not identified by it's + // pid, but by it's argv[0]. So different processes (in UNIX + // syntax) may access the same NameBindings), global for all + // processes running on one host or global for all processes on + // the net (that know the address of the net name server + // socket). Strings may be plain character strings or Wide + // character strings. A Name Binding consists of a name string + // (that's the key), a value string and an optional type string + // (no wide chars). +{ +public: + enum Context_Scope_Type + { + PROC_LOCAL, // Name lookup is local to the process. + NODE_LOCAL, // Name lookup is local to the node (host). + NET_LOCAL // Name lookup is local to the (sub)network. + }; + + // = Initialization and termination methods. + ACE_Naming_Context (void); + // "Do-nothing" constructor. + + ACE_Naming_Context (Context_Scope_Type scope_in, int light = 0); + // Specifies the scope of this namespace, opens and memory-maps the + // associated file (if accessible) or contacts the dedicated name + // server process for NET_LOCAL namespace. Note that + // specifies whether or not we want to use + // ACE_Lite_MMap_Memory_Pool. By default we use ACE_MMap_Memory_Pool. + + int open (Context_Scope_Type scope_in = ACE_Naming_Context::PROC_LOCAL, + int light = 0); + // Specifies the scope of this namespace, opens and memory-maps the + // associated file (if accessible) or contacts the dedicated name + // server process for NET_LOCAL namespace. Note that + // specifies whether or not we want to use + // ACE_Lite_MMap_Memory_Pool. By default we use ACE_MMap_Memory_Pool. + + int close (void); + // Deletes the instance of Name Space. Must be called before + // switching name spaces. + + ~ACE_Naming_Context (void); + // destructor, do some cleanup :TBD: last dtor should "compress" + // file + + // = Dynamic initialization hooks. + virtual int init (int argc, char *argv[]); + // Initialize name options and naming context when dynamically + // linked. + + virtual int fini (void); + // Close down the test when dynamically unlinked. + + virtual int info (char **strp, size_t length) const; + // Returns information about this context. + + ACE_Name_Options *name_options (void); + // Returns the ACE_Name_Options associated with the Naming_Context + + int bind (const ACE_WString &name_in, + const ACE_WString &value_in, + const char *type_in = ""); + // Bind a new name to a naming context (Wide character strings). + + int bind (const char *name_in, + const char *value_in, + const char *type_in = ""); + // Bind a new name to a naming context ( character strings). + + int rebind (const ACE_WString &name_in, + const ACE_WString &value_in, + const char *type_in = ""); + // Overwrite the value or type of an existing name in a + // ACE_Naming_Context or bind a new name to the context, if it + // didn't exist yet. (Wide charcter strings interface). + + int rebind (const char *name_in, + const char *value_in, + const char *type_in = ""); + // Overwrite the value or type of an existing name in a + // ACE_Naming_Context or bind a new name to the context, if it + // didn't exist yet. ( charcter strings interface) + + int unbind (const ACE_WString &name_in); + // Delete a name from a ACE_Naming_Context (Wide charcter strings + // Interface). + + int unbind (const char *name_in); + // Delete a name from a ACE_Naming_Context (character strings + // interface). + + int resolve (const ACE_WString &name_in, + ACE_WString &value_out, + char *&type_out); + // Get value and type of a given name binding (Wide chars). The + // caller is responsible for deleting both and ! + + int resolve (const char *name_in, + ACE_WString &value_out, + char *&type_out); + // Get value and type of a given name binding (Wide chars output). + // The caller is responsible for deleting both and + // ! + + int resolve (const char *name_in, + char *&value_out, + char *&type_out); + // Get value and type of a given name binding ( chars ). The caller + // is responsible for deleting both and ! + + int list_names (ACE_PWSTRING_SET &set_out, + const ACE_WString &pattern_in); + // Get a set of names matching a specified pattern (wchars). Matching + // means the names must begin with the pattern string. + + int list_names (ACE_PWSTRING_SET &set_out, + const char *pattern_in); + // Get a set of names matching a specified pattern (chars). Matching + // means the names must begin with the pattern string. + + int list_values (ACE_PWSTRING_SET &set_out, + const ACE_WString &pattern_in); + // Get a set of values matching a specified pattern (wchars). Matching + // means the values must begin with the pattern string. + + int list_values (ACE_PWSTRING_SET &set_out, + const char *pattern_in); + // Get a set of values matching a specified pattern (chars). Matching + // means the values must begin with the pattern string. + + int list_types (ACE_PWSTRING_SET &set_out, + const ACE_WString &pattern_in); + // Get a set of types matching a specified pattern (wchars). Matching + // means the types must begin with the pattern string. + + int list_types (ACE_PWSTRING_SET &set_out, + const char *pattern_in); + // Get a set of types matching a specified pattern (chars). Matching + // means the types must begin with the pattern string. + + virtual int list_name_entries (ACE_BINDING_SET &set_out, + const ACE_WString &pattern_in); + // Get a set of names matching a specified pattern (wchars). Matching + // means the names must begin with the pattern string. Returns the + // complete binding associated each pattern match. + + virtual int list_name_entries (ACE_BINDING_SET &set_out, + const char *pattern_in); + // Get a set of names matching a specified pattern (wchars). Matching + // means the names must begin with the pattern string. Returns the + // complete binding associated each pattern match. + + virtual int list_value_entries (ACE_BINDING_SET &set_out, + const ACE_WString &pattern_in); + // Get a set of values matching a specified pattern (wchars). Matching + // means the values must begin with the pattern string. Returns the + // complete binding associated each pattern match. + + virtual int list_value_entries (ACE_BINDING_SET &set_out, + const char *pattern_in); + // Get a set of values matching a specified pattern (wchars). Matching + // means the values must begin with the pattern string. Returns the + // complete binding associated each pattern match. + + virtual int list_type_entries (ACE_BINDING_SET &set_out, + const ACE_WString &pattern_in); + // Get a set of types matching a specified pattern (wchars). Matching + // means the types must begin with the pattern string. Returns the + // complete binding associated each pattern match. + + virtual int list_type_entries (ACE_BINDING_SET &set_out, + const char *pattern_in); + // Get a set of types matching a specified pattern (wchars). Matching + // means the types must begin with the pattern string. Returns the + // complete binding associated each pattern match. + + void dump (); + // Dump the state of the object. + +private: + ACE_Name_Options *name_options_; + // Keep track of the options such as database name etc per Naming Context + + ACE_Name_Space *name_space_; + // Name space (can be either local or remote) dynamically bound. + + char hostname_[MAXHOSTNAMELEN + 1]; + // Holds the local hostname. + + const char *netnameserver_host_; + // Holds name of net name server. + + int netnameserver_port_; + // Holds port number of the net name server. + + int local (void); + // 1 if we're on the same local machine as the name server, else 0. + +}; + +class ACE_Export ACE_Name_Options + // = TITLE + // Manages the options for the ACE Name_Server. +{ +public: + // = Initialization and termination methods. + ACE_Name_Options (void); + ~ACE_Name_Options (void); + + void parse_args (int argc, char *argv[]); + // Parse arguments + + // = Set/Get port number + void nameserver_port (int port); + int nameserver_port (void); + + // = Set/Get the context + ACE_Naming_Context::Context_Scope_Type context (void); + void context (ACE_Naming_Context::Context_Scope_Type); + + // = Set/Get host name + void nameserver_host (const char *host); + const char *nameserver_host (void); + + // = Set/Get name space directory + void namespace_dir (const char *dir); + const char *namespace_dir (void); + + // = Set/Get process name + void process_name (const char *dir); + const char *process_name (void); + + // = Set/Get database name + void database (const char *db); + const char *database (void); + + int debug (void); + // Return debug status + + int verbose (void); + // Return verbose status + +private: + int debugging_; + // Extra debugging info + + int verbosity_; + // Extra verbose messages + + int nameserver_port_; + // Port to connect to nameserver process. + + const char *nameserver_host_; + // Hostname of nameserver. + + const char *namespace_dir_; + // Directory to hold name_bindings. + + const char *process_name_; + // Name of this process. + + const char *database_; + // Name of the database that stores the name/value/type bindings. + + ACE_Naming_Context::Context_Scope_Type context_; + // The context in which the naming database will be created. +}; + +extern "C" ACE_Export ACE_Service_Object *_make_ACE_Naming_Context (void); + +#endif /* ACE_NAMING_CONTEXT_H */ diff --git a/ace/OS.cpp b/ace/OS.cpp new file mode 100644 index 00000000000..a55b8fa99c8 --- /dev/null +++ b/ace/OS.cpp @@ -0,0 +1,1224 @@ +// $Id$ + +// OS.cpp +#define ACE_BUILD_DLL +#include "ace/OS.h" + +#include "ace/Log_Msg.h" +#include "ace/ARGV.h" + +// Perhaps we should *always* include ace/OS.i in order to make sure +// we can always link against the OS symbols? +#if !defined (ACE_HAS_INLINED_OSCALLS) +#include "ace/OS.i" +#endif /* ACE_HAS_INLINED_OS_CALLS */ + +void +ACE_OS::flock_t::dump (void) const +{ +// ACE_TRACE ("ACE_OS::flock_t::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "handle_ = %u", this->handle_)); +#if defined (ACE_WIN32) + ACE_DEBUG ((LM_DEBUG, "\nInternal = %d", this->overlapped_.Internal)); + ACE_DEBUG ((LM_DEBUG, "\nInternalHigh = %d", this->overlapped_.InternalHigh)); + ACE_DEBUG ((LM_DEBUG, "\nOffsetHigh = %d", this->overlapped_.OffsetHigh)); + ACE_DEBUG ((LM_DEBUG, "\nhEvent = %d", this->overlapped_.hEvent)); +#else + ACE_DEBUG ((LM_DEBUG, "\nl_whence = %d", this->lock_.l_whence)); + ACE_DEBUG ((LM_DEBUG, "\nl_start = %d", this->lock_.l_start)); + ACE_DEBUG ((LM_DEBUG, "\nl_len = %d", this->lock_.l_len)); + ACE_DEBUG ((LM_DEBUG, "\nl_type = %d", this->lock_.l_type)); +#endif /* ACE_WIN32 */ + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +void +ACE_OS::mutex_lock_cleanup (void *mutex) +{ +// ACE_TRACE ("ACE_OS::mutex_lock_cleanup"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + ACE_mutex_t *p_lock = (ACE_mutex_t *) mutex; + ACE_OS::mutex_unlock (p_lock); +#endif /* ACE_HAS_DCETHREADS */ +#endif /* ACE_HAS_THREADS */ +} + +// = Static initialization. + +// This is necessary to deal with POSIX pthreads insanity. This +// guarantees that we've got a "zero'd" thread id even when ACE_thread_t +// is implemented as a structure... +ACE_thread_t ACE_OS::NULL_thread; + +ACE_OS::ACE_OS (void) +{ +// ACE_TRACE ("ACE_OS::ACE_OS"); +} + +#if defined (ACE_WIN32) + +// = Static initialization. + +// Keeps track of whether we've initialized the WinSock DLL. +int ACE_OS::socket_initialized_; + +// We need this to initialize the WinSock DLL. + +BOOL WINAPI +DllMain (HINSTANCE, // DLL module handle + DWORD fdwReason, // Reason called + LPVOID) // Reserved +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + if (ACE_OS::socket_init (ACE_WSOCK_VERSION) != 0) + return FALSE; + break; + + case DLL_PROCESS_DETACH: + if (ACE_OS::socket_fini () != 0) + return FALSE; + break; + + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + break; + + default: + ACE_ERROR_RETURN ((LM_ERROR, + "Sock.DLL DllMain called with unknown fdwReason = %u\n.", + fdwReason), FALSE); + /* NOTREACHED */ + } + + return TRUE; +} + +#include "ace/Synch.h" +#include "ace/Set.h" + +class ACE_TSS_Ref + // = TITLE + // "Reference count" for thread-specific storage keys. + // + // = DESCRIPTION + // Since the ACE_Unbounded_Set doesn't allow duplicates, the + // "reference count" is the identify of the thread_id. +{ +public: + ACE_TSS_Ref (ACE_thread_t id); + // Constructor + + ACE_TSS_Ref (void); + // Default constructor + + int operator== (const ACE_TSS_Ref &); + // Check for equality. + +// private: + + ACE_thread_t tid_; + // ID of thread using a specific key. +}; + +ACE_TSS_Ref::ACE_TSS_Ref (ACE_thread_t id) + : tid_(id) +{ +// ACE_TRACE ("ACE_TSS_Ref::ACE_TSS_Ref"); +} + +ACE_TSS_Ref::ACE_TSS_Ref (void) +{ +// ACE_TRACE ("ACE_TSS_Ref::ACE_TSS_Ref"); +} + +// Check for equality. +int +ACE_TSS_Ref::operator== (const ACE_TSS_Ref &info) +{ +// ACE_TRACE ("ACE_TSS_Ref::operator=="); + + return this->tid_ == info.tid_; +} + +typedef ACE_Unbounded_Set ACE_TSS_REF_TABLE; +typedef ACE_Unbounded_Set_Iterator ACE_TSS_REF_TABLE_ITERATOR; + +class ACE_TSS_Info + // = TITLE + // Thread Specific Key management. + // + // = DESCRIPTION + // This class maps a key to a "destructor." +{ +public: + ACE_TSS_Info (ACE_thread_key_t key, + void (*dest)(void *) = 0, + void *tss_inst = 0); + // Constructor + + ACE_TSS_Info (void); + // Default constructor + + int operator== (const ACE_TSS_Info &); + // Check for equality. + + void dump (void); + // Dump the state. + +// private: + ACE_thread_key_t key_; + // Key to the thread-specific storage item. + + void (*destructor_)(void *); + // "Destructor" that gets called when the item is finally released. + + void *tss_obj_; + // Pointer to ACE_TSS instance that has/will allocate the key. + + ACE_TSS_REF_TABLE ref_table_; + // Table of thread IDs that are using this key. +}; + +ACE_TSS_Info::ACE_TSS_Info (ACE_thread_key_t key, + void (*dest)(void *), + void *tss_inst) + : key_ (key), + destructor_ (dest), + tss_obj_ (tss_inst) +{ +// ACE_TRACE ("ACE_TSS_Info::ACE_TSS_Info"); +} + +ACE_TSS_Info::ACE_TSS_Info (void) +{ +// ACE_TRACE ("ACE_TSS_Info::ACE_TSS_Info"); +} + +// Check for equality. +int +ACE_TSS_Info::operator== (const ACE_TSS_Info &info) +{ +// ACE_TRACE ("ACE_TSS_Info::operator=="); + + return this->key_ == info.key_; +} + +void +ACE_TSS_Info::dump (void) +{ +// ACE_TRACE ("ACE_TSS_Info::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "key_ = %u", this->key_)); + ACE_DEBUG ((LM_DEBUG, "\ndestructor_ = %u", this->destructor_)); + ACE_DEBUG ((LM_DEBUG, "\ntss_obj_ = %u", this->tss_obj_)); + ACE_DEBUG ((LM_DEBUG, "\nref_table_.size_ = %u", this->ref_table_.size ())); + + ACE_TSS_Ref *tid_info = 0; + + ACE_DEBUG ((LM_DEBUG, "\nThread_usage_list\n[\n")); + + for (ACE_TSS_REF_TABLE_ITERATOR iter (this->ref_table_); + iter.next (tid_info) != 0; + iter.advance ()) + ACE_DEBUG ((LM_DEBUG, "\ntid_ = %d", tid_info->tid_)); + + ACE_DEBUG ((LM_DEBUG, "\n]\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// Create a set of objects that will reside +// within thread-specific storage. +typedef ACE_Unbounded_Set ACE_TSS_TABLE; +typedef ACE_Unbounded_Set_Iterator ACE_TSS_TABLE_ITERATOR; + +class ACE_TSS_Cleanup + // = TITLE + // Singleton that knows how to clean up all the thread-specific + // resources for Win32. + // + // = DESCRIPTION + // All this nonsense is required since Win32 doesn't + // automatically cleanup thread-specific storage on thread exit, + // unlike real operating systems... ;-) +{ +public: + static ACE_TSS_Cleanup *instance (void); + + void exit (void *status); + // Cleanup the thread-specific objects and exit with . + + int insert (ACE_thread_key_t key, void (*destructor)(void *), void *inst); + // Insert a tuple into the table. + + int remove (ACE_thread_key_t key); + // Remove a tuple from the table. + + int detach (void *inst); + // Detaches a tss_instance from its key. + + int detach (ACE_thread_key_t key, ACE_thread_t tid); + // Detaches a thread from the key. + + int key_used (ACE_thread_key_t key); + // Mark a key as being used by this thread. + +protected: + void dump (void); + + ACE_TSS_Cleanup (void); + // Ensure singleton. + +private: + ACE_TSS_TABLE table_; + // Table of 's. + + // = Static data. + static ACE_TSS_Cleanup *instance_; + // Pointer to the singleton instance. + +public: + static ACE_Recursive_Thread_Mutex lock_; + // Serialize initialization of . +}; + +// = Static object initialization. + +// Pointer to the singleton instance. +ACE_TSS_Cleanup *ACE_TSS_Cleanup::instance_ = 0; + +// Serialize initialization of . +ACE_Recursive_Thread_Mutex ACE_TSS_Cleanup::lock_; + +void +ACE_TSS_Cleanup::exit (void *status) +{ +// ACE_TRACE ("ACE_TSS_Cleanup::exit"); + + { + ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, ACE_TSS_Cleanup::lock_); + + // Prevent recursive deletions (note that when a recursive mutex + // is first acquired it has a nesting level of 1...). + if (ACE_TSS_Cleanup::lock_.get_nesting_level () > 1) + return; + + ACE_thread_key_t key_arr[TLS_MINIMUM_AVAILABLE]; + int index = 0; + + ACE_TSS_Info *key_info = 0; + + // Iterate through all the thread-specific items and free them all + // up. + + for (ACE_TSS_TABLE_ITERATOR iter (this->table_); + iter.next (key_info) != 0; + iter.advance ()) + { + void *tss_info = 0; + + int val = key_info->ref_table_.remove (ACE_TSS_Ref (ACE_OS::thr_self ())); + + if ((ACE_OS::thr_getspecific (key_info->key_, &tss_info) == 0) + && (key_info->destructor_) + && tss_info) + // Probably need to have an exception handler here... + (*key_info->destructor_) (tss_info); + + if (key_info->ref_table_.size () == 0 + && key_info->tss_obj_ == 0) + key_arr[index++] = key_info->key_; + } + + for (int i = 0; i < index; i++) + { + ::TlsFree (key_arr[i]); + this->table_.remove (ACE_TSS_Info (key_arr[i])); + } + } + +#if 0 + ::ExitThread ((DWORD) status); +#endif + ::_endthreadex ((DWORD) status); + + /* NOTREACHED */ +} + +ACE_TSS_Cleanup::ACE_TSS_Cleanup (void) +{ +// ACE_TRACE ("ACE_TSS_Cleanup::ACE_TSS_Cleanup"); +} + +ACE_TSS_Cleanup * +ACE_TSS_Cleanup::instance (void) +{ +// ACE_TRACE ("ACE_TSS_Cleanup::instance"); + + // Create and initialize thread-specific key. + if (ACE_TSS_Cleanup::instance_ == 0) + { + // Insure that we are serialized! + ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, ACE_TSS_Cleanup::lock_, 0); + + // Now, use the Double-Checked Locking pattern to make sure we + // only create the key once. + if (instance_ == 0) + ACE_NEW_RETURN (ACE_TSS_Cleanup::instance_, ACE_TSS_Cleanup, 0); + } + + return ACE_TSS_Cleanup::instance_; +} + +int +ACE_TSS_Cleanup::insert (ACE_thread_key_t key, + void (*destructor)(void *), + void *inst) +{ +// ACE_TRACE ("ACE_TSS_Cleanup::insert"); + ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, ACE_TSS_Cleanup::lock_, -1); + + return this->table_.insert (ACE_TSS_Info (key, destructor, inst)); +} + +int +ACE_TSS_Cleanup::remove (ACE_thread_key_t key) +{ +// ACE_TRACE ("ACE_TSS_Cleanup::remove"); + ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, ACE_TSS_Cleanup::lock_, -1); + + return this->table_.remove (ACE_TSS_Info (key)); +} + +int +ACE_TSS_Cleanup::detach (void *inst) +{ + ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, ACE_TSS_Cleanup::lock_, -1); + + ACE_TSS_Info *key_info = 0; + int success = 0; + int ref_cnt = 0; + + for (ACE_TSS_TABLE_ITERATOR iter (this->table_); + iter.next (key_info) != 0; + iter.advance ()) + { + if (key_info->tss_obj_ == inst) + { + key_info->tss_obj_ = 0; + ref_cnt = key_info->ref_table_.size (); + success = 1; + break; + } + } + + if (success == 0) + return -1; + else if (ACE_TSS_Cleanup::lock_.get_nesting_level () > 1) + ACE_ERROR_RETURN ((LM_DEBUG, "Detach() invoked from ACE_TSS_Cleanup::exit()\n"), 0); + else if (ref_cnt == 0) + { + ::TlsFree (key_info->key_); + return this->table_.remove (ACE_TSS_Info (key_info->key_)); + } + + return 0; +} + +int +ACE_TSS_Cleanup::detach (ACE_thread_key_t key, ACE_thread_t tid) +{ + return -1; +} + +int +ACE_TSS_Cleanup::key_used (ACE_thread_key_t key) +{ + ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, ACE_TSS_Cleanup::lock_, -1); + + ACE_TSS_Info *key_info = 0; + + for (ACE_TSS_TABLE_ITERATOR iter (this->table_); + iter.next (key_info) != 0; + iter.advance ()) + if (key_info->key_ == key) + return key_info->ref_table_.insert (ACE_TSS_Ref (ACE_OS::thr_self ())); + + return -1; +} + +void +ACE_TSS_Cleanup::dump (void) +{ + ACE_TSS_Info *key_info = 0; + + // Iterate through all the thread-specific items and dump them all. + + for (ACE_TSS_TABLE_ITERATOR iter (this->table_); + iter.next (key_info) != 0; + iter.advance ()) + key_info->dump (); +} + +// Special thread startup argument (used below in ). + +class ACE_Win32_Thread_Adapter +{ +public: + ACE_Win32_Thread_Adapter (ACE_THR_FUNC f, void *a); + // Constructor + + static void *svc_run (ACE_Win32_Thread_Adapter *); + // Run the thread exit point. + +private: + // = Arguments to thread startup. + ACE_THR_FUNC func_; + // Thread startup function. + + void *arg_; + // Argument to thread startup function. +}; + +ACE_Win32_Thread_Adapter::ACE_Win32_Thread_Adapter (ACE_THR_FUNC f, void *a) + : func_(f), + arg_(a) +{ +// ACE_TRACE ("ACE_Win32_Thread_Adapter::ACE_Win32_Thread_Adapter"); +} + +void * +ACE_Win32_Thread_Adapter::svc_run (ACE_Win32_Thread_Adapter *thread_args) +{ +// ACE_TRACE ("ACE_Win32_Thread_Adapter::svc_run"); + ACE_THR_FUNC func = thread_args->func_; + void *arg = thread_args->arg_; + delete thread_args; + void *status; + + ACE_SEH_TRY { + status = (*func) (arg); // Call thread entry point. + } + ACE_SEH_EXCEPT (EXCEPTION_EXECUTE_HANDLER) { + // Here's where we might want to provide a hook to report this... + // As it stands now, we just catch all Win32 structured exceptions + // so that we can make sure to clean up correctly when the thread + // exits. + } + + // If dropped off end, call destructors for thread-specific storage + // and exit. + ACE_TSS_Cleanup::instance ()->exit (status); + + /* NOTREACHED */ + return status; +} + +#endif // WIN32 + +int +ACE_OS::thr_create (ACE_THR_FUNC func, + void *args, + long flags, + ACE_thread_t *thr_id, + ACE_hthread_t *thr_handle, + u_int priority, + void *stack, + size_t stacksize) +{ +// ACE_TRACE ("ACE_OS::thr_create"); + +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + int result; + pthread_attr_t attr; + ACE_thread_t tmp_thr; + ACE_thread_t *p_thr; + +#if defined (ACE_HAS_SETKIND_NP) + if (::pthread_attr_create (&attr) != 0) +#else /* ACE_HAS_SETKIND_NP */ + if (::pthread_attr_init (&attr) != 0) +#endif /* ACE_HAS_SETKIND_NP */ + return -1; + else if (priority != 0) + { + struct sched_param sparam; + + ACE_OS::memset ((void *) &sparam, 0, sizeof sparam); + +#if defined (ACE_HAS_DCETHREADS) && !defined (ACE_HAS_SETKIND_NP) + sparam.sched_priority = priority > PRIORITY_MAX ? PRIORITY_MAX : priority; +#elif defined(ACE_HAS_IRIX62_THREADS) + sparam.sched_priority = priority > PTHREAD_MAX_PRIORITY ? PTHREAD_MAX_PRIORITY : priority; +#elif defined (PTHREAD_MAX_PRIORITY) // For MIT pthreads... + sparam.prio = priority > PTHREAD_MAX_PRIORITY ? PTHREAD_MAX_PRIORITY : priority; +#endif /* ACE_HAS_DCETHREADS */ + +#if !defined (ACE_HAS_FSU_PTHREADS) +#if defined (ACE_HAS_SETKIND_NP) + if (::pthread_attr_setsched (&attr, SCHED_OTHER) != 0) +#else /* ACE_HAS_SETKIND_NP */ + if (::pthread_attr_setschedparam (&attr, &sparam) != 0) +#endif /* ACE_HAS_SETKIND_NP */ + { +#if defined (ACE_HAS_SETKIND_NP) + ::pthread_attr_delete (&attr); +#else /* ACE_HAS_SETKIND_NP */ + ::pthread_attr_destroy (&attr); +#endif /* ACE_HAS_SETKIND_NP */ + return -1; + } +#else + if ((sparam.sched_priority >= PTHREAD_MIN_PRIORITY) + && (sparam.sched_priority <= PTHREAD_MAX_PRIORITY)) + attr.prio = sparam.sched_priority; + else + { + pthread_attr_destroy (&attr); + return -1; + } +#endif // ACE_HAS_FSU_PTHREADS + } + + if (stacksize != 0) + { + size_t size = stacksize; + +#if defined (PTHREAD_STACK_MIN) + if (size < PTHREAD_STACK_MIN) + stacksize = PTHREAD_STACK_MIN; +#endif /* PTHREAD_STACK_MIN */ + + if (::pthread_attr_setstacksize (&attr, size) != 0) + { +#if defined (ACE_HAS_SETKIND_NP) + ::pthread_attr_delete (&attr); +#else /* ACE_HAS_SETKIND_NP */ + ::pthread_attr_destroy (&attr); +#endif /* ACE_HAS_SETKIND_NP */ + return -1; + } + } + +#if !defined (ACE_LACKS_THREAD_STACK_ADDR) + if (stack != 0) + { + if (::pthread_attr_setstackaddr (&attr, stack) != 0) + { +#if defined (ACE_HAS_SETKIND_NP) + ::pthread_attr_delete (&attr); +#else /* ACE_HAS_SETKIND_NP */ + ::pthread_attr_destroy (&attr); +#endif /* ACE_HAS_SETKIND_NP */ + return -1; + } + } +#endif /* !ACE_LACKS_THREAD_STACK_ADDR */ + if (flags != 0) + { +#if !defined (ACE_LACKS_SETDETACH) + if (ACE_BIT_ENABLED (flags, THR_DETACHED) + || ACE_BIT_ENABLED (flags, THR_JOINABLE)) + { + int dstate = PTHREAD_CREATE_JOINABLE; + + if (ACE_BIT_ENABLED (flags, THR_DETACHED)) + dstate = PTHREAD_CREATE_DETACHED; + +#if defined (ACE_HAS_SETKIND_NP) + if (::pthread_attr_setdetach_np (&attr, dstate) != 0) +#else /* ACE_HAS_SETKIND_NP */ + if (::pthread_attr_setdetachstate (&attr, dstate) != 0) +#endif /* ACE_HAS_SETKIND_NP */ + { +#if defined (ACE_HAS_SETKIND_NP) + ::pthread_attr_delete (&attr); +#else /* ACE_HAS_SETKIND_NP */ + ::pthread_attr_destroy (&attr); +#endif /* ACE_HAS_SETKIND_NP */ + return -1; + } + } +#endif /* ACE_LACKS_SETDETACH */ + if (ACE_BIT_ENABLED (flags, THR_SCHED_FIFO) + || ACE_BIT_ENABLED (flags, THR_SCHED_RR) + || ACE_BIT_ENABLED (flags, THR_SCHED_DEFAULT)) + { + int spolicy; + + if (ACE_BIT_ENABLED (flags, THR_SCHED_DEFAULT)) + spolicy = SCHED_OTHER; + else if (ACE_BIT_ENABLED (flags, THR_SCHED_FIFO)) + spolicy = SCHED_FIFO; + else + spolicy = SCHED_RR; + +#if !defined (ACE_HAS_FSU_PTHREADS) +#if defined (ACE_HAS_SETKIND_NP) + if (::pthread_attr_setsched (&attr, spolicy) != 0) +#else /* ACE_HAS_SETKIND_NP */ + if (::pthread_attr_setschedpolicy (&attr, spolicy) != 0) +#endif /* ACE_HAS_SETKIND_NP */ + { +#if defined (ACE_HAS_SETKIND_NP) + ::pthread_attr_delete (&attr); +#else /* ACE_HAS_SETKIND_NP */ + ::pthread_attr_destroy (&attr); +#endif /* ACE_HAS_SETKIND_NP */ + return -1; + } +#else + int ret; + switch (spolicy) + { + case SCHED_FIFO: + case SCHED_RR: + ret = 0; + break; + default: + ret = 22; + break; + } + if (ret != 0) + { +#if defined (ACE_HAS_SETKIND_NP) + ::pthread_attr_delete (&attr); +#else /* ACE_HAS_SETKIND_NP */ + ::pthread_attr_destroy (&attr); +#endif /* ACE_HAS_SETKIND_NP */ + return -1; + } +#endif // ACE_HAS_FSU_PTHREADS + } + + if (ACE_BIT_ENABLED (flags, THR_INHERIT_SCHED) + || ACE_BIT_ENABLED (flags, THR_EXPLICIT_SCHED)) + { +#if defined (ACE_HAS_SETKIND_NP) + int sched = PTHREAD_DEFAULT_SCHED; +#else /* ACE_HAS_SETKIND_NP */ + int sched = PTHREAD_EXPLICIT_SCHED; +#endif /* ACE_HAS_SETKIND_NP */ + if (ACE_BIT_ENABLED (flags, THR_INHERIT_SCHED)) + sched = PTHREAD_INHERIT_SCHED; + if (::pthread_attr_setinheritsched (&attr, sched) != 0) + { +#if defined (ACE_HAS_SETKIND_NP) + ::pthread_attr_delete (&attr); +#else /* ACE_HAS_SETKIND_NP */ + ::pthread_attr_destroy (&attr); +#endif /* ACE_HAS_SETKIND_NP */ + return -1; + } + } +#if !defined (ACE_LACKS_THREAD_PROCESS_SCOPING) + if (ACE_BIT_ENABLED (flags, THR_SCOPE_SYSTEM) + || ACE_BIT_ENABLED (flags, THR_SCOPE_PROCESS)) + { + int scope = PTHREAD_SCOPE_PROCESS; + if (ACE_BIT_ENABLED (flags, THR_SCOPE_SYSTEM)) + scope = PTHREAD_SCOPE_SYSTEM; + + if (::pthread_attr_setscope (&attr, scope) != 0) + { +#if defined (ACE_HAS_SETKIND_NP) + ::pthread_attr_delete (&attr); +#else /* ACE_HAS_SETKIND_NP */ + ::pthread_attr_destroy (&attr); +#endif /* ACE_HAS_SETKIND_NP */ + return -1; + } + } +#endif /* !ACE_LACKS_THREAD_PROCESS_SCOPING */ + + if (ACE_BIT_ENABLED (flags, THR_NEW_LWP)) + { + // Increment the number of LWPs by one to emulate the + // Solaris semantics. + int lwps = ACE_OS::thr_getconcurrency (); + ACE_OS::thr_setconcurrency (lwps + 1); + } + } + + p_thr = (thr_id == 0 ? &tmp_thr : thr_id); + +#if defined (ACE_HAS_SETKIND_NP) + ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_create (p_thr, attr, func, args), + result), + int, -1, result); + ::pthread_attr_delete (&attr); + if (thr_handle != 0) + thr_handle = (ACE_hthread_t *) 0; +#else /* ACE_HAS_SETKIND_NP */ + ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_create (p_thr, &attr, func, args), + result), + int, -1, result); + ::pthread_attr_destroy (&attr); + if (thr_handle != 0) + *thr_handle = (ACE_hthread_t) 0; +#endif /* ACE_HAS_SETKIND_NP */ + + return result; +#elif defined (ACE_HAS_STHREADS) + int result; + ACE_OSCALL (ACE_ADAPT_RETVAL (::thr_create (stack, stacksize, func, args, + flags, thr_id), result), + int, -1, result); + if (result == 0 && thr_handle != 0) + *thr_handle = *thr_id; + return result; +#elif defined (ACE_HAS_WTHREADS) + ACE_thread_t t; + ACE_hthread_t handle; + + if (thr_id == 0) + thr_id = &t; + if (thr_handle == 0) + thr_handle = &handle; + + ACE_Win32_Thread_Adapter *thread_args; + + ACE_NEW_RETURN (thread_args, ACE_Win32_Thread_Adapter (func, args), -1); + + typedef unsigned (__stdcall *ThreadFunc) (void*); + +#if defined (ACE_HAS_MFC) + if (ACE_BIT_ENABLED (flags, THR_USE_AFX)) + { + CWinThread *cwin_thread = + // These aren't the right arguments (yet). + ::AfxBeginThread ((ThreadFunc) (ACE_Win32_Thread_Adapter::svc_run), + thread_args, 0, 0, flags); + *thr_handle = cwin_thread->m_hThread; + *thr_id = cwin_thread->m_nThreadID; + // Can we delete the memory of cwin_thread here? + } + else +#endif /* ACE_HAS_MFC */ + *thr_handle = (void *) ::_beginthreadex + (NULL, + stacksize, + (ThreadFunc) (ACE_Win32_Thread_Adapter::svc_run), + thread_args, + flags, + (unsigned int *) thr_id); + +#if 0 + *thr_handle = ::CreateThread + (NULL, stacksize, + LPTHREAD_START_ROUTINE (ACE_Win32_Thread_Adapter::svc_run), + thread_args, flags, thr_id); +#endif /* 0 */ + + // Close down the handle if no one wants to use it. + if (thr_handle == &handle) + ::CloseHandle (thr_handle); + + if (*thr_handle != 0) + return 0; + else + ACE_FAIL_RETURN (-1); + /* NOTREACHED */ +#elif defined (VXWORKS) + // If thr_id points to NULL (or is 0), the call below causes VxWorks + // to assign a unique task name of the form: "t" + an integer. + + // args must be an array of _exactly_ 10 ints. + + // stack arg is ignored: if there's a need for it, we'd have to use + // taskInit ()/taskActivate () instead of taskSpawn () + + // The hard-coded arguments are what ::sp() would use. ::taskInit() + // is used instead of ::sp() so that we can set the priority, flags, + // and stacksize. (::sp() also hardcodes priority to 100, flags + // to VX_FP_TASK, and stacksize to 20,000.) stacksize should be + // an even integer. + + // if called with thr_create() defaults, use same default values as ::sp() + if ( stacksize == 0 ) stacksize = 20000; + if ( priority == 0 ) priority = 100; + + ACE_hthread_t tid = ::taskSpawn (thr_id == 0 ? NULL : *thr_id, priority, + (int) flags, (int) stacksize, func, + ((int *) args)[0], ((int *) args)[1], + ((int *) args)[2], ((int *) args)[3], + ((int *) args)[4], ((int *) args)[5], + ((int *) args)[6], ((int *) args)[7], + ((int *) args)[8], ((int *) args)[9]); + + if ( tid == ERROR ) + return -1; + else + { + // return the thr_id and thr_handle, if addresses were provided for them + if ( thr_id != 0 ) + // taskTcb (int tid) returns the address of the WIND_TCB + // (task control block). According to the taskSpawn() + // documentation, the name of the new task is stored at + // pStackBase, but is that of the current task? If so, it + // would be a bit quicker than this extraction of the tcb . . . + *thr_id = taskTcb (tid)->name; + if ( thr_handle != 0 ) + *thr_handle = tid; + return 0; + } + +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +void +ACE_OS::thr_exit (void *status) +{ +// ACE_TRACE ("ACE_OS::thr_exit"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + ::pthread_exit (status); +#elif defined (ACE_HAS_STHREADS) + ::thr_exit (status); +#elif defined (ACE_HAS_WTHREADS) + // Cleanup the thread-specific resources and exit. + ACE_TSS_Cleanup::instance ()->exit (status); +#elif defined (VXWORKS) + *((int *) status) = ::taskDelete (ACE_OS::thr_self ()); +#endif /* ACE_HAS_STHREADS */ +#else + ; +#endif /* ACE_HAS_THREADS */ +} + +int +ACE_OS::thr_setspecific (ACE_thread_key_t key, void *data) +{ +// ACE_TRACE ("ACE_OS::thr_setspecific"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) +#if defined (ACE_HAS_FSU_PTHREADS) +// Call pthread_init() here to initialize threads package. FSU +// threads need an initialization before the first thread constructor. +// This seems to be the one; however, a segmentation fault may +// indicate that another pthread_init() is necessary, perhaps in +// Synch.cpp or Synch_T.cpp. FSU threads will not reinit if called +// more than once, so another call to pthread_init will not adversely +// affect existing threads. + pthread_init (); +#endif // ACE_HAS_FSU_PTHREADS + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setspecific (key, data), _result), + int, -1); +#elif defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_setspecific (key, data), _result), int, -1); +#elif defined (ACE_HAS_WTHREADS) + ::TlsSetValue (key, data); + ACE_TSS_Cleanup::instance ()->key_used (key); + return 0; +#elif defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +int +ACE_OS::thr_keyfree (ACE_thread_key_t key) +{ +// ACE_TRACE ("ACE_OS::thr_keyfree"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_LACKS_KEYDELETE) + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_HAS_PTHREADS) && !defined (ACE_HAS_FSU_PTHREADS) + return ::pthread_key_delete (key); +#elif defined (ACE_HAS_DCETHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_HAS_STHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_HAS_WTHREADS) + // Extract out the thread-specific table instance and and free up + // the key and destructor. + ACE_TSS_Cleanup::instance ()->remove (key); + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::TlsFree (key), _result), int, -1); +#elif defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +int +ACE_OS::thr_keycreate (ACE_thread_key_t *key, + void (*dest) (void *), + void *inst) +{ +// ACE_TRACE ("ACE_OS::thr_keycreate"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) +#if defined (ACE_HAS_SETKIND_NP) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_keycreate (key, dest), + _result), + int, -1); +#else /* ACE_HAS_SETKIND_NP */ + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_key_create (key, dest), + _result), + int, -1); +#endif /* ACE_HAS_SETKIND_NP */ +#elif defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_keycreate (key, dest), + _result), + int, -1); +#elif defined (ACE_HAS_WTHREADS) + *key = ::TlsAlloc (); + + if (*key != ACE_SYSCALL_FAILED) + // Extract out the thread-specific table instance and stash away + // the key and destructor so that we can free it up later on... + return ACE_TSS_Cleanup::instance ()->insert (*key, dest, inst); + else + ACE_FAIL_RETURN (-1); + /* NOTREACHED */ + +#elif defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +int +ACE_OS::thr_key_used (ACE_thread_key_t key) +{ +#if defined (ACE_WIN32) + return ACE_TSS_Cleanup::instance ()->key_used (key); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_WIN32 */ +} + +int +ACE_OS::thr_key_detach (void *inst) +{ +#if defined (ACE_WIN32) + return ACE_TSS_Cleanup::instance()->detach (inst); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_WIN32 */ +} + +// Create a contiguous command-line argument buffer with each arg +// separated by spaces. + +pid_t +ACE_OS::fork_exec (char *argv[]) +{ +#if defined (ACE_WIN32) + ACE_ARGV argv_buf (argv); + + char *buf = argv_buf.buf (); + + if (buf != 0) + { + PROCESS_INFORMATION process_info; + STARTUPINFO startup_info; + ACE_OS::memset ((void *) &startup_info, 0, sizeof startup_info); + startup_info.cb = sizeof startup_info; + + if (::CreateProcess (NULL, + buf, + NULL, // No process attributes. + NULL, // No thread attributes. + TRUE, // Allow handle inheritance. + CREATE_NEW_CONSOLE, // Create a new console window. + NULL, // No environment. + NULL, // No current directory. + &startup_info, + &process_info)) + { + // Free resources allocated in kernel. + ACE_OS::close (process_info.hThread); + ACE_OS::close (process_info.hProcess); + // Return new process id. + return process_info.dwProcessId; + } + } + + // CreateProcess failed. + return -1; +#else + pid_t result = ACE_OS::fork (); + + switch (result) + { + case -1: + // Error. + return -1; + case 0: + // Child process. + if (ACE_OS::execv (argv[0], argv) == -1) + { + ACE_ERROR ((LM_ERROR, "%p Exec failed\n")); + + // If the execv fails, this child needs to exit. + ACE_OS::exit (errno); + } + default: + // Server process. The fork succeeded. + return result; + } +#endif /* ACE_WIN32 */ + } + +#if defined (ACE_NEEDS_WRITEV) + +// "Fake" writev for sites without it. Note that this is totally +// broken for multi-threaded applications since the calls are +// not atomic... + +extern "C" int +writev (ACE_HANDLE handle, ACE_WRITEV_TYPE *vp, int vpcount) +{ +// ACE_TRACE ("::writev"); + + int count; + + for (count = 0; --vpcount >= 0; count += vp->iov_len, vp++) + if (ACE::send_n (handle, vp->iov_base, vp->iov_len) < 0) + return -1; + + return count; +} +#endif /* ACE_NEEDS_WRITEV */ + +#if defined (ACE_NEEDS_READV) + +// "Fake" readv for sites without it. Note that this is totally +// broken for multi-threaded applications since the calls are +// not atomic... + +extern "C" int +readv (ACE_HANDLE handle, struct iovec *vp, int vpcount) +{ +// ACE_TRACE ("::readv"); + + int count; + + for (count = 0; --vpcount >= 0; count += vp->iov_len, vp++) + if (ACE::recv_n (handle, vp->iov_base, vp->iov_len) < 0) + return -1; + + return count; +} +#endif /* ACE_NEEDS_READV */ + +#if defined (ACE_NEEDS_FTRUNCATE) +extern "C" int +ftruncate (ACE_HANDLE handle, long len) +{ + struct flock fl; + fl.l_whence = 0; + fl.l_len = 0; + fl.l_start = len; + fl.l_type = F_WRLCK; + + return ::fcntl (handle, F_FREESP, &fl); +} +#endif /* ACE_NEEDS_FTRUNCATE */ + +char * +ACE_OS::mktemp (char *s) +{ + // ACE_TRACE ("ACE_OS::mktemp"); +#if defined (ACE_LACKS_MKTEMP) + if (s == 0) + // check for null template string failed! + return 0; + else + { + char *xxxxxx = ACE_OS::strstr (s, "XXXXXX"); + + if (xxxxxx == 0) + // the template string doesn't contain "XXXXXX"! + return s; + else + { + char unique_letter = 'a'; + struct stat sb; + + // Find an unused filename for this process. It is assumed + // that the user will open the file immediately after + // getting this filename back (so, yes, there is a race + // condition if multiple threads in a process use the same + // template). This appears to match the behavior of the + // Solaris 2.5 mktemp(). + ::sprintf (xxxxxx, "%05d%c", getpid (), unique_letter); + while (::stat (s, &sb) >= 0) + { + if (++unique_letter <= 'z') + ::sprintf (xxxxxx, "%05d%c", getpid (), unique_letter); + else + { + // maximum of 26 unique files per template, per process + ::sprintf (xxxxxx, "%s", ""); + return s; + } + } + } + return s; + } + +#else + return ::mktemp (s); +#endif /* ACE_LACKS_MKTEMP */ +} + +int +ACE_OS::socket_init (int version_high, int version_low) +{ +#if defined (ACE_WIN32) + if (ACE_OS::socket_initialized_ == 0) + { + WORD version_requested = MAKEWORD (version_high, version_low); + WSADATA wsa_data; + int error = ::WSAStartup (version_requested, &wsa_data); + + if (error != 0) + ACE_ERROR_RETURN ((LM_ERROR, + "WSAStartup failed, WSAGetLastError returned %u.\n", + error), -1); + + ACE_OS::socket_initialized_ = 1; + } +#endif /* ACE_WIN32 */ + return 0; +} + +int +ACE_OS::socket_fini (void) +{ +#if defined (ACE_WIN32) + if (ACE_OS::socket_initialized_ != 0) + { + if (::WSACleanup () != 0) + { + int error = ::WSAGetLastError (); + ACE_ERROR_RETURN ((LM_ERROR, + "WSACleanup failed, WSAGetLastError returned %u.\n", + error), -1); + } + ACE_OS::socket_initialized_ = 0; + } +#endif /* ACE_WIN32 */ + return 0; +} + +#if defined (VXWORKS) +int sys_nerr = ERRMAX + 1; +#endif /* VXWORKS */ diff --git a/ace/OS.h b/ace/OS.h new file mode 100644 index 00000000000..f573e507310 --- /dev/null +++ b/ace/OS.h @@ -0,0 +1,2174 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// OS.h +// +// = AUTHOR +// Doug Schmidt , Jesper S. M|ller +// , and a cast of thousands... +// +// ============================================================================ + +#if !defined (ACE_OS_H) +#define ACE_OS_H + +// Define the default constants for ACE. Many of these are used for +// the ACE tests and applications. You may want to change some of +// these to correspond to your environment. + +#define ACE_DEFAULT_TIMEOUT 5 +#define ACE_DEFAULT_THREADS 1 + +// The following 3 defines are used in the IP multicast and broadcast tests. +#define ACE_DEFAULT_BROADCAST_PORT 10000 +#define ACE_DEFAULT_MULTICAST_PORT 10001 +#define ACE_DEFAULT_MULTICAST_ADDR "224.9.9.2" + +// Used in many IPC_SAP tests +#define ACE_DEFAULT_SERVER_PORT 10002 + +// Used in Acceptor tests +#define ACE_DEFAULT_SERVER_PORT_STR "10002" + +// Used for the Service_Directory test +#define ACE_DEFAULT_SERVICE_PORT 10003 + +// Used for the ACE_Thread_Spawn test +#define ACE_DEFAULT_THR_PORT 10004 + +// Used for SOCK_Connect::connect() tests +#define ACE_DEFAULT_LOCAL_PORT 10005 + +// Used for Connector tests +#define ACE_DEFAULT_LOCAL_PORT_STR "10005" + +// Used for the name server. +#define ACE_DEFAULT_NAME_SERVER_PORT 10006 +#define ACE_DEFAULT_NAME_SERVER_PORT_STR "10006" + +// Used for the token server. +#define ACE_DEFAULT_TOKEN_SERVER_PORT 10007 +#define ACE_DEFAULT_TOKEN_SERVER_PORT_STR "10007" + +// Used for the logging server. +#define ACE_DEFAULT_LOGGING_SERVER_PORT 10008 +#define ACE_DEFAULT_LOGGING_SERVER_PORT_STR "10008" + +// Used for the logging server. +#define ACE_DEFAULT_THR_LOGGING_SERVER_PORT 10008 +#define ACE_DEFAULT_THR_LOGGING_SERVER_PORT_STR "10008" + +// Used for the time server. +#define ACE_DEFAULT_TIME_SERVER_PORT 10010 +#define ACE_DEFAULT_TIME_SERVER_PORT_STR "10010" +#define ACE_DEFAULT_TIME_SERVER_STR "ACE_TS_TIME" + +#define ACE_DEFAULT_SERVER_HOST "localhost" + +// Default shared memory key +#define ACE_DEFAULT_SHM_KEY 1234 + +// Default address for shared memory mapped files and SYSV shared memory +// (defaults to 64 M). +#define ACE_DEFAULT_BASE_ADDR ((char *) (64 * 1024 * 1024)) + +// Default segment size used by SYSV shared memory (128 K) +#define ACE_DEFAULT_SEGMENT_SIZE 1024 * 128 + +// Maximum number of SYSV shared memory segments +// (does anyone know how to figure out the right values?!) +#define ACE_DEFAULT_MAX_SEGMENTS 6 + +// Used by the FIFO tests. +#define ACE_DEFAULT_RENDEZVOUS "/tmp/fifo.ace" + +// Name of the map that's stored in shared memory. +#define ACE_NAME_SERVER_MAP "Name Server Map" + +// Default file permissions. +#define ACE_DEFAULT_PERMS 0666 + +// Default size of the ACE Reactor. +#define ACE_DEFAULT_REACTOR_SIZE FD_SETSIZE + +// Default size of the ACE Map_Manager. +#define ACE_DEFAULT_MAP_SIZE 1024 + +// Here are all ACE-specific global declarations needed throughout +// ACE. + +// Helpful dump macros. +#define ACE_BEGIN_DUMP "\n====\n(%P|%t|%x)" +#define ACE_END_DUMP "====\n" + +// This is used to indicate that a platform doesn't support a +// particular feature. +#define ACE_NOTSUP_RETURN(FAILVALUE) do { errno = ENOTSUP ; return FAILVALUE; } while (0) + +#if defined (ACE_NDEBUG) +#define ACE_DB(X) +#else +#define ACE_DB(X) X +#endif /* ACE_NDEBUG */ + +// 10 millisecond fudge factor to account for Solaris timers... +#define ACE_TIMER_SKEW 1000 * 10 + +// The following is necessary since many C++ compilers don't support +// typedef'd types inside of classes used as formal template +// arguments... ;-(. Luckily, using the C++ preprocessor I can hide +// most of this nastiness! + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) +#define ACE_SYNCH_1 class ACE_SYNCH +#define ACE_SYNCH_2 ACE_SYNCH +#define ACE_SYNCH_MUTEX ACE_SYNCH::ACE_MUTEX +#define ACE_SYNCH_CONDITION ACE_SYNCH::ACE_CONDITION +#else /* TEMPLATES are broken (must be a cfront-based compiler...) */ +#define ACE_SYNCH_1 class ACE_SYNCH_MUTEX, class ACE_SYNCH_CONDITION +#define ACE_SYNCH_2 ACE_SYNCH_MUTEX, ACE_SYNCH_CONDITION +#define ACE_SYNCH_MUTEX ACE_SYNCH_MUTEX +#define ACE_SYNCH_CONDITION ACE_SYNCH_CONDITION +#endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ + +// Increase the range of "address families". +#define AF_SPIPE (AF_MAX + 1) +#define AF_FILE (AF_MAX + 2) +#define AF_DEV (AF_MAX + 3) +#define AF_UPIPE (AF_SPIPE) + +// Turn a number into a string. +#define ACE_ITOA(X) #X + +// Create a string of a server address with a "host:port" format. +#define ACE_SERVER_ADDRESS(H,P) H":"P + +// A couple useful inline functions for checking whether bits are +// enabled or disabled. + +// Efficiently returns the least power of two >= X... +#define ACE_POW(X) ((!X)?1:(X-=1,X|=X>>1,X|=X>>2,X|=X>>4,X|=X>>8,X|=X>>16,(++X))) +#define ACE_EVEN(NUM) (((NUM) & 1) == 0) +#define ACE_ODD(NUM) (((NUM) & 1) == 1) +#define ACE_BIT_ENABLED(WORD, BIT) (((WORD) & (BIT)) != 0) +#define ACE_BIT_DISABLED(WORD, BIT) (((WORD) & (BIT)) == 0) +#define ACE_SET_BITS(WORD, BITS) (WORD |= (BITS)) +#define ACE_CLR_BITS(WORD, BITS) (WORD &= ~(BITS)) + +// A useful abstraction for expressions involving operator new since +// we can change memory allocation error handling policies (e.g., +// depending on whether ANSI/ISO exception handling semantics are +// being used). + +#define ACE_NEW(POINTER,CONSTRUCTOR) \ + do { POINTER = new CONSTRUCTOR; \ + if (POINTER == 0) { errno = ENOMEM; return; }} while (0) +#define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \ + do { POINTER = new CONSTRUCTOR; \ + if (POINTER == 0) { errno = ENOMEM; return RET_VAL; }} while (0) + +// These hooks enable ACE to have all dynamic memory management +// automatically handled on a per-object basis. + +#if defined (ACE_HAS_ALLOC_HOOKS) +#define ACE_ALLOC_HOOK_DECLARE \ + void *operator new (size_t bytes); \ + void operator delete (void *ptr); + +// Note that these are just place holders for now. They'll +// be replaced by the ACE_Malloc stuff shortly... +#define ACE_ALLOC_HOOK_DEFINE(CLASS) \ + void *CLASS::operator new (size_t bytes) { return ::new char[bytes]; } \ + void CLASS::operator delete (void *ptr) { delete (ptr); } +#else +#define ACE_ALLOC_HOOK_DECLARE struct __Ace {} // Just need a dummy... +#define ACE_ALLOC_HOOK_DEFINE(CLASS) +#endif /* ACE_HAS_ALLOC_HOOKS */ + +#include "ace/Time_Value.h" + +// For Win32 compatibility... +#if !defined (ACE_WSOCK_VERSION) +#define ACE_WSOCK_VERSION 0, 0 +#endif /* ACE_WSOCK_VERSION */ + +#if defined (ACE_HAS_BROKEN_CTIME) +#undef ctime +#endif /* ACE_HAS_BROKEN_CTIME */ + +// Static service macros +#define ACE_STATIC_SVC_DECLARE(X) extern ACE_Static_Svc_Descriptor ace_svc_desc_##X ; +#define ACE_STATIC_SVC_DEFINE(X, NAME, TYPE, FN, FLAGS, ACTIVE) \ +ACE_Static_Svc_Descriptor ace_svc_desc_##X = { NAME, TYPE, FN, FLAGS, ACTIVE }; +#define ACE_STATIC_SVC_REQUIRE(X)\ +class ACE_Static_Svc_##X {\ +public:\ + ACE_Static_Svc_##X() { ACE_Service_Config::static_svcs ()->insert (&ace_svc_desc_##X); }\ +};\ +static ACE_Static_Svc_##X ace_static_svc_##X; + +// Dynamic/static service macros. +#define ACE_SVC_FACTORY_DECLARE(X) extern "C" ACE_Svc_Export ACE_Service_Object *_make_##X (void); +#define ACE_SVC_INVOKE(X) _make_##X () +#define ACE_SVC_NAME(X) _make_##X +#define ACE_SVC_FACTORY_DEFINE(X) ACE_Service_Object *_make_##X () { ACE_TRACE (#X); return new X; } + +#if !(defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)) +#define ACE_TSS_TYPE(T) T +#define ACE_TSS_GET(I, T) (I) +#else +#define ACE_TSS_TYPE(T) ACE_TSS< T > +#define ACE_TSS_GET(I, T) ((I)->operator T * ()) +#endif /* !(defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)) */ + +#if defined (ACE_LACKS_MODE_MASKS) +// MODE MASKS + +// the following macros are for POSIX conformance. + +#define S_IRWXU 00700 // read, write, execute: owner. +#define S_IRUSR 00400 // read permission: owner. +#define S_IWUSR 00200 // write permission: owner. +#define S_IXUSR 00100 // execute permission: owner. +#define S_IRWXG 00070 // read, write, execute: group. +#define S_IRGRP 00040 // read permission: group. +#define S_IWGRP 00020 // write permission: group. +#define S_IXGRP 00010 // execute permission: group. +#define S_IRWXO 00007 // read, write, execute: other. +#define S_IROTH 00004 // read permission: other. +#define S_IWOTH 00002 // write permission: other. +#define S_IXOTH 00001 // execute permission: other. + +#endif /* ACE_LACKS_MODE_MASKS */ + +#if defined (ACE_LACKS_SEMBUF_T) +struct sembuf +{ + u_short sem_num; // semaphore # + short sem_op; // semaphore operation + short sem_flg; // operation flags +}; +#endif /* ACE_LACKS_SEMBUF_T */ + +#if defined (ACE_LACKS_UTSNAME_T) +#define _SYS_NMLN 257 +struct utsname +{ + char sysname[_SYS_NMLN]; + char nodename[_SYS_NMLN]; + char release[_SYS_NMLN]; + char version[_SYS_NMLN]; + char machine[_SYS_NMLN]; +}; +#endif /* ACE_LACKS_UTSNAME_T */ + +#if defined (ACE_HAS_H_ERRNO) +void herror (const char *str); +#endif /* ACE_HAS_H_ERRNO */ + +#if defined (ACE_LACKS_MSGBUF_T) +struct msgbuf {}; +#endif /* ACE_LACKS_MSGBUF_T */ + +#if defined (ACE_LACKS_STRRECVFD) +struct strrecvfd {}; +#endif /* ACE_LACKS_STRRECVFD */ + +#if defined (ACE_HAS_PROC_FS) +#include +#endif /* ACE_HAS_PROC_FD */ + +#if defined (ACE_HAS_UNICODE) +#include +#endif /* ACE_HAS_UNICODE */ + +#if defined (ACE_HAS_BROKEN_WRITEV) +typedef struct iovec ACE_WRITEV_TYPE; +#else +typedef const struct iovec ACE_WRITEV_TYPE; +#endif /* ACE_HAS_BROKEN_WRITEV */ + +#if defined (ACE_HAS_BROKEN_SETRLIMIT) +typedef struct rlimit ACE_SETRLIMIT_TYPE; +#else +typedef const struct rlimit ACE_SETRLIMIT_TYPE; +#endif /* ACE_HAS_BROKEN_SETRLIMIT */ + +#if !defined (ACE_HAS_STRBUF_T) +struct strbuf +{ + int maxlen; // no. of bytes in buffer. + int len; // no. of bytes returned. + void *buf; // pointer to data. +}; +#endif /* ACE_HAS_STRBUF_T */ + +struct ACE_Export ACE_Str_Buf + // = TITLE + // Simple wrapper for STREAM pipes strbuf. +{ + int maxlen; + // Number of bytes in buffer. + + int len; + // Number of bytes returned. + + void *buf; + // Pointer to data. + + // = Initialization method + ACE_Str_Buf (void *b = 0, int l = 0, int max = 0); + // Constructor. +}; + +#if defined (ACE_MT_SAFE) +#define ACE_MT(X) X +#if !defined (_REENTRANT) +#define _REENTRANT +#endif /* _REENTRANT */ +#else +#define ACE_MT(X) +#endif /* ACE_MT_SAFE */ + +// These are the various states a thread managed by the +// can be in. +enum ACE_Thread_State +{ + ACE_THR_IDLE, + // Uninitialized. + + ACE_THR_SPAWNED, + // Created but not yet running. + + ACE_THR_RUNNING, + // Thread is active (naturally, we don't know if it's actually + // *running* because we aren't the scheduler...). + + ACE_THR_SUSPENDED, + // Thread is suspended. + + ACE_THR_CANCELLED, + // Thread has been cancelled (which is an indiction that it needs to + // terminate...). + + ACE_THR_TERMINATED + // Thread has shutdown, but the slot in the thread manager hasn't + // been reclaimed yet. +}; + +// Convenient macro for testing for deadlock, as well as for detecting +// when mutexes fail. +#define ACE_GUARD_RETURN(MUTEX,OBJ,LOCK,RETURN) \ + ACE_Guard OBJ (LOCK); \ + if (OBJ.locked () == 0) return RETURN; +#define ACE_WRITE_GUARD_RETURN(MUTEX,OBJ,LOCK,RETURN) \ + ACE_Write_Guard OBJ (LOCK); \ + if (OBJ.locked () == 0) return RETURN; +#define ACE_READ_GUARD_RETURN(MUTEX,OBJ,LOCK,RETURN) \ + ACE_Read_Guard OBJ (LOCK); \ + if (OBJ.locked () == 0) return RETURN; +#define ACE_GUARD(MUTEX,OBJ,LOCK) \ + ACE_Guard OBJ (LOCK); \ + if (OBJ.locked () == 0) return; + +#if defined (ACE_HAS_POSIX_SEM) +#include +typedef struct +{ + sem_t *sema_; + // Pointer to semaphore handle. This is allocated by ACE if we are + // working with an unnamed POSIX semaphore or by the OS if we are + // working with a named POSIX semaphore. + + char *name_; + // Name of the semaphore (if this is non-NULL then this is a named + // POSIX semaphore, else its an unnamed POSIX semaphore). +} ACE_sema_t; +#endif /* ACE_HAS_POSIX_SEM */ + +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) +#include +#include +#endif /* ACE_HAS_STHREADS */ + +struct cancel_state +{ + int cancelstate; + // e.g., PTHREAD_CANCEL_ENABLE, PTHREAD_CANCEL_DISABLE, + // PTHREAD_CANCELED. + + int canceltype; + // e.g., PTHREAD_CANCEL_DEFERRED and PTHREAD_CANCEL_ASYNCHRONOUS. +}; + +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) +// Definitions for mapping POSIX pthreads onto Solaris threads. + +#if defined (ACE_HAS_FSU_PTHREADS) +#define PTHREAD_DETACHED 0x1 +#define PTHREAD_SCOPE_SYSTEM 0x2 +#define PTHREAD_INHERIT_SCHED 0x4 +#define PTHREAD_NOFLOAT 0x8 +#define PTHREAD_CREATE_UNDETACHED 0 +#define PTHREAD_CREATE_DETACHED PTHREAD_DETACHED +#define PTHREAD_CREATE_JOINABLE 0 +#define PTHREAD_SCOPE_PROCESS 0 +#define PTHREAD_EXPLICIT_SCHED 0 +#define PTHREAD_MIN_PRIORITY 0 +#define PTHREAD_MAX_PRIORITY 126 +#endif // ACE_HAS_FSU_PTHREADS + +#if defined (ACE_HAS_SETKIND_NP) +#define PRIORITY_MAX PTHREAD_MAX_PRIORITY +#endif /* ACE_HAS_SETKIND_NP */ + +#if !defined (ACE_HAS_TID_T) +typedef pthread_t tid_t; +#endif /* ACE_HAS_TID_T */ + +// Typedefs to help compatibility with Windows NT and Pthreads. +#if defined (ACE_HAS_PTHREAD_T) +typedef pthread_t ACE_hthread_t; +#else /* ACE_HAS_PTHREAD_T */ +typedef tid_t ACE_hthread_t; +#endif /* ACE_HAS_PTHREAD_T */ + +// Make it easier to write portable thread code. +typedef pthread_t ACE_thread_t; +typedef pthread_key_t ACE_thread_key_t; +typedef pthread_mutex_t ACE_mutex_t; +typedef pthread_cond_t ACE_cond_t; +typedef pthread_mutex_t ACE_thread_mutex_t; + +#if (!defined (timespec) && !defined (m88k)) +#define timestruc_t struct timespec +#endif /* timespec */ + +#if !defined (PTHREAD_CANCEL_DISABLE) +#define PTHREAD_CANCEL_DISABLE 0 +#endif /* PTHREAD_CANCEL_DISABLE */ + +#if !defined (PTHREAD_CANCEL_ENABLE) +#define PTHREAD_CANCEL_ENABLE 0 +#endif /* PTHREAD_CANCEL_ENABLE */ + +#if !defined (PTHREAD_CANCEL_DEFERRED) +#define PTHREAD_CANCEL_DEFERRED 0 +#endif /* PTHREAD_CANCEL_DEFERRED */ + +#if !defined (PTHREAD_CANCEL_ASYNCHRONOUS) +#define PTHREAD_CANCEL_ASYNCHRONOUS 0 +#endif /* PTHREAD_CANCEL_ASYNCHRONOUS */ + +#define THR_CANCEL_DISABLE PTHREAD_CANCEL_DISABLE +#define THR_CANCEL_ENABLE PTHREAD_CANCEL_ENABLE +#define THR_CANCEL_DEFERRED PTHREAD_CANCEL_DEFERRED +#define THR_CANCEL_ASYNCHRONOUS PTHREAD_CANCEL_ASYNCHRONOUS + +#if !defined (PTHREAD_CREATE_JOINABLE) +#if defined (PTHREAD_CREATE_UNDETACHED) +#define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED +#else +#define PTHREAD_CREATE_JOINABLE 0 +#endif /* PTHREAD_CREATE_UNDETACHED */ +#endif /* PTHREAD_CREATE_JOINABLE */ + +#if !defined (PTHREAD_PROCESS_PRIVATE) +#if defined (PTHREAD_MUTEXTYPE_FAST) +#define PTHREAD_PROCESS_PRIVATE PTHREAD_MUTEXTYPE_FAST +#else +#define PTHREAD_PROCESS_PRIVATE 0 +#endif /* PTHREAD_MUTEXTYPE_FAST */ +#endif /* PTHREAD_PROCESS_PRIVATE */ + +#if !defined (PTHREAD_PROCESS_SHARED) +#if defined (PTHREAD_MUTEXTYPE_FAST) +#define PTHREAD_PROCESS_SHARED PTHREAD_MUTEXTYPE_FAST +#else +#define PTHREAD_PROCESS_SHARED 0 +#endif /* PTHREAD_MUTEXTYPE_FAST */ +#endif /* PTHREAD_PROCESS_SHARED */ + +#if defined (ACE_HAS_DCETHREADS) +#if defined (PTHREAD_PROCESS_PRIVATE) +#define USYNC_THREAD PTHREAD_PROCESS_PRIVATE +#else +#define USYNC_THREAD MUTEX_NONRECURSIVE_NP +#endif /* PTHREAD_PROCESS_PRIVATE */ + +#if defined (PTHREAD_PROCESS_SHARED) +#define USYNC_PROCESS PTHREAD_PROCESS_SHARED +#else +#define USYNC_PROCESS MUTEX_NONRECURSIVE_NP +#endif /* PTHREAD_PROCESS_SHARED */ +#elif !defined (ACE_HAS_STHREADS) +#define USYNC_THREAD PTHREAD_PROCESS_PRIVATE +#define USYNC_PROCESS PTHREAD_PROCESS_SHARED +#endif /* ACE_HAS_DCETHREADS */ + +#define THR_BOUND 0x00000001 +#define THR_NEW_LWP 0x00000002 +#define THR_DETACHED 0x00000040 +#define THR_SUSPENDED 0x00000080 +#define THR_DAEMON 0x00000100 +#define THR_JOINABLE 0x00010000 +#define THR_SCHED_FIFO 0x00020000 +#define THR_SCHED_RR 0x00040000 +#define THR_SCHED_DEFAULT 0x00080000 +#if defined (ACE_HAS_IRIX62_THREADS) +#define THR_SCOPE_SYSTEM 0x00100000 +#else +#define THR_SCOPE_SYSTEM THR_BOUND +#endif /* ACE_HAS_IRIX62_THREADS */ +#define THR_SCOPE_PROCESS 0x00200000 +#define THR_INHERIT_SCHED 0x00400000 +#define THR_EXPLICIT_SCHED 0x00800000 +#define THR_USE_AFX 0x01000000 + +#if !defined (ACE_HAS_STHREADS) +#if !defined (ACE_HAS_POSIX_SEM) +// This is used to implement semaphores for POSIX pthreads, but +// without POSIX semaphores. It is different than the POSIX sem_t. +struct ACE_sema_t +{ + ACE_mutex_t lock_; + ACE_cond_t count_nonzero_; + u_long count_; +}; +#endif /* !ACE_HAS_POSIX_SEM */ + +// This is used to implement readers/writer locks for POSIX pthreads. +struct ACE_rwlock_t +{ + ACE_mutex_t lock_; + // Serialize access to internal state. + + ACE_cond_t waiting_readers_; + // Reader threads waiting to acquire the lock. + + int num_waiting_readers_; + // Number of waiting readers. + + ACE_cond_t waiting_writers_; + // Writer threads waiting to acquire the lock. + + int num_waiting_writers_; + // Number of waiting writers. + + int ref_count_; + // Value is -1 if writer has the lock, else this keeps track of the + // number of readers holding the lock. +}; +#else +// If we are on Solaris we can just reuse the existing implementations +// of these synchronization types. +typedef rwlock_t ACE_rwlock_t; +#if !defined (ACE_HAS_POSIX_SEM) +typedef sema_t ACE_sema_t; +#endif /* !ACE_HAS_POSIX_SEM */ +#endif /* !ACE_HAS_STHREADS */ +#elif defined (ACE_HAS_STHREADS) +// Typedefs to help compatibility with Windows NT and Pthreads. +typedef thread_t ACE_thread_t; +typedef thread_key_t ACE_thread_key_t; +typedef mutex_t ACE_mutex_t; +typedef rwlock_t ACE_rwlock_t; +#if !defined (ACE_HAS_POSIX_SEM) +typedef sema_t ACE_sema_t; +#endif /* !ACE_HAS_POSIX_SEM */ +typedef cond_t ACE_cond_t; +typedef ACE_thread_t ACE_hthread_t; +typedef ACE_mutex_t ACE_thread_mutex_t; + +#define THR_CANCEL_DISABLE 0 +#define THR_CANCEL_ENABLE 0 +#define THR_CANCEL_DEFERRED 0 +#define THR_CANCEL_ASYNCHRONOUS 0 +#elif defined(VXWORKS) + +#include // for mutex implementation using mutual-exclusion + // semaphores (which can be taken recursively) +#include + +// task options: the other options are either obsolete, internal, or for +// Fortran or Ada support +#define VX_UNBREAKABLE 0x0002 /* breakpoints ignored */ +#define VX_FP_TASK 0x0008 /* floating point coprocessor */ +#define VX_PRIVATE_ENV 0x0080 /* private environment support */ +#define VX_NO_STACK_FILL 0x0100 /* do not stack fill for checkstack () */ + +#define THR_CANCEL_DISABLE 0 +#define THR_CANCEL_ENABLE 0 +#define THR_CANCEL_DEFERRED 0 +#define THR_CANCEL_ASYNCHRONOUS 0 +#define THR_BOUND 0 +#define THR_NEW_LWP 0 +#define THR_DETACHED 0 +#define THR_SUSPENDED 0 +#define THR_DAEMON 0 +#define THR_JOINABLE 0 +#define THR_SCHED_FIFO 0 +#define THR_SCHED_RR 0 +#define THR_SCHED_DEFAULT 0 +#define USYNC_THREAD 0 +#define USYNC_PROCESS 1 // it's all global on VxWorks (without MMU + // option) + +typedef SEM_ID ACE_mutex_t; +// implement ACE_thread_mutex_t with ACE_mutex_t sinces there's just one process . . . +typedef ACE_mutex_t ACE_thread_mutex_t; +#if !defined (ACE_HAS_POSIX_SEM) +// although ACE_HAS_POSIX_SEM is assumed for VxWorks +typedef semaphore * ACE_sema_t; +#endif /* !ACE_HAS_POSIX_SEM */ +typedef char * ACE_thread_t; +typedef int ACE_hthread_t; +typedef int ACE_thread_key_t; + +struct ACE_cond_t + // = TITLE + // This structure is used to implement condition variables on VxWorks + // + // = DESCRIPTION + // At the current time, this stuff only works for threads + // within the same process, which there's only one of on VxWorks. +{ + long waiters_; + // Number of waiting threads. + + ACE_sema_t sema_; + // Queue up threads waiting for the condition to become signaled. +}; + +struct ACE_rwlock_t + // = TITLE + // This is used to implement readers/writer locks on VxWorks + // + // = DESCRIPTION + // At the current time, this stuff only works for threads + // within the same process, which there's only one of on VxWorks. +{ + ACE_mutex_t lock_; + // Serialize access to internal state. + + ACE_cond_t waiting_readers_; + // Reader threads waiting to acquire the lock. + + int num_waiting_readers_; + // Number of waiting readers. + + ACE_cond_t waiting_writers_; + // Writer threads waiting to acquire the lock. + + int num_waiting_writers_; + // Number of waiting writers. + + int ref_count_; + // Value is -1 if writer has the lock, else this keeps track of the + // number of readers holding the lock. +}; + +#endif /* ACE_HAS_DCETHREADS || ACE_HAS_PTHREADS */ +#else /* !ACE_HAS_THREADS, i.e., the OS/platform doesn't support threading. */ +// Give these things some reasonable value... +#define THR_CANCEL_DISABLE 0 +#define THR_CANCEL_ENABLE 0 +#define THR_CANCEL_DEFERRED 0 +#define THR_CANCEL_ASYNCHRONOUS 0 +#define THR_DETACHED 0 // ?? ignore in most places +#define THR_BOUND 0 // ?? ignore in most places +#define THR_NEW_LWP 0 // ?? ignore in most places +#define THR_SUSPENDED 0 // ?? ignore in most places +#define USYNC_THREAD 0 +#define USYNC_PROCESS 0 +// These are dummies needed for class OS.h +typedef int ACE_cond_t; +typedef int ACE_mutex_t; +typedef int ACE_thread_mutex_t; +#if !defined (ACE_HAS_POSIX_SEM) +typedef int ACE_sema_t; +#endif /* !ACE_HAS_POSIX_SEM */ +typedef int ACE_rwlock_t; +typedef int ACE_thread_t; +typedef int ACE_hthread_t; +typedef int ACE_thread_key_t; +#endif /* ACE_HAS_THREADS */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// This must come after signal.h is #included. +#if defined (SCO) +#define SIGIO SIGPOLL +#undef sigemptyset +#undef sigfillset +#undef sigaddset +#undef sigdelset +#undef sigismember +#endif /* SCO */ + +#if defined (ACE_HAS_BROKEN_SENDMSG) +typedef struct msghdr ACE_SENDMSG_TYPE; +#else +typedef const struct msghdr ACE_SENDMSG_TYPE; +#endif /* ACE_HAS_BROKEN_SENDMSG */ + +#if defined (ACE_HAS_BROKEN_RANDR) +// The SunOS 5.x version of rand_r is inconsistent with the header files... +typedef unsigned int ACE_RANDR_TYPE; +extern "C" int rand_r (ACE_RANDR_TYPE seed); +#else +typedef unsigned int *ACE_RANDR_TYPE; +#endif /* ACE_HAS_BROKEN_RANDR */ + +#if !defined (ACE_HAS_RTLD_LAZY_V) +#define RTLD_LAZY 1 +#endif /* !ACE_HAS_RTLD_LAZY_V */ + +#if defined (ACE_HAS_UTIME) +#include +#endif /* ACE_HAS_UTIME */ + +#if !defined (ACE_HAS_MSG) && !defined (SCO) +struct msghdr {}; +#endif /* ACE_HAS_MSG */ + +#if !defined (ACE_HAS_HI_RES_TIMER) +typedef int hrtime_t; +#endif /* ACE_HAS_HI_RES_TIMER */ + +#if !defined (ACE_HAS_SIG_ATOMIC_T) +typedef int sig_atomic_t; +#endif /* !ACE_HAS_SIG_ATOMIC_T */ + +#if !defined (ACE_HAS_SSIZE_T) +typedef int ssize_t; +#endif /* ACE_HAS_SSIZE_T */ + +#if defined (ACE_HAS_OLD_MALLOC) +typedef char *ACE_MALLOC_T; +#else +typedef void *ACE_MALLOC_T; +#endif /* ACE_HAS_OLD_MALLOC */ + +#if defined (ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES) +// Prototypes for both signal() and struct sigaction are consistent.. +typedef void (*ACE_SignalHandler)(int); +typedef void (*ACE_SignalHandlerV)(int); +#elif defined (ACE_HAS_IRIX_53_SIGNALS) +typedef void (*ACE_SignalHandler)(...); +typedef void (*ACE_SignalHandlerV)(...); +#elif defined (ACE_HAS_SPARCWORKS_401_SIGNALS) +typedef void (*ACE_SignalHandler)(int, ...); +typedef void (*ACE_SignalHandlerV)(int,...); +#elif defined (ACE_HAS_SUNOS4_SIGNAL_T) +typedef void (*ACE_SignalHandler)(void); +typedef void (*ACE_SignalHandlerV)(void); +#elif defined (ACE_HAS_SVR4_SIGNAL_T) +// SVR4 Signals are inconsistent (e.g., see struct sigaction).. +typedef void (*ACE_SignalHandler)(int); +#if !defined (m88k) // with SVR4_SIGNAL_T +typedef void (*ACE_SignalHandlerV)(void); +#else +typedef void (*ACE_SignalHandlerV)(int); +#endif // m88k // with SVR4_SIGNAL_T +#elif defined (ACE_WIN32) +typedef void (__cdecl *ACE_SignalHandler)(int); +typedef void (__cdecl *ACE_SignalHandlerV)(int); +#elif defined (ACE_HAS_UNIXWARE_SVR4_SIGNAL_T) +typedef void (*ACE_SignalHandler)(int); +typedef void (*ACE_SignalHandlerV)(...); +#else /* This is necessary for some older broken version of cfront */ +#define ACE_SignalHandler SIG_PF +typedef void (*ACE_SignalHandlerV)(...); +#endif /* ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES */ + +#if defined (ACE_WIN32) +// Turn off warnings for /W4 +// To resume any of these warning: #pragma warning(default: 4xxx) +// which should be placed after these defines +#ifndef ALL_WARNINGS +// #pragma warning(disable: 4101) // unreferenced local variable +#pragma warning(disable: 4127) // constant expression for TRACE/ASSERT +#pragma warning(disable: 4134) // message map member fxn casts +#pragma warning(disable: 4511) // private copy constructors are good to have +#pragma warning(disable: 4512) // private operator= are good to have +#pragma warning(disable: 4514) // unreferenced inlines are common +#pragma warning(disable: 4710) // private constructors are disallowed +#pragma warning(disable: 4705) // statement has no effect in optimized code +// #pragma warning(disable: 4701) // local variable *may* be used without init +// #pragma warning(disable: 4702) // unreachable code caused by optimizations +#pragma warning(disable: 4791) // loss of debugging info in retail version +// #pragma warning(disable: 4204) // non-constant aggregate initializer +#pragma warning(disable: 4275) // deriving exported class from non-exported +#pragma warning(disable: 4251) // using non-exported as public in exported +#pragma warning(disable: 4786) // identifier was truncated to '255' characters in the browser information +#endif //!ALL_WARNINGS +// We're on WinNT or Win95 +#define ACE_PLATFORM "Win32" +#define ACE_PLATFORM_EXE_SUFFIX ".exe" + +#include + +// The following 3 defines are used by the ACE Name Server... +#define ACE_DEFAULT_NAMESPACE_DIR "C:\\temp" +#define ACE_DEFAULT_LOCALNAME "\\localnames" +#define ACE_DEFAULT_GLOBALNAME "\\globalnames" + +// Used for ACE_MMAP_Memory_Pool +#define ACE_DEFAULT_BACKING_STORE "C:\\temp\\ace-malloc-XXXXXX" + +// Used for logging +#define ACE_DEFAULT_LOGFILE "C:\\temp\\logfile" + +// Used for dynamic linking +#define ACE_DEFAULT_SVC_CONF ".\\svc.conf" + +// The following are #defines and #includes that are specific to +// WIN32. + +#define ACE_STDIN GetStdHandle (STD_INPUT_HANDLE) +#define ACE_STDOUT GetStdHandle (STD_OUTPUT_HANDLE) +#define ACE_STDERR GetStdHandle (STD_ERROR_HANDLE) + +// Default semaphore key and mutex name +#define ACE_DEFAULT_SEM_KEY "ACE_SEM_KEY" +#define ACE_INVALID_SEM_KEY 0 +#define ACE_DEFAULT_MUTEX "ACE_MUTEX" + +// This flag speeds up the inclusion of Win32 header files. +#if !defined (WIN32_LEAN_AND_MEAN) +#define WIN32_LEAN_AND_MEAN 1 +#endif /* !defined (WIN32_LEAN_AND_MEAN) */ + +#define ACE_SEH_TRY __try +#define ACE_SEH_EXCEPT(X) __except(X) + +// The "null" device on Win32. +#define ACE_DEV_NULL "nul" + +// Define the pathname separator characters for Win32 (ugh). +#define ACE_DIRECTORY_SEPARATOR_STR "\\" +#define ACE_DIRECTORY_SEPARATOR_CHAR '\\' +#define ACE_LD_SEARCH_PATH "PATH" +#define ACE_LD_SEARCH_PATH_SEPARATOR_STR ";" + +// This will help until we figure out everything: +#define NFDBITS 32 // only used in unused functions... +// These two may be used for internal flags soon: +#define MAP_PRIVATE 1 +#define MAP_SHARED 2 +#define MAP_FIXED 4 + +#define RUSAGE_SELF 1 + +struct shmaddr { }; +struct shmid_ds { }; +struct msqid_ds {}; + +// Fake the UNIX rusage structure. Perhaps we can add more to this +// later on? +struct rusage +{ + FILETIME ru_utime; + FILETIME ru_stime; +}; + +// Win32 doesn't use numeric values to name its semaphores, it uses +// strings! +typedef char *key_t; + +// MMAP flags +#define PROT_READ PAGE_READONLY +#define PROT_WRITE PAGE_READWRITE +#define PROT_RDWR PAGE_READWRITE +/* If we can find suitable use for these flags, here they are: +PAGE_WRITECOPY +PAGE_EXECUTE +PAGE_EXECUTE_READ +PAGE_EXECUTE_READWRITE +PAGE_EXECUTE_WRITECOPY +PAGE_GUARD +PAGE_NOACCESS +PAGE_NOCACHE */ + +// This is necessary since MFC users apparently can't #include +// directly. +#if !defined (__AFX_H__) +#include +#endif /* __AFX_H__ */ + +#include + +#define MAXHOSTNAMELEN (MAX_COMPUTERNAME_LENGTH+1) // This should be around 16 or so... + +// error code mapping +#define ETIME ERROR_SEM_TIMEOUT +#define EWOULDBLOCK WSAEWOULDBLOCK +#define EINPROGRESS WSAEINPROGRESS +#define EALREADY WSAEALREADY +#define ENOTSOCK WSAENOTSOCK +#define EDESTADDRREQ WSAEDESTADDRREQ +#define EMSGSIZE WSAEMSGSIZE +#define EPROTOTYPE WSAEPROTOTYPE +#define ENOPROTOOPT WSAENOPROTOOPT +#define EPROTONOSUPPORT WSAEPROTONOSUPPORT +#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT +#define EOPNOTSUPP WSAEOPNOTSUPP +#define EPFNOSUPPORT WSAEPFNOSUPPORT +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#define EADDRINUSE WSAEADDRINUSE +#define EADDRNOTAVAIL WSAEADDRNOTAVAIL +#define ENETDOWN WSAENETDOWN +#define ENETUNREACH WSAENETUNREACH +#define ENETRESET WSAENETRESET +#define ECONNABORTED WSAECONNABORTED +#define ECONNRESET WSAECONNRESET +#define ENOBUFS WSAENOBUFS +#define EISCONN WSAEISCONN +#define ENOTCONN WSAENOTCONN +#define ESHUTDOWN WSAESHUTDOWN +#define ETOOMANYREFS WSAETOOMANYREFS +#define ETIMEDOUT WSAETIMEDOUT +#define ECONNREFUSED WSAECONNREFUSED +#define ELOOP WSAELOOP +#define EHOSTDOWN WSAEHOSTDOWN +#define EHOSTUNREACH WSAEHOSTUNREACH +#define EPROCLIM WSAEPROCLIM +#define EUSERS WSAEUSERS +#define EDQUOT WSAEDQUOT +#define ESTALE WSAESTALE +#define EREMOTE WSAEREMOTE +// Grrr! These two are already defined by the horrible 'standard' +// library. +// #define ENAMETOOLONG WSAENAMETOOLONG +// #define ENOTEMPTY WSAENOTEMPTY + +#include +#include +#include +#include + +typedef OVERLAPPED ACE_OVERLAPPED; +typedef DWORD ACE_thread_t; +typedef HANDLE ACE_hthread_t; +typedef long pid_t; +typedef DWORD ACE_thread_key_t; +typedef DWORD nlink_t; + +// 64-bit quad-word definitions +#if !defined (_MSC_VER) /* Borland? */ +typedef uint64 ACE_QWORD; +inline ACE_QWORD ACE_MAKE_QWORD (DWORD lo, DWORD hi) { return unit64 (lo, hi); } +inline DWORD ACE_LOW_DWORD (ACE_QWORD q) { return q.LowPart; } +inline DWORD ACE_HIGH_DWORD (ACE_QWORD q) { return q.HighPart; } +#else +typedef unsigned __int64 ACE_QWORD; +inline ACE_QWORD ACE_MAKE_QWORD (DWORD lo, DWORD hi) { return ACE_QWORD (lo) | (ACE_QWORD (hi) << 32); } +inline DWORD ACE_LOW_DWORD (ACE_QWORD q) { return (DWORD) q; } +inline DWORD ACE_HIGH_DWORD (ACE_QWORD q) { return (DWORD) (q >> 32); } +#endif /* !defined (_MSC_VER) */ + +// Win32 dummys to help compilation + +typedef void *sigset_t; // Who knows? +typedef int mode_t; +typedef CRITICAL_SECTION ACE_thread_mutex_t; +typedef struct +{ + int type_; // Either USYNC_THREAD or USYNC_PROCESS + union + { + HANDLE proc_mutex_; + CRITICAL_SECTION thr_mutex_; + }; +} ACE_mutex_t; +typedef HANDLE ACE_sema_t; +typedef int uid_t; +typedef int gid_t; +typedef int hrtime_t; +typedef char *caddr_t; + +struct ACE_cond_t + // = TITLE + // This structure is used to implement condition variables on NT. + // + // = DESCRIPTION + // At the current time, this stuff only works for threads + // within the same process. +{ + DWORD waiters_; + // Number of waiting threads. + + ACE_sema_t sema_; + // Queue up threads waiting for the condition to become signaled. +}; + +struct ACE_rwlock_t + // = TITLE + // This is used to implement readers/writer locks on NT. + // + // = DESCRIPTION + // At the current time, this stuff only works for threads + // within the same process. +{ + ACE_mutex_t lock_; + // Serialize access to internal state. + + ACE_cond_t waiting_readers_; + // Reader threads waiting to acquire the lock. + + int num_waiting_readers_; + // Number of waiting readers. + + ACE_cond_t waiting_writers_; + // Writer threads waiting to acquire the lock. + + int num_waiting_writers_; + // Number of waiting writers. + + int ref_count_; + // Value is -1 if writer has the lock, else this keeps track of the + // number of readers holding the lock. +}; + +// Wrapper for NT Events. +typedef HANDLE ACE_event_t; + +// This is for file descriptors. +typedef HANDLE ACE_HANDLE; + +// For Win32 compatibility. +typedef SOCKET ACE_SOCKET; + +#define ACE_INVALID_HANDLE INVALID_HANDLE_VALUE +#define ACE_SYSCALL_FAILED 0xFFFFFFFF + +// These need to be different values, neither of which can be 0... +#define USYNC_THREAD 1 +#define USYNC_PROCESS 2 + +#define THR_CANCEL_DISABLE 0 +#define THR_CANCEL_ENABLE 0 +#define THR_CANCEL_DEFERRED 0 +#define THR_CANCEL_ASYNCHRONOUS 0 +#define THR_DETACHED 0 // ?? ignore in most places +#define THR_BOUND 0 // ?? ignore in most places +#define THR_NEW_LWP 0 // ?? ignore in most places +#define THR_SUSPENDED CREATE_SUSPENDED + +// Needed to map calls to NT transparently. +#define MS_ASYNC 0 +#define MS_INVALIDATE 0 + +// Reliance on CRT - I don't really like this. + +#define O_NDELAY 0 +#define MAXPATHLEN _MAX_PATH +#define MAXNAMLEN _MAX_FNAME +#define EADDRINUSE WSAEADDRINUSE + +// Undefined structs becomes undeclared overloads with MSVC++ 2.0 +// Thus we need to resort to this for unsupported system calls. + +struct sigaction +{ + int sa_flags; + ACE_SignalHandlerV sa_handler; + sigset_t sa_mask; +}; + +struct iovec +{ + char *iov_base; // data to be read/written + size_t iov_len; // byte count to read/write +}; + +struct rlimit { }; +struct t_call { }; +struct t_bind { }; +struct t_info { }; +struct t_optmgmt { }; +struct t_discon { }; +struct t_unitdata { }; +struct t_uderr { }; +struct netbuf { }; +struct flock { }; // not used with Win32 locking... + +// Deal with whatever UNICODE mapping the application is compiling +// with! + +#else /* !defined (ACE_WIN32) */ + +// We're some kind of UNIX... +#define ACE_PLATFORM "UNIX" +#define ACE_PLATFORM_EXE_SUFFIX "" + +typedef const char *LPCTSTR; +typedef char *LPTSTR; +typedef char TCHAR; + +#if defined (m88k) +#define RUSAGE_SELF 1 +#endif // m88k + +// Default semaphore key +#define ACE_DEFAULT_SEM_KEY 1234 +#define ACE_INVALID_SEM_KEY -1 +#define ACE_DEFAULT_MUTEX "ACE_MUTEX" + +// The following 3 defines are used by the ACE Name Server... +#define ACE_DEFAULT_NAMESPACE_DIR "/tmp" +#define ACE_DEFAULT_LOCALNAME "/localnames" +#define ACE_DEFAULT_GLOBALNAME "/globalnames" + +// Used for ACE_MMAP_Memory_Pool +#define ACE_DEFAULT_BACKING_STORE "/tmp/ace-malloc-XXXXXX" + +// Used for logging +#define ACE_DEFAULT_LOGFILE "/tmp/logfile" + +// Used for dynamic linking. +#define ACE_DEFAULT_SVC_CONF "./svc.conf" + +// The following are #defines and #includes that are specific to UNIX. + +#define ACE_STDIN 0 +#define ACE_STDOUT 1 +#define ACE_STDERR 2 + +// Be consistent with Winsock naming +#define ACE_INVALID_HANDLE -1 +#define ACE_SYSCALL_FAILED -1 + +#define ACE_SEH_TRY +#define ACE_SEH_EXCEPT(X) + +// The "null" device on UNIX. +#define ACE_DEV_NULL "/dev/null" + +// Define the pathname separator characters for UNIX. +#define ACE_DIRECTORY_SEPARATOR_STR "/" +#define ACE_DIRECTORY_SEPARATOR_CHAR '/' +#define ACE_LD_SEARCH_PATH "LD_LIBRARY_PATH" +#define ACE_LD_SEARCH_PATH_SEPARATOR_STR ":" + +// Wrapper for NT events on UNIX. +struct ACE_event_t +{ + ACE_mutex_t lock_; + // Protect critical section. + + ACE_cond_t condition_; + // Keeps track of waiters. + + int manual_reset_; + // Specifies if this is an auto- or manual-reset event. + + int is_signaled_; + // "True" if signaled. + + u_long waiting_threads_; + // Number of waiting threads. +}; + +// Provide compatibility with Windows NT. +typedef int ACE_HANDLE; +// For Win32 compatibility. +typedef ACE_HANDLE ACE_SOCKET; + +struct ACE_OVERLAPPED +{ + u_long Internal; + u_long InternalHigh; + u_long Offset; + u_long OffsetHigh; + ACE_HANDLE hEvent; +}; + +// Add some typedefs and macros to enhance Win32 conformance... +typedef int LPSECURITY_ATTRIBUTES; +#define GENERIC_READ 0 +#define FILE_SHARE_READ 0 +#define OPEN_EXISTING 0 +#define FILE_ATTRIBUTE_NORMAL 0 +#define MAXIMUM_WAIT_OBJECTS 0 +#define FILE_FLAG_OVERLAPPED 0 + +#if defined (ACE_HAS_BROKEN_IF_HEADER) +struct ifafilt; +#endif +#include +extern "C" { +#if !defined (VXWORKS) +#include +#endif /* VXWORKS */ +#include +#include +#include +} +#if defined (VXWORKS) +#include +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif /* VXWORKS */ +#include +#include +#include +#include +#include + +#if !defined (ACE_LACKS_PARAM_H) +#include +#endif /* ACE_LACKS_PARAM_H */ + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) && !defined (VXWORKS) +#include +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ + +#if defined (ACE_HAS_SIGINFO_T) +#if !defined (ACE_LACKS_SIGINFO_H) +#include +#endif /* ACE_LACKS_SIGINFO_H */ +#if !defined (ACE_LACKS_UCONTEXT_H) +#include +#endif /* ACE_LACKS_UCONTEXT_H */ +#endif /* ACE_HAS_SIGINFO_T */ + +#if defined (ACE_HAS_POLL) +#include +#endif /* ACE_HAS_POLL */ + +#if defined (ACE_HAS_STREAMS) +#if defined (AIX) +#if !defined (_XOPEN_EXTENDED_SOURCE) +#define _XOPEN_EXTENDED_SOURCE +#endif /* !_XOPEN_EXTENDED_SOURCE */ +#include +#undef _XOPEN_EXTENDED_SOURCE +#else +#include +#endif /* AIX */ +#endif /* ACE_HAS_STREAMS */ + +#if defined (ACE_LACKS_T_ERRNO) +extern int t_errno; +#endif /* ACE_LACKS_T_ERRNO */ + +#if !defined (ACE_HAS_SIGWAIT) +extern "C" int sigwait (sigset_t *set); +#endif /* ACE_HAS_SIGWAIT */ + +#if defined (ACE_HAS_SELECT_H) +#include +#endif /* ACE_HAS_SELECT_H */ + +#if defined (ACE_HAS_ALLOCA_H) +#include +#endif /* ACE_HAS_ALLOCA_H */ + +#if defined (ACE_HAS_TIUSER_H) +#include +#endif /* ACE_HAS_TIUSER_H */ + +#if defined (ACE_HAS_SVR4_DYNAMIC_LINKING) +#include +#endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */ + +#if defined (ACE_HAS_SOCKIO_H) +#include +#endif /* ACE_HAS_SOCKIO_ */ + +#if defined (ACE_HAS_TIMOD_H) +#include +#elif defined (ACE_HAS_OSF_TIMOD_H) +#include +#endif /* ACE_HAS_TIMOD_H */ + +// There must be a better way to do this... +#if defined (Linux) || defined (AIX) || defined (SCO) +#if defined (RLIMIT_OFILE) +#define RLIMIT_NOFILE RLIMIT_OFILE +#else +#define RLIMIT_NOFILE 200 +#endif /* RLIMIT_OFILE */ +#endif /* defined (Linux) || defined (AIX) || defined (SCO) */ + +#if !defined (ACE_HAS_TLI_PROTOTYPES) +// Define ACE_TLI headers for systems that don't prototype them.... +extern "C" +{ + int t_accept(int fildes, int resfd, struct t_call *call); + char *t_alloc(int fildes, int struct_type, int fields); + int t_bind(int fildes, struct t_bind *req, struct t_bind *ret); + int t_close(int fildes); + int t_connect(int fildes, struct t_call *sndcall, + struct t_call *rcvcall); + void t_error(char *errmsg); + int t_free(char *ptr, int struct_type); + int t_getinfo(int fildes, struct t_info *info); + int t_getname (int fildes, struct netbuf *namep, int type); + int t_getstate(int fildes); + int t_listen(int fildes, struct t_call *call); + int t_look(int fildes); + int t_open(char *path, int oflag, struct t_info *info); + int t_optmgmt(int fildes, struct t_optmgmt *req, + struct t_optmgmt *ret); + int t_rcv(int fildes, char *buf, unsigned nbytes, int *flags); + int t_rcvconnect(int fildes, struct t_call *call); + int t_rcvdis(int fildes, struct t_discon *discon); + int t_rcvrel(int fildes); + int t_rcvudata(int fildes, struct t_unitdata *unitdata, int *flags); + int t_rcvuderr(int fildes, struct t_uderr *uderr); + int t_snd(int fildes, char *buf, unsigned nbytes, int flags); + int t_snddis(int fildes, struct t_call *call); + int t_sndrel(int fildes); + int t_sndudata(int fildes, struct t_unitdata *unitdata); + int t_sync(int fildes); + int t_unbind(int fildes); +} +#endif /* !ACE_HAS_TLI_PROTOTYPES */ + +// IRIX5 defines bzero() in this odd file... +#if defined (ACE_HAS_BSTRING) +#include +#endif /* ACE_HAS_BSTRING */ + +// AIX defines bzero() in this odd file... +#if defined (ACE_HAS_STRINGS) +#include +#endif /* ACE_HAS_STRINGS */ + +#if defined (ACE_HAS_TERM_IOCTLS) +#include +#endif /* ACE_HAS_TERM_IOCTLS */ + +#if defined (ACE_LACKS_MMAP) +#define PROT_READ 0 +#define PROT_WRITE 0 +#define PROT_EXEC 0 +#define PROT_NONE 0 +#define PROT_RDWR 0 +#define MAP_PRIVATE 0 +#define MAP_SHARED 0 +#define MAP_FIXED 0 +#endif /* ACE_LACKS_MMAP */ + +// Fixes a problem with HP/UX. +#if defined (ACE_HAS_BROKEN_MMAP_H) +extern "C" +{ +#include +} +#elif !defined (ACE_LACKS_MMAP) +#include +#endif /* ACE_HAS_BROKEN_MMAP_H */ + +// OSF1 has problems with sys/msg.h and C++... +#if defined (ACE_HAS_BROKEN_MSG_H) +#define _KERNEL +#endif /* ACE_HAS_BROKEN_MSG_H */ +#if !defined (VXWORKS) +#include +#endif /* VXWORKS */ +#if defined (ACE_HAS_BROKEN_MSG_H) +#undef _KERNEL +#endif /* ACE_HAS_BROKEN_MSG_H */ + +#if defined (ACE_LACKS_SYSV_MSQ_PROTOS) +extern "C" +{ + int msgget (key_t, int); + int msgrcv (int, void *, size_t, long, int); + int msgsnd (int, const void *, size_t, int); + int msgctl (int, int, struct msqid_ds *); +} +#endif /* ACE_LACKS_SYSV_MSQ_PROTOS */ +#endif /* ACE_WIN32 */ + +#if defined (VXWORKS) +typedef int key_t; + +#include + +#if defined (ACE_HAS_GREENHILLS_SOCKETS) +#include +#include +#include +#include +#include + +extern "C" +struct sockaddr_un { + short sun_family; // AF_UNIX. + char sun_path[108]; // path name. +}; +#endif /* ACE_HAS_GREENHILLS_SOCKETS */ + +#define MAXPATHLEN 1024 +#define MAXNAMLEN 255 +#define NSIG _NSIGS +#endif /* VXWORKS */ + +#if defined (ACE_SELECT_USES_INT) +typedef int ACE_FD_SET_TYPE; +#else +typedef fd_set ACE_FD_SET_TYPE; +#endif /* ACE_SELECT_USES_INT */ + +#if !defined (MAXNAMELEN) +#if defined (FILENAME_MAX) +#define MAXNAMELEN FILENAME_MAX +#else +#define MAXNAMELEN 256 +#endif /* FILENAME_MAX */ +#endif /* MAXNAMELEN */ + +// This one exists only to please Service_Config.h and +// Service_Manager.cpp +#if !defined (SIGHUP) +#define SIGHUP 1 +#endif /* SIGHUP */ + +#if !defined (SIGQUIT) +#define SIGQUIT 3 +#endif /* SIGQUIT */ + +#if !defined (SIGPIPE) +#define SIGPIPE 13 +#endif /* SIGPIPE */ + +#if !defined (O_NONBLOCK) +#define O_NONBLOCK 1 +#endif /* O_NONBLOCK */ + +#if !defined (SIG_BLOCK) +#define SIG_BLOCK 1 +#endif /* SIG_BLOCK */ + +#if !defined (SIG_UNBLOCK) +#define SIG_UNBLOCK 2 +#endif /* SIG_UNBLOCK */ + +#if !defined (SIG_SETMASK) +#define SIG_SETMASK 3 +#endif /* SIG_SETMASK */ + +#if !defined (IPC_CREAT) +#define IPC_CREAT 0 +#endif /* IPC_CREAT */ + +#if !defined (IPC_NOWAIT) +#define IPC_NOWAIT 0 +#endif /* IPC_NOWAIT */ + +#if !defined (IPC_RMID) +#define IPC_RMID 0 +#endif /* IPC_RMID */ + +#if !defined (IPC_EXCL) +#define IPC_EXCL 0 +#endif /* IPC_EXCL */ + +#if !defined (IPC_PRIVATE) +#define IPC_PRIVATE ACE_INVALID_SEM_KEY +#endif /* IPC_PRIVATE */ + +#if !defined (IPC_STAT) +#define IPC_STAT 0 +#endif /* IPC_STAT */ + +#if !defined (GETVAL) +#define GETVAL 0 +#endif /* GETVAL */ + +#if !defined (SETVAL) +#define SETVAL 0 +#endif /* SETVAL */ + +#if !defined (GETALL) +#define GETALL 0 +#endif /* GETALL */ + +#if !defined (SETALL) +#define SETALL 0 +#endif /* SETALL */ + +#if !defined (SEM_UNDO) +#define SEM_UNDO 0 +#endif /* SEM_UNDO */ + +// Why is this defined? It must be a std C library symbol. +#if !defined (NSIG) +#define NSIG 1 +#endif /* NSIG */ + +#if !defined (R_OK) +#define R_OK 04 // Test for Read permission. +#endif /* R_OK */ + +#if !defined (W_OK) +#define W_OK 02 // Test for Write permission. +#endif /* W_OK */ + +#if !defined (X_OK) +#define X_OK 01 // Test for eXecute permission. +#endif /* X_OK */ + +#if !defined (F_OK) +#define F_OK 0 // Test for existence of File. +#endif /* F_OK */ + +#if !defined (EIDRM) +#define EIDRM 0 +#endif /* !EIDRM */ + +#if !defined (ENOTSUP) +#define ENOTSUP ENOSYS // Operation not supported . +#endif /* !ENOTSUP */ + +#if !defined (EDEADLK) +#define EDEADLK 1000 // Some large number.... +#endif /* !ENOTSUP */ + +#if !defined (MS_SYNC) +#define MS_SYNC 0x0 +#endif /* !MS_SYNC */ + +#if !defined (PIPE_BUF) +#define PIPE_BUF 5120 +#endif /* PIPE_BUF */ + +#if !defined (PROT_RDWR) +#define PROT_RDWR (PROT_READ|PROT_WRITE) +#endif /* PROT_RDWR */ + +#if defined (ACE_HAS_POSIX_NONBLOCK) +#define ACE_NONBLOCK O_NONBLOCK +#else +#define ACE_NONBLOCK O_NDELAY +#endif /* ACE_HAS_POSIX_NONBLOCK */ + +#define LOCALNAME 0 +#define REMOTENAME 1 + +#if defined (ACE_HAS_64BIT_LONGS) +// Necessary to support the Alphas, which have 64 bit longs and 32 bit +// ints... +typedef u_int ACE_UINT32; +#else +typedef u_long ACE_UINT32; +#endif /* ACE_HAS_64BIT_LONGS */ + +#if !defined (ETIMEDOUT) && defined (ETIME) +#define ETIMEDOUT ETIME +#endif /* ETIMEDOUT */ + +#if !defined (ETIME) && defined (ETIMEDOUT) +#define ETIME ETIMEDOUT +#endif /* ETIMED */ + +// Note that this assumes shorts are 16 bits. +typedef u_short ACE_USHORT16; + +#if defined (ACE_HAS_STRUCT_NETDB_DATA) +typedef char ACE_HOSTENT_DATA[sizeof(struct hostent_data)]; +typedef char ACE_SERVENT_DATA[sizeof(struct servent_data)]; +typedef char ACE_PROTOENT_DATA[sizeof(struct protoent_data)]; +#else +#if !defined ACE_HOSTENT_DATA_SIZE +#define ACE_HOSTENT_DATA_SIZE (4*1024) +#endif /*ACE_HOSTENT_DATA_SIZE */ +#if !defined ACE_SERVENT_DATA_SIZE +#define ACE_SERVENT_DATA_SIZE (4*1024) +#endif /*ACE_SERVENT_DATA_SIZE */ +#if !defined ACE_PROTOENT_DATA_SIZE +#define ACE_PROTOENT_DATA_SIZE (2*1024) +#endif /*ACE_PROTOENT_DATA_SIZE */ +typedef char ACE_HOSTENT_DATA[ACE_HOSTENT_DATA_SIZE]; +typedef char ACE_SERVENT_DATA[ACE_SERVENT_DATA_SIZE]; +typedef char ACE_PROTOENT_DATA[ACE_PROTOENT_DATA_SIZE]; +#endif /* ACE_HAS_STRUCT_NETDB_DATA */ + +#if !defined (ACE_HAS_SEMUN) +union semun +{ + int val; // value for SETVAL + struct semid_ds *buf; // buffer for IPC_STAT & IPC_SET + u_short *array; // array for GETALL & SETALL +}; +#endif /* !ACE_HAS_SEMUN */ + +// Max size of an ACE Token. +#define ACE_MAXTOKENNAMELEN 40 + +// Max size of an ACE Token client ID. +#define ACE_MAXCLIENTIDLEN MAXHOSTNAMELEN + 20 + +// Create some useful typedefs. +typedef void *(*ACE_THR_FUNC)(void *); +typedef const char **SYS_SIGLIST; + +#if !defined (MAP_FAILED) +#define MAP_FAILED ((void *) -1) +#elif defined (ACE_HAS_LONG_MAP_FAILED) +#undef MAP_FAILED +#define MAP_FAILED ((void *) -1L) +#endif /* MAP_FAILED */ + +#if defined (ACE_HAS_CHARPTR_DL) +typedef LPTSTR ACE_DL_TYPE; +#else +typedef LPCTSTR ACE_DL_TYPE; +#endif /* ACE_HAS_CHARPTR_DL */ + +#if !defined (ACE_HAS_SIGINFO_T) +typedef int siginfo_t; +#endif /* ACE_HAS_SIGINFO_T */ + +#if !defined (ACE_HAS_UCONTEXT_T) +typedef int ucontext_t; +#endif /* ACE_HAS_UCONTEXT_T */ + +#if !defined (SA_SIGINFO) +#define SA_SIGINFO 0 +#endif /* SA_SIGINFO */ + +#if !defined (SA_RESTART) +#define SA_RESTART 0 +#endif /* SA_RESTART */ + +// Type of the extended signal handler. +typedef void (*ACE_Sig_Handler_Ex) (int, siginfo_t *siginfo, ucontext_t *ucontext); + +// If the xti.h file redefines the function names, do it now, else +// when the function definitions are encountered, they won't match the +// declaration here. + +#if defined (ACE_REDEFINES_XTI_FUNCTIONS) +#include +#ifdef UNIXWARE // They apparantly forgot one... +extern "C" int _xti_error(char *); +#endif /* UNIXWARE */ +#endif /* ACE_REDEFINES_XTI_FUNCTIONS */ + +class ACE_Export ACE_OS + // = TITLE + // This class defines an operating system independent + // programming API that shields developers from non-portable + // aspects of writing efficient system programs on Win32, POSIX, + // and other versions of UNIX. + // + // = DESCRIPTION + // This class encapsulates all the differences between various + // versions of UNIX and WIN32! The other components in + // ACE are programmed to use only the methods in this class, + // which makes it *much* easier to move ACE to a new platform. + // The methods in this class also automatically restart when + // interrupts occur during system calls (assuming that the + // ACE_Log_Msg::restart() flag is enabled). +{ +public: + struct flock_t + // = TITLE + // OS file locking structure. + { + void dump (void) const; + // Dump state of the object. + +#if defined (ACE_WIN32) + ACE_OVERLAPPED overlapped_; +#else + struct flock lock_; +#endif /* ACE_WIN32 */ + + ACE_HANDLE handle_; + // Handle to the underlying file. + }; + + // = A set of wrappers for miscellaneous operations. + static int atoi (const char *s); + static char *getenv (const char *symbol); + static int getopt (int argc, char *const *argv, const char *optstring); + static long sysconf (int); + + // = A set of wrappers for condition variables. + static int cond_broadcast (ACE_cond_t *cv); + static int cond_destroy (ACE_cond_t *cv); + static int cond_init (ACE_cond_t *cv, int type = USYNC_THREAD, LPCTSTR name = 0, void *arg = 0); + static int cond_signal (ACE_cond_t *cv); + static int cond_timedwait (ACE_cond_t *cv, ACE_mutex_t *m, ACE_Time_Value *); + static int cond_wait (ACE_cond_t *cv, ACE_mutex_t *m); +#if defined (ACE_WIN32) + static int cond_timedwait (ACE_cond_t *cv, ACE_thread_mutex_t *m, ACE_Time_Value *); + static int cond_wait (ACE_cond_t *cv, ACE_thread_mutex_t *m); +#endif /* ACE_WIN32 */ + + // = A set of wrappers for determining config info. + static char *cuserid (char *user, size_t maxlen = 32); + static int uname (struct utsname *name); + static long sysinfo (int cmd, char *buf, long count); + static int hostname (char *name, size_t maxnamelen); + + // = A set of wrappers for explicit dynamic linking. + static int dlclose (void *handle); + static char *dlerror (void); + static void *dlopen (ACE_DL_TYPE filename, int mode); + static void *dlsym (void *handle, ACE_DL_TYPE symbol); + + // = A set of wrappers for stdio file operations. + static int last_error (void); + static void last_error (int); + static int fclose (FILE *fp); + static int fcntl (ACE_HANDLE handle, int cmd, int val = 0); + static int fdetach (const char *file); + static FILE *fdopen (ACE_HANDLE handle, const char *mode); + static char *fgets (char *buf, int size, FILE *fp); + static int fflush (FILE *fp); + static FILE *fopen (const char *filename, const char *mode); + static int fprintf (FILE *fp, const char *format, ...); + static size_t fread (void *ptr, size_t size, size_t nelems, FILE + *fp); + static int fstat (ACE_HANDLE, struct stat *); + static int ftruncate (ACE_HANDLE, off_t); + static size_t fwrite (const void *ptr, size_t size, size_t nitems, + FILE *fp); + static char *gets (char *str); + static void perror (const char *s); + static int printf (const char *format, ...); + static int puts (const char *s); + static void rewind (FILE *fp); + static int sprintf (char *buf, const char *format, ...); + + // = A set of wrappers for file locks. + static int flock_init (ACE_OS::flock_t *lock, int flags = 0, + LPCTSTR name = 0, mode_t perms = 0); + static int flock_destroy (ACE_OS::flock_t *lock); + static int flock_rdlock (ACE_OS::flock_t *lock, short whence = 0, + off_t start = 0, off_t len = 0); + static int flock_tryrdlock (ACE_OS::flock_t *lock, short whence = 0, + off_t start = 0, off_t len = 0); + static int flock_trywrlock (ACE_OS::flock_t *lock, short whence = 0, + off_t start = 0, off_t len = 0); + static int flock_unlock (ACE_OS::flock_t *lock, short whence = 0, + off_t start = 0, off_t len = 0); + static int flock_wrlock (ACE_OS::flock_t *lock, short whence = 0, + off_t start = 0, off_t len = 0); + + // = A set of wrappers for low-level process operations. + static int execl (const char *path, const char *arg0, ...); + static int execle (const char *path, const char *arg0, ...); + static int execlp (const char *file, const char *arg0, ...); + static int execv (const char *path, char *const argv[]); + static int execvp (const char *file, char *const argv[]); + static int execve (const char *path, char *const argv[], char *const envp[]); + static void _exit (int status = 0); + static void exit (int status = 0); + static pid_t fork (void); + static pid_t fork_exec (char *argv[]); + // Forks and exec's a process in a manner that works on Solaris and + // NT. argv[0] must be the full path name to the executable. + static uid_t getgid (void); + static pid_t getpid (void); + static uid_t getuid (void); + static pid_t setsid (void); + static int system (const char *s); + static pid_t wait (int * = 0); + static pid_t waitpid (pid_t, int * = 0, int = 0); + + // = A set of wrappers for timers and resource stats. + static u_int alarm (u_int delay); + static hrtime_t gethrtime (void); + static ACE_Time_Value gettimeofday (void); + static int getrusage (int who, struct rusage *rusage); + static int getrlimit (int resource, struct rlimit *rl); + static int setrlimit (int resource, ACE_SETRLIMIT_TYPE *rl); + static int sleep (u_int seconds); + static int sleep (const ACE_Time_Value &tv); + + // = A set of wrappers for operations on time. + static time_t time (time_t *tloc); + static struct tm *localtime (const time_t *clock); + static struct tm *localtime_r (const time_t *clock, struct tm *res); + static char *asctime (const struct tm *tm); + static char *ctime (const time_t *t); + static char *ctime_r (const time_t *clock, char *buf, int buflen); + static char *asctime_r (const struct tm *tm, char *buf, int buflen); + + // = A set of wrappers for memory managment. + static void *sbrk (int brk); + static void *malloc (size_t); + static void *realloc (void *, size_t); + static void free (void *); + + // = A set of wrappers for memory copying operations. + static int memcmp (const void *s, const void *t, size_t len); + static void *memcpy (void *s, const void *t, size_t len); + static void *memset (void *s, int c, size_t len); + + // = A set of wrappers for System V message queues. + static int msgctl (int msqid, int cmd, struct msqid_ds *); + static int msgget (key_t key, int msgflg); + static int msgrcv (int int_id, void *buf, size_t len, + long type, int flags); + static int msgsnd (int int_id, const void *buf, size_t len, int + flags); + + // = A set of wrappers for memory mapped files. + static int madvise (caddr_t addr, size_t len, int advice); + static void *mmap (void *addr, size_t len, int prot, int flags, + ACE_HANDLE handle, off_t off = 0, + ACE_HANDLE *file_mapping = 0); + static int mprotect (void *addr, size_t len, int prot); + static int msync (void *addr, size_t len, int sync); + static int munmap (void *addr, size_t len); + + // = A set of wrappers for mutex locks. + static int mutex_init (ACE_mutex_t *m, int type = USYNC_THREAD, + LPCTSTR name = 0, void *arg = 0); + static int mutex_destroy (ACE_mutex_t *m); + static int mutex_lock (ACE_mutex_t *m); + static int mutex_trylock (ACE_mutex_t *m); + static int mutex_unlock (ACE_mutex_t *m); + + + // = A set of wrappers for mutex locks that only work within a + // single process. + static int thread_mutex_init (ACE_thread_mutex_t *m, int type = USYNC_THREAD, + LPCTSTR name = 0, void *arg = 0); + static int thread_mutex_destroy (ACE_thread_mutex_t *m); + static int thread_mutex_lock (ACE_thread_mutex_t *m); + static int thread_mutex_trylock (ACE_thread_mutex_t *m); + static int thread_mutex_unlock (ACE_thread_mutex_t *m); + + // = A set of wrappers for low-level file operations. + static int access (const char *path, int amode); + static int close (ACE_HANDLE handle); + static ACE_HANDLE creat (LPCTSTR filename, mode_t mode); + static ACE_HANDLE dup (ACE_HANDLE handle); + static int dup2 (ACE_HANDLE oldfd, ACE_HANDLE newfd); + static int fattach (int handle, const char *path); + static long filesize (ACE_HANDLE handle); + static int getmsg (ACE_HANDLE handle, struct strbuf *ctl, struct strbuf + *data, int *flags); + static getpmsg (ACE_HANDLE handle, struct strbuf *ctl, struct strbuf + *data, int *band, int *flags); + static int ioctl (ACE_HANDLE handle, int cmd, void * = 0); + static int isastream (ACE_HANDLE handle); + static int isatty (ACE_HANDLE handle); + static off_t lseek (ACE_HANDLE handle, off_t offset, int whence); + static ACE_HANDLE open (LPCTSTR filename, int mode, int perms = 0); + static int putmsg (ACE_HANDLE handle, const struct strbuf *ctl, const + struct strbuf *data, int flags); + static putpmsg (ACE_HANDLE handle, const struct strbuf *ctl, const + struct strbuf *data, int band, int flags); + static ssize_t read (ACE_HANDLE handle, void *buf, size_t len); + static ssize_t read (ACE_HANDLE handle, void *buf, size_t len, ACE_OVERLAPPED *); + static ssize_t readv (ACE_HANDLE handle, struct iovec *iov, int iovlen); + static int recvmsg (ACE_HANDLE handle, struct msghdr *msg, int flags); + static int sendmsg (ACE_HANDLE handle, ACE_SENDMSG_TYPE *msg, int flags); + static ssize_t write (ACE_HANDLE handle, const void *buf, size_t nbyte); + static ssize_t write (ACE_HANDLE handle, const void *buf, size_t nbyte, ACE_OVERLAPPED *); + static int writev (ACE_HANDLE handle, ACE_WRITEV_TYPE *iov, int iovcnt); + + // = A set of wrappers for event demultiplexing and IPC. + static int select (int width, fd_set *rfds, fd_set *wfds, fd_set *efds, ACE_Time_Value *tv = 0); + static int select (int width, fd_set *rfds, fd_set *wfds, fd_set *efds, const ACE_Time_Value &tv); + static int poll (struct pollfd *pollfds, u_long len, ACE_Time_Value *tv = 0); + static int poll (struct pollfd *pollfds, u_long len, const ACE_Time_Value &tv); + static int pipe (ACE_HANDLE handles[]); + + // = A set of wrappers for directory operations. + static int chdir (const char *path); + static int mkfifo (const char *file, mode_t mode); + static char *mktemp (char *t); + static char *getcwd (char *, size_t); + static mode_t umask (mode_t cmask); + static int unlink (const char *path); + + // = A set of wrappers for random number operations. + static int rand (void); + static int rand_r (ACE_RANDR_TYPE seed); + static void srand (u_int seed); + + // = A set of wrappers for readers/writer locks. + static int rwlock_init (ACE_rwlock_t *rw, int type = USYNC_THREAD, + LPCTSTR name = 0, void *arg = 0); + static int rwlock_destroy (ACE_rwlock_t *rw); + static int rw_rdlock (ACE_rwlock_t *rw); + static int rw_tryrdlock (ACE_rwlock_t *rw); + static int rw_trywrlock (ACE_rwlock_t *rw); + static int rw_unlock (ACE_rwlock_t *rw); + static int rw_wrlock (ACE_rwlock_t *rw); + + // = A set of wrappers for auto-reset and manuaevents. + static int event_init (ACE_event_t *event, + int manual_reset = 0, + int initial_state = 0, + int type = USYNC_THREAD, + LPCTSTR name = 0, + void *arg = 0); + static int event_destroy (ACE_event_t *event); + static int event_wait (ACE_event_t *event); + static int event_timedwait (ACE_event_t *event, + ACE_Time_Value *timeout); + static int event_signal (ACE_event_t *event); + static int event_pulse (ACE_event_t *event); + static int event_reset (ACE_event_t *event); + + // = A set of wrappers for semaphores. + static int sema_destroy (ACE_sema_t *s); + static int sema_init (ACE_sema_t *s, u_int count, int type = USYNC_THREAD, + LPCTSTR name = 0, void *arg = 0, + int max = 0x7fffffff); + static int sema_post (ACE_sema_t *s); + static int sema_trywait (ACE_sema_t *s); + static int sema_wait (ACE_sema_t *s); + + // = A set of wrappers for System V semaphores. + static int semctl (int int_id, int semnum, int cmd, semun); + static int semget (key_t key, int nsems, int flags); + static int semop (int int_id, struct sembuf *sops, size_t nsops); + + // = A set of wrappers for System V shared memory. + static void *shmat (int int_id, void *shmaddr, int shmflg); + static int shmctl (int int_id, int cmd, struct shmid_ds *buf); + static int shmdt (void *shmaddr); + static int shmget (key_t key, int size, int flags); + + // = A set of wrappers for Signals. + static int kill (pid_t pid, int signum); + static int sigaction (int signum, const struct sigaction *nsa, + struct sigaction *osa); + static int sigaddset (sigset_t *s, int signum); + static int sigdelset (sigset_t *s, int signum); + static int sigemptyset (sigset_t *s); + static int sigfillset (sigset_t *s); + static int sigismember (sigset_t *s, int signum); + static ACE_SignalHandler signal (int signum, ACE_SignalHandler); + static int sigprocmask (int how, const sigset_t *nsp, sigset_t *osp); + + // = A set of wrappers for sockets. + static ACE_HANDLE accept (ACE_HANDLE handle, struct sockaddr *addr, + int *addrlen); + static int bind (ACE_HANDLE s, struct sockaddr *name, int namelen); + static int connect (ACE_HANDLE handle, struct sockaddr *addr, int + addrlen); + static int closesocket (ACE_HANDLE s); + static struct hostent *gethostbyaddr (const char *addr, int length, + int type); + static struct hostent *gethostbyname (const char *name); + static struct hostent *gethostbyaddr_r (const char *addr, int length, + int type, struct hostent *result, + ACE_HOSTENT_DATA buffer, + int *h_errnop); + static struct hostent *gethostbyname_r (const char *name, struct + hostent *result, ACE_HOSTENT_DATA buffer, + int *h_errnop); + static int getpeername (ACE_HANDLE handle, struct sockaddr *addr, + int *addrlen); + static struct protoent *getprotobyname (const char *name); + static struct protoent *getprotobyname_r (const char *name, + struct protoent *result, + ACE_PROTOENT_DATA buffer); + static struct protoent *getprotobynumber (int proto); + static struct protoent *getprotobynumber_r (int proto, + struct protoent *result, + ACE_PROTOENT_DATA buffer); + static struct servent *getservbyname (const char *svc, const char + *proto); + static struct servent *getservbyname_r (const char *svc, const char *proto, + struct servent *result, + ACE_SERVENT_DATA buf); + static int getsockname (ACE_HANDLE handle, struct sockaddr *addr, + int *addrlen); + static int getsockopt (ACE_HANDLE handle, int level, int optname, char + *optval, int *optlen); + static long inet_addr (const char *name); + static char *inet_ntoa (const struct in_addr addr); + static int listen (ACE_HANDLE handle, int backlog); + static int recv (ACE_HANDLE handle, char *buf, int len, int flags = 0); + static int recvfrom (ACE_HANDLE handle, char *buf, int len, int flags, + struct sockaddr *addr, int *addrlen); + static int send (ACE_HANDLE handle, const char *buf, int len, int + flags = 0); + static int sendto (ACE_HANDLE handle, const char *buf, int len, int + flags, const struct sockaddr *addr, int addrlen); + static int setsockopt (ACE_HANDLE handle, int level, int optname, + const char *optval, int optlen); + static int shutdown (ACE_HANDLE handle, int how); + static ACE_HANDLE socket (int domain, int type, int proto); + static int socketpair (int domain, int type, int protocol, + ACE_HANDLE sv[2]); + static int socket_init (int version_high = 1, int version_low = 1); + // Initialize WinSock before first use (e.g., when a DLL is first + // loaded or the first use of a socket() call. + + static int socket_fini (void); + // Finialize WinSock after last use (e.g., when a DLL is unloaded). + + // = A set of wrappers for regular expressions. + static char *compile (const char *instring, char *expbuf, char + *endbuf); + static int step (const char *str, char *expbuf); + + // = A set of wrappers for non-UNICODE string operations. + static int strcasecmp (const char *s, const char *t); + static char *strcat (char *s, const char *t); + static char *strchr (const char *s, int c); + static char *strrchr (const char *s, int c); + static int strcmp (const char *s, const char *t); + static char *strcpy (char *s, const char *t); + static size_t strspn(const char *s1, const char *s2); + static char *strstr (const char *s, const char *t); + static char *strdup (const char *s); + static size_t strlen (const char *s); + static int strncmp (const char *s, const char *t, size_t len); + static char *strncpy (char *s, const char *t, size_t len); + static char *strtok (char *s, const char *tokens); + static char *strtok_r (char *s, const char *tokens, char **lasts); + static long strtol (const char *s, char **ptr, int base); + +#if defined (ACE_HAS_UNICODE) + // = A set of wrappers for non-UNICODE string operations. + static wchar_t *strcat (wchar_t *s, const wchar_t *t); + static wchar_t *strchr (const wchar_t *s, int c); + static wchar_t *strrchr (const wchar_t *s, int c); + static int strcmp (const wchar_t *s, const wchar_t *t); + static wchar_t *strcpy (wchar_t *s, const wchar_t *t); +// static wchar_t *strstr (const wchar_t *s, const wchar_t *t); +// static wchar_t *strdup (const wchar_t *s); + static size_t strlen (const wchar_t *s); + static int strncmp (const wchar_t *s, const wchar_t *t, size_t len); + static wchar_t *strncpy (wchar_t *s, const wchar_t *t, size_t len); + static wchar_t *strtok (wchar_t *s, const wchar_t *tokens); + static long strtol (const wchar_t *s, wchar_t **ptr, int base); +#endif /* ACE_HAS_UNICODE */ + + // = A set of wrappers for TLI. + static int t_accept (ACE_HANDLE fildes, int resfd, struct t_call + *call); + static char *t_alloc (ACE_HANDLE fildes, int struct_type, int + fields); + static int t_bind (ACE_HANDLE fildes, struct t_bind *req, struct + t_bind *ret); + static int t_close (ACE_HANDLE fildes); + static int t_connect(int fildes, struct t_call *sndcall, + struct t_call *rcvcall); + static void t_error (char *errmsg); + static int t_free (char *ptr, int struct_type); + static int t_getinfo (ACE_HANDLE fildes, struct t_info *info); + static int t_getname (ACE_HANDLE fildes, struct netbuf *namep, int + type); + static int t_getstate (ACE_HANDLE fildes); + static int t_listen (ACE_HANDLE fildes, struct t_call *call); + static int t_look (ACE_HANDLE fildes); + static int t_open (char *path, int oflag, struct t_info *info); + static int t_optmgmt (ACE_HANDLE fildes, struct t_optmgmt *req, + struct t_optmgmt *ret); + static int t_rcv (ACE_HANDLE fildes, char *buf, unsigned nbytes, int + *flags); + static int t_rcvdis (ACE_HANDLE fildes, struct t_discon *discon); + static int t_rcvrel (ACE_HANDLE fildes); + static int t_rcvudata (ACE_HANDLE fildes, struct t_unitdata + *unitdata, int *flags); + static int t_rcvuderr (ACE_HANDLE fildes, struct t_uderr *uderr); + static int t_snd (ACE_HANDLE fildes, char *buf, unsigned nbytes, int + flags); + static int t_snddis (ACE_HANDLE fildes, struct t_call *call); + static int t_sndrel (ACE_HANDLE fildes); + static int t_sync (ACE_HANDLE fildes); + static int t_unbind (ACE_HANDLE fildes); + + // = A set of wrappers for threads. + static int thr_continue (ACE_hthread_t target_thread); + static int thr_create (ACE_THR_FUNC, + void *args, + long flags, + ACE_thread_t *thr_id, + ACE_hthread_t *t_handle = 0, + u_int priority = 0, + void *stack = 0, + size_t stacksize = 0); + static int thr_cmp (ACE_hthread_t t1, ACE_hthread_t t2); + static int thr_equal (ACE_thread_t t1, ACE_thread_t t2); + static void thr_exit (void *status = 0); + static int thr_getconcurrency (void); + static int thr_getprio (ACE_hthread_t thr_id, int *prio); + static int thr_getspecific (ACE_thread_key_t key, void **data); + static int thr_join (ACE_hthread_t waiter_id, void **status); + static int thr_join (ACE_thread_t waiter_id, ACE_thread_t *thr_id, void **status); + static int thr_keyfree (ACE_thread_key_t key); + static int thr_key_detach (void *inst); + static int thr_keycreate (ACE_thread_key_t *key, void (*dest)(void *), void *inst = 0); + static int thr_key_used (ACE_thread_key_t key); + static int thr_kill (ACE_thread_t thr_id, int signum); + static size_t thr_min_stack (void); + static ACE_thread_t thr_self (void); + static void thr_self (ACE_hthread_t &); + static int thr_setconcurrency (int hint); + static int thr_setprio (ACE_hthread_t thr_id, int prio); + static int thr_setspecific (ACE_thread_key_t key, void *data); + static int thr_sigsetmask (int how, const sigset_t *nsm, sigset_t *osm); + static int thr_suspend (ACE_hthread_t target_thread); + static int thr_setcancelstate (int new_state, int *old_state); + static int thr_setcanceltype (int new_type, int *old_type); + static int thr_cancel (ACE_thread_t t_id); + static int sigwait (sigset_t *set, int *sig = 0); + static void thr_testcancel (void); + static void thr_yield (void); + + static ACE_thread_t NULL_thread; + // This is necessary to deal with POSIX pthreads insanity... + +#if defined (ACE_WIN32) + static int socket_initialized_; + // Keeps track of whether we've already initialized WinSock... +#endif /* ACE_WIN32 */ + +private: + ACE_OS (void); + // Ensure we can't define an instance of this class. + + static void mutex_lock_cleanup (void *lock); +}; + +#include "ace/Trace.h" + +#if defined (ACE_HAS_INLINED_OSCALLS) +#if defined (ACE_INLINE) +#undef ACE_INLINE +#endif /* ACE_INLINE */ +#define ACE_INLINE inline +#include "ace/OS.i" +#endif /* ACE_HAS_INLINED_OSCALLS */ + +#endif /* ACE_OS_H */ diff --git a/ace/OS.i b/ace/OS.i new file mode 100644 index 00000000000..2fcbad1847f --- /dev/null +++ b/ace/OS.i @@ -0,0 +1,5297 @@ +/* -*- C++ -*- */ +// $Id$ + +#if !defined (ACE_HAS_INLINED_OSCALLS) +#undef ACE_INLINE +#define ACE_INLINE +#endif /* ACE_HAS_INLINED_OSCALLS */ + +#if !defined (ACE_HAS_STRERROR) +#if defined (ACE_HAS_SYS_ERRLIST) +extern char *sys_errlist[]; +#define strerror(err) sys_errlist[err] +#else +#define strerror(err) "strerror is unsupported" +#endif /* ACE_HAS_SYS_ERRLIST */ +#endif /* !ACE_HAS_STERROR */ + +#if !defined (ACE_HAS_SYS_SIGLIST) +#if !defined (_sys_siglist) +#define _sys_siglist sis_siglist +#endif /* !defined (sys_siglist) */ +extern char **_sys_siglist; +#endif /* !ACE_HAS_SYS_SIGLIST */ + +#if defined (ACE_HAS_SIZET_SOCKET_LEN) +typedef size_t ACE_SOCKET_LEN; +#else +typedef int ACE_SOCKET_LEN; +#endif /* ACE_HAS_SIZET_SOCKET_LEN */ + +#if defined (ACE_HAS_VOIDPTR_SOCKOPT) +typedef void *ACE_SOCKOPT_TYPE1; +#elif defined (ACE_HAS_CHARPTR_SOCKOPT) +typedef char *ACE_SOCKOPT_TYPE1; +#else +typedef const char *ACE_SOCKOPT_TYPE1; +#endif /* ACE_HAS_VOIDPTR_SOCKOPT */ + +#if defined (ACE_NEEDS_WRITEV) +extern "C" int writev (ACE_HANDLE handle, ACE_WRITEV_TYPE *iov, int iovcnt); +#endif /* ACE_NEEDS_WRITEV */ + +#if defined (ACE_NEEDS_READV) +extern "C" ssize_t readv (ACE_HANDLE handle, struct iovec *iov, int iovcnt); +#endif /* ACE_NEEDS_READV */ + +#if defined (ACE_HAS_VOIDPTR_MMAP) +// Needed for some odd OS's (e.g., SGI). +typedef void *ACE_MMAP_TYPE; +#else +typedef char *ACE_MMAP_TYPE; +#endif /* ACE_HAS_VOIDPTR_MMAP */ + +#if defined (ACE_HAS_XLI) +#include +#endif /* ACE_HAS_XLI */ + +#if !defined (ACE_HAS_CPLUSPLUS_HEADERS) +#include +#include +#endif /* ACE_HAS_CPLUSPLUS_HEADERS */ + +#if defined (ACE_HAS_SYSENT_H) +#include +#endif /* ACE_HAS_SYSENT_H_*/ + +#if defined (ACE_HAS_SYS_FILIO_H) +#include +#endif /* ACE_HAS_SYS_FILIO_H */ + +#if defined (ACE_HAS_SVR4_GETTIMEOFDAY) +#if !defined (m88k) +extern "C" int gettimeofday (struct timeval *tp, void * = 0); +#else +extern "C" int gettimeofday (struct timeval *tp); +#endif // m88k +#elif defined (ACE_HAS_OSF1_GETTIMEOFDAY) +extern "C" int gettimeofday (struct timeval *tp, struct timezone * = 0); +#elif defined (ACE_HAS_SUNOS4_GETTIMEOFDAY) +#define ACE_HAS_SVR4_GETTIMEOFDAY +/* +#elif defined (ACE_HAS_IRIX_GETTIMEOFDAY) +extern "C" int gettimeofday (struct timeval *tp, ...); +#else +extern "C" int gettimeofday (struct timeval *tp); +*/ +#endif /* ACE_HAS_SVR4_GETTIMEOFDAY */ + +#if !defined (ACE_LACKS_MALLOC_H) +#include +#endif /* ACE_LACKS_MALLOC_H */ + +#if !defined (ACE_WIN32) + +#if !defined (ACE_LACKS_RPC_H) +#include +#endif /* ACE_LACKS_RPC_H */ + + +// Matthew Stevens 7-10-95 Fix GNU GCC 2.7 for memchr() problem. +#if !defined (ACE_HAS_GNU_CSTRING_H) + +#if defined (VXWORKS) +#include +#else +#include +#endif /* VXWORKS */ +#endif /* ACE_HAS_GNU_CSTRING_H */ + +// These prototypes are chronically lacking from many versions of +// UNIX. +extern "C" int t_getname (int, struct netbuf *, int); +extern "C" int isastream (int); +extern "C" int getrusage (int who, struct rusage *rusage); + +#if defined (ACE_LACKS_SYSCALL) +extern "C" int syscall (int, ACE_HANDLE, struct rusage *); +#endif /* ACE_LACKS_SYSCALL */ + +#if defined (ACE_LACKS_MKTEMP) +extern "C" char *mktemp (char *); +#endif /* ACE_LACKS_MKTEMP */ + +// The following are #defines and #includes that must be visible for +// ACE to compile it's OS wrapper class implementation correctly. We +// put them inside of here to reduce compiler overhead if we're not +// inlining... + +#if defined (ACE_HAS_REGEX) +#include +#endif /* ACE_HAS_REGEX */ + +#if defined (ACE_HAS_SYSINFO) +#include +#endif /* ACE_HAS_SYS_INFO */ + +#if defined (ACE_HAS_SYSCALL_H) +#include +#endif /* ACE_HAS_SYSCALL_H */ + +#if defined (UNIXWARE) // See strcasecmp, below +#include +#endif /* UNIXWARE */ + +// Adapt the weird threading and synchronization routines (which don't +// return -1 normally) so that they return -1 and work correctly with +// the ACE_OSCALL macros. +#if defined (VXWORKS) +#define ACE_ADAPT_RETVAL(OP,RESULT) ((RESULT = (OP)) != OK ? (errno = RESULT, -1) : 0) +#else +#define ACE_ADAPT_RETVAL(OP,RESULT) ((RESULT = (OP)) != 0 ? (errno = RESULT, -1) : 0) +#endif /* VXWORKS */ + +#if defined (SIGNAL_SAFE_OS_CALLS) +#include "ace/Log_Msg.h" +// The following two macros ensure that system calls are properly +// restarted (if necessary) when interrupts occur. +#define ACE_OSCALL(OP,TYPE,FAILVALUE,RESULT) \ + do \ + RESULT = (TYPE) OP; \ + while (RESULT == FAILVALUE && errno == EINTR && ACE_LOG_MSG->restart ()) +#define ACE_OSCALL_RETURN(OP,TYPE,FAILVALUE) \ + do { \ + TYPE _result; \ + do \ + _result = (TYPE) OP; \ + while (_result == FAILVALUE && errno == EINTR && ACE_LOG_MSG->restart ()); \ + return _result; \ + } while (0) +#else +#define ACE_OSCALL_RETURN(OP,TYPE,FAILVALUE) do { TYPE _result; return OP; } while (0) +#define ACE_OSCALL(OP,TYPE,FAILVALUE,RESULT) do { RESULT = (TYPE) OP; } while (0) +#endif /* SIGNAL_SAFE_OS_CALLS */ + +ACE_INLINE int +ACE_OS::chdir (const char *path) +{ +// ACE_TRACE ("ACE_OS::chdir"); +#if defined (VXWORKS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::chdir ((char *) path), _result), + int, ERROR); +#else + ACE_OSCALL_RETURN (::chdir (path), int, -1); +#endif /* VXWORKS */ +} + +ACE_INLINE int +ACE_OS::fcntl (ACE_HANDLE handle, int cmd, int value) +{ +// ACE_TRACE ("ACE_OS::fcntl"); +#if defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + ACE_OSCALL_RETURN (::fcntl (handle, cmd, value), int, -1); +#endif /* VXWORKS */ +} + +ACE_INLINE int +ACE_OS::fstat (ACE_HANDLE handle, struct stat *stp) +{ +// ACE_TRACE ("ACE_OS::fstat"); + ACE_OSCALL_RETURN (::fstat (handle, stp), int, -1); +} + +ACE_INLINE uid_t +ACE_OS::getgid (void) +{ +// ACE_TRACE ("ACE_OS::getgid"); +#if defined (VXWORKS) + // getgid() is not supported: just one group anyways + return 0; +#else + ACE_OSCALL_RETURN (::getgid (), uid_t, -1); +#endif /* VXWORKS */ +} + +ACE_INLINE int +ACE_OS::getopt (int argc, char *const *argv, const char *optstring) +{ +// ACE_TRACE ("ACE_OS::getopt"); +#if defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_LACKS_POSIX_PROTO) + ACE_OSCALL_RETURN (::getopt (argc, (const char* const *) argv, optstring), int, -1); +#else + ACE_OSCALL_RETURN (::getopt (argc, argv, optstring), int, -1); +#endif /* ACE_LACKS_POSIX_PROTO */ +} + +ACE_INLINE uid_t +ACE_OS::getuid (void) +{ +// ACE_TRACE ("ACE_OS::getuid"); +#if defined (VXWORKS) + // getuid() is not supported: just one user anyways + return 0; +#else + ACE_OSCALL_RETURN (::getuid (), uid_t, -1); +#endif /* VXWORKS */ +} + +ACE_INLINE int +ACE_OS::isatty (ACE_HANDLE fd) +{ +// ACE_TRACE ("ACE_OS::isatty"); + ACE_OSCALL_RETURN (::isatty (fd), int, -1); +} + +ACE_INLINE int +ACE_OS::mkfifo (const char *file, mode_t mode) +{ +// ACE_TRACE ("ACE_OS::mkfifo"); +#if defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + ACE_OSCALL_RETURN (::mkfifo (file, mode), int, -1); +#endif /* VXWORKS */ +} + +ACE_INLINE int +ACE_OS::pipe (ACE_HANDLE fds[]) +{ +// ACE_TRACE ("ACE_OS::pipe"); +#if defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + ACE_OSCALL_RETURN (::pipe (fds), int, -1); +#endif /* VXWORKS */ +} + +ACE_INLINE int +ACE_OS::rand_r (ACE_RANDR_TYPE seed) +{ +// ACE_TRACE ("ACE_OS::rand_r"); +#if defined (ACE_HAS_REENTRANT_FUNCTIONS) && defined (ACE_MT_SAFE) + ACE_OSCALL_RETURN (::rand_r (seed), int, -1); +#else + ACE_OSCALL_RETURN (::rand (), int, -1); +#endif +} + +ACE_INLINE void * +ACE_OS::sbrk (int brk) +{ +// ACE_TRACE ("ACE_OS::sbrk"); + +#if defined (VXWORKS) + ACE_NOTSUP_RETURN (0); +#else + ACE_OSCALL_RETURN (::sbrk (brk), void *, 0); +#endif /* VXWORKS */ +} + +ACE_INLINE pid_t +ACE_OS::setsid (void) +{ +// ACE_TRACE ("ACE_OS::setsid"); +#if defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + ACE_OSCALL_RETURN (::setsid (), int, -1); +#endif /* VXWORKS */ +} + +ACE_INLINE int +ACE_OS::sigaddset (sigset_t *s, int signum) +{ +// ACE_TRACE ("ACE_OS::sigaddset"); + ACE_OSCALL_RETURN (::sigaddset (s, signum), int, -1); +} + +ACE_INLINE int +ACE_OS::sigdelset (sigset_t *s, int signum) +{ +// ACE_TRACE ("ACE_OS::sigdelset"); + ACE_OSCALL_RETURN (::sigdelset (s, signum), int, -1); +} + +ACE_INLINE int +ACE_OS::sigemptyset (sigset_t *s) +{ +// ACE_TRACE ("ACE_OS::sigemptyset"); + ACE_OSCALL_RETURN (::sigemptyset (s), int, -1); +} + +ACE_INLINE int +ACE_OS::sigfillset (sigset_t *s) +{ +// ACE_TRACE ("ACE_OS::sigfillset"); + ACE_OSCALL_RETURN (::sigfillset (s), int, -1); +} + +ACE_INLINE int +ACE_OS::sigismember (sigset_t *s, int signum) +{ +// ACE_TRACE ("ACE_OS::sigismember"); + ACE_OSCALL_RETURN (::sigismember (s, signum), int, -1); +} + +ACE_INLINE int +ACE_OS::sigprocmask (int how, const sigset_t *nsp, sigset_t *osp) +{ +// ACE_TRACE ("ACE_OS::sigprocmask"); +#if defined (ACE_LACKS_POSIX_PROTO) + ACE_OSCALL_RETURN (::sigprocmask (how, (int*) nsp, osp), int, -1); +#else + ACE_OSCALL_RETURN (::sigprocmask (how, nsp, osp), int, -1); +#endif /* ACE_LACKS_POSIX_PROTO */ +} + +ACE_INLINE int +ACE_OS::strcasecmp (const char *s, const char *t) +{ +// ACE_TRACE ("ACE_OS::strcasecmp"); +#if defined (UNIXWARE) || defined (VXWORKS) + + // Handles most of what the BSD version does, but does not indicate + // lexicographic ordering if the strings are unequal. Just + // indicates equal (ignoring case) by return value == 0, else not + // equal. + int result = 0; + + while (*s != '\0' && *t != '\0') + { + if (tolower (*s) != tolower (*t)) + { + result = 1; + break; + } + ++s; ++t; + } + + return result; // == 0 for match, else 1 +#else + return ::strcasecmp (s, t); +#endif /* UNIXWARE || VXWORKS */ +} + +ACE_INLINE mode_t +ACE_OS::umask (mode_t cmask) +{ +// ACE_TRACE ("ACE_OS::umask"); +#if defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + ACE_OSCALL_RETURN (::umask (cmask), mode_t, -1); +#endif /* VXWORKS */ +} + +#else // ACE_WIN32 + +// This is for Win32 exclusively! + +// Adapt the Win32 System Calls (which return BOOLEAN values of TRUE +// and FALSE) into int values expected by the ACE_OSCALL macros. +#define ACE_ADAPT_RETVAL(OP,RESULT) ((RESULT = (OP)) == FALSE ? -1 : 0) + +// Perform a mapping of Win32 error numbers into POSIX errnos. +#define ACE_FAIL_RETURN(RESULT) do { \ + switch (errno = ::GetLastError ()) { \ + case ERROR_NOT_ENOUGH_MEMORY: errno = ENOMEM; break; \ + } \ + return RESULT; } while (0) +#define ACE_OSCALL_RETURN(X,TYPE,FAILVALUE) \ + do { \ + TYPE _result = (TYPE) X; \ + if (_result == FAILVALUE) \ + errno = ::GetLastError (); \ + return _result; \ + } while (0) +#define ACE_OSCALL(X,TYPE,FAILVALUE,RESULT) \ + do { \ + RESULT = (TYPE) X; \ + if (RESULT == FAILVALUE) \ + errno = ::GetLastError (); \ + } while (0) + +ACE_INLINE int +ACE_OS::chdir (const char *path) +{ +// ACE_TRACE ("ACE_OS::chdir"); + ACE_OSCALL_RETURN (::_chdir (path), int, -1); +} + +ACE_INLINE int +ACE_OS::strcasecmp (const char *s, const char *t) +{ +// ACE_TRACE ("ACE_OS::strcasecmp"); + ACE_NOTSUP_RETURN (0); +} + +ACE_INLINE int +ACE_OS::fcntl (ACE_HANDLE handle, int cmd, int value) +{ +// ACE_TRACE ("ACE_OS::fcntl"); + ACE_NOTSUP_RETURN (0); // We should be able to map this stuff +} + +ACE_INLINE uid_t +ACE_OS::getgid (void) +{ +// ACE_TRACE ("ACE_OS::getgid"); + ACE_NOTSUP_RETURN (-1); +} + +ACE_INLINE int +ACE_OS::getopt (int argc, char *const *argv, const char *optstring) +{ +// ACE_TRACE ("ACE_OS::getopt"); + ACE_NOTSUP_RETURN (-1); +} + +ACE_INLINE uid_t +ACE_OS::getuid (void) +{ +// ACE_TRACE ("ACE_OS::getuid"); + ACE_NOTSUP_RETURN (-1); +} + +ACE_INLINE int +ACE_OS::isatty (ACE_HANDLE fd) +{ +// ACE_TRACE ("ACE_OS::isatty"); + ACE_NOTSUP_RETURN (-1); +// ACE_OSCALL_RETURN (::_isatty (fd), int, -1); +} + +ACE_INLINE int +ACE_OS::mkfifo (const char *file, mode_t mode) +{ +// ACE_TRACE ("ACE_OS::mkfifo"); + ACE_NOTSUP_RETURN (-1); +} + +ACE_INLINE int +ACE_OS::pipe (ACE_HANDLE fds[]) +{ +// ACE_TRACE ("ACE_OS::pipe"); + ACE_NOTSUP_RETURN (-1); +// ACE_OSCALL_RETURN (::_pipe (fds, PIPE_BUF, 0), int, -1); // Use default mode +} + +ACE_INLINE int +ACE_OS::rand_r (ACE_RANDR_TYPE seed) +{ +// ACE_TRACE ("ACE_OS::rand_r"); + ACE_NOTSUP_RETURN (-1); +} + +ACE_INLINE void * +ACE_OS::sbrk (int brk) +{ +// ACE_TRACE ("ACE_OS::sbrk"); + ACE_NOTSUP_RETURN (0); +} + +ACE_INLINE pid_t +ACE_OS::setsid (void) +{ +// ACE_TRACE ("ACE_OS::setsid"); + ACE_NOTSUP_RETURN (0); +} + +ACE_INLINE int +ACE_OS::sigaddset (sigset_t *s, int signum) +{ +// ACE_TRACE ("ACE_OS::sigaddset"); + ACE_NOTSUP_RETURN (0); +} + +ACE_INLINE int +ACE_OS::sigdelset (sigset_t *s, int signum) +{ +// ACE_TRACE ("ACE_OS::sigdelset"); + ACE_NOTSUP_RETURN (0); +} + +ACE_INLINE int +ACE_OS::sigemptyset (sigset_t *s) +{ +// ACE_TRACE ("ACE_OS::sigemptyset"); + ACE_NOTSUP_RETURN (0); +} + +ACE_INLINE int +ACE_OS::sigfillset (sigset_t *s) +{ +// ACE_TRACE ("ACE_OS::sigfillset"); + ACE_NOTSUP_RETURN (0); +} + +ACE_INLINE int +ACE_OS::sigismember (sigset_t *s, int signum) +{ +// ACE_TRACE ("ACE_OS::sigismember"); + ACE_NOTSUP_RETURN (0); +} + +ACE_INLINE int +ACE_OS::sigprocmask (int how, const sigset_t *nsp, sigset_t *osp) +{ +// ACE_TRACE ("ACE_OS::sigprocmask"); + ACE_NOTSUP_RETURN (0); +} + +ACE_INLINE mode_t +ACE_OS::umask (mode_t cmask) +{ +// ACE_TRACE ("ACE_OS::umask"); + ACE_NOTSUP_RETURN (-1); +} + +ACE_INLINE int +ACE_OS::fstat (ACE_HANDLE handle, struct stat *stp) +{ +// ACE_TRACE ("ACE_OS::fstat"); + ACE_NOTSUP_RETURN (-1); +} + +#endif /* WIN32 */ + +ACE_INLINE time_t +ACE_OS::time (time_t *tloc) +{ +// ACE_TRACE ("ACE_OS::time"); + ACE_OSCALL_RETURN (::time (tloc), time_t, (time_t) -1); +} + +ACE_INLINE void +ACE_OS::srand (u_int seed) +{ +// ACE_TRACE ("ACE_OS::srand"); + ::srand (seed); +} + +ACE_INLINE int +ACE_OS::rand (void) +{ +// ACE_TRACE ("ACE_OS::rand"); + ACE_OSCALL_RETURN (::rand (), int, -1); +} + +ACE_INLINE int +ACE_OS::unlink (const char *path) +{ +// ACE_TRACE ("ACE_OS::unlink"); +#if defined (VXWORKS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::unlink ((char *) path), _result), + int, ERROR); +#else + ACE_OSCALL_RETURN (::unlink (path), int, -1); +#endif /* VXWORKS */ +} + +ACE_INLINE char * +ACE_OS::cuserid (char *user, size_t maxlen) +{ +// ACE_TRACE ("ACE_OS::cuserid"); +#if defined (VXWORKS) + ACE_NOTSUP_RETURN (0); +#elif defined (ACE_WIN32) + // Hackish because of missing buffer size! + return ::GetUserName (user, (unsigned long *) &maxlen) ? user : 0; +#else + ACE_OSCALL_RETURN (::cuserid (user), char *, 0); +#endif /* VXWORKS */ +} + +// Doesn't need a macro since it *never* returns! + +ACE_INLINE void +ACE_OS::_exit (int status) +{ +// ACE_TRACE ("ACE_OS::_exit"); +#if defined (VXWORKS) + ::exit (status); +#else + ::_exit (status); +#endif /* VXWORKS */ +} + +ACE_INLINE int +ACE_OS::memcmp (const void *s, const void *t, size_t len) +{ +// ACE_TRACE ("ACE_OS::memcmp"); + return ::memcmp (s, t, len); +} + +ACE_INLINE void * +ACE_OS::memcpy (void *s, const void *t, size_t len) +{ +// ACE_TRACE ("ACE_OS::memcpy"); + return ::memcpy (s, t, len); +} + +ACE_INLINE void * +ACE_OS::memset (void *s, int c, size_t len) +{ +// ACE_TRACE ("ACE_OS::memset"); + return ::memset (s, c, len); +} + +ACE_INLINE long +ACE_OS::sysconf (int name) +{ +// ACE_TRACE ("ACE_OS::sysconf"); +#if defined (ACE_WIN32) || defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + ACE_OSCALL_RETURN (::sysconf (name), long, -1); +#endif /* ACE_WIN32 || VXWORKS */ +} + +ACE_INLINE int +ACE_OS::mutex_init (ACE_mutex_t *m, + int type, + LPCTSTR name, + void *arg) +{ +// ACE_TRACE ("ACE_OS::mutex_init"); + +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || defined(ACE_HAS_PTHREADS) + pthread_mutexattr_t attributes; + int result = -1; + +#if defined (ACE_HAS_SETKIND_NP) +#if defined (ACE_HAS_PTHREAD_ATTR_INIT) + if (::pthread_mutexattr_init (&attributes) == 0 + && ::pthread_mutexattr_setkind_np (&attributes, type) == 0 + && ::pthread_mutex_init (m, &attributes) == 0) +#else + if (::pthread_mutexattr_create (&attributes) == 0 + && ::pthread_mutexattr_setkind_np (&attributes, type) == 0 + && ::pthread_mutex_init (m, attributes) == 0) +#endif /* ACE_HAS_PTHREAD_ATTR_INIT */ +#else + if (::pthread_mutexattr_init (&attributes) == 0 + && ::pthread_mutex_init (m, &attributes) == 0) +#endif /* ACE_HAS_SETKIND_NP */ + result = 0; + +#if defined (ACE_HAS_SETKIND_NP) +#if defined (ACE_HAS_PTHREAD_ATTR_DESTROY) + ::pthread_mutexattr_destroy (&attributes); +#else + ::pthread_mutexattr_delete (&attributes); +#endif /* ACE_HAS_PTHREAD_ATTR_DESTROY */ +#else + ::pthread_mutexattr_destroy (&attributes); +#endif /* ACE_HAS_SETKIND_NP */ + + return result; +#elif defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mutex_init (m, type, arg), + _result), + int, -1); +#elif defined (ACE_HAS_WTHREADS) + m->type_ = type; + + switch (type) + { + case USYNC_PROCESS: + m->proc_mutex_ = ::CreateMutex (NULL, FALSE, name); + if (m->proc_mutex_ == 0) + ACE_FAIL_RETURN (-1); + else + return 0; + case USYNC_THREAD: + return ACE_OS::thread_mutex_init (&m->thr_mutex_, type, name, arg); + default: + errno = EINVAL; + return -1; + } + /* NOTREACHED */ +#elif defined (VXWORKS) + // Type includes these options: SEM_Q_PRIORITY, SEM_Q_FIFO, SEM_DELETE_SAFE, + // and SEM_INVERSION_SAFE that are currently outside of the ACE mutex model. + return (*m = ::semMCreate (type)) == NULL ? -1 : 0; +#endif /* ACE_HAS_DCETHREADS || ACE_HAS_PTHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::mutex_destroy (ACE_mutex_t *m) +{ +// ACE_TRACE ("ACE_OS::mutex_destroy"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_mutex_destroy (m), _result), int, -1); +#elif defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mutex_destroy (m), _result), int, -1); +#elif defined (ACE_HAS_WTHREADS) + switch (m->type_) + { + case USYNC_PROCESS: + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::CloseHandle (m->proc_mutex_), + _result), + int, -1); + case USYNC_THREAD: + return ACE_OS::thread_mutex_destroy (&m->thr_mutex_); + default: + errno = EINVAL; + return -1; + } + /* NOTREACHED */ +#elif defined (VXWORKS) + return ::semDelete (*m) == OK ? 0 : -1; +#endif /* ACE_HAS_DCETHREADS || ACE_HAS_PTHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::mutex_lock (ACE_mutex_t *m) +{ +// ACE_TRACE ("ACE_OS::mutex_lock"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_mutex_lock (m), _result), int, -1); +#elif defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mutex_lock (m), _result), int, -1); +#elif defined (ACE_HAS_WTHREADS) + switch (m->type_) + { + case USYNC_PROCESS: + // Timeout can't occur, so don't bother checking... + if (::WaitForSingleObject(m->proc_mutex_, INFINITE) == WAIT_OBJECT_0) + return 0; + else + // This is a hack, we need to find an appropriate mapping... + ACE_FAIL_RETURN (-1); + case USYNC_THREAD: + return ACE_OS::thread_mutex_lock (&m->thr_mutex_); + default: + errno = EINVAL; + return -1; + } + /* NOTREACHED */ +#elif defined (VXWORKS) + return ::semTake (*m, WAIT_FOREVER) == OK ? 0 : -1; +#endif /* ACE_HAS_DCETHREADS || ACE_HAS_PTHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::mutex_trylock (ACE_mutex_t *m) +{ +// ACE_TRACE ("ACE_OS::mutex_trylock"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_mutex_trylock (m), _result), int, -1); +#elif defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mutex_trylock (m), _result), int, -1); +#elif defined (ACE_HAS_WTHREADS) + switch (m->type_) + { + case USYNC_PROCESS: + { + // Try for 0 milliseconds - i.e. nonblocking. + DWORD result = ::WaitForSingleObject(m->proc_mutex_, 0); + + if (result == WAIT_OBJECT_0) + return 0; + else + { + errno = result == WAIT_TIMEOUT ? ETIME : ::GetLastError (); + // This is a hack, we need to find an appropriate mapping... + return -1; + } + } + case USYNC_THREAD: + return ACE_OS::thread_mutex_trylock (&m->thr_mutex_); + default: + errno = EINVAL; + return -1; + } + /* NOTREACHED */ +#elif defined (VXWORKS) + if ( ::semTake (*m, NO_WAIT) == ERROR ) + if ( errno == S_objLib_OBJ_TIMEOUT ) + // couldn't get the semaphore + return 1; + else + // error + return -1; + else + // got the semaphore + return 0; +#endif /* ACE_HAS_DCETHREADS || ACE_HAS_PTHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::mutex_unlock (ACE_mutex_t *m) +{ +// ACE_TRACE ("ACE_OS::mutex_unlock"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_mutex_unlock (m), _result), int, -1); +#elif defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mutex_unlock (m), _result), int, -1); +#elif defined (ACE_HAS_WTHREADS) + switch (m->type_) + { + case USYNC_PROCESS: + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::ReleaseMutex (m->proc_mutex_), + _result), + int, -1); + case USYNC_THREAD: + return ACE_OS::thread_mutex_unlock (&m->thr_mutex_); + default: + errno = EINVAL; + return -1; + } + /* NOTREACHED */ +#elif defined (VXWORKS) + return ::semGive (*m) == OK ? 0 : -1; +#endif /* ACE_HAS_DCETHREADS || ACE_HAS_PTHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::thread_mutex_init (ACE_thread_mutex_t *m, + int type, + LPCTSTR name, + void *arg) +{ + // ACE_TRACE ("ACE_OS::thread_mutex_init"); + +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) || defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + // Force the use of USYNC_THREAD! + return ACE_OS::mutex_init (m, USYNC_THREAD, name, arg); +#elif defined (ACE_HAS_WTHREADS) + ::InitializeCriticalSection (m); + return 0; +#elif defined (VXWORKS) + return mutex_init (m, type, name, arg); +#endif /* ACE_HAS_STHREADS || ACE_HAS_DCETHREADS || ACE_HAS_PTHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::thread_mutex_destroy (ACE_thread_mutex_t *m) +{ +// ACE_TRACE ("ACE_OS::thread_mutex_destroy"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) || defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + return ACE_OS::mutex_destroy (m); +#elif defined (ACE_HAS_WTHREADS) + ::DeleteCriticalSection (m); + return 0; +#elif defined (VXWORKS) + return mutex_destroy (m); +#endif /* ACE_HAS_STHREADS || ACE_HAS_DCETHREADS || ACE_HAS_PTHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::thread_mutex_lock (ACE_thread_mutex_t *m) +{ +// ACE_TRACE ("ACE_OS::thread_mutex_lock"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) || defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + return ACE_OS::mutex_lock (m); +#elif defined (ACE_HAS_WTHREADS) + ::EnterCriticalSection (m); + return 0; +#elif defined (VXWORKS) + return mutex_lock (m); +#endif /* ACE_HAS_STHREADS || ACE_HAS_DCETHREADS || ACE_HAS_PTHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::thread_mutex_trylock (ACE_thread_mutex_t *m) +{ +// ACE_TRACE ("ACE_OS::thread_mutex_trylock"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) || defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + return ACE_OS::mutex_trylock (m); +#elif defined (ACE_HAS_WTHREADS) +#if defined (ACE_HAS_WIN32_TRYLOCK) + ::TryEnterCriticalSection (m); + return 0; +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_WIN32_TRYLOCK */ +#elif defined (VXWORKS) + return mutex_trylock (m); +#endif /* ACE_HAS_STHREADS || ACE_HAS_DCETHREADS || ACE_HAS_PTHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::thread_mutex_unlock (ACE_thread_mutex_t *m) +{ +// ACE_TRACE ("ACE_OS::thread_mutex_unlock"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) || defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + return ACE_OS::mutex_unlock (m); +#elif defined (ACE_HAS_WTHREADS) + ::LeaveCriticalSection (m); + return 0; +#elif defined (VXWORKS) + return mutex_unlock (m); +#endif /* ACE_HAS_STHREADS || ACE_HAS_DCETHREADS || ACE_HAS_PTHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::cond_broadcast (ACE_cond_t *cv) +{ +// ACE_TRACE ("ACE_OS::cond_broadcast"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_cond_broadcast (cv), + _result), + int, -1); +#elif defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_broadcast (cv), + _result), + int, -1); +#elif defined (ACE_HAS_WTHREADS) || defined (VXWORKS) + int result = 0; + int error = 0; + + for (int i = cv->waiters_; i > 0; i--) + if (ACE_OS::sema_post (&cv->sema_) != 0) + { + error = errno; + result = -1; + break; + } + + errno = error; + return result; +#endif /* ACE_HAS_STHREADS */ +#else + cv = cv; + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::cond_destroy (ACE_cond_t *cv) +{ +// ACE_TRACE ("ACE_OS::cond_destroy"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_cond_destroy (cv), _result), int, -1); +#elif defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_destroy (cv), _result), int, -1); +#elif defined (ACE_HAS_WTHREADS) || defined (VXWORKS) + return ACE_OS::sema_destroy (&cv->sema_); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::cond_init (ACE_cond_t *cv, int type, LPCTSTR name, void *arg) +{ +// ACE_TRACE ("ACE_OS::cond_init"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + pthread_condattr_t attributes; + int result = -1; + +#if defined (ACE_HAS_SETKIND_NP) +#if defined (ACE_HAS_PTHREAD_ATTR_INIT) + if (::pthread_condattr_init (&attributes) == 0 + && ::pthread_cond_init (cv, &attributes) == 0 +#else + if (::pthread_condattr_create (&attributes) == 0 + && ::pthread_cond_init (cv, attributes) == 0 +#endif /* ACE_HAS_PTHREAD_ATTR_INIT */ +#else + if (::pthread_condattr_init (&attributes) == 0 + && ::pthread_cond_init (cv, &attributes) == 0 +#endif /* ACE_HAS_SETKIND_NP */ +#if !defined (ACE_LACKS_CONDATTR_PSHARED) + && ::pthread_condattr_setpshared (&attributes, type) == 0 +#endif /* ACE_LACKS_CONDATTR_PSHARED */ + ) + result = 0; + +#if defined (ACE_HAS_SETKIND_NP) +#if defined (ACE_HAS_PTHREAD_ATTR_DESTROY) + ::pthread_condattr_destroy (&attributes); +#else + ::pthread_condattr_delete (&attributes); +#endif /* ACE_HAS_PTHREAD_ATTR_DESTROY */ +#else + ::pthread_condattr_destroy (&attributes); +#endif /* ACE_HAS_SETKIND_NP */ + + return result; +#elif defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_init (cv, type, arg), + _result), + int, -1); +#elif defined (ACE_HAS_WTHREADS) || defined (VXWORKS) + cv->waiters_ = 0; + + return ACE_OS::sema_init (&cv->sema_, 0, type, name, arg); +#endif /* ACE_HAS_STHREADS */ +#else + cv = cv; + type = type; + name = name; + arg = arg; + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::cond_signal (ACE_cond_t *cv) +{ +// ACE_TRACE ("ACE_OS::cond_signal"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_cond_signal (cv), _result), int, -1); +#elif defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_signal (cv), _result), int, -1); +#elif defined (ACE_HAS_WTHREADS) || defined (VXWORKS) + // If there aren't any waiters, then this is a no-op. Note that + // this function *must* be called with the held + // since other wise there is a race condition that can lead to the + // lost wakeup bug... + if (cv->waiters_ > 0) + return ACE_OS::sema_post (&cv->sema_); + else + return 0; +#endif /* ACE_HAS_STHREADS */ +#else + cv = cv; + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::cond_timedwait (ACE_cond_t *cv, + ACE_mutex_t *external_mutex, + ACE_Time_Value *timeout) +{ +// ACE_TRACE ("ACE_OS::cond_timedwait"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_WTHREADS) + // Note that it is ok to increment this because the + // is locked! + cv->waiters_++; + + if (ACE_OS::mutex_unlock (external_mutex) != 0) + return -1; + + DWORD result; + + if (timeout == 0) + // Wait forever. + result = ::WaitForSingleObject (cv->sema_, INFINITE); + else if (timeout->sec () == 0 && timeout->usec () == 0) + // Do a "poll". + result = ::WaitForSingleObject (cv->sema_, 0); + else + { + // Wait for upto number of milliseconds. Note + // that we must convert between absolute time (which is passed + // as a parameter) and relative time (which is what + // WaitForSingleObjects() expects). + ACE_Time_Value relative_time (*timeout - ACE_OS::gettimeofday ()); + result = ::WaitForSingleObject (cv->sema_, relative_time.msec ()); + } + + ACE_OS::mutex_lock (external_mutex); + + cv->waiters_--; + + if (result == WAIT_OBJECT_0) + return 0; + else + { + errno = result == WAIT_TIMEOUT ? ETIME : ::GetLastError (); + // This is a hack, we need to find an appropriate mapping... + return -1; + } + +#elif defined (VXWORKS) + // POSIX semaphores don't have a timed wait. Should implement conds with + // VxWorks semaphores instead, they do have a timed wait. But all of the + // other cond operations would have to be modified. + ACE_NOTSUP_RETURN (-1); + +#else /* PTHREADS or STHREADS or DCETHREADS */ + int result; + timestruc_t ts = *timeout; // Calls ACE_Time_Value::operator timestruc_t(). +#if (defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS)) && !defined (ACE_HAS_FSU_PTHREADS) + ACE_OSCALL (ACE_ADAPT_RETVAL ((timeout == 0 + ? ::pthread_cond_wait (cv, external_mutex) + : ::pthread_cond_timedwait (cv, external_mutex, +#if defined (HPUX) // They forgot a const in the system prototype... + (struct timespec *) &ts)), +#else + (const struct timespec *) &ts)), +#endif /* HPUX */ + result), + int, -1, result); + // We need to adjust this to make the POSIX and Solaris return + // values consistent. + if (result == -1 && errno == ETIMEDOUT) + errno = ETIME; +#elif defined (ACE_HAS_STHREADS) + ACE_OSCALL (ACE_ADAPT_RETVAL ((timeout == 0 + ? ::cond_wait (cv, external_mutex) + : ::cond_timedwait (cv, external_mutex, &ts)), result), + int, -1, result); +#endif /* ACE_HAS_STHREADS */ + timeout->set (ts); // Update the time value before returning. + return result; +#endif /* ACE_HAS_WTHREADS */ +#else + cv = cv; + external_mutex = external_mutex; + timeout = timeout; + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::cond_wait (ACE_cond_t *cv, + ACE_mutex_t *external_mutex) +{ +// ACE_TRACE ("ACE_OS::cond_wait"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_cond_wait (cv, external_mutex), _result), + int, -1); +#elif defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_wait (cv, external_mutex), _result), + int, -1); +#elif defined (ACE_HAS_WTHREADS) || defined (VXWORKS) + // Note that it is ok to increment this because the + // is locked. + cv->waiters_++; + + if (ACE_OS::mutex_unlock (external_mutex) != 0) + return -1; + + int result = 0; + int error = 0; + + if (ACE_OS::sema_wait (&cv->sema_) != 0) + { + result = -1; + error = errno; + } + + // We must always regain the mutex, even when errors occur so that + // we can atomically decrement the count of the waiters. + ACE_OS::mutex_lock (external_mutex); + + // By making the waiter responsible for decrementing its count we + // don't have to worry about having an internal mutex. Thanks to + // Karlheinz for recognizing this optimization. + cv->waiters_--; + + // Reset errno in case mutex_lock() also fails... + errno = error; + return result; +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +#if defined (ACE_WIN32) +ACE_INLINE int +ACE_OS::cond_timedwait (ACE_cond_t *cv, + ACE_thread_mutex_t *external_mutex, + ACE_Time_Value *timeout) +{ +// ACE_TRACE ("ACE_OS::cond_timedwait"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_WTHREADS) + cv->waiters_++; + + if (ACE_OS::thread_mutex_unlock (external_mutex) != 0) + return -1; + + DWORD result; + + if (timeout == 0) + // Wait forever. + result = ::WaitForSingleObject (cv->sema_, INFINITE); + else if (timeout->sec () == 0 && timeout->usec () == 0) + // Do a "poll". + result = ::WaitForSingleObject (cv->sema_, 0); + else + { + // Wait for upto number of milliseconds. Note + // that we must convert between absolute time (which is passed + // as a parameter) and relative time (which is what + // WaitForSingleObjects() expects). + ACE_Time_Value relative_time (*timeout - ACE_OS::gettimeofday ()); + result = ::WaitForSingleObject (cv->sema_, relative_time.msec ()); + } + + ACE_OS::thread_mutex_lock (external_mutex); + + cv->waiters_--; + + if (result == WAIT_OBJECT_0) + return 0; + else + { + errno = result == WAIT_TIMEOUT ? ETIME : ::GetLastError (); + // This is a hack, we need to find an appropriate mapping... + return -1; + } +#endif /* ACE_HAS_WTHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::cond_wait (ACE_cond_t *cv, + ACE_thread_mutex_t *external_mutex) +{ +// ACE_TRACE ("ACE_OS::cond_wait"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_WTHREADS) + cv->waiters_++; + + if (ACE_OS::thread_mutex_unlock (external_mutex) != 0) + return -1; + + int result = 0; + int error = 0; + + if (ACE_OS::sema_wait (&cv->sema_) != 0) + { + result = -1; + error = errno; + } + + // We must always regain the mutex, even when errors occur. + ACE_OS::thread_mutex_lock (external_mutex); + + cv->waiters_--; + + // Reset errno in case mutex_lock() also fails... + errno = error; + return result; + +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} +#endif /* ACE_WIN32 */ + +ACE_INLINE int +ACE_OS::rw_rdlock (ACE_rwlock_t *rw) +{ +// ACE_TRACE ("ACE_OS::rw_rdlock"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_rdlock (rw), _result), int, -1); +#else // NT, POSIX, and VxWorks don't support this natively. +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + pthread_cleanup_push (ACE_OS::mutex_lock_cleanup, (void *) &rw->lock_); +#endif /* ACE_HAS_DCETHREADS */ + int result = 0; + if (ACE_OS::mutex_lock (&rw->lock_) == -1) + result = -1; // -1 means didn't get the mutex. + else + { + // Give preference to writers who are waiting. + while (rw->ref_count_ < 0 || rw->num_waiting_writers_ > 0) + { + rw->num_waiting_readers_++; + if (ACE_OS::cond_wait (&rw->waiting_readers_, &rw->lock_) == -1) + { + result = -2; // -2 means that we need to release the mutex. + break; + } + rw->num_waiting_readers_--; + } + } + if (result == 0) + rw->ref_count_++; + if (result != -1) + ACE_OS::mutex_unlock (&rw->lock_); +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + pthread_cleanup_pop (0); +#endif + return 0; +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::rw_tryrdlock (ACE_rwlock_t *rw) +{ +// ACE_TRACE ("ACE_OS::rw_tryrdlock"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_tryrdlock (rw), _result), int, -1); +#else // NT, POSIX, and VxWorks don't support this natively. + int result = -1; + + if (ACE_OS::mutex_lock (&rw->lock_) != -1) + { + int error = 0; + + if (rw->ref_count_ == -1 || rw->num_waiting_writers_ > 0) + { + error = EBUSY; + result = -1; + } + else + { + rw->ref_count_++; + result = 0; + } + + ACE_OS::mutex_unlock (&rw->lock_); + errno = error; + } + return result; +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::rw_trywrlock (ACE_rwlock_t *rw) +{ +// ACE_TRACE ("ACE_OS::rw_trywrlock"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_trywrlock (rw), _result), int, -1); +#else // NT, POSIX, and VxWorks don't support this natively. + int result = -1; + + if (ACE_OS::mutex_lock (&rw->lock_) != -1) + { + int error = 0; + + if (rw->ref_count_ != 0) + { + error = EBUSY; + result = -1; + } + else + { + rw->ref_count_ = -1; + result = 0; + } + + ACE_OS::mutex_unlock (&rw->lock_); + errno = error; + } + return result; +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::rw_unlock (ACE_rwlock_t *rw) +{ +// ACE_TRACE ("ACE_OS::rw_unlock"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_unlock (rw), _result), int, -1); +#else // NT, POSIX, and VxWorks don't support this natively. + if (ACE_OS::mutex_lock (&rw->lock_) == -1) + return -1; + + if (rw->ref_count_ > 0) // Releasing a reader. + rw->ref_count_--; + else if (rw->ref_count_ == -1) // Releasing a writer. + rw->ref_count_ = 0; + else + assert (!"count should not be 0!\n"); + + int result; + int error = 0; + + // Give preference to writers over readers... + if (rw->num_waiting_writers_ > 0) + { + result = ACE_OS::cond_signal (&rw->waiting_writers_); + error = errno; + } + else if (rw->num_waiting_readers_ > 0) + { + result = ACE_OS::cond_broadcast (&rw->waiting_readers_); + error = errno; + } + else + result = 0; + + ACE_OS::mutex_unlock (&rw->lock_); + errno = error; + return result; +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::rw_wrlock (ACE_rwlock_t *rw) +{ +// ACE_TRACE ("ACE_OS::rw_wrlock"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_wrlock (rw), _result), int, -1); +#else // NT, POSIX, and VxWorks don't support this natively. +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + pthread_cleanup_push (ACE_OS::mutex_lock_cleanup, (void *) &rw->lock_); +#endif + int result = 0; + if (ACE_OS::mutex_lock (&rw->lock_) == -1) + result = -1; // -1 means didn't get the mutex. + else + { + while (rw->ref_count_ != 0) + { + rw->num_waiting_writers_++; + + if (ACE_OS::cond_wait (&rw->waiting_writers_, &rw->lock_) == -1) + { + result = -2; // -2 means we need to release the mutex. + break; + } + + rw->num_waiting_writers_--; + } + } + if (result == 0) + rw->ref_count_ = -1; + if (result != -1) + ACE_OS::mutex_unlock (&rw->lock_); +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + pthread_cleanup_pop (0); +#endif + return 0; +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::rwlock_init (ACE_rwlock_t *rw, + int type, + LPCTSTR name, + void *arg) +{ +// ACE_TRACE ("ACE_OS::rwlock_init"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rwlock_init (rw, type, arg), _result), int, -1); +#else // NT, POSIX, and VxWorks don't support this natively. + int result = -1; + + if (ACE_OS::mutex_init (&rw->lock_, type, name, arg) == 0 + && ACE_OS::cond_init (&rw->waiting_readers_, type, name, arg) == 0 + && ACE_OS::cond_init (&rw->waiting_writers_, type, name, arg) == 0) + { + // Success! + rw->ref_count_ = 0; + rw->num_waiting_writers_ = 0; + rw->num_waiting_readers_ = 0; + + result = 0; + } + + if (result == -1) + { + int error = errno; + ACE_OS::mutex_destroy (&rw->lock_); + ACE_OS::cond_destroy (&rw->waiting_readers_); + ACE_OS::cond_destroy (&rw->waiting_writers_); + errno = error; + } + return result; +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::rwlock_destroy (ACE_rwlock_t *rw) +{ +// ACE_TRACE ("ACE_OS::rwlock_destroy"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rwlock_destroy (rw), _result), int, -1); +#else // NT, POSIX, and VxWorks don't support this natively. + ACE_OS::mutex_destroy (&rw->lock_); + ACE_OS::cond_destroy (&rw->waiting_readers_); + return ACE_OS::cond_destroy (&rw->waiting_writers_); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::event_init (ACE_event_t *event, + int manual_reset, + int initial_state, + int type, + LPCTSTR name, + void *arg) +{ +#if defined (ACE_WIN32) + *event = ::CreateEvent (0, // no security attributes + manual_reset, + initial_state, + name); + if (*event == NULL) + ACE_FAIL_RETURN (-1); + else + return 0; +#elif defined (ACE_HAS_THREADS) + event->manual_reset_ = manual_reset; + event->is_signaled_ = initial_state; + event->waiting_threads_ = 0; + + int result = ACE_OS::cond_init (&event->condition_, + type, + name, + arg); + if (result == 0) + result = ACE_OS::mutex_init (&event->lock_, + type, + name, + arg); + return result; +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::event_destroy (ACE_event_t *event) +{ +#if defined (ACE_WIN32) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::CloseHandle (*event), _result), int, -1); +#elif defined (ACE_HAS_THREADS) + int r1 = ACE_OS::mutex_destroy (&event->lock_); + int r2 = ACE_OS::cond_destroy (&event->condition_); + return r1 != 0 || r2 != 0 ? -1 : 0; +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::event_wait (ACE_event_t *event) +{ +#if defined (ACE_WIN32) + if (::WaitForSingleObject (*event, INFINITE) == WAIT_OBJECT_0) + return 0; + else + ACE_FAIL_RETURN (-1); +#elif defined (ACE_HAS_THREADS) + int wait_failed = 0; + int result = 0; + int error = 0; + + // grab the lock first + if (ACE_OS::mutex_lock (&event->lock_) != 0) + return -1; + + if (event->is_signaled_ == 1) + // event is currently signaled + { + if (event->manual_reset_ == 0) + // AUTO: reset state + event->is_signaled_ = 0; + } + else + // event is currently not signaled + { + event->waiting_threads_++; + + if (ACE_OS::cond_wait (&event->condition_, + &event->lock_) != 0) + { + wait_failed = 1; + error = errno; + } + event->waiting_threads_--; + } + + // now we can let go of the lock + result = ACE_OS::mutex_unlock (&event->lock_); + + if (wait_failed) + { + // Reset errno in case mutex_unlock() also fails... + errno = error; + return -1; + } + else + return result; + +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_WIN32 */ + +} + +ACE_INLINE int +ACE_OS::event_timedwait (ACE_event_t *event, + ACE_Time_Value *timeout) +{ +#if defined (ACE_WIN32) + DWORD result; + + if (timeout == 0) + // Wait forever + result = ::WaitForSingleObject (*event, INFINITE); + else if (timeout->sec () == 0 && timeout->usec () == 0) + // Do a "poll". + result = ::WaitForSingleObject (*event, 0); + else + { + // Wait for upto number of milliseconds. Note + // that we must convert between absolute time (which is passed + // as a parameter) and relative time (which is what + // WaitForSingleObjects() expects). + ACE_Time_Value relative_time (*timeout - ACE_OS::gettimeofday ()); + result = ::WaitForSingleObject (*event, relative_time.msec ()); + } + if (result == WAIT_OBJECT_0) + return 0; + else + { + errno = result == WAIT_TIMEOUT ? ETIME : ::GetLastError (); + // This is a hack, we need to find an appropriate mapping... + return -1; + } +#elif defined (ACE_HAS_THREADS) + int wait_failed = 0; + int result = 0; + int error = 0; + + // grab the lock first + if (ACE_OS::mutex_lock (&event->lock_) != 0) + return -1; + + if (event->is_signaled_ == 1) + // event is currently signaled + { + if (event->manual_reset_ == 0) + // AUTO: reset state + event->is_signaled_ = 0; + } + else + // event is currently not signaled + { + event->waiting_threads_++; + + if (ACE_OS::cond_timedwait (&event->condition_, + &event->lock_, + timeout) != 0) + { + wait_failed = 1; + error = errno; + } + event->waiting_threads_--; + } + + // now we can let go of the lock + result = ACE_OS::mutex_unlock (&event->lock_); + + if (wait_failed) + { + // Reset errno in case mutex_unlock() also fails... + errno = error; + return -1; + } + else + return result; + +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::event_signal (ACE_event_t *event) +{ +#if defined (ACE_WIN32) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::SetEvent (*event), _result), int, -1); +#elif defined (ACE_HAS_THREADS) + int result = 0; + int wakeup_failed = 0; + int error = 0; + + // grab the lock first + if (ACE_OS::mutex_lock (&event->lock_) != 0) + return -1; + + // Manual-reset event. + if (event->manual_reset_ == 1) + { + // signal event + event->is_signaled_ = 1; + // wakeup all + if (ACE_OS::cond_broadcast (&event->condition_) != 0) + { + wakeup_failed = 1; + error = errno; + } + } + // Auto-reset event + else + { + if (event->waiting_threads_ == 0) + // No waiters: signal event. + event->is_signaled_ = 1; + + // Waiters: wakeup one waiter. + else if (ACE_OS::cond_signal (&event->condition_) != 0) + { + wakeup_failed = 1; + error = errno; + } + } + + // Now we can let go of the lock. + result = ACE_OS::mutex_unlock (&event->lock_); + + if (wakeup_failed) + { + // Reset errno in case mutex_unlock() also fails... + errno = error; + return -1; + } + else + return result; +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::event_pulse (ACE_event_t *event) +{ +#if defined (ACE_WIN32) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::PulseEvent (*event), _result), int, -1); +#elif defined (ACE_HAS_THREADS) + int result = 0; + int wakeup_failed = 0; + int error = 0; + + // grab the lock first + if (ACE_OS::mutex_lock (&event->lock_) != 0) + return -1; + + // Manual-reset event. + if (event->manual_reset_ == 1) + { + // Wakeup all waiters. + if (ACE_OS::cond_broadcast (&event->condition_) != 0) + { + wakeup_failed = 1; + error = errno; + } + } + // Auto-reset event: wakeup one waiter. + else if (ACE_OS::cond_signal (&event->condition_) != 0) + { + wakeup_failed = 1; + error = errno; + } + + // Reset event. + event->is_signaled_ = 0; + + // Now we can let go of the lock. + result = ACE_OS::mutex_unlock (&event->lock_); + + if (wakeup_failed) + { + // Reset errno in case mutex_unlock() also fails... + errno = error; + return -1; + } + else + return result; +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::event_reset (ACE_event_t *event) +{ +#if defined (ACE_WIN32) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::ResetEvent (*event), _result), int, -1); +#elif defined (ACE_HAS_THREADS) + // Grab the lock first. + if (ACE_OS::mutex_lock (&event->lock_) != 0) + return -1; + + // Reset event. + event->is_signaled_ = 0; + + // Now we can let go of the lock. + return ACE_OS::mutex_unlock (&event->lock_); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_WIN32 */ +} + +#if defined (ACE_WIN32) +#define ACE_SOCKCALL_RETURN(OP,TYPE,FAILVALUE) \ + do { TYPE _result = (TYPE) OP; \ + if ((ACE_SOCKET) _result == SOCKET_ERROR) { errno = ::WSAGetLastError (); return (TYPE) FAILVALUE; } else return _result; \ + } while (0) +#else +#define ACE_SOCKCALL_RETURN(OP,TYPE,FAILVALUE) ACE_OSCALL_RETURN(OP,TYPE,FAILVALUE) +#endif /* ACE_WIN32 */ + +ACE_INLINE char * +ACE_OS::strcat (char *s, const char *t) +{ +// ACE_TRACE ("ACE_OS::strcat"); + return ::strcat (s, t); +} + +ACE_INLINE char * +ACE_OS::strstr (const char *s, const char *t) +{ +// ACE_TRACE ("ACE_OS::strstr"); + return ::strstr (s, t); +} + +ACE_INLINE size_t +ACE_OS::strspn (const char *s, const char *t) +{ +// ACE_TRACE ("ACE_OS::strstr"); + return ::strspn (s, t); +} + +ACE_INLINE char * +ACE_OS::strchr (const char *s, int c) +{ +// ACE_TRACE ("ACE_OS::strchr"); + return ::strchr (s, c); +} + +ACE_INLINE char * +ACE_OS::strrchr (const char *s, int c) +{ +// ACE_TRACE ("ACE_OS::strrchr"); + return ::strrchr (s, c); +} + +ACE_INLINE int +ACE_OS::strcmp (const char *s, const char *t) +{ +// ACE_TRACE ("ACE_OS::strcmp"); + return ::strcmp (s, t); +} + +ACE_INLINE char * +ACE_OS::strcpy (char *s, const char *t) +{ +// ACE_TRACE ("ACE_OS::strcpy"); + return ::strcpy (s, t); +} + +ACE_INLINE char * +ACE_OS::strdup (const char *s) +{ +// ACE_TRACE ("ACE_OS::strdup"); +#if defined (VXWORKS) + char *t = (char *) ::malloc (::strlen (s) + 1); + if (t == 0) + return 0; + else + return ACE_OS::strcpy (t, s); +#else + return ::strdup (s); +#endif /* VXWORKS */ +} + +ACE_INLINE size_t +ACE_OS::strlen (const char *s) +{ +// ACE_TRACE ("ACE_OS::strlen"); + return ::strlen (s); +} + +ACE_INLINE int +ACE_OS::strncmp (const char *s, const char *t, size_t len) +{ +// ACE_TRACE ("ACE_OS::strncmp"); + return ::strncmp (s, t, len); +} + +ACE_INLINE char * +ACE_OS::strncpy (char *s, const char *t, size_t len) +{ +// ACE_TRACE ("ACE_OS::strncpy"); + return ::strncpy (s, t, len); +} + +ACE_INLINE char * +ACE_OS::strtok (char *s, const char *tokens) +{ +// ACE_TRACE ("ACE_OS::strtok"); + return ::strtok (s, tokens); +} + +ACE_INLINE char * +ACE_OS::strtok_r (char *s, const char *tokens, char **lasts) +{ +// ACE_TRACE ("ACE_OS::strtok_r"); +#if defined (ACE_HAS_REENTRANT_FUNCTIONS) && defined (ACE_MT_SAFE) + return ::strtok_r (s, tokens, lasts); +#else + return ::strtok (s, tokens); +#endif /* (ACE_HAS_REENTRANT_FUNCTIONS) && defined (ACE_MT_SAFE) */ +} + +ACE_INLINE long +ACE_OS::strtol (const char *s, char **ptr, int base) +{ +// ACE_TRACE ("ACE_OS::strtol"); + return ::strtol (s, ptr, base); +} + +ACE_INLINE ACE_HANDLE +ACE_OS::accept (ACE_HANDLE handle, struct sockaddr *addr, + int *addrlen) +{ +// ACE_TRACE ("ACE_OS::accept"); + ACE_SOCKCALL_RETURN (::accept ((ACE_SOCKET) handle, addr, (ACE_SOCKET_LEN *) addrlen), + ACE_HANDLE, ACE_INVALID_HANDLE); +} + +ACE_INLINE int +ACE_OS::bind (ACE_HANDLE handle, struct sockaddr *addr, int addrlen) +{ +// ACE_TRACE ("ACE_OS::bind"); + ACE_SOCKCALL_RETURN (::bind ((ACE_SOCKET) handle, addr, (ACE_SOCKET_LEN) addrlen), int, -1); +} + +ACE_INLINE int +ACE_OS::connect (ACE_HANDLE handle, struct sockaddr *addr, int addrlen) +{ +// ACE_TRACE ("ACE_OS::connect"); + ACE_SOCKCALL_RETURN (::connect ((ACE_SOCKET) handle, addr, (ACE_SOCKET_LEN) addrlen), int, -1); +} + +ACE_INLINE struct hostent * +ACE_OS::gethostbyaddr (const char *addr, int length, int type) +{ +// ACE_TRACE ("ACE_OS::gethostbyaddr"); +#if defined (VXWORKS) + ACE_NOTSUP_RETURN (0); +#elif defined (ACE_HAS_NONCONST_GETBY) + char laddr[length]; + ACE_OS::memcpy(laddr, addr, (size_t)length); + ACE_SOCKCALL_RETURN (::gethostbyaddr (laddr, (ACE_SOCKET_LEN) length, type), + struct hostent *, 0); +#else + ACE_SOCKCALL_RETURN (::gethostbyaddr (addr, (ACE_SOCKET_LEN) length, type), + struct hostent *, 0); +#endif /* ACE_HAS_NONCONST_GETBY */ +} + +ACE_INLINE struct hostent * +ACE_OS::gethostbyname (const char *name) +{ +// ACE_TRACE ("ACE_OS::gethostbyname"); +#if defined (VXWORKS) + ACE_NOTSUP_RETURN (0); +#elif defined (ACE_HAS_NONCONST_GETBY) + char lname[::strlen (name) + 1]; + ACE_OS::strcpy (lname, name); + ACE_SOCKCALL_RETURN (::gethostbyname (lname), struct hostent *, 0); +#else + ACE_SOCKCALL_RETURN (::gethostbyname (name), struct hostent *, 0); +#endif /* ACE_HAS_NONCONST_GETBY */ +} + +ACE_INLINE int +ACE_OS::select (int width, + fd_set *rfds, fd_set *wfds, fd_set *efds, + ACE_Time_Value *timeout) +{ +// ACE_TRACE ("ACE_OS::select"); + ACE_SOCKCALL_RETURN (::select (width, + (ACE_FD_SET_TYPE *) rfds, + (ACE_FD_SET_TYPE *) wfds, + (ACE_FD_SET_TYPE *) efds, + (timeval *) timeout) , int, -1); +} + +ACE_INLINE int +ACE_OS::select (int width, + fd_set *rfds, fd_set *wfds, fd_set *efds, + const ACE_Time_Value &timeout) +{ +// ACE_TRACE ("ACE_OS::select"); + ACE_SOCKCALL_RETURN (::select (width, + (ACE_FD_SET_TYPE *) rfds, + (ACE_FD_SET_TYPE *) wfds, + (ACE_FD_SET_TYPE *) efds, + (timeval *) &timeout) , int, -1); +} + +ACE_INLINE int +ACE_OS::recv (ACE_HANDLE handle, char *buf, int len, int flags) +{ +// ACE_TRACE ("ACE_OS::recv"); + ACE_SOCKCALL_RETURN (::recv ((ACE_SOCKET) handle, buf, len, flags), int, -1); +} + +ACE_INLINE int +ACE_OS::recvfrom (ACE_HANDLE handle, char *buf, int len, + int flags, struct sockaddr *addr, int *addrlen) +{ +// ACE_TRACE ("ACE_OS::recvfrom"); + ACE_SOCKCALL_RETURN (::recvfrom ((ACE_SOCKET) handle, buf, (ACE_SOCKET_LEN) len, flags, + addr, (ACE_SOCKET_LEN *) addrlen), + int, -1); +} + +ACE_INLINE int +ACE_OS::send (ACE_HANDLE handle, const char *buf, int len, int flags) +{ +// ACE_TRACE ("ACE_OS::send"); +#if defined (VXWORKS) || defined (HPUX) + ACE_SOCKCALL_RETURN (::send ((ACE_SOCKET) handle, (char *) buf, len, flags), int, ERROR); +#else + ACE_SOCKCALL_RETURN (::send ((ACE_SOCKET) handle, buf, len, flags), int, -1); +#endif /* VXWORKS */ +} + +ACE_INLINE int +ACE_OS::sendto (ACE_HANDLE handle, const char *buf, int len, + int flags, const struct sockaddr *addr, int addrlen) +{ +// ACE_TRACE ("ACE_OS::sendto"); +#if defined (VXWORKS) + ACE_SOCKCALL_RETURN (::sendto ((ACE_SOCKET) handle, (char *) buf, len, flags, + (struct sockaddr *) addr, addrlen), int, ERROR); +#else + ACE_SOCKCALL_RETURN (::sendto ((ACE_SOCKET) handle, buf, len, flags, + (struct sockaddr *) addr, addrlen), int, -1); +#endif /* VXWORKS */ +} + +ACE_INLINE int +ACE_OS::getpeername (ACE_HANDLE handle, struct sockaddr *addr, + int *addrlen) +{ +// ACE_TRACE ("ACE_OS::getpeername"); + ACE_SOCKCALL_RETURN (::getpeername ((ACE_SOCKET) handle, addr, (ACE_SOCKET_LEN *) addrlen), + int, -1); +} + +ACE_INLINE struct protoent * +ACE_OS::getprotobyname (const char *name) +{ +#if defined (VXWORKS) + ACE_NOTSUP_RETURN (0); +#else + ACE_SOCKCALL_RETURN (::getprotobyname (name), + struct protoent *, 0); +#endif /* VXWORKS */ +} + +ACE_INLINE struct protoent * +ACE_OS::getprotobyname_r (const char *name, + struct protoent *result, + ACE_PROTOENT_DATA buffer) +{ +#if defined (VXWORKS) + ACE_NOTSUP_RETURN (0); +#elif defined (ACE_HAS_REENTRANT_FUNCTIONS) && defined (ACE_MT_SAFE) && !defined (UNIXWARE) +#if !defined (AIX) + ACE_SOCKCALL_RETURN (::getprotobyname_r (name, result, buffer, sizeof (ACE_PROTOENT_DATA)), + struct protoent *, 0); +#else + if (::getprotobyname_r (name, result, (struct protoent_data *) buffer) == 0) + return result; + else + return 0; +#endif /* !AIX */ +#else + ACE_SOCKCALL_RETURN (::getprotobyname (name), + struct protoent *, 0); +#endif /* defined (ACE_HAS_REENTRANT_FUNCTIONS) && defined (ACE_MT_SAFE) && !defined (UNIXWARE) */ +} + +ACE_INLINE struct protoent * +ACE_OS::getprotobynumber (int proto) +{ +#if defined (VXWORKS) + ACE_NOTSUP_RETURN( 0 ); +#else + ACE_SOCKCALL_RETURN (::getprotobynumber (proto), + struct protoent *, 0); +#endif /* VXWORKS */ +} + +ACE_INLINE struct protoent * +ACE_OS::getprotobynumber_r (int proto, + struct protoent *result, + ACE_PROTOENT_DATA buffer) +{ +#if defined (VXWORKS) + ACE_NOTSUP_RETURN (0); +#elif defined (ACE_HAS_REENTRANT_FUNCTIONS) && defined (ACE_MT_SAFE) && !defined (UNIXWARE) +#if !defined (AIX) + ACE_SOCKCALL_RETURN (::getprotobynumber_r (proto, result, buffer, sizeof (ACE_PROTOENT_DATA)), + struct protoent *, 0); +#else + if (::getprotobynumber_r (proto, result, (struct protoent_data *) buffer) == 0) + return result; + else + return 0; +#endif /* !AIX */ +#else + ACE_SOCKCALL_RETURN (::getprotobynumber (proto), + struct protoent *, 0); +#endif /* defined (ACE_HAS_REENTRANT_FUNCTIONS) && defined (ACE_MT_SAFE) && !defined (UNIXWARE) */ +} + +ACE_INLINE struct servent * +ACE_OS::getservbyname (const char *svc, const char *proto) +{ +// ACE_TRACE ("ACE_OS::getservbyname"); +#if defined (VXWORKS) + ACE_NOTSUP_RETURN (0); +#elif defined (ACE_HAS_NONCONST_GETBY) + char lsvc[::strlen (svc) + 1]; + char lproto[::strlen (proto) + 1]; + ACE_OS::strcpy (lsvc, svc); + ACE_OS::strcpy (lproto, proto); + ACE_SOCKCALL_RETURN (::getservbyname (lsvc, lproto), + struct servent *, 0); +#else + ACE_SOCKCALL_RETURN (::getservbyname (svc, proto), + struct servent *, 0); +#endif /* ACE_HAS_NONCONST_GETBY */ +} + +ACE_INLINE int +ACE_OS::getsockname (ACE_HANDLE handle, + struct sockaddr *addr, + int *addrlen) +{ +// ACE_TRACE ("ACE_OS::getsockname"); + + ACE_SOCKCALL_RETURN (::getsockname ((ACE_SOCKET) handle, addr, (ACE_SOCKET_LEN *) addrlen), + int, -1); +} + +ACE_INLINE int +ACE_OS::getsockopt (ACE_HANDLE handle, + int level, + int optname, + char *optval, + int *optlen) +{ +// ACE_TRACE ("ACE_OS::getsockopt"); + ACE_SOCKCALL_RETURN (::getsockopt ((ACE_SOCKET) handle, level, optname, optval, (ACE_SOCKET_LEN *) optlen), + int, -1); +} + +ACE_INLINE int +ACE_OS::listen (ACE_HANDLE handle, int backlog) +{ +// ACE_TRACE ("ACE_OS::listen"); + ACE_SOCKCALL_RETURN (::listen ((ACE_SOCKET) handle, backlog), int, -1); +} + +ACE_INLINE int +ACE_OS::setsockopt (ACE_HANDLE handle, int level, int optname, + const char *optval, int optlen) +{ +// ACE_TRACE ("ACE_OS::setsockopt"); + + ACE_SOCKCALL_RETURN (::setsockopt ((ACE_SOCKET) handle, level, optname, + (ACE_SOCKOPT_TYPE1) optval, optlen), + int, -1); +} + +ACE_INLINE int +ACE_OS::shutdown (ACE_HANDLE handle, int how) +{ +// ACE_TRACE ("ACE_OS::shutdown"); + ACE_SOCKCALL_RETURN (::shutdown ((ACE_SOCKET) handle, how), int, -1); +} + +ACE_INLINE ACE_HANDLE +ACE_OS::socket (int domain, int type, int proto) +{ +// ACE_TRACE ("ACE_OS::socket"); + ACE_SOCKCALL_RETURN (::socket (domain, type, proto), + ACE_HANDLE, ACE_INVALID_HANDLE); +} + +ACE_INLINE int +ACE_OS::atoi (const char *s) +{ +// ACE_TRACE ("ACE_OS::atoi"); + ACE_OSCALL_RETURN (::atoi (s), int, -1); +} + +ACE_INLINE int +ACE_OS::recvmsg (ACE_HANDLE handle, struct msghdr *msg, int flags) +{ +// ACE_TRACE ("ACE_OS::recvmsg"); +#if !defined (ACE_LACKS_RECVMSG) + ACE_OSCALL_RETURN (::recvmsg (handle, msg, flags), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_MSG */ +} + +ACE_INLINE int +ACE_OS::sendmsg (ACE_HANDLE handle, ACE_SENDMSG_TYPE *msg, int flags) +{ +// ACE_TRACE ("ACE_OS::sendmsg"); +#if !defined (ACE_LACKS_SENDMSG) +#if defined (ACE_LACKS_POSIX_PROTO) + ACE_OSCALL_RETURN (::sendmsg (handle, (struct msghdr *) msg, flags), int, -1); +#else + ACE_OSCALL_RETURN (::sendmsg (handle, msg, flags), int, -1); +#endif /* ACE_LACKS_POSIX_PROTO */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_MSG */ +} + +ACE_INLINE int +ACE_OS::fclose (FILE *fp) +{ +// ACE_TRACE ("ACE_OS::fclose"); + ACE_OSCALL_RETURN (::fclose (fp), int, -1); +} + +ACE_INLINE char * +ACE_OS::fgets (char *buf, int size, FILE *fp) +{ +// ACE_TRACE ("ACE_OS::fgets"); + ACE_OSCALL_RETURN (::fgets (buf, size, fp), char *, 0); +} + +ACE_INLINE int +ACE_OS::fflush (FILE *fp) +{ +// ACE_TRACE ("ACE_OS::fflush"); + ACE_OSCALL_RETURN (::fflush (fp), int, -1); +} + +ACE_INLINE FILE * +ACE_OS::fopen (const char *filename, const char *mode) +{ +// ACE_TRACE ("ACE_OS::fopen"); + ACE_OSCALL_RETURN (::fopen (filename, mode), FILE *, 0); +} + +ACE_INLINE int +ACE_OS::fprintf (FILE *fp, const char *format, ...) +{ +// ACE_TRACE ("ACE_OS::fprintf"); + int result = 0; + va_list ap; + va_start (ap, format); + ACE_OSCALL (::vfprintf (fp, format, ap), int, -1, result); + va_end (ap); + return result; +} + +ACE_INLINE size_t +ACE_OS::fread (void *ptr, size_t size, size_t nelems, FILE *fp) +{ +// ACE_TRACE ("ACE_OS::fread"); +#if defined (ACE_LACKS_POSIX_PROTO) + ACE_OSCALL_RETURN (::fread ((char *) ptr, size, nelems, fp), int, 0); +#else + ACE_OSCALL_RETURN (::fread (ptr, size, nelems, fp), int, 0); +#endif /* ACE_LACKS_POSIX_PROTO */ +} + +ACE_INLINE size_t +ACE_OS::fwrite (const void *ptr, size_t size, size_t nitems, FILE *fp) +{ +// ACE_TRACE ("ACE_OS::fwrite"); +#if defined (ACE_LACKS_POSIX_PROTO) + ACE_OSCALL_RETURN (::fwrite ((const char *) ptr, size, nitems, fp), int, 0); +#else + ACE_OSCALL_RETURN (::fwrite (ptr, size, nitems, fp), int, 0); +#endif /* ACE_LACKS_POSIX_PROTO */ +} + +ACE_INLINE void * +ACE_OS::malloc (size_t nbytes) +{ +// ACE_TRACE ("ACE_OS::malloc"); + return ::malloc (nbytes); +} + +ACE_INLINE void * +ACE_OS::realloc (void *ptr, size_t nbytes) +{ +// ACE_TRACE ("ACE_OS::realloc"); + return ::realloc (ACE_MALLOC_T (ptr), nbytes); +} + +ACE_INLINE void +ACE_OS::free (void *ptr) +{ +// ACE_TRACE ("ACE_OS::free"); + ::free (ACE_MALLOC_T (ptr)); +} + +ACE_INLINE struct hostent * +ACE_OS::gethostbyaddr_r (const char *addr, int length, int type, + hostent *result, ACE_HOSTENT_DATA buffer, + int *h_errnop) +{ +// ACE_TRACE ("ACE_OS::gethostbyaddr_r"); +#if defined (VXWORKS) + ACE_NOTSUP_RETURN (0); +#elif defined (ACE_HAS_REENTRANT_FUNCTIONS) && defined (ACE_MT_SAFE) && !defined (UNIXWARE) +#if !defined (AIX) + ACE_SOCKCALL_RETURN (::gethostbyaddr_r (addr, length, type, result, + buffer, sizeof (ACE_HOSTENT_DATA), + h_errnop), + struct hostent *, 0); +#else + ::memset (buffer, 0, sizeof (ACE_HOSTENT_DATA)); + + if (::gethostbyaddr_r ((char *) addr, length, type, result, + (struct hostent_data *) buffer)== 0) + return result; + else + { + *h_errnop = h_errno; + return (struct hostent *) 0; + } +#endif /* !defined (AIX) */ +#elif defined (ACE_HAS_NONCONST_GETBY) + char laddr[length]; + ACE_OS::memcpy (laddr, addr, (size_t) length); + ACE_SOCKCALL_RETURN (::gethostbyaddr (laddr, (ACE_SOCKET_LEN) length, type), + struct hostent *, 0); +#else + ACE_SOCKCALL_RETURN (::gethostbyaddr (addr, (ACE_SOCKET_LEN) length, type), + struct hostent *, 0); +#endif /* defined (ACE_HAS_REENTRANT_FUNCTIONS) && defined (ACE_MT_SAFE) && !defined (UNIXWARE) */ +} + +ACE_INLINE struct hostent * +ACE_OS::gethostbyname_r (const char *name, hostent *result, + ACE_HOSTENT_DATA buffer, + int *h_errnop) +{ +// ACE_TRACE ("ACE_OS::gethostbyname_r"); +#if defined (VXWORKS) + ACE_NOTSUP_RETURN (0); +#elif defined (ACE_HAS_REENTRANT_FUNCTIONS) && defined (ACE_MT_SAFE) && !defined (UNIXWARE) +#if !defined (AIX) + ACE_SOCKCALL_RETURN (::gethostbyname_r (name, result, buffer, + sizeof (ACE_HOSTENT_DATA), h_errnop), + struct hostent *, 0); +#else + ::memset (buffer, 0, sizeof (ACE_HOSTENT_DATA)); + + if (::gethostbyname_r (name, result, (struct hostent_data *) buffer) == 0) + return result; + else + { + *h_errnop = h_errno; + return (struct hostent *) 0; + } +#endif /* ! defined (AIX) */ +#elif defined (ACE_HAS_NONCONST_GETBY) + char lname[::strlen (name) + 1]; + ACE_OS::strcpy (lname, name); + ACE_SOCKCALL_RETURN (::gethostbyname (lname), struct hostent *, 0); +#else + ACE_SOCKCALL_RETURN (::gethostbyname (name), struct hostent *, 0); +#endif /* defined (ACE_HAS_REENTRANT_FUNCTIONS) && defined (ACE_MT_SAFE) && !defined (UNIXWARE) */ +} + +ACE_INLINE char * +ACE_OS::gets (char *str) +{ +// ACE_TRACE ("ACE_OS::gets"); + ACE_OSCALL_RETURN (::gets (str), char *, 0); +} + +ACE_INLINE struct servent * +ACE_OS::getservbyname_r (const char *svc, const char *proto, + struct servent *result, ACE_SERVENT_DATA buf) +{ +// ACE_TRACE ("ACE_OS::getservbyname_r"); +#if defined (VXWORKS) + ACE_NOTSUP_RETURN (0); +#elif defined (ACE_HAS_REENTRANT_FUNCTIONS) && defined (ACE_MT_SAFE) && !defined (UNIXWARE) +#if !defined (AIX) + ACE_SOCKCALL_RETURN (::getservbyname_r (svc, proto, result, buf, + sizeof (ACE_SERVENT_DATA)), + struct servent *, 0); +#else + ::memset (buf, 0, sizeof (ACE_SERVENT_DATA)); + + if (::getservbyname_r (svc, proto, result, (struct servent_data *) buf) == 0) + return result; + else + return (struct servent *) 0; +#endif /* !defined (AIX) */ +#elif defined (ACE_HAS_NONCONST_GETBY) + char lsvc[::strlen (svc) + 1]; + char lproto[::strlen (proto) + 1]; + ACE_OS::strcpy (lsvc, svc); + ACE_OS::strcpy (lproto, proto); + ACE_SOCKCALL_RETURN (::getservbyname (lsvc, lproto), + struct servent *, 0); +#else + ACE_SOCKCALL_RETURN (::getservbyname (svc, proto), + struct servent *, 0); +#endif /* defined (ACE_HAS_REENTRANT_FUNCTIONS) && defined (ACE_MT_SAFE) && !defined (UNIXWARE) */ +} + +ACE_INLINE long +ACE_OS::inet_addr (const char *name) +{ +// ACE_TRACE ("ACE_OS::inet_addr"); +#if defined (VXWORKS) + + u_long retval = 0; + u_int segment; + + for (u_int i = 0; i < 4; ++i) + { + retval <<= 8; + if (*name != '\0') + { + segment = 0; + + while (*name >= '0' && *name <= '9') + { + segment *= 10; + segment += *name++ - '0'; + } + retval |= segment; + + if (*name == '.') + { + ++name; + } + } + } + return (long) htonl (retval); +#elif defined (ACE_HAS_NONCONST_GETBY) + char _name[::strlen (name) + 1]; + ACE_OS::strcpy (_name, name); + return ::inet_addr (_name); +#else + return ::inet_addr (name); +#endif /* ACE_HAS_NONCONST_GETBY */ +} + +ACE_INLINE char * +ACE_OS::inet_ntoa (const struct in_addr addr) +{ +// ACE_TRACE ("ACE_OS::inet_ntoa"); +#if defined (VXWORKS) + // the following storage is not thread-specific! + static char buf[32]; + // assumes that addr is already in network byte order + sprintf (buf, "%d.%d.%d.%d", addr.S_un.S_addr / (256*256*256) & 255, + addr.S_un.S_addr / (256*256) & 255, + addr.S_un.S_addr / 256 & 255, + addr.S_un.S_addr & 255); + return buf; +#else + ACE_OSCALL_RETURN (::inet_ntoa (addr), char *, 0); +#endif /* VXWORKS */ +} + +ACE_INLINE int +ACE_OS::last_error (void) +{ +// ACE_TRACE ("ACE_OS::last_error"); +#if defined (ACE_WIN32) + return ::GetLastError (); +#else + return errno; +#endif /* ACE_HAS_WIN32 */ +} + +ACE_INLINE void +ACE_OS::last_error (int error) +{ +// ACE_TRACE ("ACE_OS::last_error"); +#if defined (ACE_WIN32) + ::SetLastError (error); +#else + errno = error; +#endif /* ACE_HAS_WIN32 */ +} + +ACE_INLINE void +ACE_OS::perror (const char *s) +{ +// ACE_TRACE ("ACE_OS::perror"); + ::perror (s); +} + +ACE_INLINE int +ACE_OS::printf (const char *format, ...) +{ +// ACE_TRACE ("ACE_OS::printf"); + int result; + va_list ap; + va_start (ap, format); + ACE_OSCALL (::vprintf (format, ap), int, -1, result); + va_end (ap); + return result; +} + +ACE_INLINE int +ACE_OS::puts (const char *s) +{ +// ACE_TRACE ("ACE_OS::puts"); + ACE_OSCALL_RETURN (::puts (s), int, -1); +} + +ACE_INLINE int +ACE_OS::sema_destroy (ACE_sema_t *s) +{ +// ACE_TRACE ("ACE_OS::sema_destroy"); +#if defined (ACE_HAS_POSIX_SEM) + if (s->name_) + { + ACE_OS::free ((void *) s->name_); + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sem_unlink (s->name_), _result), int, -1); + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sem_close (s->sema_), _result), int, -1); + } + else + { + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sem_destroy (s->sema_), _result), int, -1); + delete s->sema_; + s->sema_ = 0; + } +#elif defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_destroy (s), _result), int, -1); +#elif defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + int r1 = ACE_OS::mutex_destroy (&s->lock_); + int r2 = ACE_OS::cond_destroy (&s->count_nonzero_); + return r1 != 0 || r2 != 0 ? -1 : 0; +#elif defined (ACE_HAS_WTHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::CloseHandle (*s), _result), int, -1); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_POSIX_SEM */ +} + +ACE_INLINE int +ACE_OS::sema_init (ACE_sema_t *s, u_int count, int type, + LPCTSTR name, void *arg, int max) +{ +// ACE_TRACE ("ACE_OS::sema_init"); +#if defined (ACE_HAS_POSIX_SEM) + if (name) + { + s->name_ = ACE_OS::strdup (name); + s->sema_ = ::sem_open (s->name_, O_CREAT, ACE_DEFAULT_PERMS, count); + return (int) s->sema_ == -1 ? -1 : 0; + } + else + { + s->name_ = 0; + ACE_NEW_RETURN (s->sema_, sem_t, -1); + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sem_init (s->sema_, type != USYNC_THREAD, count), _result), + int, -1); + } +#elif defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_init (s, count, type, arg), _result), + int, -1); +#elif defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + int result = -1; + + if (ACE_OS::mutex_init (&s->lock_, type, name, arg) == 0 + && ACE_OS::cond_init (&s->count_nonzero_, type, name, arg) == 0 + && ACE_OS::mutex_lock (&s->lock_) == 0) + { + s->count_ = count; + if (ACE_OS::mutex_unlock (&s->lock_) == 0) + result = 0; + } + + if (result == -1) + { + ACE_OS::mutex_destroy (&s->lock_); + ACE_OS::cond_destroy (&s->count_nonzero_); + } + return result; +#elif defined (ACE_HAS_WTHREADS) + // Create the semaphore with its value initialized to and + // its maximum value initialized to . + *s = ::CreateSemaphore (0, count, max, name); + + if (*s == 0) + ACE_FAIL_RETURN (-1); + /* NOTREACHED */ + else + return 0; +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_POSIX_SEM */ +} + +ACE_INLINE int +ACE_OS::sema_post (ACE_sema_t *s) +{ +// ACE_TRACE ("ACE_OS::sema_post"); +#if defined (ACE_HAS_POSIX_SEM) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sem_post (s->sema_), _result), int, -1); +#elif defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_post (s), _result), int, -1); +#elif defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + + int result = -1; + int count_was_zero; + + if (ACE_OS::mutex_lock (&s->lock_) == 0) + { + count_was_zero = s->count_++ == 0; + if (ACE_OS::mutex_unlock (&s->lock_) == 0) + { + if (count_was_zero) + // Allows a waiter to continue. + result = ACE_OS::cond_signal (&s->count_nonzero_); + else + result = 0; + } + } + return result; +#elif defined (ACE_HAS_WTHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::ReleaseSemaphore (*s, 1, 0), + _result), + int, -1); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_POSIX_SEM */ +} + +ACE_INLINE int +ACE_OS::sema_trywait (ACE_sema_t *s) +{ +// ACE_TRACE ("ACE_OS::sema_trywait"); +#if defined (ACE_HAS_POSIX_SEM) + // POSIX semaphores set errno to EAGAIN if trywait fails + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sem_trywait (s->sema_), _result), + int, -1); +#elif defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + // STHREADS semaphores set errno to EBUSY if trywait fails + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_trywait (s), + _result), + int, -1); +#elif defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + + int result = -1; + + if (ACE_OS::mutex_lock (&s->lock_) == 0) + { + if (s->count_ > 0) + { + --s->count_; + result = 0; + } + else + errno = EBUSY; + + ACE_OS::mutex_unlock (&s->lock_); + } + return result; +#elif defined (ACE_HAS_WTHREADS) + int result = ::WaitForSingleObject (*s, 0); + + if (result == WAIT_OBJECT_0) + return 0; + else + { + errno = result == WAIT_TIMEOUT ? EBUSY : ::GetLastError (); + // This is a hack, we need to find an appropriate mapping... + return -1; + } + +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_POSIX_SEM */ +} + +ACE_INLINE int +ACE_OS::sema_wait (ACE_sema_t *s) +{ +// ACE_TRACE ("ACE_OS::sema_wait"); +#if defined (ACE_HAS_POSIX_SEM) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sem_wait (s->sema_), _result), int, -1); +#elif defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_wait (s), _result), int, -1); +#elif defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + int result = 0; + + pthread_cleanup_push (ACE_OS::mutex_lock_cleanup, (void *) &s->lock_); + + if (ACE_OS::mutex_lock (&s->lock_) != 0) + result = -1; + else + { + while (s->count_ == 0) + if (ACE_OS::cond_wait (&s->count_nonzero_, &s->lock_) == -1) + { + result = -2; + break; + } + } + + if (result == 0) + --s->count_; + if (result != -1) + ACE_OS::mutex_unlock (&s->lock_); + pthread_cleanup_pop (1); + return result; + +#elif defined (ACE_HAS_WTHREADS) + if (::WaitForSingleObject (*s, INFINITE) == WAIT_OBJECT_0) + return 0; + else + ACE_FAIL_RETURN (-1); + /* NOTREACHED */ +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_POSIX_SEM */ +} + +ACE_INLINE ACE_SignalHandler +ACE_OS::signal (int signum, ACE_SignalHandler func) +{ + return ::signal (signum, func); +} + +ACE_INLINE int +ACE_OS::sprintf (char *buf, const char *format, ...) +{ +// ACE_TRACE ("ACE_OS::sprintf"); + int result; + va_list ap; + va_start (ap, format); + ACE_OSCALL (::vsprintf (buf, format, ap), int, -1, result); + va_end (ap); + return result; +} + +ACE_INLINE int +ACE_OS::system (const char *s) +{ +// ACE_TRACE ("ACE_OS::system"); + ACE_OSCALL_RETURN (::system (s), int, -1); +} + +ACE_INLINE int +ACE_OS::thr_continue (ACE_hthread_t target_thread) +{ +// ACE_TRACE ("ACE_OS::thr_continue"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_continue (target_thread), _result), int, -1); +#elif defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_HAS_WTHREADS) + return ::ResumeThread (target_thread) != ACE_SYSCALL_FAILED ? 0 : -1; +#elif defined (VXWORKS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::taskResume (target_thread), _result), int, ERROR); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::thr_equal (ACE_thread_t t1, ACE_thread_t t2) +{ +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) +#if defined (pthread_equal) +// If it's a macro we can't say "::pthread_equal"... + return pthread_equal (t1, t2); +#else + return ::pthread_equal (t1, t2); +#endif /* pthread_equal */ +#elif defined (VXWORKS) + return ! ACE_OS::strcmp (t1, t2); +#else // For both STHREADS and WTHREADS... +// Hum, Do we need to treat WTHREAD differently? + return t1 == t2; +#endif /* ACE_HAS_DCETHREADS */ +} + +ACE_INLINE int +ACE_OS::thr_cmp (ACE_hthread_t t1, ACE_hthread_t t2) +{ +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) +#if defined (ACE_HAS_TID_T) && !defined (ACE_HAS_SETKIND_NP) + return t1 == t2; // I hope these aren't structs! +#elif defined (pthread_equal) +// If it's a macro we can't say "::pthread_equal"... + return pthread_equal (t1, t2); +#else + return ::pthread_equal (t1, t2); +#endif /* pthread_equal */ +#else // For STHREADS, WTHREADS, and VXWORKS ... +// Hum, Do we need to treat WTHREAD differently? + return t1 == t2; +#endif /* ACE_HAS_DCETHREADS */ +} + +ACE_INLINE int +ACE_OS::thr_getconcurrency (void) +{ +// ACE_TRACE ("ACE_OS::thr_getconcurrency"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + return ::thr_getconcurrency (); +#elif defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) || defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_HAS_WTHREADS) + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::thr_getprio (ACE_hthread_t thr_id, int *prio) +{ +// ACE_TRACE ("ACE_OS::thr_getprio"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_getprio (thr_id, prio), _result), int, -1); +#elif defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_HAS_WTHREADS) + + int result = ::GetThreadPriority (thr_id); + return result == THREAD_PRIORITY_ERROR_RETURN ? -1 : result; +#elif defined (VXWORKS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::taskPriorityGet (thr_id, prio), _result), int, ERROR); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::thr_getspecific (ACE_thread_key_t key, void **data) +{ +// ACE_TRACE ("ACE_OS::thr_getspecific"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_getspecific (key, data), _result), int, -1); +#elif defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) +#if !defined (ACE_HAS_FSU_PTHREADS) && !defined (ACE_HAS_SETKIND_NP) + *data = ::pthread_getspecific (key); +#elif !defined (ACE_HAS_FSU_PTHREADS) && defined (ACE_HAS_SETKIND_NP) + ::pthread_getspecific (key, data); +#else /* ACE_HAS_FSU_PTHREADS */ + // Is this really used anywhere? + *data = ::pthread_getspecific (key, data); +#endif /* ACE_HAS_FSU_PTHREADS */ + return 0; +#elif defined (ACE_HAS_WTHREADS) + *data = ::TlsGetValue (key); + return 0; +#elif defined (VXWORKS) + // VxWorks doesn't support thread specific storage, though it's probably + // doable without too much trouble . . . + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::thr_join (ACE_thread_t waiter_id, ACE_thread_t *thr_id, void **status) +{ +// ACE_TRACE ("ACE_OS::thr_join"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_join (waiter_id, thr_id, status), _result), + int, -1); +#elif defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_join (waiter_id, status), _result), + int, -1); +#elif defined (ACE_HAS_WTHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::thr_join (ACE_hthread_t thr_handle, void **status) +{ +// ACE_TRACE ("ACE_OS::thr_join"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_HAS_WTHREADS) + if (::WaitForSingleObject (thr_handle, INFINITE) == WAIT_OBJECT_0 + && ::GetExitCodeThread (thr_handle, (LPDWORD) status) != FALSE) + { + ::CloseHandle (thr_handle); + return 0; + } + + ACE_FAIL_RETURN (-1); + /* NOTREACHED */ +#elif defined (VXWORKS) + // VxWorks could possibly support thread join with + // ::taskSafe()/::taskUnsafe(). But, a task can only calls those + // functions on itself. Until there's really a need . . . + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::thr_setcancelstate (int new_state, int *old_state) +{ +// ACE_TRACE ("ACE_OS::thr_setcancelstate"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || (defined (ACE_HAS_PTHREADS) && defined (ACE_HAS_STHREADS)) +#if defined (ACE_HAS_SETKIND_NP) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setcancel (new_state), + _result), + int, -1); +#else /* ACE_HAS_SETKIND_NP */ + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setcancelstate (new_state, old_state), + _result), + int, -1); +#endif /* ACE_HAS_SETKIND_NP */ +#elif defined (ACE_HAS_PTHREADS) +// I didn't manage to find pthread_cancel anywhere in the MIT pthread +// implementation. So I'll just leave this instead, and see what +// breaks. -- jwr + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_HAS_STHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_HAS_WTHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::thr_setcanceltype (int new_type, int *old_type) +{ +// ACE_TRACE ("ACE_OS::thr_setcanceltype"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || (defined (ACE_HAS_PTHREADS) && defined (ACE_HAS_STHREADS)) +#if defined (ACE_HAS_SETKIND_NP) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setcancel (new_type), + _result), + int, -1); +#else /* ACE_HAS_SETKIND_NP */ + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setcanceltype (new_type, old_type), + _result), + int, -1); +#endif /* ACE_HAS_SETKIND_NP */ +#elif defined (ACE_HAS_PTHREADS) +// I didn't manage to find pthread_cancel anywhere int the MIT pthread +// implementation. So I'll just leave this instead, and see what +// breaks. -- jwr + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_HAS_STHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_HAS_WTHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::thr_cancel (ACE_thread_t t_id) +{ +// ACE_TRACE ("ACE_OS::thr_cancel"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || (defined (ACE_HAS_PTHREADS) && defined (ACE_HAS_STHREADS)) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_cancel(t_id), + _result), + int, -1); +#elif defined (ACE_HAS_PTHREADS) +// I didn't manage to find pthread_cancel anywhere int the MIT +// pthread implementation. So I'll just leave this instead, and +// see what breaks. -- jwr + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_HAS_STHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_HAS_WTHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::sigwait (sigset_t *set, int *sig) +{ +// ACE_TRACE ("ACE_OS::sigwait"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) || defined (ACE_HAS_FSU_PTHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sigwait (set), + _result), + int, -1); +#elif defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) +#if defined (ACE_HAS_SETKIND_NP) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sigwait (set), + _result), + int, -1); +#else /* ACE_HAS_SETKIND_NP */ + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sigwait (set, sig), + _result), + int, -1); +#endif /* ACE_HAS_SETKIND_NP */ +#elif defined (ACE_HAS_WTHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (VXWORKS) + // second arg is a struct siginfo *, which we don't need (the selected + // signal number is returned) + // third arg is timeout: NULL means forever + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sigtimedwait (set, NULL, NULL), + _result), + int, -1); // yes, the doc says -1, not ERROR +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE void +ACE_OS::thr_testcancel (void) +{ +// ACE_TRACE ("ACE_OS::thr_testcancel"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || (defined (ACE_HAS_PTHREADS) && defined (ACE_HAS_STHREADS)) + ::pthread_testcancel (); +#elif defined (ACE_HAS_PTHREADS) +// I didn't manage to find pthread_cancel anywhere int the MIT +// pthread implementation. So I'll just leave this instead, and +// see what breaks. -- jwr +#elif defined (ACE_HAS_STHREADS) +#elif defined (ACE_HAS_WTHREADS) +#elif defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STHREADS */ +#else +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::thr_sigsetmask (int how, + const sigset_t *nsm, + sigset_t *osm) +{ +// ACE_TRACE ("ACE_OS::thr_sigsetmask"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_sigsetmask (how, nsm, osm), + _result), + int, -1); +#elif defined (ACE_HAS_SETKIND_NP) + // ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sigaction (how, nsm, osm), + // _result), + // int, -1); + // commented this out since nothing appropriate + // found in the man pages... + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_HAS_DCETHREADS) +#if defined (ACE_HAS_PTHREADS_1003_DOT_1C) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_sigaction (how, nsm, osm), + _result), int, -1); +#else + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sigthreadmask (how, nsm, osm), + _result), int, -1); +#endif /* ACE_HAS_PTHREADS_1003_DOT_1C */ + +#elif defined (ACE_HAS_PTHREADS) && !defined (ACE_HAS_FSU_PTHREADS) +#if defined (ACE_HAS_IRIX62_THREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_sigmask (how, nsm, osm), + _result),int, -1); +#else +// as far as I can tell, this is now pthread_sigaction() -- jwr + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_sigaction (how, nsm, osm), + _result), int, -1); +#endif /* ACE_HAS_IRIX62_THREADS */ +#elif defined (ACE_HAS_WTHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (VXWORKS) + switch (how) + { + case SIG_BLOCK: + case SIG_UNBLOCK: + { + // get the old mask + *osm = ::sigsetmask (nsm); + // create a new mask: the following assumes that sigset_t is an int, + // so abitwise operations can be done simply . . . + ::sigsetmask (how == SIG_BLOCK ? (*osm |= *nsm) : (*osm &= ~*nsm)); + break; + } + case SIG_SETMASK: + *osm = ::sigsetmask (nsm); + break; + default: + return -1; + } + + return 0; + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sigprocmask (how, nsm, osm), + _result), + int, -1); +#else // Should not happen. + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE size_t +ACE_OS::thr_min_stack (void) +{ +// ACE_TRACE ("ACE_OS::thr_min_stack"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_min_stack (), + _result), + int, -1); +#elif (defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS)) && !defined (ACE_HAS_SETKIND_NP) +#if defined (ACE_HAS_IRIX62_THREADS) + return (size_t) ACE_OS::sysconf (_SC_THREAD_STACK_MIN); +#else + return PTHREAD_STACK_MIN; +#endif /* ACE_HAS_IRIX62_THREADS */ +#elif (defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS)) && !defined (ACE_HAS_SETKIND_NP) + ACE_NOTSUP_RETURN (0); +#elif defined (ACE_HAS_WTHREADS) + ACE_NOTSUP_RETURN (0); +#elif defined (VXWORKS) + TASK_DESC taskDesc; + STATUS status; + ACE_OSCALL (ACE_ADAPT_RETVAL (::taskInfoGet (ACE_OS::thr_self (), &taskDesc), + _result), + int, ERROR, status); + return status == 0 ? taskDesc.td_stackSize : 0; +#else // Should not happen... + ACE_NOTSUP_RETURN (0); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (0); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::thr_kill (ACE_thread_t thr_id, int signum) +{ +// ACE_TRACE ("ACE_OS::thr_kill"); +#if defined (ACE_HAS_THREADS) +#if (defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS)) && !defined (ACE_HAS_SETKIND_NP) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_kill (thr_id, signum), + _result), + int, -1); +#elif defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_kill (thr_id, signum), + _result), + int, -1); +#elif defined (ACE_HAS_WTHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (VXWORKS) + ACE_htread_t tid; + ACE_OSCALL (ACE_ADAPT_RETVAL (::taskNameToId (thr_id), _result), + int, ERROR, tid); + + if ( tid == ERROR ) + return -1; + else + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::kill (tid, signum), _result), + int, ERROR); + +#else // This should not happen! + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE void +ACE_OS::thr_self (ACE_hthread_t &self) +{ +// ACE_TRACE ("ACE_OS::thr_self"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_PTHREADS) || defined (ACE_HAS_SETKIND_NP) || defined (ACE_HAS_IRIX62_THREADS) + self = ::pthread_self (); +#elif defined (ACE_HAS_DCETHREADS) + self = ::thread_self (); +#elif defined (ACE_HAS_STHREADS) + self = ::thr_self (); +#elif defined (ACE_HAS_WTHREADS) + self = ::GetCurrentThread (); +#elif defined (VXWORKS) + self = ::taskIdSelf (); +#endif /* ACE_HAS_STHREADS */ +#else + self = 1; // Might as well make it the first thread ;-) +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE ACE_thread_t +ACE_OS::thr_self (void) +{ +// ACE_TRACE ("ACE_OS::thr_self"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + ACE_OSCALL_RETURN (::pthread_self (), int, -1); +#elif defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (::thr_self (), int, -1); +#elif defined (ACE_HAS_WTHREADS) + return ::GetCurrentThreadId (); +#elif defined (VXWORKS) + return ::taskIdSelf (); +#endif /* ACE_HAS_STHREADS */ +#else + return 1; // Might as well make it the first thread ;-) +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::thr_setconcurrency (int hint) +{ +// ACE_TRACE ("ACE_OS::thr_setconcurrency"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_setconcurrency (hint), + _result), + int, -1); +#elif defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_HAS_WTHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::thr_setprio (ACE_hthread_t thr_id, int prio) +{ +// ACE_TRACE ("ACE_OS::thr_setprio"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_setprio (thr_id, prio), + _result), + int, -1); +#elif defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_HAS_WTHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::SetThreadPriority (thr_id, prio), + _result), + int, -1); +#elif defined (VXWORKS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::taskPrioritySet (thr_id, prio), _result), int, ERROR); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::thr_suspend (ACE_hthread_t target_thread) +{ +// ACE_TRACE ("ACE_OS::thr_suspend"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_suspend (target_thread), _result), int, -1); +#elif defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) + ACE_NOTSUP_RETURN (-1); +#elif defined (ACE_HAS_WTHREADS) + + if (::SuspendThread (target_thread) != ACE_SYSCALL_FAILED) + return 0; + else + ACE_FAIL_RETURN (-1); + /* NOTREACHED */ +#elif defined (VXWORKS) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::taskSuspend (target_thread), _result), int, ERROR); +#endif /* ACE_HAS_STHREADS */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE void +ACE_OS::thr_yield (void) +{ +// ACE_TRACE ("ACE_OS::thr_yield"); +#if defined (ACE_HAS_THREADS) +#if defined (ACE_HAS_STHREADS) + ::thr_yield (); +#elif defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) +#if defined (ACE_HAS_IRIX62_THREADS) || defined (ACE_HAS_PTHREADS_1003_DOT_1C) + ::sched_yield (); +#elif defined (ACE_HAS_FSU_PTHREADS) || defined (ACE_HAS_YIELD_VOID_PTR) + ::pthread_yield (NULL); +#else + ::pthread_yield (); +#endif // ACE_HAS_IRIX62_THREADS */ +#elif defined (ACE_HAS_WTHREADS) + ::Sleep (0); +#elif defined (VXWORKS) + ::taskDelay (0); +#endif /* ACE_HAS_STHREADS */ +#else + ; +#endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE void +ACE_OS::rewind (FILE *fp) +{ +// ACE_TRACE ("ACE_OS::rewind"); + ::rewind (fp); +} + +// This function returns the number of bytes in the file referenced by +// FD. + +ACE_INLINE long +ACE_OS::filesize (ACE_HANDLE handle) +{ +// ACE_TRACE ("ACE::filesize"); +#if defined (ACE_WIN32) + ACE_OSCALL_RETURN (::GetFileSize (handle, NULL), int, ACE_SYSCALL_FAILED); +#else /* !ACE_WIN32 */ + struct stat sb; + + return ACE_OS::fstat (handle, &sb) == -1 ? (long) -1 : sb.st_size; +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::writev (ACE_HANDLE handle, + ACE_WRITEV_TYPE *iov, + int iovcnt) +{ +// ACE_TRACE ("ACE_OS::writev"); + ACE_OSCALL_RETURN (::writev (handle, iov, iovcnt), int, -1); +} + +ACE_INLINE ssize_t +ACE_OS::readv (ACE_HANDLE handle, + struct iovec *iov, + int iovlen) +{ +// ACE_TRACE ("ACE_OS::readv"); + ACE_OSCALL_RETURN (::readv (handle, iov, iovlen), ssize_t, -1); +} + +ACE_INLINE ACE_Time_Value +ACE_OS::gettimeofday (void) +{ +// ACE_TRACE ("ACE_OS::gettimeofday"); + timeval tv; +#if defined (ACE_WIN32) + // From Todd Montgomery... + struct _timeb tb; + ::_ftime (&tb); + tv.tv_sec = tb.time; + tv.tv_usec = 1000 * tb.millitm; +#if 0 + // This version of the code has bugs -- don't use until it's been fixed... + // Alternative form. + SYSTEMTIME system_time; + FILETIME file_time; + + ::GetSystemTime (&system_time); + ::SystemTimeToFileTime (&system_time, &file_time); + ACE_QWORD _100ns = ACE_MAKE_QWORD (file_time.dwLowDateTime, + file_time.dwHighDateTime); + // Convert 100ns units to seconds; + tv.tv_sec = long (_100ns / (10000 * 1000)); + // Convert remainder to microseconds; + tv.tv_usec = long ((_100ns - (tv.tv_sec * (10000 * 1000))) * 10); +#endif +#else + int result; +#if defined (ACE_HAS_TIMEZONE_GETTIMEOFDAY) || (defined (ACE_HAS_SVR4_GETTIMEOFDAY) && !defined (m88k)) + ACE_OSCALL (::gettimeofday (&tv, 0), int, -1, result); +#elif defined (VXWORKS) + // assumes that struct timespec is same size as struct timeval, + // which assumes that time_t is a long: it currently (v 5.2) is + ACE_OSCALL (ACE_ADAPT_RETVAL (::clock_gettime (CLOCK_REALTIME, (struct timespec *) &tv), _result), + int, ERROR, result); +#else + ACE_OSCALL (::gettimeofday (&tv), int, -1, result); +#endif /* ACE_HAS_SVR4_GETTIMEOFDAY */ +#endif /* ACE_WIN32 */ + return ACE_Time_Value (tv); +} + +ACE_INLINE int +ACE_OS::poll (struct pollfd *pollfds, u_long len, ACE_Time_Value *timeout) +{ +// ACE_TRACE ("ACE_OS::poll"); +#if defined (ACE_HAS_POLL) + int to = timeout == 0 ? -1 : int (timeout->msec ()); + ACE_OSCALL_RETURN (::poll (pollfds, len, to), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_POLL */ +} + +ACE_INLINE int +ACE_OS::poll (struct pollfd *pollfds, u_long len, const ACE_Time_Value &timeout) +{ +// ACE_TRACE ("ACE_OS::poll"); +#if defined (ACE_HAS_POLL) + ACE_OSCALL_RETURN (::poll (pollfds, len, int (timeout.msec ())), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_POLL */ +} + +ACE_INLINE int +ACE_OS::t_accept (ACE_HANDLE handle, int reshandle, + struct t_call *call) +{ +// ACE_TRACE ("ACE_OS::t_accept"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_accept (handle, reshandle, call), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE char * +ACE_OS::t_alloc (ACE_HANDLE handle, int struct_type, + int fields) +{ +// ACE_TRACE ("ACE_OS::t_alloc"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_alloc (handle, struct_type, fields), + char *, 0); +#else + ACE_NOTSUP_RETURN (0); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_bind (ACE_HANDLE handle, struct t_bind *req, + struct t_bind *ret) +{ +// ACE_TRACE ("ACE_OS::t_bind"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_bind (handle, req, ret), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_close (ACE_HANDLE handle) +{ +// ACE_TRACE ("ACE_OS::t_close"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_close (handle), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_connect(int fildes, + struct t_call *sndcall, + struct t_call *rcvcall) +{ +// ACE_TRACE ("ACE_OS::t_connect"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_connect (fildes, sndcall, rcvcall), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE void +ACE_OS::t_error (char *errmsg) +{ +// ACE_TRACE ("ACE_OS::t_error"); +#if defined (ACE_HAS_TLI) + ::t_error (errmsg); +#else +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_free (char *ptr, int struct_type) +{ +// ACE_TRACE ("ACE_OS::t_free"); +#if defined (ACE_HAS_TLI) + if (ptr != 0) + return 0; + ACE_OSCALL_RETURN (::t_free (ptr, struct_type), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_getinfo (ACE_HANDLE handle, struct t_info *info) +{ +// ACE_TRACE ("ACE_OS::t_getinfo"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_getinfo (handle, info), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_getname (ACE_HANDLE handle, + struct netbuf *namep, + int type) +{ +// ACE_TRACE ("ACE_OS::t_getname"); +#if defined (ACE_HAS_SVR4_TLI) + ACE_OSCALL_RETURN (::t_getname (handle, namep, type), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STREAM_PIPES */ +} + +ACE_INLINE int +ACE_OS::t_getstate (ACE_HANDLE handle) +{ +// ACE_TRACE ("ACE_OS::t_getstate"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_getstate (handle), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_listen (ACE_HANDLE handle, struct t_call *call) +{ +// ACE_TRACE ("ACE_OS::t_listen"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_listen (handle, call), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_look (ACE_HANDLE handle) +{ +// ACE_TRACE ("ACE_OS::t_look"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_look (handle), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_open (char *path, int oflag, struct t_info *info) +{ +// ACE_TRACE ("ACE_OS::t_open"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_open (path, oflag, info), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_optmgmt (ACE_HANDLE handle, + struct t_optmgmt *req, + struct t_optmgmt *ret) +{ +// ACE_TRACE ("ACE_OS::t_optmgmt"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_optmgmt (handle, req, ret), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_rcv (ACE_HANDLE handle, + char *buf, + unsigned nbytes, + int *flags) +{ +// ACE_TRACE ("ACE_OS::t_rcv"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_rcv (handle, buf, nbytes, flags), + int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_rcvdis (ACE_HANDLE handle, struct t_discon *discon) +{ +// ACE_TRACE ("ACE_OS::t_rcvdis"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_rcvdis (handle, discon), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_rcvrel (ACE_HANDLE handle) +{ +// ACE_TRACE ("ACE_OS::t_rcvrel"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_rcvrel (handle), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_rcvudata (ACE_HANDLE handle, + struct t_unitdata *unitdata, + int *flags) +{ +// ACE_TRACE ("ACE_OS::t_rcvudata"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_rcvudata (handle, unitdata, flags), + int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_rcvuderr (ACE_HANDLE handle, struct t_uderr *uderr) +{ +// ACE_TRACE ("ACE_OS::t_rcvuderr"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_rcvuderr (handle, uderr), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_snd (ACE_HANDLE handle, char *buf, unsigned nbytes, int flags) +{ +// ACE_TRACE ("ACE_OS::t_snd"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_snd (handle, buf, nbytes, flags), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_snddis (ACE_HANDLE handle, struct t_call *call) +{ +// ACE_TRACE ("ACE_OS::t_snddis"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_snddis (handle, call), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_sndrel (ACE_HANDLE handle) +{ +// ACE_TRACE ("ACE_OS::t_sndrel"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_sndrel (handle), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_sync (ACE_HANDLE handle) +{ +// ACE_TRACE ("ACE_OS::t_sync"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_sync (handle), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE int +ACE_OS::t_unbind (ACE_HANDLE handle) +{ +// ACE_TRACE ("ACE_OS::t_unbind"); +#if defined (ACE_HAS_TLI) + ACE_OSCALL_RETURN (::t_unbind (handle), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TLI */ +} + +ACE_INLINE char * +ACE_OS::compile (const char *instring, char *expbuf, char *endbuf) +{ +// ACE_TRACE ("ACE_OS::compile"); +#if defined (ACE_HAS_REGEX) + ACE_OSCALL_RETURN (::compile (instring, expbuf, endbuf), char *, 0); +#else + ACE_NOTSUP_RETURN (0); +#endif /* ACE_HAS_REGEX */ +} + +ACE_INLINE int +ACE_OS::close (ACE_HANDLE handle) +{ +// ACE_TRACE ("ACE_OS::close"); +#if defined (ACE_WIN32) + return ::CloseHandle (handle) ? 0 : -1; +#else + ACE_OSCALL_RETURN (::close (handle), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::closesocket (ACE_HANDLE handle) +{ +// ACE_TRACE ("ACE_OS::close"); +#if defined (ACE_WIN32) + return ::closesocket ((u_int) handle) == 0 ? 0 : -1; +#else + ACE_OSCALL_RETURN (::close (handle), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::access (const char *path, int amode) +{ +// ACE_TRACE ("ACE_OS::access"); +#if defined (ACE_WIN32) + ACE_OSCALL_RETURN (::_access (path, amode), int, -1); +#elif defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + ACE_OSCALL_RETURN (::access (path, amode), int, -1); +#endif /* ACE_WIN32 && VXWORKS */ +} + + +ACE_INLINE ACE_HANDLE +ACE_OS::creat (LPCTSTR filename, mode_t mode) +{ +// ACE_TRACE ("ACE_OS::creat"); +#if defined (ACE_WIN32) + ACE_OSCALL_RETURN (ACE_OS::open (filename, mode), + ACE_HANDLE, ACE_INVALID_HANDLE); +#else + ACE_OSCALL_RETURN (::creat (filename, mode), + ACE_HANDLE, ACE_INVALID_HANDLE); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::uname (struct utsname *name) +{ +// ACE_TRACE ("ACE_OS::uname"); +#if defined (ACE_WIN32) + size_t maxnamelen = sizeof name->nodename; + ::strcpy (name->sysname, "Win32"); + // Any ideas what these should be? + ::strcpy (name->release, "???"); + ::strcpy (name->version, "???"); + ::strcpy (name->machine, "???"); + + return ACE_OS::hostname (name->nodename, maxnamelen); +#elif defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + ACE_OSCALL_RETURN (::uname (name), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::hostname (char name[], size_t maxnamelen) +{ +// ACE_TRACE ("ACE_OS::uname"); +#if defined (ACE_WIN32) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::GetComputerName (name, LPDWORD (&maxnamelen)), + _result), int, -1); +#else /* !ACE_WIN32 */ + struct utsname host_info; + + if (ACE_OS::uname (&host_info) == -1) + return -1; + else + { + ACE_OS::strncpy (name, host_info.nodename, maxnamelen); + return 0; + } +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::msgctl (int msqid, int cmd, msqid_ds *val) +{ +// ACE_TRACE ("ACE_OS::msgctl"); +#if defined (ACE_HAS_SYSV_IPC) + ACE_OSCALL_RETURN (::msgctl (msqid, cmd, val), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_SYSV_IPC */ +} + +ACE_INLINE int +ACE_OS::msgget (key_t key, int msgflg) +{ +// ACE_TRACE ("ACE_OS::msgget"); +#if defined (ACE_HAS_SYSV_IPC) + ACE_OSCALL_RETURN (::msgget (key, msgflg), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_SYSV_IPC */ +} + +ACE_INLINE int +ACE_OS::msgrcv (int int_id, void *buf, size_t len, + long type, int flags) +{ +// ACE_TRACE ("ACE_OS::msgrcv"); +#if defined (ACE_HAS_SYSV_IPC) +#if defined (ACE_LACKS_POSIX_PROTO) + ACE_OSCALL_RETURN (::msgrcv (int_id, (msgbuf *) buf, len, type, flags), + int, -1); +#else + ACE_OSCALL_RETURN (::msgrcv (int_id, buf, len, type, flags), + int, -1); +#endif /* ACE_LACKS_POSIX_PROTO */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_SYSV_IPC */ +} + +ACE_INLINE int +ACE_OS::msgsnd (int int_id, const void *buf, size_t len, int flags) +{ +// ACE_TRACE ("ACE_OS::msgsnd"); +#if defined (ACE_HAS_SYSV_IPC) +#if defined (ACE_LACKS_POSIX_PROTO) + ACE_OSCALL_RETURN (::msgsnd (int_id, (msgbuf *) buf, len, flags), int, -1); +#else + ACE_OSCALL_RETURN (::msgsnd (int_id, buf, len, flags), int, -1); +#endif /* ACE_LACKS_POSIX_PROTO */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_SYSV_IPC */ +} + +ACE_INLINE u_int +ACE_OS::alarm (u_int delay) +{ +// ACE_TRACE ("ACE_OS::alarm"); + +#if defined (ACE_WIN32) || defined (VXWORKS) + ACE_NOTSUP_RETURN (0); +#else + return ::alarm (delay); +#endif /* ACE_WIN32 || VXWORKS */ +} + +ACE_INLINE int +ACE_OS::dlclose (void *handle) +{ +// ACE_TRACE ("ACE_OS::dlclose"); +#if defined (ACE_HAS_SVR4_DYNAMIC_LINKING) + +#if !defined (ACE_HAS_AUTOMATIC_INIT_FINI) + // SunOS4 does not automatically call _fini()! + void *ptr; + + ACE_OSCALL (::dlsym (handle, "_fini"), void *, 0, ptr); + + if (ptr != 0) + (*((int (*)(void)) ptr)) (); // Call _fini hook explicitly. +#endif /* ACE_HAS_AUTOMATIC_INIT_FINI */ + ACE_OSCALL_RETURN (::dlclose (handle), int, -1); +#elif defined (ACE_WIN32) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::FreeLibrary (handle), _result), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */ +} + +ACE_INLINE char * +ACE_OS::dlerror (void) +{ +// ACE_TRACE ("ACE_OS::dlerror"); +#if defined (ACE_HAS_SVR4_DYNAMIC_LINKING) + ACE_OSCALL_RETURN (::dlerror (), char *, 0); +#else + ACE_NOTSUP_RETURN (0); +#endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */ +} + +ACE_INLINE void * +ACE_OS::dlopen (ACE_DL_TYPE filename, int mode) +{ +// ACE_TRACE ("ACE_OS::dlopen"); +#if defined (ACE_HAS_SVR4_DYNAMIC_LINKING) + void *handle; + ACE_OSCALL (::dlopen (filename, mode), void *, 0, handle); +#if !defined (ACE_HAS_AUTOMATIC_INIT_FINI) + // Some systems (e.g., SunOS4) do not automatically call _init(), so + // we'll have to call it manually. + + void *ptr; + + ACE_OSCALL (::dlsym (handle, "_init"), void *, 0, ptr); + + if (ptr != 0 && (*((int (*)(void)) ptr)) () == -1) // Call _init hook explicitly. + return 0; +#endif /* ACE_HAS_AUTOMATIC_INIT_FINI */ + return handle; +#elif defined (ACE_WIN32) + ACE_OSCALL_RETURN (::LoadLibrary (filename), void *, 0); +#else + ACE_NOTSUP_RETURN (0); +#endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */ +} + +ACE_INLINE void * +ACE_OS::dlsym (void *handle, ACE_DL_TYPE symbolname) +{ +// ACE_TRACE ("ACE_OS::dlsym"); +#if defined (ACE_HAS_SVR4_DYNAMIC_LINKING) +#if defined (ACE_LACKS_POSIX_PROTO) + ACE_OSCALL_RETURN (::dlsym (handle, (char*) symbolname), void *, 0); +#else + ACE_OSCALL_RETURN (::dlsym (handle, symbolname), void *, 0); +#endif /* ACE_LACKS_POSIX_PROTO */ +#elif defined (ACE_WIN32) + ACE_OSCALL_RETURN (::GetProcAddress (handle, symbolname), void *, 0); +#else + ACE_NOTSUP_RETURN (0); +#endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */ +} + +ACE_INLINE void +ACE_OS::exit (int status) +{ +// ACE_TRACE ("ACE_OS::exit"); +#if defined (ACE_WIN32) + ::ExitProcess ((UINT) status); +#else + ::exit (status); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::step (const char *str, char *expbuf) +{ +// ACE_TRACE ("ACE_OS::step"); +#if defined (ACE_HAS_REGEX) + ACE_OSCALL_RETURN (::step (str, expbuf), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_REGEX */ +} + +ACE_INLINE long +ACE_OS::sysinfo (int cmd, char *buf, long count) +{ +// ACE_TRACE ("ACE_OS::sysinfo"); +#if defined (ACE_HAS_SYSINFO) + ACE_OSCALL_RETURN (::sysinfo (cmd, buf, count), long, -1); +#else + ACE_NOTSUP_RETURN (0); +#endif /* ACE_HAS_SYSINFO */ +} + +ACE_INLINE ssize_t +ACE_OS::write (ACE_HANDLE handle, const void *buf, size_t nbyte) +{ +// ACE_TRACE ("ACE_OS::write"); +#if defined (ACE_WIN32) + DWORD bytes_written; // This is set to 0 byte WriteFile. + + if (::WriteFile (handle, buf, nbyte, &bytes_written, 0)) + return (ssize_t) bytes_written; + else + return -1; +#else +#if defined (ACE_LACKS_POSIX_PROTO) + ACE_OSCALL_RETURN (::write (handle, (const char *) buf, nbyte), ssize_t, -1); +#elif defined (ACE_HAS_CHARPTR_SOCKOPT) + ACE_OSCALL_RETURN (::write (handle, (char *) buf, nbyte), ssize_t, -1); +#else + ACE_OSCALL_RETURN (::write (handle, buf, nbyte), ssize_t, -1); +#endif /* ACE_LACKS_POSIX_PROTO */ +#endif /* ACE_WIN32 */ +} + +ACE_INLINE ssize_t +ACE_OS::write (ACE_HANDLE handle, const void *buf, size_t nbyte, + ACE_OVERLAPPED *overlapped) +{ +// ACE_TRACE ("ACE_OS::write"); +#if defined (ACE_WIN32) + DWORD bytes_written; // This is set to 0 byte WriteFile. + + if (::WriteFile (handle, buf, nbyte, &bytes_written, overlapped)) + return (ssize_t) bytes_written; + else + return -1; +#else + return ACE_OS::write (handle, buf, nbyte); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE ssize_t +ACE_OS::read (ACE_HANDLE handle, void *buf, size_t len) +{ +// ACE_TRACE ("ACE_OS::read"); +#if defined (ACE_WIN32) + DWORD ok_len; + return ::ReadFile (handle, buf, len, &ok_len, 0) ? (ssize_t) ok_len : -1; +#else +#if defined (ACE_LACKS_POSIX_PROTO) || defined (ACE_HAS_CHARPTR_SOCKOPT) + ACE_OSCALL_RETURN (::read (handle, (char *) buf, len), ssize_t, -1); +#else + ACE_OSCALL_RETURN (::read (handle, buf, len), ssize_t, -1); +#endif /* ACE_LACKS_POSIX_PROTO */ +#endif /* ACE_WIN32 */ +} + +ACE_INLINE ssize_t +ACE_OS::read (ACE_HANDLE handle, void *buf, size_t len, + ACE_OVERLAPPED *overlapped) +{ +// ACE_TRACE ("ACE_OS::read"); +#if defined (ACE_WIN32) + DWORD ok_len; + return ::ReadFile (handle, buf, len, &ok_len, overlapped) ? (ssize_t) ok_len : -1; +#else + return ACE_OS::read (handle, buf, len); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::getmsg (ACE_HANDLE handle, + struct strbuf *ctl, + struct strbuf *data, + int *flags) +{ +// ACE_TRACE ("ACE_OS::getmsg"); +#if defined (ACE_HAS_STREAM_PIPES) + ACE_OSCALL_RETURN (::getmsg (handle, ctl, data, flags), int, -1); +#else + // I'm not sure how to implement this correctly. + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STREAM_PIPES */ +} + +ACE_INLINE int +ACE_OS::getpmsg (ACE_HANDLE handle, + struct strbuf *ctl, + struct strbuf *data, + int *band, + int *flags) +{ +// ACE_TRACE ("ACE_OS::getpmsg"); +#if defined (ACE_HAS_STREAM_PIPES) + ACE_OSCALL_RETURN (::getpmsg (handle, ctl, data, band, flags), int, -1); +#else + // I'm not sure how to implement this correctly. + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STREAM_PIPES */ +} + +ACE_INLINE int +ACE_OS::getrusage (int who, struct rusage *ru) +{ +// ACE_TRACE ("ACE_OS::getrusage"); + +#if defined (ACE_HAS_SYSCALL_GETRUSAGE) +// This nonsense is necessary for HP/UX... + ACE_OSCALL_RETURN (::syscall (SYS_GETRUSAGE, who, ru), int, -1); +#elif defined (ACE_HAS_GETRUSAGE) +#if defined (ACE_WIN32) + FILETIME dummy_1, dummy_2; + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::GetProcessTimes (::GetCurrentProcess(), + &dummy_1, // start + &dummy_2, // exited + &ru->ru_stime, + &ru->ru_utime), + _result), + int, -1); +#else + ACE_OSCALL_RETURN (::getrusage (who, ru), int, -1); +#endif /* ACE_WIN32 */ +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_SYSCALL_GETRUSAGE */ +} + +ACE_INLINE int +ACE_OS::isastream (ACE_HANDLE handle) +{ +// ACE_TRACE ("ACE_OS::isastream"); +#if defined (ACE_HAS_STREAM_PIPES) + ACE_OSCALL_RETURN (::isastream (handle), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STREAM_PIPES */ +} + +ACE_INLINE void * +ACE_OS::mmap (void *addr, + size_t len, + int prot, + int flags, + ACE_HANDLE file_handle, + off_t off, + ACE_HANDLE *file_mapping) +{ +// ACE_TRACE ("ACE_OS::mmap"); +#if defined (ACE_WIN32) + int nt_flags; + ACE_HANDLE local_handle = ACE_INVALID_HANDLE; + + // Ensure that file_mapping is non-zero. + if (file_mapping == 0) + file_mapping = &local_handle; + + if (ACE_BIT_ENABLED (flags, MAP_PRIVATE)) + { + prot = PAGE_WRITECOPY; + nt_flags = FILE_MAP_COPY; + } + else if (ACE_BIT_ENABLED (flags, MAP_SHARED)) + { + if (ACE_BIT_ENABLED (prot, PAGE_READONLY)) + nt_flags = FILE_MAP_READ; + if (ACE_BIT_ENABLED (prot, PAGE_READWRITE)) + nt_flags = FILE_MAP_WRITE; + } + + // Only create a new handle if we didn't have a valid one passed in. + if (*file_mapping == ACE_INVALID_HANDLE) + *file_mapping = ::CreateFileMapping (file_handle, 0, + prot, 0, len, 0); + if (*file_mapping == 0) + ACE_FAIL_RETURN (MAP_FAILED); + /* NOTREACHED */ + + void *addr_mapping = ::MapViewOfFileEx (*file_mapping, nt_flags, 0, + off, len, addr); + + // Only close this down if we used the temporary. + if (file_mapping == &local_handle) + ::CloseHandle (*file_mapping); + + if (addr_mapping == 0) + ACE_FAIL_RETURN (MAP_FAILED); + /* NOTREACHED */ + else if (ACE_BIT_ENABLED (flags, MAP_FIXED) + && addr_mapping != addr) + { + errno = EINVAL; + return MAP_FAILED; + } + else + return addr_mapping; +#elif !defined (ACE_LACKS_MMAP) + ACE_OSCALL_RETURN ((void *) ::mmap ((ACE_MMAP_TYPE) addr, len, + prot, flags, file_handle, off), + void *, MAP_FAILED); +#else + ACE_NOTSUP_RETURN (MAP_FAILED); +#endif /*ACE_WIN32 */ +} + +// Implements simple read/write control for pages. Affects a page if +// part of the page is referenced. Currently PROT_READ, PROT_WRITE, +// and PROT_RDWR has been mapped in OS.h. This needn't have anything +// to do with a mmap region. + +ACE_INLINE int +ACE_OS::mprotect (void *addr, size_t len, int prot) +{ +// ACE_TRACE ("ACE_OS::mprotect"); +#if defined (ACE_WIN32) + DWORD dummy; // Sigh! + return ::VirtualProtect(addr, len, prot, &dummy) ? 0 : -1; +#elif !defined (ACE_LACKS_MMAP) + ACE_OSCALL_RETURN (::mprotect ((ACE_MMAP_TYPE) addr, len, prot), int, -1); +#else + ACE_NOTSUP_RETURN ((int) MAP_FAILED); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::msync (void *addr, size_t len, int sync) +{ +// ACE_TRACE ("ACE_OS::msync"); +#if defined (ACE_WIN32) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::FlushViewOfFile (addr, len), _result), int, -1); +#elif !defined (ACE_LACKS_MSYNC) + ACE_OSCALL_RETURN (::msync ((ACE_MMAP_TYPE) addr, len, sync), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::munmap (void *addr, size_t len) +{ +// ACE_TRACE ("ACE_OS::munmap"); +#if defined (ACE_WIN32) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::UnmapViewOfFile (addr), _result), int, -1); +#elif !defined (ACE_LACKS_MMAP) + ACE_OSCALL_RETURN (::munmap ((ACE_MMAP_TYPE) addr, len), int, -1); +#else + ACE_NOTSUP_RETURN ((int) MAP_FAILED); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::madvise (caddr_t addr, size_t len, int advice) +{ +// ACE_TRACE ("ACE_OS::madvise"); +#if defined (ACE_WIN32) + ACE_NOTSUP_RETURN (-1); +#elif !defined (ACE_LACKS_MADVISE) + ACE_OSCALL_RETURN (::madvise (addr, len, advice), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::putmsg (ACE_HANDLE handle, const struct strbuf *ctl, + const struct strbuf *data, int flags) +{ +// ACE_TRACE ("ACE_OS::putmsg"); +#if defined (ACE_HAS_STREAM_PIPES) + ACE_OSCALL_RETURN (::putmsg (handle, ctl, data, flags), int, -1); +#else + if (ctl == 0 && data == 0) + { + errno = EINVAL; + return 0; + } + // Handle the two easy cases. + else if (ctl != 0) + return ACE_OS::write (handle, ctl->buf, ctl->len); + else if (data != 0) + return ACE_OS::write (handle, data->buf, data->len); + else + { + // This is the hard case. + char *buf; + ACE_NEW_RETURN (buf, char [ctl->len + data->len], -1); + ACE_OS::memcpy (buf, ctl->buf, ctl->len); + ACE_OS::memcpy (buf + ctl->len, data->buf, data->len); + int result = ACE_OS::write (handle, buf, ctl->len + data->len); + delete [] buf; + return result; + } +#endif /* ACE_HAS_STREAM_PIPES */ +} + +ACE_INLINE int +ACE_OS::putpmsg (ACE_HANDLE handle, const struct strbuf *ctl, + const struct strbuf *data, int band, int flags) +{ +// ACE_TRACE ("ACE_OS::putpmsg"); +#if defined (ACE_HAS_STREAM_PIPES) + ACE_OSCALL_RETURN (::putpmsg (handle, ctl, data, band, flags), int, -1); +#else + return ACE_OS::putmsg (handle, ctl, data, flags); +#endif /* ACE_HAS_STREAM_PIPES */ +} + +ACE_INLINE int +ACE_OS::semctl (int int_id, int semnum, int cmd, semun value) +{ +// ACE_TRACE ("ACE_OS::semctl"); +#if defined (ACE_HAS_SYSV_IPC) + ACE_OSCALL_RETURN (::semctl (int_id, semnum, cmd, value), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_SYSV_IPC */ +} + +ACE_INLINE int +ACE_OS::semget (key_t key, int nsems, int flags) +{ +// ACE_TRACE ("ACE_OS::semget"); +#if defined (ACE_HAS_SYSV_IPC) + ACE_OSCALL_RETURN (::semget (key, nsems, flags), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_SYSV_IPC */ +} + +ACE_INLINE int +ACE_OS::semop (int int_id, struct sembuf *sops, size_t nsops) +{ +// ACE_TRACE ("ACE_OS::semop"); +#if defined (ACE_HAS_SYSV_IPC) + ACE_OSCALL_RETURN (::semop (int_id, sops, nsops), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_SYSV_IPC */ +} + +ACE_INLINE void * +ACE_OS::shmat (int int_id, void *shmaddr, int shmflg) +{ +// ACE_TRACE ("ACE_OS::shmat"); +#if defined (ACE_HAS_SYSV_IPC) +#if defined (ACE_LACKS_POSIX_PROTO) + ACE_OSCALL_RETURN (::shmat (int_id, (char *)shmaddr, shmflg), void *, (void *) -1); +#else + ACE_OSCALL_RETURN (::shmat (int_id, shmaddr, shmflg), void *, (void *) -1); +#endif /* ACE_LACKS_POSIX_PROTO */ +#else + ACE_NOTSUP_RETURN ((void *) -1); +#endif /* ACE_HAS_SYSV_IPC */ +} + +ACE_INLINE int +ACE_OS::shmctl (int int_id, int cmd, struct shmid_ds *buf) +{ +// ACE_TRACE ("ACE_OS::shmctl"); +#if defined (ACE_HAS_SYSV_IPC) + ACE_OSCALL_RETURN (::shmctl (int_id, cmd, buf), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_SYSV_IPC */ +} + +ACE_INLINE int +ACE_OS::shmdt (void *shmaddr) +{ +// ACE_TRACE ("ACE_OS::shmdt"); +#if defined (ACE_HAS_SYSV_IPC) + ACE_OSCALL_RETURN (::shmdt ((char *) shmaddr), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_SYSV_IPC */ +} + +ACE_INLINE int +ACE_OS::shmget (key_t key, int size, int flags) +{ +// ACE_TRACE ("ACE_OS::shmget"); +#if defined (ACE_HAS_SYSV_IPC) + ACE_OSCALL_RETURN (::shmget (key, size, flags), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_SYSV_IPC */ +} + +ACE_INLINE ACE_HANDLE +ACE_OS::open (LPCTSTR filename, + int mode, + int perms) +{ +// ACE_TRACE ("ACE_OS::open"); +#if defined (ACE_WIN32) + // Warning: This function ignores _O_APPEND + + DWORD access = GENERIC_READ; + if (ACE_BIT_ENABLED (mode, O_WRONLY)) + access = GENERIC_WRITE; + else if (ACE_BIT_ENABLED (mode, O_RDWR)) + access = GENERIC_READ | GENERIC_WRITE; + + DWORD creation = OPEN_EXISTING; + + if ((mode & (_O_CREAT | _O_EXCL)) == (_O_CREAT | _O_EXCL)) + creation = CREATE_NEW; + else if (ACE_BIT_ENABLED (mode, _O_CREAT)) + creation = OPEN_ALWAYS; + else if (ACE_BIT_ENABLED (mode, _O_TRUNC)) + creation = TRUNCATE_EXISTING; + + DWORD flags = 0; + if (ACE_BIT_ENABLED (mode, FILE_FLAG_OVERLAPPED)) + flags = FILE_FLAG_OVERLAPPED; + if (ACE_BIT_ENABLED (mode, _O_TEMPORARY)) + flags |= FILE_FLAG_DELETE_ON_CLOSE; + + ACE_HANDLE h = ::CreateFile (filename, access, + FILE_SHARE_READ | FILE_SHARE_WRITE, + 0, creation, + flags, + 0); + + if (h == ACE_INVALID_HANDLE) + { + switch ((errno = ::GetLastError ())) + { + case ERROR_FILE_EXISTS: + errno = EEXIST; + } + } + return h; +#else + ACE_OSCALL_RETURN (::open (filename, mode, perms), ACE_HANDLE, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE char * +ACE_OS::ctime (const time_t *t) +{ +// ACE_TRACE ("ACE_OS::ctime"); +#if defined (ACE_HAS_BROKEN_CTIME) + ACE_OSCALL_RETURN (::asctime (::localtime (t)), char *, 0); +#else + ACE_OSCALL_RETURN (::ctime (t), char *, 0); +#endif // ACE_HAS_BROKEN_CTIME) +} + +ACE_INLINE char * +ACE_OS::ctime_r (const time_t *t, char *buf, int buflen) +{ +// ACE_TRACE ("ACE_OS::ctime_r"); + char *result; +#if defined (ACE_HAS_REENTRANT_FUNCTIONS) && defined (ACE_MT_SAFE) +#if !defined (AIX) && !defined (UNIXWARE) + ACE_OSCALL (::ctime_r (t, buf, buflen), char *, 0, result); +#elif defined (ACE_HAS_ONLY_TWO_PARAMS_FOR_ASCTIME_R_AND_CTIME_R) + char *result; + ACE_OSCALL (::ctime_r (t, buf), char *, 0, result); + ::strncpy (buf, result, TIMELEN); + return buf; +#else + ACE_OSCALL (::ctime_r (t, buf), char *, 0, result); +#endif /* !defined (AIX) */ +#else + ACE_OSCALL (::ctime (t), char *, 0, result); +#endif + ::strncpy (buf, result, buflen); + return buf; +} + +ACE_INLINE struct tm * +ACE_OS::localtime (const time_t *t) +{ +// ACE_TRACE ("ACE_OS::localtime"); + ACE_OSCALL_RETURN (::localtime (t), struct tm *, 0); +} + +ACE_INLINE struct tm * +ACE_OS::localtime_r (const time_t *t, struct tm *res) +{ +// ACE_TRACE ("ACE_OS::localtime_r"); +#if defined (ACE_HAS_REENTRANT_FUNCTIONS) && defined (ACE_MT_SAFE) + ACE_OSCALL_RETURN (::localtime_r (t, res), struct tm *, 0); +#else + ACE_OSCALL_RETURN (::localtime (t), struct tm *, 0); +#endif +} + +ACE_INLINE char * +ACE_OS::asctime (const struct tm *t) +{ +// ACE_TRACE ("ACE_OS::asctime"); + ACE_OSCALL_RETURN (::asctime (t), char *, 0); +} + +ACE_INLINE char * +ACE_OS::asctime_r (const struct tm *t, char *buf, int buflen) +{ +// ACE_TRACE ("ACE_OS::asctime_r"); +#if defined (ACE_HAS_REENTRANT_FUNCTIONS) && defined (ACE_MT_SAFE) +#if !defined (AIX) && !defined (UNIXWARE) + ACE_OSCALL_RETURN (::asctime_r (t, buf, buflen), char *, 0); +#elif defined (ACE_HAS_ONLY_TWO_PARAMS_FOR_ASCTIME_R_AND_CTIME_R) + char *result; + ACE_OSCALL (::asctime_r (t, buf), char *, 0, result); + ::strncpy (buf, result, TIMELEN); + return buf; +#else + ACE_OSCALL_RETURN (::asctime_r (t, buf), char *, 0); +#endif /* !defined (AIX) */ +#else + ACE_OSCALL_RETURN (::asctime (t), char *, 0); +#endif +} + +ACE_INLINE int +ACE_OS::flock_init (ACE_OS::flock_t *lock, + int flags, + LPCTSTR name, + mode_t perms) +{ +// ACE_TRACE ("ACE_OS::flock_init"); +#if defined (ACE_WIN32) + // Once initialized, these values are never changed. + lock->overlapped_.Internal = 0; + lock->overlapped_.InternalHigh = 0; + lock->overlapped_.OffsetHigh = 0; + lock->overlapped_.hEvent = INVALID_HANDLE_VALUE; +#endif /* ACE_WIN32 */ + lock->handle_ = ACE_INVALID_HANDLE; + + if (name != 0) + { + ACE_OSCALL (ACE_OS::open (name, flags, perms), + ACE_HANDLE, + ACE_INVALID_HANDLE, + lock->handle_); + return lock->handle_ == ACE_INVALID_HANDLE ? -1 : 0; + } + else + return 0; +} + +ACE_INLINE int +ACE_OS::flock_wrlock (ACE_OS::flock_t *lock, short whence, off_t start, off_t len) +{ +// ACE_TRACE ("ACE_OS::flock_wrlock"); +#if defined (ACE_WIN32) + lock->overlapped_.Offset = start; + if (len == 0) + len = ::GetFileSize (lock->handle_, NULL); + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::LockFileEx (lock->handle_, LOCKFILE_EXCLUSIVE_LOCK, 0, len, 0, &lock->overlapped_), + _result), int, -1); +#elif defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + lock->lock_.l_whence = whence; + lock->lock_.l_start = start; + lock->lock_.l_len = len; + lock->lock_.l_type = F_WRLCK; // set write lock + // block, if no access + ACE_OSCALL_RETURN (::fcntl (lock->handle_, F_SETLKW, &lock->lock_), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::flock_rdlock (ACE_OS::flock_t *lock, short whence, off_t start, off_t len) +{ +// ACE_TRACE ("ACE_OS::flock_rdlock"); +#if defined (ACE_WIN32) + lock->overlapped_.Offset = start; + if (len == 0) + len = ::GetFileSize (lock->handle_, NULL); + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::LockFileEx (lock->handle_, 0, 0, len, 0, &lock->overlapped_), + _result), int, -1); +#elif defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + lock->lock_.l_whence = whence; + lock->lock_.l_start = start; + lock->lock_.l_len = len; + lock->lock_.l_type = F_RDLCK; // set read lock + // block, if no access + ACE_OSCALL_RETURN (::fcntl (lock->handle_, F_SETLKW, &lock->lock_), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::flock_trywrlock (ACE_OS::flock_t *lock, short whence, off_t start, off_t len) +{ +// ACE_TRACE ("ACE_OS::flock_trywrlock"); +#if defined (ACE_WIN32) + lock->overlapped_.Offset = start; + if (len == 0) + len = ::GetFileSize (lock->handle_, NULL); + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::LockFileEx (lock->handle_, LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK, 0, len, 0, &lock->overlapped_), + _result), int, -1); +#elif defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + lock->lock_.l_whence = whence; + lock->lock_.l_start = start; + lock->lock_.l_len = len; + lock->lock_.l_type = F_WRLCK; // set write lock + + // Does not block, if no access, returns -1. + ACE_OSCALL_RETURN (::fcntl (lock->handle_, F_SETLK, &lock->lock_), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::flock_tryrdlock (ACE_OS::flock_t *lock, short whence, off_t start, off_t len) +{ +// ACE_TRACE ("ACE_OS::flock_tryrdlock"); +#if defined (ACE_WIN32) + lock->overlapped_.Offset = start; + if (len == 0) + len = ::GetFileSize (lock->handle_, NULL); + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::LockFileEx (lock->handle_, LOCKFILE_FAIL_IMMEDIATELY, 0, len, 0, &lock->overlapped_), + _result), int, -1); +#elif defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + lock->lock_.l_whence = whence; + lock->lock_.l_start = start; + lock->lock_.l_len = len; + lock->lock_.l_type = F_RDLCK; // set read lock + + // Does not block, if no access, returns -1. + ACE_OSCALL_RETURN (::fcntl (lock->handle_, F_SETLK, &lock->lock_), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::flock_unlock (ACE_OS::flock_t *lock, short whence, off_t start, off_t len) +{ +// ACE_TRACE ("ACE_OS::flock_unlock"); +#if defined (ACE_WIN32) + lock->overlapped_.Offset = start; + if (len == 0) + len = ::GetFileSize (lock->handle_, NULL); + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::UnlockFileEx (lock->handle_, 0, len, 0, &lock->overlapped_), + _result), int, -1); +#elif defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + lock->lock_.l_whence = whence; + lock->lock_.l_start = start; + lock->lock_.l_len = len; + lock->lock_.l_type = F_UNLCK; // Unlock file. + + // release lock + ACE_OSCALL_RETURN (::fcntl (lock->handle_, F_SETLK, &lock->lock_), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::flock_destroy (ACE_OS::flock_t *lock) +{ +// ACE_TRACE ("ACE_OS::flock_destroy"); + if (lock->handle_ != ACE_INVALID_HANDLE) + { + ACE_OS::flock_unlock (lock); + ACE_OS::close (lock->handle_); + lock->handle_ = ACE_INVALID_HANDLE; + } + return 0; +} + +ACE_INLINE int +ACE_OS::execv (const char *path, char *const argv[]) +{ +// ACE_TRACE ("ACE_OS::execv"); +#if defined (ACE_WIN32) || defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + ACE_OSCALL_RETURN (::execv (path, argv), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::execve (const char *path, char *const argv[], char *const envp[]) +{ +// ACE_TRACE ("ACE_OS::execve"); +#if defined (ACE_WIN32) || defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + ACE_OSCALL_RETURN (::execve (path, argv, envp), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::execvp (const char *file, char *const argv[]) +{ +// ACE_TRACE ("ACE_OS::execvp"); +#if defined (ACE_WIN32) || defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + ACE_OSCALL_RETURN (::execvp (file, argv), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::execl (const char *path, const char *arg0, ...) +{ +// ACE_TRACE ("ACE_OS::execl"); +#if defined (ACE_WIN32) || defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + ACE_NOTSUP_RETURN (-1); +// Need to write this code. +// ACE_OSCALL_RETURN (::execv (path, argv), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::execle (const char *path, const char *arg0, ...) +{ +// ACE_TRACE ("ACE_OS::execle"); +#if defined (ACE_WIN32) || defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + ACE_NOTSUP_RETURN (-1); +// Need to write this code. +// ACE_OSCALL_RETURN (::execve (path, argv, envp), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::execlp (const char *file, const char *arg0, ...) +{ +// ACE_TRACE ("ACE_OS::execlp"); +#if defined (ACE_WIN32) || defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + ACE_NOTSUP_RETURN (-1); +// Need to write this code. +// ACE_OSCALL_RETURN (::execvp (file, argv), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE FILE * +ACE_OS::fdopen (ACE_HANDLE handle, const char *mode) +{ +// ACE_TRACE ("ACE_OS::fdopen"); +#if defined (ACE_WIN32) + // kernel file handle -> FILE* conversion... + // Options: _O_APPEND, _O_RDONLY and _O_TEXT are lost + + FILE *file = 0; + + int crt_handle = ::_open_osfhandle ((long) handle, 0); + + if (crt_handle != -1) + { + file = ::_fdopen (crt_handle, mode); + + if (!file) + ::_close (crt_handle); + } + + return file; +#else + ACE_OSCALL_RETURN (::fdopen (handle, mode), FILE *, 0); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::ftruncate (ACE_HANDLE handle, off_t offset) +{ +// ACE_TRACE ("ACE_OS::ftruncate"); +#if defined (ACE_WIN32) + if (::SetFilePointer (handle, offset, NULL, FILE_BEGIN) != -1) + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::SetEndOfFile (handle), _result), int, -1); + else + ACE_FAIL_RETURN (-1); + /* NOTREACHED */ +#else + ACE_OSCALL_RETURN (::ftruncate (handle, offset), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::getrlimit (int resource, struct rlimit *rl) +{ +// ACE_TRACE ("ACE_OS::getrlimit"); + +#if defined (ACE_WIN32) || defined (ACE_LACKS_RLIMIT) + ACE_NOTSUP_RETURN (-1); +#else + ACE_OSCALL_RETURN (::getrlimit (resource, rl), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::setrlimit (int resource, ACE_SETRLIMIT_TYPE *rl) +{ +// ACE_TRACE ("ACE_OS::setrlimit"); + +#if defined (ACE_WIN32) || defined (ACE_LACKS_RLIMIT) + ACE_NOTSUP_RETURN (-1); +#else + ACE_OSCALL_RETURN (::setrlimit (resource, rl), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::socketpair (int domain, int type, + int protocol, ACE_HANDLE sv[2]) +{ +// ACE_TRACE ("ACE_OS::socketpair"); +#if defined (ACE_WIN32) || defined (ACE_LACKS_SOCKETPAIR) + ACE_NOTSUP_RETURN (-1); +#else + ACE_OSCALL_RETURN (::socketpair (domain, type, protocol, sv), + int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE ACE_HANDLE +ACE_OS::dup (ACE_HANDLE handle) +{ +// ACE_TRACE ("ACE_OS::dup"); +#if defined (ACE_WIN32) + ACE_HANDLE new_fd; + if (::DuplicateHandle(::GetCurrentProcess (), + handle, + ::GetCurrentProcess(), + &new_fd, + 0, + TRUE, + DUPLICATE_SAME_ACCESS)) + return new_fd; + else + ACE_FAIL_RETURN (ACE_INVALID_HANDLE); + /* NOTREACHED */ +#elif defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + ACE_OSCALL_RETURN (::dup (handle), ACE_HANDLE, ACE_INVALID_HANDLE); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::dup2 (ACE_HANDLE oldhandle, ACE_HANDLE newhandle) +{ +// ACE_TRACE ("ACE_OS::dup2"); +#if defined (ACE_WIN32) || defined (VXWORKS) + ACE_NOTSUP_RETURN (-1); +#else + ACE_OSCALL_RETURN (::dup2 (oldhandle, newhandle), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE hrtime_t +ACE_OS::gethrtime (void) +{ +// ACE_TRACE ("ACE_OS::gethrtime"); +#if defined (ACE_HAS_HI_RES_TIMER) + ACE_OSCALL_RETURN (::gethrtime (), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_HI_RES_TIMER */ +} + +ACE_INLINE int +ACE_OS::fdetach (const char *file) +{ +// ACE_TRACE ("ACE_OS::fdetach"); +#if defined (ACE_HAS_STREAM_PIPES) + ACE_OSCALL_RETURN (::fdetach (file), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STREAM_PIPES */ +} + +ACE_INLINE int +ACE_OS::fattach (int handle, const char *path) +{ +// ACE_TRACE ("ACE_OS::fattach"); +#if defined (ACE_HAS_STREAM_PIPES) + ACE_OSCALL_RETURN (::fattach (handle, path), int, -1); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STREAM_PIPES */ +} + +ACE_INLINE pid_t +ACE_OS::fork (void) +{ +// ACE_TRACE ("ACE_OS::fork"); +#if defined (ACE_WIN32) || defined (VXWORKS) + ACE_NOTSUP_RETURN (pid_t (-1)); +#else + ACE_OSCALL_RETURN (::fork (), pid_t, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE pid_t +ACE_OS::getpid (void) +{ +// ACE_TRACE ("ACE_OS::getpid"); +#if defined (ACE_WIN32) + return ::GetCurrentProcessId(); +#elif defined (VXWORKS) + // getpid() is not supported: just one process anyways + return 0; +#else + ACE_OSCALL_RETURN (::getpid (), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE off_t +ACE_OS::lseek (ACE_HANDLE handle, off_t offset, int whence) +{ +// ACE_TRACE ("ACE_OS::lseek"); + +#if defined (ACE_WIN32) +#if SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END +#error Windows NT is evil AND rude! + switch (whence) + { + case SEEK_SET: + whence = FILE_BEGIN; + break; + case SEEK_CUR: + whence = FILE_CURRENT; + break; + case SEEK_END: + whence = FILE_END; + break; + default: + errno = EINVAL; + return -1; // rather safe than sorry + } +#endif /* SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END */ + return ::SetFilePointer (handle, offset, NULL, whence); +#else + ACE_OSCALL_RETURN (::lseek (handle, offset, whence), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE pid_t +ACE_OS::wait (int *stat_loc) +{ +// ACE_TRACE ("ACE_OS::wait"); +#if defined (ACE_WIN32) || defined (VXWORKS) + ACE_NOTSUP_RETURN (0); +#else +#if !defined (AIX) +#if defined (ACE_HAS_UNION_WAIT) + ACE_OSCALL_RETURN (::wait ((union wait *) stat_loc), pid_t, -1); +#else + ACE_OSCALL_RETURN (::wait (stat_loc), pid_t, -1); +#endif /* ACE_HAS_UNION_WAIT */ +#else + ACE_OSCALL_RETURN (::wait ((union wait *) stat_loc), pid_t, -1); +#endif /* defined (AIX) */ +#endif /* defined (ACE_WIN32) */ +} + +ACE_INLINE pid_t +ACE_OS::waitpid (pid_t pid, int *stat_loc, int options) +{ +// ACE_TRACE ("ACE_OS::waitpid"); +#if defined (ACE_WIN32) || defined (VXWORKS) + ACE_NOTSUP_RETURN (0); +#else + ACE_OSCALL_RETURN (::waitpid (pid, stat_loc, options), + pid_t, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::ioctl (ACE_HANDLE handle, int cmd, void *val) +{ +// ACE_TRACE ("ACE_OS::ioctl"); + +#if defined (ACE_WIN32) + ACE_SOCKET sock = (ACE_SOCKET) handle; + ACE_SOCKCALL_RETURN (::ioctlsocket (sock, cmd, (u_long *) val), int, -1); +#elif defined (VXWORKS) + // this may not work very well... + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::ioctl (handle, cmd, (int) val), _result), + int, ERROR); +#else + ACE_OSCALL_RETURN (::ioctl (handle, cmd, val), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::kill (pid_t pid, int signum) +{ + // ACE_TRACE ("ACE_OS::kill"); +#if defined (ACE_WIN32) + // Create a handle for the given process id. + ACE_HANDLE process_handle = + ::OpenProcess (PROCESS_ALL_ACCESS, + FALSE, // New handle is not inheritable. + pid); + + if (process_handle == ACE_INVALID_HANDLE) + return -1; + else + { + // Kill the process associated with process_handle. + BOOL terminate_result = ::TerminateProcess (process_handle, 0); + // Free up the kernel resources. + ACE_OS::close (process_handle); + return terminate_result; + } +#else + ACE_OSCALL_RETURN (::kill (pid, signum), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::sigaction (int signum, + const struct sigaction *nsa, + struct sigaction *osa) +{ +// ACE_TRACE ("ACE_OS::sigaction"); +#if defined (ACE_WIN32) + struct sigaction sa; + + if (osa == 0) + osa = &sa; + + osa->sa_handler = ::signal (signum, nsa->sa_handler); + return osa->sa_handler == SIG_ERR ? -1 : 0; +#elif defined (ACE_LACKS_POSIX_PROTO) + ACE_OSCALL_RETURN (::sigaction (signum, (struct sigaction*) nsa, osa), int, -1); +#else + ACE_OSCALL_RETURN (::sigaction (signum, nsa, osa), int, -1); +#endif /* ACE_LACKS_POSIX_PROTO */ +} + +ACE_INLINE char * +ACE_OS::getcwd (char *buf, size_t size) +{ +// ACE_TRACE ("ACE_OS::getcwd"); +#if defined (ACE_WIN32) + return ::_getcwd (buf, size); +#else + ACE_OSCALL_RETURN (::getcwd (buf, size), char *, 0); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::sleep (u_int seconds) +{ +// ACE_TRACE ("ACE_OS::sleep"); +#if defined (ACE_WIN32) + ::Sleep (seconds * 1000); + return 0; +#elif defined (VXWORKS) + struct timespec rqtp; + // Initializer doesn't work with Green Hills 1.8.7 + rqtp.tv_sec = seconds; + rqtp.tv_nsec = 0L; + ACE_OSCALL_RETURN (::nanosleep (&rqtp, NULL), int, -1); +#else + ACE_OSCALL_RETURN (::sleep (seconds), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_OS::sleep (const ACE_Time_Value &tv) +{ +// ACE_TRACE ("ACE_OS::sleep"); +#if defined (ACE_WIN32) + ::Sleep (tv.msec ()); + return 0; +#elif defined (ACE_HAS_POLL) + ACE_OSCALL_RETURN (::poll (0, 0, tv.msec ()), int, -1); +#else + ACE_OSCALL_RETURN (::select (0, 0, 0, 0, (timeval *) &tv), int, -1); +#endif /* ACE_WIN32 */ +} + +ACE_INLINE char * +ACE_OS::getenv (const char *symbol) +{ +// ACE_TRACE ("ACE_OS::getenv"); + ACE_OSCALL_RETURN (::getenv (symbol), char *, 0); +} + +ACE_INLINE +ACE_Str_Buf::ACE_Str_Buf (void *b, int l, int max) + : buf (b), + len (l), + maxlen (max) +{ +} + +#if defined (ACE_HAS_UNICODE) + +ACE_INLINE wchar_t * +ACE_OS::strcat (wchar_t *s, const wchar_t *t) +{ +// ACE_TRACE ("ACE_OS::strcat"); + return ::wcscat (s, t); +} + +#if 0 +ACE_INLINE wchar_t * +ACE_OS::strstr (const wchar_t *s, const wchar_t *t) +{ +// ACE_TRACE ("ACE_OS::strstr"); + return ::wcsstr (s, t); +} + +ACE_INLINE wchar_t * +ACE_OS::strdup (const wchar_t *s) +{ +// ACE_TRACE ("ACE_OS::strdup"); + return ::wcsdup (s); +} +#endif /* 0 */ + +ACE_INLINE wchar_t * +ACE_OS::strchr (const wchar_t *s, int c) +{ +// ACE_TRACE ("ACE_OS::strchr"); + return ::wcschr (s, c); +} + +ACE_INLINE wchar_t * +ACE_OS::strrchr (const wchar_t *s, int c) +{ +// ACE_TRACE ("ACE_OS::strrchr"); + return ::wcsrchr (s, c); +} + +ACE_INLINE int +ACE_OS::strcmp (const wchar_t *s, const wchar_t *t) +{ +// ACE_TRACE ("ACE_OS::strcmp"); + return ::wcscmp (s, t); +} + +ACE_INLINE wchar_t * +ACE_OS::strcpy (wchar_t *s, const wchar_t *t) +{ +// ACE_TRACE ("ACE_OS::strcpy"); + return ::wcscpy (s, t); +} + +ACE_INLINE size_t +ACE_OS::strlen (const wchar_t *s) +{ +// ACE_TRACE ("ACE_OS::strlen"); + return ::wcslen (s); +} + +ACE_INLINE int +ACE_OS::strncmp (const wchar_t *s, const wchar_t *t, size_t len) +{ +// ACE_TRACE ("ACE_OS::strncmp"); + return ::wcsncmp (s, t, len); +} + +ACE_INLINE wchar_t * +ACE_OS::strncpy (wchar_t *s, const wchar_t *t, size_t len) +{ +// ACE_TRACE ("ACE_OS::strncpy"); + return ::wcsncpy (s, t, len); +} + +ACE_INLINE wchar_t * +ACE_OS::strtok (wchar_t *s, const wchar_t *tokens) +{ +// ACE_TRACE ("ACE_OS::strtok"); + return ::wcstok (s, tokens); +} + +ACE_INLINE long +ACE_OS::strtol (const wchar_t *s, wchar_t **ptr, int base) +{ +// ACE_TRACE ("ACE_OS::strtol"); + return ::wcstol (s, ptr, base); +} +#endif /* ACE_HAS_UNICODE */ diff --git a/ace/Obstack.cpp b/ace/Obstack.cpp new file mode 100644 index 00000000000..5bd969201bb --- /dev/null +++ b/ace/Obstack.cpp @@ -0,0 +1,119 @@ +// Obstack.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Obstack.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_Obstack) + +void +ACE_Obstack::dump (void) const +{ + ACE_TRACE ("ACE_Obstack::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "size_ = %d\n", this->size_)); + ACE_DEBUG ((LM_DEBUG, "head_ = %x\n", this->head_)); + ACE_DEBUG ((LM_DEBUG, "curr_ = %x\n", this->curr_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Obchunk) + +void +ACE_Obchunk::dump (void) const +{ + ACE_TRACE ("ACE_Obchunk::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "end_ = %x\n", this->end_)); + ACE_DEBUG ((LM_DEBUG, "cur_ = %x\n", this->cur_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +class ACE_Obchunk * +ACE_Obstack::new_chunk (void) +{ + ACE_TRACE ("ACE_Obstack::new_chunk"); + class ACE_Obchunk *temp = (class ACE_Obchunk *) + new char[sizeof (class ACE_Obchunk) + this->size_]; + + if (temp == 0) + { + errno = ENOMEM; + return 0; + } + + temp->next_ = 0; + temp->end_ = temp->contents_ + this->size_; + temp->cur_ = temp->contents_; + + return temp; +} + +ACE_Obstack::ACE_Obstack (int sz) + : size_ (sz), + head_ (0) +{ + ACE_TRACE ("ACE_Obstack::ACE_Obstack"); + this->head_ = this->new_chunk (); + this->curr_ = this->head_; +} + +ACE_Obstack::~ACE_Obstack (void) +{ + ACE_TRACE ("ACE_Obstack::~ACE_Obstack"); + class ACE_Obchunk *temp = this->head_; + + while (temp != 0) + { + class ACE_Obchunk *next = temp->next_; + temp->next_ = 0; + delete [] temp; + temp = next; + } +} + +char * +ACE_Obstack::copy (const char *s, + size_t len) +{ + ACE_TRACE ("ACE_Obstack::copy"); + char *result; + + ACE_ASSERT (this->size_ >= len + 1); + + // Check whether we need to grow our chunk... + + if (this->curr_->cur_ + len + 1 >= this->curr_->end_) + { + // Check whether we can just reuse previously allocated memory. + + if (this->curr_->next_ == 0) + { + this->curr_->next_ = this->new_chunk (); + this->curr_ = this->curr_->next_; + } + else + { + this->curr_ = this->curr_->next_; + this->curr_->cur_ = this->curr_->contents_; + } + } + + result = this->curr_->cur_; + ACE_OS::memcpy (result, s, len); + result[len] = '\0'; + this->curr_->cur_ += (len + 1); + return result; +} + +void +ACE_Obstack::release (void) +{ + ACE_TRACE ("ACE_Obstack::release"); + this->curr_ = this->head_; + this->curr_->cur_ = this->curr_->contents_; +} + + diff --git a/ace/Obstack.h b/ace/Obstack.h new file mode 100644 index 00000000000..91540994bc2 --- /dev/null +++ b/ace/Obstack.h @@ -0,0 +1,79 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Obstack.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_OBSTACK_H) +#define ACE_OBSTACK_H + +#include "ace/ACE.h" + +class ACE_Export ACE_Obchunk + // = TITLE + // A "chunk" of memory. This should be a nested class but some + // compilers don't like them yet. +{ +friend class ACE_Obstack; + +public: + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + char *end_; + char *cur_; + ACE_Obchunk *next_; + char contents_[4]; +}; + +class ACE_Export ACE_Obstack + // = TITLE + // Define a simple "mark and release" memory allocation utility. + // This class is based on the GNU obstack utility. +{ +public: + // = Initialization and termination methods. + ACE_Obstack (int size = 4080); + ~ACE_Obstack (void); + + char *copy (const char* data, size_t len); + // Copy the data into the current Obchunk. + + void release (void); + // "Release" the entire stack (without freeing it). + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + class ACE_Obchunk *new_chunk (void); + + size_t size_; + // Current size of the Obstack; + + class ACE_Obchunk *head_; + // Head of the Obchunk chain. + + class ACE_Obchunk *curr_; + // Pointer to the current Obchunk. +}; + +#endif /* ACE_OBSTACK_H */ diff --git a/ace/Obstack.i b/ace/Obstack.i new file mode 100644 index 00000000000..893b926ad3a --- /dev/null +++ b/ace/Obstack.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// $Id$ + +// Obstack.i diff --git a/ace/Parse_Node.cpp b/ace/Parse_Node.cpp new file mode 100644 index 00000000000..e22f2969944 --- /dev/null +++ b/ace/Parse_Node.cpp @@ -0,0 +1,545 @@ +// Parse_Node.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Service_Config.h" +#include "ace/Service_Repository.h" +#include "ace/Task.h" +#include "ace/Parse_Node.h" + +// Provide the class hierarchy that defines the parse tree of Service +// Nodes. + +#if !defined (__ACE_INLINE__) +#include "ace/Parse_Node.i" +#endif /* ____ */ + +// Keeps track of the number of errors encountered so far. +extern int ace_yyerrno; + +// Global variable used to communicate between the parser and the main +// program. +extern ACE_Service_Config *ace_this_svc; + +ACE_ALLOC_HOOK_DEFINE(ACE_Stream_Node) + +void +ACE_Stream_Node::dump (void) const +{ + ACE_TRACE ("ACE_Stream_Node::dump"); +} + +void +ACE_Stream_Node::apply (void) +{ + ACE_TRACE ("ACE_Stream_Node::apply"); + + if (ACE_Service_Config::initialize (this->node_->record (), + this->node_->parameters ()) == -1) + ace_yyerrno++; + + ACE_DEBUG ((LM_DEBUG, "did stream on %s, error = %d\n", + this->node_->name (), + ace_yyerrno)); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Parse_Node) + +void +ACE_Parse_Node::dump (void) const +{ + ACE_TRACE ("ACE_Parse_Node::dump"); +} + +const char * +ACE_Parse_Node::name (void) const +{ + ACE_TRACE ("ACE_Parse_Node::name"); + return this->name_; +} + +ACE_Parse_Node * +ACE_Parse_Node::link (void) const +{ + ACE_TRACE ("ACE_Parse_Node::link"); + return this->next_; +} + +void +ACE_Parse_Node::link (ACE_Parse_Node *n) +{ + ACE_TRACE ("ACE_Parse_Node::link"); + this->next_ = n; +} + +ACE_Stream_Node::ACE_Stream_Node (const ACE_Static_Node *str_ops, + const ACE_Parse_Node *str_mods) + : node_ (str_ops), + mods_ (str_mods), + ACE_Parse_Node (str_ops->name ()) +{ + ACE_TRACE ("ACE_Stream_Node::ACE_Stream_Node"); +} + + +ACE_Stream_Node::~ACE_Stream_Node (void) +{ + ACE_TRACE ("ACE_Stream_Node::~ACE_Stream_Node"); + delete (ACE_Static_Node *) this->node_; + delete (ACE_Parse_Node *) this->mods_; +} + +ACE_Parse_Node::ACE_Parse_Node (void) + : next_ (0) +{ + ACE_TRACE ("ACE_Parse_Node::ACE_Parse_Node"); +} + + +ACE_Parse_Node::ACE_Parse_Node (const char *nm) + : name_ (nm), + next_ (0) +{ + ACE_TRACE ("ACE_Parse_Node::ACE_Parse_Node"); +} + +void +ACE_Parse_Node::print (void) const +{ + ACE_TRACE ("ACE_Parse_Node::print"); + ACE_DEBUG ((LM_DEBUG, "svc = %s\n", this->name ())); + if (this->next_) + this->next_->print (); +} + + +ACE_Parse_Node::~ACE_Parse_Node (void) +{ + ACE_TRACE ("ACE_Parse_Node::~ACE_Parse_Node"); + delete this->next_; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Suspend_Node) + +void +ACE_Suspend_Node::dump (void) const +{ + ACE_TRACE ("ACE_Suspend_Node::dump"); +} + +ACE_Suspend_Node::ACE_Suspend_Node (const char *name) + : ACE_Parse_Node (name) +{ + ACE_TRACE ("ACE_Suspend_Node::ACE_Suspend_Node"); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Resume_Node) + +void +ACE_Resume_Node::dump (void) const +{ + ACE_TRACE ("ACE_Resume_Node::dump"); +} + +ACE_Resume_Node::ACE_Resume_Node (const char *name) + : ACE_Parse_Node (name) +{ + ACE_TRACE ("ACE_Resume_Node::ACE_Resume_Node"); +} + +void +ACE_Suspend_Node::apply (void) +{ + ACE_TRACE ("ACE_Suspend_Node::apply"); + if (ACE_Service_Config::suspend (this->name ()) == -1) + ace_yyerrno++; + + ACE_DEBUG ((LM_DEBUG, "did suspend on %s, error = %d\n", + this->name (), ace_yyerrno)); +} + +void +ACE_Resume_Node::apply (void) +{ + ACE_TRACE ("ACE_Resume_Node::apply"); + if (ACE_Service_Config::resume (this->name ()) == -1) + ace_yyerrno++; + + ACE_DEBUG ((LM_DEBUG, "did resume on %s, error = %d\n", + this->name (), ace_yyerrno)); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Remove_Node) + +void +ACE_Remove_Node::dump (void) const +{ + ACE_TRACE ("ACE_Remove_Node::dump"); +} + +ACE_Remove_Node::ACE_Remove_Node (const char *name) + : ACE_Parse_Node (name) +{ + ACE_TRACE ("ACE_Remove_Node::ACE_Remove_Node"); +} + +void +ACE_Remove_Node::apply (void) +{ + ACE_TRACE ("ACE_Remove_Node::apply"); + if (ACE_Service_Config::remove (this->name ()) == -1) + ace_yyerrno++; + + ACE_DEBUG ((LM_DEBUG, "did remove on %s, error = %d\n", + this->name (), ace_yyerrno)); + +} + + +ACE_Dynamic_Node::ACE_Dynamic_Node (const ACE_Service_Record *sr, + char *parms) + : record_ (sr), + ACE_Static_Node (sr->name (), parms) +{ + ACE_TRACE ("ACE_Dynamic_Node::ACE_Dynamic_Node"); +} + +const ACE_Service_Record * +ACE_Dynamic_Node::record (void) const +{ + ACE_TRACE ("ACE_Dynamic_Node::record"); + return this->record_; +} + +void +ACE_Dynamic_Node::apply (void) +{ + ACE_TRACE ("ACE_Dynamic_Node::apply"); + if (ACE_Service_Config::initialize (this->record (), + this->parameters ()) == -1) + ace_yyerrno++; + + ACE_DEBUG ((LM_DEBUG, "did dynamic on %s, error = %d\n", + this->name (), ace_yyerrno)); + +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Dynamic_Node) + +void +ACE_Dynamic_Node::dump (void) const +{ + ACE_TRACE ("ACE_Dynamic_Node::dump"); +} + +ACE_Dynamic_Node::~ACE_Dynamic_Node (void) +{ + ACE_TRACE ("ACE_Dynamic_Node::~ACE_Dynamic_Node"); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Static_Node) + +void +ACE_Static_Node::dump (void) const +{ + ACE_TRACE ("ACE_Static_Node::dump"); +} + +ACE_Static_Node::ACE_Static_Node (const char *nm, + char *params) + : ACE_Parse_Node (nm), + parameters_ (params) +{ + ACE_TRACE ("ACE_Static_Node::ACE_Static_Node"); +} + +const ACE_Service_Record * +ACE_Static_Node::record (void) const +{ + ACE_TRACE ("ACE_Static_Node::record"); + ACE_Service_Record *sr; + + if (ACE_Service_Config::svc_rep ()->find (this->name (), + (const ACE_Service_Record **) &sr) == -1) + return 0; + else + return sr; +} + +char * +ACE_Static_Node::parameters (void) const +{ + ACE_TRACE ("ACE_Static_Node::parameters"); + return this->parameters_; +} + +void +ACE_Static_Node::apply (void) +{ + ACE_TRACE ("ACE_Static_Node::apply"); + if (ACE_Service_Config::initialize (this->name (), + this->parameters ()) == -1) + ace_yyerrno++; + + ACE_DEBUG ((LM_DEBUG, "did static on %s, error = %d\n", + this->name (), ace_yyerrno)); +} + + +ACE_Static_Node::~ACE_Static_Node (void) +{ + ACE_TRACE ("ACE_Static_Node::~ACE_Static_Node"); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Location_Node) + +void +ACE_Location_Node::dump (void) const +{ + ACE_TRACE ("ACE_Location_Node::dump"); +} + +ACE_Location_Node::ACE_Location_Node (void) + : handle_ (0), + symbol_ (0), + pathname_ (0) +{ + ACE_TRACE ("ACE_Location_Node::ACE_Location_Node"); +} + +ACE_Location_Node::~ACE_Location_Node (void) +{ + ACE_TRACE ("ACE_Location_Node::~ACE_Location_Node"); +} + +const char * +ACE_Location_Node::pathname (void) const +{ + ACE_TRACE ("ACE_Location_Node::pathname"); + return this->pathname_; +} + +void +ACE_Location_Node::pathname (const char *p) +{ + ACE_TRACE ("ACE_Location_Node::pathname"); + this->pathname_ = p; +} + +void +ACE_Location_Node::handle (const void *h) +{ + ACE_TRACE ("ACE_Location_Node::handle"); + this->handle_ = h; +} + +const void * +ACE_Location_Node::handle (void) const +{ + ACE_TRACE ("ACE_Location_Node::handle"); + return this->handle_; +} + +void +ACE_Location_Node::set_symbol (const void *s) +{ + ACE_TRACE ("ACE_Location_Node::set_symbol"); + this->symbol_ = s; +} + +int +ACE_Location_Node::dispose (void) const +{ + ACE_TRACE ("ACE_Location_Node::dispose"); + return this->must_delete_; +} + +const void * +ACE_Location_Node::open_handle (void) +{ + ACE_TRACE ("ACE_Location_Node::open_handle"); + + char dl_pathname[MAXPATHLEN]; + + // Transform the pathname into the appropriate dynamic link library + // by searching the ACE_LD_SEARCH_PATH. + ACE::ldfind (this->pathname (), dl_pathname, sizeof dl_pathname); + + this->handle (ACE_OS::dlopen (dl_pathname, RTLD_LAZY)); + + if (this->handle () == 0) + { + ace_yyerrno++; + + ACE_ERROR ((LM_ERROR, "dlopen failed for %s", dl_pathname)); + + char *errmsg = ACE_OS::dlerror (); + + if (errmsg != 0) + ACE_ERROR_RETURN ((LM_ERROR, ": %s\n", errmsg), 0); + else + ACE_ERROR_RETURN ((LM_ERROR, "\n"), 0); + } + else + return this->handle (); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Object_Node) + +void +ACE_Object_Node::dump (void) const +{ + ACE_TRACE ("ACE_Object_Node::dump"); +} + +ACE_Object_Node::ACE_Object_Node (const char *path, + const char *obj_name) + : object_name_ (obj_name) +{ + ACE_TRACE ("ACE_Object_Node::ACE_Object_Node"); + this->pathname (path); + this->must_delete_ = 0; +} + +const void * +ACE_Object_Node::symbol (void) +{ + ACE_TRACE ("ACE_Object_Node::symbol"); + if (this->open_handle () != 0) + { + this->symbol_ = (const void *) + ACE_OS::dlsym ((void *) this->handle (), (char *) this->object_name_); + + if (this->symbol_ == 0) + { + ace_yyerrno++; + + ACE_ERROR ((LM_ERROR, + "dlsym failed for object %s", + this->object_name_)); + + char *errmsg = ACE_OS::dlerror (); + + if (errmsg != 0) + ACE_ERROR_RETURN ((LM_ERROR, ": %s\n", errmsg), 0); + else + ACE_ERROR_RETURN ((LM_ERROR, "\n"), 0); + } + } + return this->symbol_; +} + +ACE_Object_Node::~ACE_Object_Node (void) +{ + ACE_TRACE ("ACE_Object_Node::~ACE_Object_Node"); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Function_Node) + +void +ACE_Function_Node::dump (void) const +{ + ACE_TRACE ("ACE_Function_Node::dump"); +} + +ACE_Function_Node::ACE_Function_Node (const char *path, + const char *func_name) + : function_name_ (func_name) +{ + ACE_TRACE ("ACE_Function_Node::ACE_Function_Node"); + this->pathname (path); + this->must_delete_ = 1; +} + +const void * +ACE_Function_Node::symbol (void) +{ + ACE_TRACE ("ACE_Function_Node::symbol"); + if (this->open_handle () != 0) + { + const void *(*func) (void) = 0; + this->symbol_ = 0; + + // Locate the factory function in the shared + // object. + + func = (const void *(*)(void)) + ACE_OS::dlsym ((void *) this->handle (), + (ACE_DL_TYPE) this->function_name_); + + if (func == 0) + { + ace_yyerrno++; + + if (this->symbol_ == 0) + { + ace_yyerrno++; + + ACE_ERROR ((LM_ERROR, "dlsym failed for function %s", + this->function_name_)); + + char *errmsg = ACE_OS::dlerror (); + + if (errmsg != 0) + ACE_ERROR_RETURN ((LM_ERROR, ": %s\n", errmsg), 0); + else + ACE_ERROR_RETURN ((LM_ERROR, "\n"), 0); + } + } + // Invoke the factory function and record it's return value. + this->symbol_ = (*func) (); + + if (this->symbol_ == 0) + { + ace_yyerrno++; + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", this->function_name_), 0); + } + } + return this->symbol_; +} + +ACE_Function_Node::~ACE_Function_Node (void) +{ + ACE_TRACE ("ACE_Function_Node::~ACE_Function_Node"); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Dummy_Node) + +void +ACE_Dummy_Node::dump (void) const +{ + ACE_TRACE ("ACE_Dummy_Node::dump"); +} + +ACE_Dummy_Node::ACE_Dummy_Node (const ACE_Static_Node *static_node, + const ACE_Parse_Node *str_mods) + : node_ (static_node), + mods_ (str_mods), + ACE_Parse_Node (static_node->name ()) +{ + ACE_TRACE ("ACE_Dummy_Node::ACE_Dummy_Node"); +} + +void +ACE_Dummy_Node::apply (void) +{ + ACE_TRACE ("ACE_Dummy_Node::apply"); + ACE_DEBUG ((LM_DEBUG, "did operations on stream %s, error = %d\n", + this->name (), ace_yyerrno)); +} + +ACE_Dummy_Node::~ACE_Dummy_Node (void) +{ + ACE_TRACE ("ACE_Dummy_Node::~ACE_Dummy_Node"); + delete (ACE_Static_Node *) this->node_; + delete (ACE_Parse_Node *) this->mods_; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +#if defined (ACE_HAS_THREADS) +// template class ACE_Message_Queue; +// template class ACE_Task; +// template class ACE_Task_Exit; +// template class ACE_TSS >; +#endif /* ACE_HAS_THREADS */ +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/ace/Parse_Node.h b/ace/Parse_Node.h new file mode 100644 index 00000000000..9423a7d5af8 --- /dev/null +++ b/ace/Parse_Node.h @@ -0,0 +1,256 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Parse_Node.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_PARSE_NODE_H) +#define ACE_PARSE_NODE_H + +#include "ace/Service_Record.h" + +class ACE_Export ACE_Parse_Node + // = TITLE + // Provide the base of the object hierarchy that defines the parse + // tree of Service Nodes. +{ +public: + ACE_Parse_Node (void); + ACE_Parse_Node (const char *name); + virtual ~ACE_Parse_Node (void); + + ACE_Parse_Node *link (void) const; + void link (ACE_Parse_Node *); + virtual void apply (void) = 0; + + const char *name (void) const; + void print (void) const; + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + const char *name_; + ACE_Parse_Node *next_; +}; + +class ACE_Export ACE_Suspend_Node : public ACE_Parse_Node + // = TITLE + // Suspend a Service Node. +{ +public: + ACE_Suspend_Node (const char *name); + + virtual void apply (void); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +class ACE_Export ACE_Resume_Node : public ACE_Parse_Node + // = TITLE + // Resume a Service Node. +{ +public: + ACE_Resume_Node (const char *name); + + virtual void apply (void); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +class ACE_Export ACE_Remove_Node : public ACE_Parse_Node + // = TITLE + // Remove a Service Node. +{ +public: + ACE_Remove_Node (const char *name); + + virtual void apply (void); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +class ACE_Export ACE_Static_Node : public ACE_Parse_Node + // = TITLE + // Handle a statically linked node. +{ +public: + ACE_Static_Node (const char *name, char *params = 0); + virtual ~ACE_Static_Node (void); + + virtual void apply (void); + virtual const ACE_Service_Record *record (void) const; + char *parameters (void) const; + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + char *parameters_; +}; + +class ACE_Export ACE_Dynamic_Node : public ACE_Static_Node + // = TITLE + // Handle a dynamically linked node. +{ +public: + ACE_Dynamic_Node (const ACE_Service_Record *, char *params); + virtual ~ACE_Dynamic_Node (void); + + virtual const ACE_Service_Record *record (void) const; + virtual void apply (void); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + const ACE_Service_Record *record_; +}; + +class ACE_Export ACE_Stream_Node : public ACE_Parse_Node + // = TITLE + // Handle a Stream. +{ +public: + ACE_Stream_Node (const ACE_Static_Node *, const ACE_Parse_Node *); + virtual ~ACE_Stream_Node (void); + + virtual void apply (void); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + const ACE_Static_Node *node_; + const ACE_Parse_Node *mods_; +}; + +class ACE_Export ACE_Location_Node + // = TITLE + // Keep track of where a shared library is located. +{ +public: + ACE_Location_Node (void); + virtual const void *symbol (void) = 0; + virtual void set_symbol (const void *h); + const void *handle (void) const; + void handle (const void *h); + const char *pathname (void) const; + void pathname (const char *h); + int dispose (void) const; + + virtual ~ACE_Location_Node (void); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + const void *open_handle (void); + + const void *handle_; + const void *symbol_; + const char *pathname_; + int must_delete_; +}; + +class ACE_Export ACE_Object_Node : public ACE_Location_Node + // = TITLE + // Keeps track of the symbol name for a shared object. +{ +public: + ACE_Object_Node (const char *pathname, const char *obj_name); + virtual const void *symbol (void); + virtual ~ACE_Object_Node (void); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + const char *object_name_; +}; + +class ACE_Export ACE_Function_Node : public ACE_Location_Node + // = TITLE + // Keeps track of the symbol name of for a shared function. +{ +public: + ACE_Function_Node (const char *pathname, const char *func_name); + virtual const void *symbol (void); + virtual ~ACE_Function_Node (void); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + const char *function_name_; +}; + +class ACE_Export ACE_Dummy_Node : public ACE_Parse_Node + // = TITLE + // I forget why this is here... ;-) +{ +public: + ACE_Dummy_Node (const ACE_Static_Node *, const ACE_Parse_Node *); + ~ACE_Dummy_Node (void); + virtual void apply (void); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + const ACE_Static_Node *node_; + const ACE_Parse_Node *mods_; +}; + +#if defined (__ACE_INLINE__) +#include "ace/Parse_Node.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_PARSE_NODE_H */ diff --git a/ace/Parse_Node.i b/ace/Parse_Node.i new file mode 100644 index 00000000000..84c7266d734 --- /dev/null +++ b/ace/Parse_Node.i @@ -0,0 +1,6 @@ +/* -*- C++ -*- */ +// $Id$ + +// Parse_Node.i + + diff --git a/ace/Pipe.cpp b/ace/Pipe.cpp new file mode 100644 index 00000000000..31ab6d95d85 --- /dev/null +++ b/ace/Pipe.cpp @@ -0,0 +1,132 @@ +// Pipe.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/SOCK_Connector.h" +#include "ace/Pipe.h" + +void +ACE_Pipe::dump (void) const +{ + ACE_TRACE ("ACE_Pipe::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "handles_[0] = %d", this->handles_[0])); + ACE_DEBUG ((LM_DEBUG, "\nhandles_[1] = %d", this->handles_[1])); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +int +ACE_Pipe::open (void) +{ + ACE_TRACE ("ACE_Pipe::open"); +#if defined (ACE_WIN32) || defined (ACE_LACKS_SOCKETPAIR) + ACE_INET_Addr my_addr; + ACE_SOCK_Acceptor acceptor; + ACE_SOCK_Connector connector; + ACE_SOCK_Stream reader; + ACE_SOCK_Stream writer; + int result = 0; + + // Bind listener to any port. + if (acceptor.open (ACE_Addr::sap_any) == -1) + result = -1; + else if (acceptor.get_local_addr (my_addr) == -1) + result = -1; + else + { + ACE_INET_Addr sv_addr (my_addr.get_port_number (), "localhost"); + + // Establish a connection within the same process! + if (connector.connect (writer, sv_addr) == -1) + result = -1; + else if (acceptor.accept (reader) == -1) + { + writer.close (); + result = -1; + } + } + + // Close down the acceptor endpoint since we don't need it anymore. + acceptor.close (); + if (result == -1) + return -1; + + this->handles_[0] = reader.get_handle (); + this->handles_[1] = writer.get_handle (); + +#elif defined (ACE_HAS_STREAM_PIPES) + if (ACE_OS::pipe (this->handles_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "pipe"), -1); + + int arg = RMSGN; + + // Enable "msg no discard" mode, which ensures that record + // boundaries are maintained when messages are sent and received. + if (ACE_OS::ioctl (this->handles_[0], I_SRDOPT, (void *) arg) == -1 + || ACE_OS::ioctl (this->handles_[1], I_SRDOPT, (void *) arg) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ioctl"), -1); +#else + if (ACE_OS::socketpair (AF_UNIX, SOCK_DGRAM, 0, this->handles_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "socketpair"), -1); +#endif /* ACE_WIN32 */ + // Point both the read and write HANDLES to the appropriate socket + // HANDLEs. + + return 0; +} + +int +ACE_Pipe::open (ACE_HANDLE handles[2]) +{ + ACE_TRACE ("ACE_Pipe::open"); + + if (this->open () == -1) + return -1; + else + { + handles[0] = this->handles_[0]; + handles[1] = this->handles_[1]; + return 0; + } +} + +// Do nothing... + +ACE_Pipe::ACE_Pipe (void) +{ + ACE_TRACE ("ACE_Pipe::ACE_Pipe"); + + this->handles_[0] = ACE_INVALID_HANDLE; + this->handles_[1] = ACE_INVALID_HANDLE; +} + +ACE_Pipe::ACE_Pipe (ACE_HANDLE handles[2]) +{ + ACE_TRACE ("ACE_Pipe::ACE_Pipe"); + + if (this->open (handles) == -1) + ACE_ERROR ((LM_ERROR, "ACE_Pipe::ACE_Pipe")); +} + +ACE_Pipe::ACE_Pipe (ACE_HANDLE read, + ACE_HANDLE write) +{ + ACE_TRACE ("ACE_Pipe::ACE_Pipe"); + this->handles_[0] = read; + this->handles_[1] = write; +} + +int +ACE_Pipe::close (void) +{ + ACE_TRACE ("ACE_Pipe::close"); + + if (ACE_OS::close (this->handles_[0]) == -1 + || ACE_OS::close (this->handles_[1]) == -1) + return -1; + else + return 0; +} diff --git a/ace/Pipe.h b/ace/Pipe.h new file mode 100644 index 00000000000..485e1133f87 --- /dev/null +++ b/ace/Pipe.h @@ -0,0 +1,73 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Pipe.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_PIPE_H) +#define ACE_PIPE_H + +#include "ace/ACE.h" + +class ACE_Export ACE_Pipe + // = TITLE + // Provides a bidirectional "pipe" abstraction that is portable + // to Windows NT, SVR4 UNIX, and BSD UNIX. + // + // = DESCRIPTION + // Uses "name" for lookup in the ACE service repository. Obtains + // the object and returns it as the appropriate type. +{ +public: + // = Initialization and termination. + ACE_Pipe (void); + // Default constructor (does nothing...). + + ACE_Pipe (ACE_HANDLE handles[2]); + // Open the pipe and initialize the handles. + + ACE_Pipe (ACE_HANDLE read, ACE_HANDLE write); + // Initialize the from the and handles. + + int open (ACE_HANDLE handles[2]); + // Open the pipe and initialize the handles. + + int open (void); + // Open the pipe. + + int close (void); + // Close down the pipe HANDLEs; + + // = Accessors. + + ACE_HANDLE read_handle (void); + // This is the "read" side of the pipe. Note, however, that + // processes can also write to this handle as well since pipes are + // bi-directional. + + ACE_HANDLE write_handle (void); + // This is the "write" side of the pipe. Note, however, that + // processes can also read to this handle as well since pipes are + // bi-directional. + + void dump (void) const; + // Dump the state of the object. + +private: + ACE_HANDLE handles_[2]; +}; + +#include "ace/Pipe.i" + +#endif /* ACE_PIPE_H */ diff --git a/ace/Pipe.i b/ace/Pipe.i new file mode 100644 index 00000000000..3808263eb18 --- /dev/null +++ b/ace/Pipe.i @@ -0,0 +1,18 @@ +/* -*- C++ -*- */ +// $Id$ + +// Pipe.i + +inline ACE_HANDLE +ACE_Pipe::read_handle (void) +{ + ACE_TRACE ("ACE_Pipe::read_handle"); + return this->handles_[0]; +} + +inline ACE_HANDLE +ACE_Pipe::write_handle (void) +{ + ACE_TRACE ("ACE_Pipe::write_handle"); + return this->handles_[1]; +} diff --git a/ace/Proactor.cpp b/ace/Proactor.cpp new file mode 100644 index 00000000000..54379d8a28c --- /dev/null +++ b/ace/Proactor.cpp @@ -0,0 +1,536 @@ +// Proactor.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Proactor.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Proactor.i" +#endif /* __ACE_INLINE__ */ + +class ACE_Overlapped_IO : public ACE_OVERLAPPED + // = TITLE + // A wrapper for Win32 OVERLAPPED. + // + // = DESCRIPTION + // Acts as a magic cookie storing additional state associated + // with overlapped I/O operations. ReadFile and WriteFile take + // OVERLAPPED, so we pass in Overlapped_IO. OVERLAPPEDs are + // returned through GetQueuedCompletionStatus. They are cast + // back into Overlapped_IOs to get the handler_ etc. +{ +public: + // = Initialization and termination methods. + ACE_Overlapped_IO (ACE_Reactor_Mask mask, + ACE_Event_Handler *handler, + ACE_Message_Block *message, + ACE_Overlapped_File *file, + ACE_HANDLE event_handle); + + ~ACE_Overlapped_IO (void); + // Death. + + int dispatch (u_long bytes_transfered); + // Callback the appropriate handle_* method on handler_. + + int initiate (u_long &bytes_transfered); + // Call ReadFile or Writefile. + + operator ACE_OVERLAPPED * (void); + // Return this. + + void re_init (void); + // Reset the object to be reused. Calls get_message on the handler_ + // for a new message. + + ACE_Reactor_Mask mask_; + // Reading or writing. + ACE_Event_Handler *handler_; + // The IO handler. + ACE_Message_Block *message_; + // The current message to send/recv. + ACE_Overlapped_File *file_; + // The optional file pointer to update. + +private: + void init (void); + // Reset everything. +}; + +ACE_Overlapped_IO::ACE_Overlapped_IO (ACE_Reactor_Mask mask, + ACE_Event_Handler *handler, + ACE_Message_Block *message, + ACE_Overlapped_File *file, + ACE_HANDLE event_handle) + : mask_ (mask), + handler_ (handler), + message_ (message), + file_ (file) +{ + this->hEvent = event_handle; + this->init (); +} + +void +ACE_Overlapped_IO::init (void) +{ + if (file_ == 0) + this->Offset = 0; + else + this->Offset = file_->offset (); + + this->Internal = 0; + this->InternalHigh = 0; + this->OffsetHigh = 0; +} + +void +ACE_Overlapped_IO::re_init (void) +{ + this->message_ = this->handler_->get_message (); + + this->init (); +} + +ACE_Overlapped_IO::~ACE_Overlapped_IO (void) +{ +} + +int +ACE_Overlapped_IO::dispatch (u_long bytes_transfered) +{ + if (this->file_ != 0) + // Move the file pointer forward. + file_->lseek (bytes_transfered, SEEK_CUR); + + if (this->mask_ == ACE_Event_Handler::WRITE_MASK) + { + // Update the message length to reflect what was sent. + this->message_->rd_ptr (bytes_transfered); + return handler_->handle_output_complete (this->message_, + bytes_transfered); + } + else // this->mask_ == ACE_Event_Handler::READ_MASK + { + // Update the message length to reflect what was received. + this->message_->wr_ptr (bytes_transfered); + return this->handler_->handle_input_complete (this->message_, + bytes_transfered); + } +} + +// When we port this to use Posix async I/O, these calls will be +// replace will generic ACE_OS calls. + +int +ACE_Overlapped_IO::initiate (u_long &bytes_transfered) +{ +#if defined (ACE_WIN32) + if (this->mask_ == ACE_Event_Handler::WRITE_MASK) + { + // Try to write. + return ::WriteFile (this->handler_->get_handle (), + this->message_->rd_ptr (), + this->message_->length (), + &bytes_transfered, + this); + } + else + { + // READ_MASK is set, so try to read. + return ::ReadFile (this->handler_->get_handle (), + this->message_->wr_ptr (), + this->message_->size (), + &bytes_transfered, + this); + } +#else + ACE_NOTSUP_RETURN (-1); +#endif +} + +ACE_Overlapped_IO::operator ACE_OVERLAPPED * (void) +{ + return (ACE_OVERLAPPED *) this; +} + +ACE_Proactor::ACE_Proactor (size_t number_of_threads) + : completion_port_ (0), + number_of_threads_ (number_of_threads), + timer_skew_ (0, ACE_TIMER_SKEW) +{ +#if defined (ACE_WIN32) + // Create an "auto-reset" event to indicate that one or more I/O + // overlapped events have completed. + this->global_handle_ = ::CreateEvent (NULL, TRUE, FALSE, NULL); +#endif /* ACE_HAS_WIN32 */ +} + +int +ACE_Proactor::close (void) +{ + if (this->completion_port_ != 0) + ACE_OS::close (this->completion_port_); + + ACE_OS::close (this->global_handle_); + return 0; +} + +int +ACE_Proactor::handle_signal (int index, siginfo_t *, ucontext_t *) +{ + ACE_TRACE ("ACE_Proactor::handle_signal"); + + ACE_Time_Value timeout (0, 0); + +#if defined (ACE_WIN32) + // Reset the handle to a non-signaled state. + if (::ResetEvent (global_handle_) == FALSE) + ACE_ERROR_RETURN ((LM_ERROR, "ResetEvent failed.\n"), -1); +#endif /* ACE_HAS_WIN32 */ + + // Perform a non-blocking "poll" for all the I/O events that have + // completed in the I/O completion queue. + + int result; + + while ((result = this->handle_events (&timeout)) == 1) + continue; + + // If our handle_events failed, we'll report a failure to the + // ReactorEx. + return result == -1 ? -1 : 0; +} + + +int +ACE_Proactor::schedule_timer (ACE_Event_Handler *handler, + const void *arg, + const ACE_Time_Value &delta_time, + const ACE_Time_Value &interval) +{ + ACE_TRACE ("ACE_Proactor::schedule_timer"); + + return this->timer_queue_.schedule + (handler, arg, ACE_OS::gettimeofday () + delta_time, interval); +} + +int +ACE_Proactor::handle_events (ACE_Time_Value *how_long) +{ + // Stash the current time. + ACE_Time_Value prev_time = ACE_OS::gettimeofday (); + + how_long = timer_queue_.calculate_timeout (how_long); + + ACE_Overlapped_IO *overlapped = 0; + u_long bytes_transfered = 0; + +#if defined (ACE_WIN32) + int error = 0; + ACE_HANDLE io_handle = ACE_INVALID_HANDLE; + + // When we port this to use Posix async I/O, this call will be + // replace will a generic ACE_OS call. + BOOL result; + + result = ::GetQueuedCompletionStatus (this->completion_port_, + &bytes_transfered, + (u_long *) &io_handle, + (ACE_OVERLAPPED **) &overlapped, + how_long == 0 ? INFINITE : how_long->msec ()); + + // Check for a failed dequeue. Stash the error value. + if (result == FALSE && overlapped == 0) + error = ::GetLastError (); + + // Check for any timers that can be handled before we dispatch the + // dequeued event. Note that this is done irrespective of whether + // an error occurred. + if (!this->timer_queue_.is_empty ()) + // Fudge factor accounts for problems with Solaris timers... + this->timer_queue_.expire (ACE_OS::gettimeofday () + this->timer_skew_); + + // @@ Need to make sure that if GetQueuedCompletionStatus fails due + // to a time out that this information is propagated correctly to + // the caller! + + // GetQueued returned because of a error or timer. + if (error != 0) + { + // Compute the time while the Proactor is processing. + ACE_Time_Value elapsed_time = ACE_OS::gettimeofday () - prev_time; + + // Update -how_long- to reflect the amount of time since + // handle_events was called. + if (how_long != 0) + { + if (*how_long > elapsed_time) + *how_long = *how_long - elapsed_time; + else + *how_long = ACE_Time_Value::zero; // Used all of timeout. + } + + // @@ What's the WIN32 constant for 258?!?!?! + if (error == 258) + // Returning because of timeout. + return 0; + // Returning because of error. + ACE_ERROR_RETURN ((LM_ERROR, + "%p GetQueuedCompletionStatus failed errno = %d.\n" + "ACE_Proactor::handle_events", error), -1); + } + +#endif /* ACE_WIN32 */ + + // Dequeued a failed or successful operation. Dispatch the + // Event_Handler. Note that GetQueuedCompletionStatus returns false + // when operations fail, but they still need to be dispatched. + // Should we propogate this to the handler somehow? Maybe an extra + // failed/succeeded flag in the dispatch call? + int dispatch_result = this->dispatch (overlapped, bytes_transfered); + + // Compute the time while the Proactor is processing. + ACE_Time_Value elapsed_time = ACE_OS::gettimeofday () - prev_time; + + // Update to reflect the amount of time since + // was called. + if (how_long != 0) + { + if (*how_long > elapsed_time) + *how_long = *how_long - elapsed_time; + else + *how_long = ACE_Time_Value::zero; // Used all of timeout. + } + + // Return -1 (failure), or return 1. Remember that 0 is reserved + // for timeouts only, so we have to turn dispatch_results to 1. So, + // if this->dispatch() returns a 1 or 0, we return 1. Otherwise, + // we return -1. + return dispatch_result == -1 ? -1 : 1; +} + +// Returns 0 or 1 on success, -1 on failure. +int +ACE_Proactor::dispatch (ACE_Overlapped_IO *overlapped, + u_long bytes_transfered) +{ + // Call back the Event_Handler and do what it wants based on the + // return value. + int dispatch_result = overlapped->dispatch (bytes_transfered); + + switch (dispatch_result) + { + case 1: // Start another operation. + // Reinitialize by getting a new message and resetting the + // overlapped offset. + overlapped->re_init (); + return this->initiate (overlapped); + case -1: // Handler is closing. + overlapped->handler_-> + handle_close (overlapped->handler_->get_handle (), + overlapped->mask_); + // Fallthrough. + default: + // Handler succeeded, but does not want another operation + // started. + delete overlapped; + return 0; + } +} + +// Returns 0 or 1 on success, -1 on failure. +int +ACE_Proactor::initiate (ACE_Event_Handler *handler, + ACE_Reactor_Mask mask, + ACE_Message_Block *msg, + ACE_Overlapped_File *file) +{ + if (msg == 0) + msg = handler->get_message (); + + // Create the state for this operation. This object "is-a" + // OVERLAPPED structure, and holds other data and methods for this + // operation. + ACE_Overlapped_IO *overlapped; + + ACE_NEW_RETURN (overlapped, + ACE_Overlapped_IO (mask, handler, msg, + file, this->global_handle_), + -1); + + return this->initiate (overlapped); +} + +// Returns 0 or 1 on success, -1 on failure. +// Returns 1 when initiate succeeded immediately. +int +ACE_Proactor::initiate (ACE_Overlapped_IO *overlapped) +{ +#if defined (ACE_WIN32) + u_long bytes_transfered = 0; + + ACE_HANDLE io_handle = overlapped->handler_->get_handle (); + ACE_HANDLE cp; + + cp = ::CreateIoCompletionPort (io_handle, + this->completion_port_, + (u_long) io_handle, + this->number_of_threads_); + + if (cp != 0) + // Success. + this->completion_port_ = cp; + else // Failure. + { + int error = ::GetLastError (); + // If errno == ERROR_INVALID_PARAMETER, then this handle was + // already registered. + if (error != ERROR_INVALID_PARAMETER) + ACE_ERROR_RETURN ((LM_ERROR, + "%p CreateIoCompletionPort failed errno = %d.\n", + "ACE_Proactor::initiate", error), -1); + } + + // Initiate a WriteFile/ReadFile. If it succeeds, dispatch the + // handler. + int initiate_result = overlapped->initiate (bytes_transfered); + + if (initiate_result) + // Return 1; the OVERLAPPED will still get queued. + return 1; + + // If initiate failed, check for a bad error. + int err = ::GetLastError (); + switch (err) + { + case ERROR_HANDLE_EOF: + case ERROR_NETNAME_DELETED: + // The OVERLAPPED will *not* get queued for this case. Thus, we + // have to dispatch immediately. + return this->dispatch (overlapped, bytes_transfered); + + case ERROR_IO_PENDING: + // The IO will complete proactively. + return 0; + default: + // This is a *bad* error. + ACE_ERROR ((LM_ERROR, "I/O error %d\n", err)); + return -1; + } +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_WIN32 */ +} + +ACE_Overlapped_File::ACE_Overlapped_File (const ACE_Overlapped_File &file) + : offset_ (file.offset ()), + handle_ (file.get_handle ()), + file_size_ (0), + delete_handle_ (0) +{ +} + +ACE_Overlapped_File::ACE_Overlapped_File (void) + : offset_ (0), + handle_ (ACE_INVALID_HANDLE), + file_size_ (0), + delete_handle_ (0) +{ +} + +ACE_Overlapped_File::ACE_Overlapped_File (const char *file_name, + int mode, + int perms) + : delete_handle_ (1) +{ + this->open (file_name, mode, perms); +} + +ACE_Overlapped_File::~ACE_Overlapped_File (void) +{ + this->close (); +} + +void +ACE_Overlapped_File::close (void) +{ + if (this->handle_ != ACE_INVALID_HANDLE + && this->delete_handle_ != 0) + { + ACE_OS::close (this->handle_); + this->handle_ = ACE_INVALID_HANDLE; + } +} + +int +ACE_Overlapped_File::open (ACE_HANDLE handle) +{ + this->handle_ = handle; + this->delete_handle_ = 0; + + if (this->handle_ == ACE_INVALID_HANDLE) + return -1; + else + return 0; +} + +int +ACE_Overlapped_File::open (const char *file_name, + int access, + int share, + LPSECURITY_ATTRIBUTES security, + int creation, + int flags, + ACE_HANDLE template_file) +{ +#if defined (ACE_WIN32) + if (file_name != 0) + this->handle_ = ::CreateFile (file_name, access, share, + security, creation, flags, + template_file); + + if (this->handle_ == ACE_INVALID_HANDLE) + { + errno = ENOENT; + return -1; + } + else + { + this->delete_handle_ = 1; + return 0; + } +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_WIN32 */ +} + +off_t +ACE_Overlapped_File::lseek (off_t offset, + int whence) +{ + switch (whence) + { + case SEEK_SET: + this->offset_ = offset; + break; + case SEEK_CUR: + this->offset_ += offset; + break; + case SEEK_END: + if (handle_ == ACE_INVALID_HANDLE) + { + errno = ENFILE; + return -1; + } + else + this->offset_ = ACE_OS::filesize (handle_) + offset; + break; + default : + errno = EINVAL; + ACE_ERROR_RETURN ((LM_ERROR, "ACE_Overlapped_File::lseek" + "Invalid whence = %d.\n"), -1); + } + + return this->offset_; +} diff --git a/ace/Proactor.h b/ace/Proactor.h new file mode 100644 index 00000000000..8fb845b0f3e --- /dev/null +++ b/ace/Proactor.h @@ -0,0 +1,256 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Proactor.h +// +// = AUTHOR +// Doug Schmidt (schmidt@cs.wustl.edu), +// Tim Harrison (harrison@cs.wustl.edu), and +// Irfan Pyarali (ip1@cs.wustl.edu). +// +// ============================================================================ + +#if !defined (ACE_Proactor_H) +#define ACE_Proactor_H + +#include "ace/OS.h" +#include "ace/Message_Block.h" +#include "ace/Timer_Queue.h" +#include "ace/Event_Handler.h" + +// Forward declaration. +class ACE_Overlapped_File; + +// Cheshire cat declaration (meow). +class ACE_Overlapped_IO; + +class ACE_Export ACE_Proactor : public ACE_Event_Handler +// = TITLE +// An abstraction for Proactive I/O. +// +// = DESCRIPTION +// +// The ACE_Proactor encapsulates Win32 overlapped I/O. The ACE_Proactor +// is also an ACE_Event_Handler which can be registered with the +// ACE_ReactorEx, as follows: +// +// int +// main () +// { +// // ... +// +// // Register Proactor with ReactorEx. +// ACE_Service_Config::reactorEx ()->register_handler +// (ACE_Service_Config::proactor ()); +// +// // Demultiplex all ReactorEx and Proactor events from a single +// // thread. +// ACE_Service_Config::run_reactorEx_event_loop (); +// +// return 42; +// } +// +// This makes it possible to seemlessly integrate the ACE_Proactor (which +// handles only overlapped I/O) with other forms of Win32 HANDLE-based +// synchronization (e.g., Mutexes, Semaphores, Threads, Processes, etc.). +{ +public: + // = Initialization and termination methods. + + ACE_Proactor (size_t number_of_threads = 0); + // Initialize a proactor and give it the number of threads to allow + // to run concurrently (note that we don't spawn the threads, the NT + // kernel does). + + int close (void); + // Close completion port. + + // = Event demultiplexing hooks inherited from Event_Handler. + virtual int handle_signal (int, siginfo_t * = 0, ucontext_t * = 0); + // Called back when used in the context of the ReactorEx. + + virtual ACE_HANDLE get_handle (void) const; + // Returns the underlying Win32 Event HANDLE that is used to + // integrate I/O completion ports with the ReactorEx. + + // = Event loop methods. + virtual int handle_events (ACE_Time_Value *how_long = 0); + virtual int handle_events (ACE_Time_Value &how_long); + // Main event loop driver that blocks for -how_long- before + // returning (will return earlier if I/O or signal events occur). + // Note that -how_long- can be 0, in which case this method blocks + // until I/O events or signals occur. handle_events just blocks + // on GetQueuedCompletionStatus at completion_port_. When I/O + // completions arrive, it calls back the Event_Handler associated + // with completed I/O operation. Returns 0 if -how_long- elapses + // before an event occurs, 1 when if an event occured, and -1 on + // failure. + + // = Communication method. + virtual int initiate (ACE_Event_Handler *handler, + ACE_Reactor_Mask mask = ACE_Event_Handler::WRITE_MASK, + ACE_Message_Block *msg = 0, + ACE_Overlapped_File *file = 0); + // Invoke proactive I/O on . If == 0, the Proactor + // will call handler::get_message to obtain an ACE_Message_Block + // to send/recv according to . If == + // ACE_Event_Handler::WRITE_MASK, the Proactor calls WriteFile using + // the and Event_Handler::get_handle. Returns 1 if the operation + // succeeded immediately, 0 if the operation is pending (in which + // case the will be called back), and -1 if an error + // occurred. represents the offset into the file to initiate + // the operation with. When using the proactor for overlapped file + // I/O, the user is responsible for maintaining the pointer to the + // file. If you perform multiple initiates with the same or no + // File_Pointer value, initiate will fill in the same file data into + // multiple Message_Blocks. is ignored for network I/O or if + // == 0. If != 0 it is updated (via lseek) respective to + // the operation initiated. + + // = Timer management. + virtual int schedule_timer (ACE_Event_Handler *, + const void *arg, + const ACE_Time_Value &delta, + const ACE_Time_Value &interval = ACE_Time_Value::zero); + // Schedule an that will expire after amount + // of time. If it expires then is passed in as the value to + // the 's callback method. If + // is != to then it is used to + // reschedule the automatically. This method + // returns a timer handle that uniquely identifies the + // in an internal list. This timer handle can be + // used to cancel an before it expires. The + // cancellation ensures that timer_ids are unique up to values of + // greater than 2 billion timers. As long as timers don't stay + // around longer than this there should be no problems with + // accidentally deleting the wrong timer. + + virtual int cancel_timer (ACE_Event_Handler *handler); + // Cancel all that match the address of + // . + + virtual int cancel_timer (int timer_id, const void **arg = 0); + // Cancel the single that matches the + // value (which was returned from the method). If arg is + // non-NULL then it will be set to point to the ``magic cookie'' + // argument passed in when the was registered. This + // makes it possible to free up the memory and avoid memory leaks. + +protected: + + ACE_Timer_Queue timer_queue_; + // Maintains the list of pending timers. + + ACE_Time_Value timer_skew_; + // Adjusts for timer skew in various clocks. + + virtual int initiate (ACE_Overlapped_IO *overlapped); + // Helper to initiate. + + int dispatch (ACE_Overlapped_IO *overlapped, + u_long bytes_transfered); + // Helper function which dispatches results to Event_Handlers. + + ACE_HANDLE completion_port_; + // The completion_port_ is where should tell a completed + // I/O operation to queue up. All proactive I/O operation + // completions queue up on this handle. This handle is set by the + // method. + + size_t number_of_threads_; + // Max threads that will be allowed to run in a completion port. + + ACE_HANDLE global_handle_; + // Win32 HANDLE associated with every operation that signals when + // any operation completes (used to transparently integrate the + // with the ). +}; + +class ACE_Export ACE_Overlapped_File + // = TITLE + // A wrapper for overlapped file I/O. + // + // = DESCRIPTION + // ACE_Overlapped_File is place-holder for file I/O. When + // performing overlapped I/O in win32, a file pointer is not + // managed by the kernel. Instead, the user is responsible for + // maintaining file pointers for all open files. This wrapper + // provides an abstraction for a file pointer. The Proactor + // updates Overlapped_File objects when overlapped I/O operations + // complete. Eventually, this class may be integrated with + // ACE_FILE_IO. +{ +public: + // = Initialization and termination methods. + ACE_Overlapped_File (void); + // Open must be called. + + ACE_Overlapped_File (const ACE_Overlapped_File &file); + // Copy . + + ACE_Overlapped_File (const char *file_name, int mode, int perms = 0); + // Construction of an ACE_Overlapped_File. Calls open. + + ~ACE_Overlapped_File (void); + // Destruction. Calls close. + + int open (const char *file_name, + int access = GENERIC_READ, + int share = FILE_SHARE_READ, + LPSECURITY_ATTRIBUTES security = 0, + int creation = OPEN_EXISTING, + int flags = FILE_ATTRIBUTE_NORMAL, + ACE_HANDLE template_file = ACE_INVALID_HANDLE); + // Opens according to and . This method + // is equivalent to CreateFile. Returns 0 on success, -1 on failure + // with errno == reason. + + int open (ACE_HANDLE handle); + // Uses the given . Returns 0 on success, -1 on failure. + // This will only return -1 when == ACE_INVALID_HANDLE. + + void close (void); + // Closes the file if open. Can be called explicitly, or implicitly + // through the destructor. + + off_t offset (void) const; + // Return the current offset into the file. + + off_t size (void) const; + // Return the current size of the file. + + off_t lseek (off_t offset, int whence); + // If == SEEK_SET, then the file pointer is set to + // . If == SEEK_CUR, then the file pointer is set + // to its current location plus . If == SEEK_END, + // the file pointer is set to the size of the file plus . + + ACE_HANDLE get_handle (void) const; + // Get the handle to the file. + +protected: + off_t offset_; + // Current offset into the file. + + off_t file_size_; + // Size of the file. + + ACE_HANDLE handle_; + // Handle to the I/O device. + + int delete_handle_; + // Keeps track of whether we need to delete the . +}; + +#if defined (__ACE_INLINE__) +#include "ace/Proactor.i" +#endif /* __ACE_INLINE__ */ +#endif /* ACE_Proactor_H */ + diff --git a/ace/Proactor.i b/ace/Proactor.i new file mode 100644 index 00000000000..fe58070da78 --- /dev/null +++ b/ace/Proactor.i @@ -0,0 +1,54 @@ +/* -*- C++ -*- */ +// $Id$ + + +ACE_INLINE off_t +ACE_Overlapped_File::offset (void) const +{ + ACE_TRACE ("ACE_Overlapped_File::offset"); + return this->offset_; +} + +ACE_INLINE off_t +ACE_Overlapped_File::size (void) const +{ + ACE_TRACE ("ACE_Overlapped_File::size"); + return ACE_OS::filesize (this->handle_); +} + +ACE_INLINE ACE_HANDLE +ACE_Overlapped_File::get_handle (void) const +{ + ACE_TRACE ("ACE_Overlapped_File::get_handle"); + return this->handle_; +} + +ACE_INLINE int +ACE_Proactor::cancel_timer (ACE_Event_Handler *handler) +{ + ACE_TRACE ("ACE_Proactor::cancel_timer"); + return this->timer_queue_.cancel (handler); +} + +ACE_INLINE int +ACE_Proactor::cancel_timer (int timer_id, + const void **arg) +{ + ACE_TRACE ("ACE_Proactor::cancel_timer"); + return this->timer_queue_.cancel (timer_id, arg); +} + +ACE_INLINE ACE_HANDLE +ACE_Proactor::get_handle (void) const +{ + ACE_TRACE ("ACE_Proactor::get_handle"); + + return this->global_handle_; +} + +ACE_INLINE int +ACE_Proactor::handle_events (ACE_Time_Value &how_long) +{ + return this->handle_events (&how_long); +} + diff --git a/ace/Process.cpp b/ace/Process.cpp new file mode 100644 index 00000000000..c2aa3ba9a84 --- /dev/null +++ b/ace/Process.cpp @@ -0,0 +1,197 @@ +#define ACE_BUILD_DLL +// $Id$ + +#include "ace/Process.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Process.i" +#endif /* __ACE_INLINE__ */ + +int +ACE_Process::wait (void) +{ +#if defined (ACE_WIN32) + return ::WaitForSingleObject (process_info_.hProcess, INFINITE); +#else /* ACE_WIN32 */ + return ACE_OS::waitpid (this->child_id_, 0, 0); +#endif /* ACE_WIN32 */ +} + +ACE_Process::ACE_Process (void) +#if defined (ACE_WIN32) + : set_handles_called_ (0) +#else /* ACE_WIN32 */ + : stdin_ (ACE_INVALID_HANDLE), + stdout_ (ACE_INVALID_HANDLE), + stderr_ (ACE_INVALID_HANDLE) +#endif /* ACE_WIN32 */ +{ +#if defined (ACE_WIN32) + ACE_OS::memset ((void *) &startup_info_, 0, sizeof startup_info_); + ACE_OS::memset ((void *) &process_info_, 0, sizeof process_info_); + startup_info_.cb = sizeof startup_info_; +#endif /* ACE_WIN32 */ +} + +ACE_Process::~ACE_Process (void) +{ +#if defined (ACE_WIN32) + // Just in case start wasn't called. + if (set_handles_called_) + { + ::CloseHandle (startup_info_.hStdInput); + ::CloseHandle (startup_info_.hStdOutput); + ::CloseHandle (startup_info_.hStdOutput); + set_handles_called_ = 0; + } + + // Free resources allocated in kernel. + ACE_OS::close (process_info_.hThread); + ACE_OS::close (process_info_.hProcess); + +#endif /* ACE_WIN32 */ +} + +int +ACE_Process::set_handles (ACE_HANDLE std_in, + ACE_HANDLE std_out, + ACE_HANDLE std_err) +{ +#if defined (ACE_WIN32) + set_handles_called_ = 1; + + // Tell the new process to use our std handles. + startup_info_.dwFlags = STARTF_USESTDHANDLES; + + if (std_in == ACE_INVALID_HANDLE) + std_in = ACE_STDIN; + if (std_out == ACE_INVALID_HANDLE) + std_out = ACE_STDOUT; + if (std_err == ACE_INVALID_HANDLE) + std_err = ACE_STDERR; + + if (!::DuplicateHandle (::GetCurrentProcess(), + std_in, + ::GetCurrentProcess(), + &startup_info_.hStdInput, + NULL, + TRUE, + DUPLICATE_SAME_ACCESS)) + return -1; + + if (!::DuplicateHandle (::GetCurrentProcess(), + std_out, + ::GetCurrentProcess(), + &startup_info_.hStdOutput, + NULL, + TRUE, + DUPLICATE_SAME_ACCESS)) + return -1; + + if (!::DuplicateHandle (::GetCurrentProcess(), + std_err, + ::GetCurrentProcess(), + &startup_info_.hStdError, + NULL, + TRUE, + DUPLICATE_SAME_ACCESS)) + return -1; +#else /* ACE_WIN32 */ + stdin_ = std_in; + stdout_ = std_out; + stderr_ = std_err; +#endif /* ACE_WIN32 */ + + return 0; // Success. +} + +int +ACE_Process::start (char *argv[]) +{ +#if defined (ACE_WIN32) + ACE_ARGV argv_buf (argv); + + char *buf = argv_buf.buf (); + + if (buf == 0) + return -1; + + BOOL fork_result = + ::CreateProcess (NULL, + buf, + NULL, // No process attributes. + NULL, // No thread attributes. + TRUE, // Allow handle inheritance. + NULL, // CREATE_NEW_CONSOLE, // Create a new console window. + NULL, // No environment. + NULL, // No current directory. + &startup_info_, + &process_info_); + + if (set_handles_called_) + { + ::CloseHandle (startup_info_.hStdInput); + ::CloseHandle (startup_info_.hStdOutput); + ::CloseHandle (startup_info_.hStdOutput); + set_handles_called_ = 0; + } + + if (fork_result) // If success. + return 0; + else + // CreateProcess failed. + return -1; +#else /* ACE_WIN32 */ + // Fork the new process. + this->child_id_ = ACE_OS::fork (); + + switch (this->child_id_) + { + case -1: + // Error. + return -1; + case 0: + if (stdin_ != ACE_INVALID_HANDLE + && ACE_OS::dup2 (stdin_, ACE_STDIN) == -1) + return -1; + else if (stdout_ != ACE_INVALID_HANDLE + && ACE_OS::dup2 (stdout_, ACE_STDOUT) == -1) + return -1; + else if (stderr_ != ACE_INVALID_HANDLE + && ACE_OS::dup2 (stderr_, ACE_STDERR) == -1) + return -1; + + // Child process executes the command. + if (ACE_OS::execv (argv[0], argv) == -1) + // If the execv fails, this child needs to exit. + ACE_OS::exit (errno); + default: + // Server process. The fork succeeded. + return 0; + } +#endif /* ACE_WIN32 */ +} + +ACE_Process::ACE_Process (char *argv[], + ACE_HANDLE std_in, + ACE_HANDLE std_out, + ACE_HANDLE std_err) +#if defined (ACE_WIN32) + : set_handles_called_ (0) +#else /* ACE_WIN32 */ + : stdin_ (ACE_INVALID_HANDLE), + stdout_ (ACE_INVALID_HANDLE), + stderr_ (ACE_INVALID_HANDLE) +#endif /* ACE_WIN32 */ +{ +#if defined (ACE_WIN32) + ACE_OS::memset ((void *) &startup_info_, 0, sizeof startup_info_); + ACE_OS::memset ((void *) &process_info_, 0, sizeof process_info_); + startup_info_.cb = sizeof startup_info_; +#endif /* ACE_WIN32 */ + + if (this->set_handles (std_in, std_out, std_err) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "set_handles")); + else if (this->start (argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "start")); +} diff --git a/ace/Process.h b/ace/Process.h new file mode 100644 index 00000000000..094fa78216d --- /dev/null +++ b/ace/Process.h @@ -0,0 +1,106 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Process.h +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#if !defined (ACE_PROCESS_H) +#define ACE_PROCESS_H + +#include "ace/OS.h" +#include "ace/ARGV.h" +#include "ace/ACE.h" +#include "ace/Mem_Map.h" +#include "ace/Svc_Handler.h" +#include "ace/Synch.h" +#include "ace/Acceptor.h" +#include "ace/SOCK_Acceptor.h" + +class ACE_Export ACE_Process +// = TITLE +// A Portable encapsulation for creating new processes and +// allows assignment of STDIN, STDOUT, and STDERR of the new +// process. +// +// = DESCRIPTION +// On UNIX, ACE_Process uses fork and exec. On Win32, it uses +// CreateProcess. Since we can set the standard handles, we can +// mimic UNIX pipes on Win32 by building chains of processes. +// This class should be used instead ACE_OS::fork_exec. I'm +// implementing the functionality that I need as I go, instead of +// trying to build an all encompassing process abstraction. If +// anyone needs more functionality, please feel free to add it and +// send us the updates. We'll put it in ACE. +{ +public: + ACE_Process (void); + // Default construction. + + ACE_Process (char *argv[], + ACE_HANDLE std_in, + ACE_HANDLE std_out = ACE_INVALID_HANDLE, + ACE_HANDLE std_err = ACE_INVALID_HANDLE); + // Set the standard handles of the new process to the respective + // handles and start the new process. -argv- must be specified. It + // should be of the following form: argv = { + // "c:\full\path\to\foo.exe", "-a", "arg1", "etc", 0 } Returns the + // new process id on success, -1 on failure. If you want to affect + // a subset of the handles, make sure to set the others to + // ACE_INVALID_HANDLE. + + ~ACE_Process (void); + // Death incarnate. + + int set_handles (ACE_HANDLE std_in, + ACE_HANDLE std_out = ACE_INVALID_HANDLE, + ACE_HANDLE std_err = ACE_INVALID_HANDLE); + // Set the standard handles of the new process to the respective + // handles. If you want to affect a subset of the handles, make + // sure to set the others to ACE_INVALID_HANDLE. Returns 0 on + // success, -1 on failure. + + int start (char *argv[]); + // Start the new process. -argv- must be specified. It should be + // of the following form: argv = { "c:\full\path\to\foo.exe", "-a", + // "arg1", "etc", 0 } Returns the new process id on success, -1 on + // failure. + + int wait (void); + // Wait for the process we just created to exit. + + int kill (int signum = SIGINT); + // Send the process a signal. + + pid_t getpid (void); + // Return the pid of the new process. + +private: +#if defined (ACE_WIN32) + PROCESS_INFORMATION process_info_; + STARTUPINFO startup_info_; + int set_handles_called_; + // Is 1 if stdhandles was called. +#else /* ACE_WIN32 */ + ACE_HANDLE stdin_; + ACE_HANDLE stdout_; + ACE_HANDLE stderr_; + pid_t child_id_; +#endif /* ACE_WIN32 */ +}; + +#if defined (__ACE_INLINE__) +#include "ace/Process.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_PROCESS_H */ diff --git a/ace/Process.i b/ace/Process.i new file mode 100644 index 00000000000..3e7dafb44d6 --- /dev/null +++ b/ace/Process.i @@ -0,0 +1,19 @@ +/* -*- C++ -*- */ +// $Id$ + + +ACE_INLINE pid_t +ACE_Process::getpid (void) +{ +#if defined (ACE_WIN32) + return process_info_.dwProcessId; +#else /* ACE_WIN32 */ + return child_id_; +#endif /* ACE_WIN32 */ +} + +ACE_INLINE int +ACE_Process::kill (int signum) +{ + return ACE_OS::kill (this->getpid (), signum); +} diff --git a/ace/Process_Manager.cpp b/ace/Process_Manager.cpp new file mode 100644 index 00000000000..1ef354593f1 --- /dev/null +++ b/ace/Process_Manager.cpp @@ -0,0 +1,331 @@ +#if 0 +// $Id$ + +// Process_Manager.cpp +#define ACE_BUILD_DLL +#include "ace/Process_Manager.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Process_Manager.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Process_Control) +ACE_ALLOC_HOOK_DEFINE(ACE_Process_Manager) + +void +ACE_Process_Manager::dump (void) const +{ + ACE_TRACE ("ACE_Process_Manager::dump"); +} + +ACE_Process_Descriptor::ACE_Process_Descriptor (void) +{ + ACE_TRACE ("ACE_Process_Descriptor::ACE_Process_Descriptor"); +} + +int +ACE_Process_Manager::resize (size_t size) +{ + ACE_TRACE ("ACE_Process_Manager::resize"); + return -1; +} + +// Create and initialize the table to keep track of the process pool. + +int +ACE_Process_Manager::open (size_t size) +{ + ACE_TRACE ("ACE_Process_Manager::open"); + return -1; +} + +// Initialize the synchronization variables. + +ACE_Process_Manager::ACE_Process_Manager (size_t size) +{ + ACE_TRACE ("ACE_Process_Manager::ACE_Process_Manager"); +} + +// Close up and release all resources. + +int +ACE_Process_Manager::close (void) +{ + ACE_TRACE ("ACE_Process_Manager::close"); + return -1; +} + +ACE_Process_Manager::~ACE_Process_Manager (void) +{ + ACE_TRACE ("ACE_Process_Manager::~ACE_Process_Manager"); + this->close (); +} + +// Call the appropriate OS routine to spawn a process. Should *not* +// be called with the lock_ held... + +int +ACE_Process_Manager::spawn_i (ACE_THR_FUNC func, + void *args, + long flags, + pid_t *t_id, + u_int priority, + void *stack, + size_t stack_size) +{ + ACE_TRACE ("ACE_Process_Manager::spawn_i"); + return -1; +} + +// Create a new process running FUNC. *Must* be called with the lock_ +// held... + +int +ACE_Process_Manager::spawn (ACE_THR_FUNC func, + void *args, + long flags, + pid_t *t_id, + u_int priority, + void *stack, + size_t stack_size) +{ + ACE_TRACE ("ACE_Process_Manager::spawn"); + return -1; +} + +// Create N new processs running FUNC. + +int +ACE_Process_Manager::spawn_n (int n, + ACE_THR_FUNC func, + void *args, + long flags, + u_int priority) +{ + ACE_TRACE ("ACE_Process_Manager::spawn_n"); + return -1; +} + +// Append a process into the pool (does not check for duplicates). +// Must be called with locks held. + +int +ACE_Process_Manager::append_proc (pid_t t_id, + ACE_Process_Descriptor::Process_State proc_state) +{ + ACE_TRACE ("ACE_Process_Manager::append_proc"); + + return -1; +} + +// Insert a process into the pool (checks for duplicates and doesn't +// allow them to be inserted twice). + +int +ACE_Process_Manager::insert_proc (pid_t t_id) +{ + ACE_TRACE ("ACE_Process_Manager::insert_proc"); + return -1; +} + +// Remove a process from the pool. Must be called with locks held. + +void +ACE_Process_Manager::remove_proc (int i) +{ + ACE_TRACE ("ACE_Process_Manager::remove_proc"); +} + +int +ACE_Process_Manager::resume_proc (int i) +{ + ACE_TRACE ("ACE_Process_Manager::resume_proc"); + return -1; +} + +int +ACE_Process_Manager::suspend_proc (int i) +{ + ACE_TRACE ("ACE_Process_Manager::suspend_proc"); + + return -1; +} + +int +ACE_Process_Manager::kill_proc (int i, int signum) +{ + ACE_TRACE ("ACE_Process_Manager::kill_proc"); + + return -1; +} + +// Locate the index in the table associated with . Must be +// called with the lock held. + +int +ACE_Process_Manager::find (pid_t t_id) +{ + ACE_TRACE ("ACE_Process_Manager::find"); + return -1; +} + +// Suspend a single process. + +int +ACE_Process_Manager::suspend (pid_t t_id) +{ + ACE_TRACE ("ACE_Process_Manager::suspend"); + return -1; +} + +// Resume a single process. + +int +ACE_Process_Manager::resume (pid_t t_id) +{ + ACE_TRACE ("ACE_Process_Manager::resume"); + return -1; +} + +// Kill a single process. +int +ACE_Process_Manager::kill (pid_t t_id, int signum) +{ + ACE_TRACE ("ACE_Process_Manager::kill"); + return -1; +} + +// Get group ids for a particular process id. + +int +ACE_Process_Manager::get_grp (pid_t t_id, int &grp_id) +{ + ACE_TRACE ("ACE_Process_Manager::get_grp"); + return -1; +} + +// Set group ids for a particular process id. + +int +ACE_Process_Manager::set_grp (pid_t t_id, int grp_id) +{ + ACE_TRACE ("ACE_Process_Manager::set_grp"); + return -1; +} + +// Suspend a group of processs. + +int +ACE_Process_Manager::apply_grp (int grp_id, + PROC_FUNC func, + int arg) +{ + ACE_TRACE ("ACE_Process_Manager::apply_grp"); + return -1; +} + +int +ACE_Process_Manager::suspend_grp (int grp_id) +{ + ACE_TRACE ("ACE_Process_Manager::suspend_grp"); + return -1; +} + +// Resume a group of processs. + +int +ACE_Process_Manager::resume_grp (int grp_id) +{ + ACE_TRACE ("ACE_Process_Manager::resume_grp"); + return -1; +} + +// Kill a group of processs. + +int +ACE_Process_Manager::kill_grp (int grp_id, int signum) +{ + ACE_TRACE ("ACE_Process_Manager::kill_grp"); + return -1; +} + +int +ACE_Process_Manager::apply_all (PROC_FUNC func, int arg) +{ + ACE_TRACE ("ACE_Process_Manager::apply_all"); + return -1; +} + +// Resume all processs that are suspended. + +int +ACE_Process_Manager::resume_all (void) +{ + ACE_TRACE ("ACE_Process_Manager::resume_all"); + return -1; +} + +int +ACE_Process_Manager::suspend_all (void) +{ + ACE_TRACE ("ACE_Process_Manager::suspend_all"); + return -1; +} + +int +ACE_Process_Manager::kill_all (int sig) +{ + ACE_TRACE ("ACE_Process_Manager::kill_all"); + return -1; +} + +// Must be called when process goes out of scope to clean up its table +// slot. + +void * +ACE_Process_Manager::exit (void *status) +{ + ACE_TRACE ("ACE_Process_Manager::exit"); + return 0; +} + +// Wait for all the processs to exit. + +int +ACE_Process_Manager::wait (ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_Process_Manager::wait"); + return -1; +} + +void +ACE_Process_Control::dump (void) const +{ + ACE_TRACE ("ACE_Process_Control::dump"); +} + +// Initialize the process controller. + +ACE_Process_Control::ACE_Process_Control (ACE_Process_Manager *t, + int insert) +{ + ACE_TRACE ("ACE_Process_Control::ACE_Process_Control"); +} + +// Automatically kill process on exit. + +ACE_Process_Control::~ACE_Process_Control (void) +{ + ACE_TRACE ("ACE_Process_Control::~ACE_Process_Control"); +} + +// Exit from process (but clean up first). + +void * +ACE_Process_Control::exit (void *exit_status) +{ + ACE_TRACE ("ACE_Process_Control::exit"); + return 0; +} + +#endif diff --git a/ace/Process_Manager.h b/ace/Process_Manager.h new file mode 100644 index 00000000000..79d8c3b9c3d --- /dev/null +++ b/ace/Process_Manager.h @@ -0,0 +1,250 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Process_Manager.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_PROCESS_MANAGER_H) +#define ACE_PROCESS_MANAGER_H + +#include "ace/Log_Msg.h" +#include "ace/Synch.h" + +#if 0 +class ACE_Export ACE_Process_Descriptor + // = Title + // Information for controlling groups of processs. +{ +friend class ACE_Process_Manager; +public: + enum Process_State + { + IDLE, + SPAWNED, + RUNNING, + SUSPENDED, + TERMINATED + }; +private: + + ACE_Process_Descriptor (void); + + pid_t proc_id_; + // Unique process ID. + + int grp_id_; + // Unique group ID. + + Process_State proc_state_; + // Current state of the process. +}; + +// Forward declaration. + +class ACE_Process_Control; + +class ACE_Export ACE_Process_Manager + // = TITLE + // Manages a pool of processs. + // + // = DESCRIPTION + // This class allows operations on groups of processs atomically. +{ +friend class ACE_Process_Control; +public: + enum + { + DEFAULT_SIZE = 100 + }; + + // = Initialization and termination methods. + ACE_Process_Manager (size_t size = ACE_Process_Manager::DEFAULT_SIZE); + ~ACE_Process_Manager (void); + + int open (size_t size = DEFAULT_SIZE); + // Initialize the manager with room for SIZE processs. + + int close (void); + // Release all resources. + + int spawn (ACE_THR_FUNC func, + void *args, + long flags, + pid_t * = 0, + u_int priority = 0, + void *stack = 0, + size_t stack_size = 0); + // Create a new process, which executes . + + // Returns: on success a unique group id that can be used to control + // other processs added to the same group. On failure, returns -1. + + int spawn_n (int n, + ACE_THR_FUNC func, + void *args, + long flags, + u_int priority = 0); + // Create N new processs, all of which execute . + + // Returns: on success a unique group id that can be used to control + // all of the processs in the same group. On failure, returns -1. + + void *exit (void *status); + // Called to clean up when a process exits. + + int wait (ACE_Time_Value *timeout = 0); + // Block until there are no more processs running or + // expires. Returns 0 on success and -1 on failure. + + // = Suspend methods. + int suspend_all (void); + // Suspend all processs + int suspend (pid_t); + // Suspend a single process. + int suspend_grp (int grp_id); + // Suspend a group of processs. + + // = Resume methods. + int resume_all (void); + // Resume all stopped processs + int resume (pid_t); + // Resume a single process. + int resume_grp (int grp_id); + // Resume a group of processs. + + // = Kill methods (send signals...). + int kill_all (int signum); + // Send signum to all stopped processs + int kill (pid_t, int signum); + // Kill a single process. + int kill_grp (int grp_id, int signum); + // Kill a group of processs. + + // = Set/get group ids for a particular process id. + int set_grp (pid_t, int grp_id); + int get_grp (pid_t, int &grp_id); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + int resize (size_t); + // Resize the pool of Process_Descriptors. + + int spawn_i (ACE_THR_FUNC func, + void *args, + long flags, + pid_t * = 0, + u_int priority = 0, + void *stack = 0, + size_t stack_size = 0); + // Create a new process (must be called with locks held). + + int find (pid_t p_id); + // Locate the index of the table slot occupied by . Returns + // -1 if is not in the table doesn't contain . + + int insert_proc (pid_t p_id); + // Insert a process in the table (checks for duplicates). + // Omitting the process handle won't work on Win32... + + int append_proc (pid_t p_id, ACE_Process_Descriptor::Process_State); + // Append a process in the table (adds at the end, growing the table + // if necessary). + + void remove_proc (int i); + // Remove process from the table. + + // = The following four methods implement a simple scheme for + // operating on a collection of processs atomically. + + typedef int (ACE_Process_Manager::*PROC_FUNC)(int, int); + + int apply_grp (int grp_id, PROC_FUNC, int = 0); + // Apply to all members of the table that match the . + + int apply_all (PROC_FUNC, int = 0); + // Apply to all members of the table. + + int resume_proc (int i); + // Resume the process at index . + + int suspend_proc (int i); + // Suspend the process at index . + + int kill_proc (int i, int signum); + // Send signal to the process at index . + + ACE_Process_Descriptor *proc_table_; + // Vector that describes process state within the Process_Manager. + + size_t max_table_size_; + // Maximum number of processs we can manage (should be dynamically + // allocated). + + size_t current_count_; + // Current number of processs we are managing. + + int grp_id_; + // Keeps track of the next group id to assign. +}; + +class ACE_Export ACE_Process_Control + // = TITLE + // Used to keep track of a process's activities within its entry + // point function. +{ +public: + ACE_Process_Control (ACE_Process_Manager *tm, int insert = 0); + // Initialize the process control object. If INSERT != 0, then + // register the process with the ProcessManager. + + ~ACE_Process_Control (void); + // Implicitly kill the process on exit and remove it from its + // associated ProcessManager. + + void *exit (void *status); + // Explicitly kill the process on exit and remove it from its + // associated ProcessManager. + + void *status (void *status); + // Set the exit status (and return existing status). + + void *status (void); + // Get the current exit status. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Process_Manager *tm_; + // Pointer to the process manager for this block of code. + + void *status_; + // Keeps track of the exit status for the process. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Process_Manager.i" +#endif /* __ACE_INLINE__ */ +#endif + +#endif /* ACE_PROCESS_MANAGER_H */ + diff --git a/ace/Process_Manager.i b/ace/Process_Manager.i new file mode 100644 index 00000000000..1be8c04c67d --- /dev/null +++ b/ace/Process_Manager.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// $Id$ + +// Process_Manager.i diff --git a/ace/Profile_Timer.cpp b/ace/Profile_Timer.cpp new file mode 100644 index 00000000000..406623c37df --- /dev/null +++ b/ace/Profile_Timer.cpp @@ -0,0 +1,226 @@ +// Profile_Timer.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Profile_Timer.h" + +#if defined (ACE_HAS_PRUSAGE_T) || defined (ACE_HAS_GETRUSAGE) + +#if !defined (__ACE_INLINE__) +#include "ace/Profile_Timer.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Profile_Timer) + +void +ACE_Profile_Timer::dump (void) const +{ + ACE_TRACE ("ACE_Profile_Timer::dump"); +} + +// Initialize interval timer. + +ACE_Profile_Timer::ACE_Profile_Timer (void) +{ + ACE_TRACE ("ACE_Profile_Timer::ACE_Profile_Timer"); + ACE_OS::memset (&this->end_usage_, 0, sizeof this->end_usage_); + ACE_OS::memset (&this->begin_usage_, 0, sizeof this->begin_usage_); + ACE_OS::memset (&this->last_usage_, 0, sizeof this->last_usage_); + +#if defined (ACE_HAS_PRUSAGE_T) + ACE_OS::memset (&this->last_usage_, 0, sizeof this->last_usage_); + char buf[20]; + ACE_OS::sprintf (buf, "/proc/%d", ACE_OS::getpid ()); + + if ((this->proc_handle_ = ACE_OS::open (buf, O_RDONLY, 0)) == -1) + ACE_OS::perror (buf); +#elif defined (ACE_HAS_GETRUSAGE) + ACE_OS::memset (&this->begin_time_, 0, sizeof this->begin_time_); + ACE_OS::memset (&this->end_time_, 0, sizeof this->end_time_); + ACE_OS::memset (&this->last_time_, 0, sizeof this->last_time_); +#endif /* ACE_HAS_PRUSAGE_T */ +} + +// Terminate the interval timer. +ACE_Profile_Timer::~ACE_Profile_Timer (void) +{ + ACE_TRACE ("ACE_Profile_Timer::~ACE_Profile_Timer"); +#if defined (ACE_HAS_PRUSAGE_T) + if (ACE_OS::close (this->proc_handle_) == -1) + ACE_OS::perror ("ACE_Profile_Timer::~ACE_Profile_Timer"); +#endif /* ACE_HAS_PRUSAGE_T */ +} + +// Return the resource utilization. + +void +ACE_Profile_Timer::get_rusage (ACE_Profile_Timer::Rusage &usage) +{ + ACE_TRACE ("ACE_Profile_Timer::get_rusage"); + usage = this->end_usage_; +} + +#if defined (ACE_HAS_PRUSAGE_T) + +// Compute the amount of resource utilization since the start time. + +void +ACE_Profile_Timer::elapsed_rusage (ACE_Profile_Timer::Rusage &rusage) +{ + ACE_TRACE ("ACE_Profile_Timer::elapsed_rusage"); + rusage.pr_lwpid = this->end_usage_.pr_lwpid - this->last_usage_.pr_lwpid; + rusage.pr_count = this->end_usage_.pr_count - this->last_usage_.pr_count; + rusage.pr_minf = this->end_usage_.pr_minf - this->last_usage_.pr_minf; + rusage.pr_majf = this->end_usage_.pr_majf - this->last_usage_.pr_majf; + rusage.pr_inblk = this->end_usage_.pr_inblk - this->last_usage_.pr_inblk; + rusage.pr_oublk = this->end_usage_.pr_oublk - this->last_usage_.pr_oublk; + rusage.pr_msnd = this->end_usage_.pr_msnd - this->last_usage_.pr_msnd; + rusage.pr_mrcv = this->end_usage_.pr_mrcv - this->last_usage_.pr_mrcv; + rusage.pr_sigs = this->end_usage_.pr_sigs - this->last_usage_.pr_sigs; + this->subtract (rusage.pr_wtime, this->end_usage_.pr_wtime, this->last_usage_.pr_wtime); + this->subtract (rusage.pr_ltime, this->end_usage_.pr_ltime, this->last_usage_.pr_ltime); + this->subtract (rusage.pr_slptime, this->end_usage_.pr_slptime, this->last_usage_.pr_slptime); + rusage.pr_vctx = this->end_usage_.pr_vctx - this->last_usage_.pr_vctx; + rusage.pr_ictx = this->end_usage_.pr_ictx - this->last_usage_.pr_ictx; + rusage.pr_sysc = this->end_usage_.pr_sysc - this->last_usage_.pr_sysc; + rusage.pr_ioch = this->end_usage_.pr_ioch - this->last_usage_.pr_ioch; +} + +// Compute the elapsed time. + +void +ACE_Profile_Timer::compute_times (ACE_Elapsed_Time &et) +{ + ACE_TRACE ("ACE_Profile_Timer::compute_times"); + timestruc_t td; + + ACE_Profile_Timer::Rusage &end = this->end_usage_; + ACE_Profile_Timer::Rusage &begin = this->begin_usage_; + + this->subtract (td, end.pr_tstamp, begin.pr_tstamp); + et.real_time = td.tv_sec + ((double) td.tv_nsec) / (1000 * 1000 * 1000); + this->subtract (td, end.pr_utime, begin.pr_utime); + et.user_time = td.tv_sec + ((double) td.tv_nsec) / (1000 * 1000 * 1000); + this->subtract (td, end.pr_stime, begin.pr_stime); + et.system_time = td.tv_sec + ((double) td.tv_nsec) / (1000 * 1000 * 1000); +} + +// Determine the difference between T1 and T2. + +void +ACE_Profile_Timer::subtract (timestruc_t &tdiff, timestruc_t &t1, timestruc_t &t0) +{ + ACE_TRACE ("ACE_Profile_Timer::subtract"); + tdiff.tv_sec = t1.tv_sec - t0.tv_sec; + tdiff.tv_nsec = t1.tv_nsec - t0.tv_nsec; + + // Normalize the time. + + while (tdiff.tv_nsec < 0) + { + tdiff.tv_sec--; + tdiff.tv_nsec += (1000 * 1000 * 1000); + } +} + +#elif defined (ACE_HAS_GETRUSAGE) +// Compute the amount of resource utilization since the start time. + +void +ACE_Profile_Timer::elapsed_rusage (ACE_Profile_Timer::Rusage &usage) +{ + ACE_TRACE ("ACE_Profile_Timer::elapsed_rusage"); +#if !defined (ACE_WIN32) + // integral shared memory size + usage.ru_ixrss = this->end_usage_.ru_ixrss - this->last_usage_.ru_ixrss; + // integral unshared data " + usage.ru_idrss = this->end_usage_.ru_idrss - this->last_usage_.ru_idrss; + // integral unshared stack " + usage.ru_isrss = this->end_usage_.ru_isrss - this->last_usage_.ru_isrss; + // page reclaims - total vmfaults + usage.ru_minflt = this->end_usage_.ru_minflt - this->last_usage_.ru_minflt; + // page faults + usage.ru_majflt = this->end_usage_.ru_majflt - this->last_usage_.ru_majflt; + // swaps + usage.ru_nswap = this->end_usage_.ru_nswap - this->last_usage_.ru_nswap; + // block input operations + usage.ru_inblock = this->end_usage_.ru_inblock - + this->last_usage_.ru_inblock; + // block output operations + usage.ru_oublock = this->end_usage_.ru_oublock - + this->last_usage_.ru_oublock; + // messages sent + usage.ru_msgsnd = this->end_usage_.ru_msgsnd - this->last_usage_.ru_msgsnd; + // messages received + usage.ru_msgrcv = this->end_usage_.ru_msgrcv - this->last_usage_.ru_msgrcv; + // signals received + usage.ru_nsignals = this->end_usage_.ru_nsignals - + this->last_usage_.ru_nsignals; + // voluntary context switches + usage.ru_nvcsw = this->end_usage_.ru_nvcsw - this->last_usage_.ru_nvcsw; + // involuntary context switches + usage.ru_nivcsw = this->end_usage_.ru_nivcsw - this->last_usage_.ru_nivcsw; +#endif /* ACE_WIN32 */ +} + +void +ACE_Profile_Timer::compute_times (ACE_Elapsed_Time &et) +{ + ACE_TRACE ("ACE_Profile_Timer::compute_times"); + +#if defined (ACE_WIN32) + ACE_Time_Value atv = this->end_time_ - this->begin_time_; + et.real_time = atv.sec () + ((double) atv.usec ()) / (1000 * 1000); + + atv = ACE_Time_Value (this->end_usage_.ru_utime) + - ACE_Time_Value (this->begin_usage_.ru_utime); + + et.user_time = atv.sec () + ((double) atv.usec ()) / (1000 * 1000); + + atv = ACE_Time_Value (this->end_usage_.ru_stime) + - ACE_Time_Value (this->begin_usage_.ru_stime); + et.system_time = atv.sec () + ((double) atv.usec ()) / (1000 * 1000); +#else + timeval td; + + this->subtract (td, this->end_time_, this->begin_time_); + et.real_time = td.tv_sec + ((double) td.tv_usec) / (1000 * 1000); + + this->subtract (td, this->end_usage_.ru_utime, this->begin_usage_.ru_utime); + et.user_time = td.tv_sec + ((double) td.tv_usec) / (1000 * 1000); + + this->subtract (td, this->end_usage_.ru_stime, this->begin_usage_.ru_stime); + et.system_time = td.tv_sec + ((double) td.tv_usec) / (1000 * 1000); +#endif /* ACE_WIN32 */ +} + +// Determine the difference between T1 and T2. + +void +ACE_Profile_Timer::subtract (timeval &tdiff, timeval &t1, timeval &t0) +{ + ACE_TRACE ("ACE_Profile_Timer::subtract"); + tdiff.tv_sec = t1.tv_sec - t0.tv_sec; + tdiff.tv_usec = t1.tv_usec - t0.tv_usec; + + // Normalize the time. + + while (tdiff.tv_usec < 0) + { + tdiff.tv_sec--; + tdiff.tv_usec += (1000 * 1000); + } +} + +#endif /* ACE_HAS_PRUSAGE_T */ + +// Compute the amount of time that has elapsed between start and stop. + +int +ACE_Profile_Timer::elapsed_time (ACE_Elapsed_Time &et) +{ + ACE_TRACE ("ACE_Profile_Timer::elapsed_time"); + this->compute_times (et); + return 0; +} +#endif /* defined (ACE_HAS_PRUSAGE_T) || defined (ACE_HAS_GETRUSAGE) */ diff --git a/ace/Profile_Timer.h b/ace/Profile_Timer.h new file mode 100644 index 00000000000..4234aef14f6 --- /dev/null +++ b/ace/Profile_Timer.h @@ -0,0 +1,142 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Profile_Timer.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_PROFILE_TIMER_H) +#define ACE_PROFILE_TIMER_H + +#include "ace/ACE.h" +#include "ace/Time_Value.h" + +#if !(defined (ACE_HAS_PRUSAGE_T) || defined (ACE_HAS_GETRUSAGE)) + +class ACE_Export ACE_Profile_Timer +{ +public: + struct ACE_Elapsed_Time + { + double real_time; + double user_time; + double system_time; + }; + + ACE_Profile_Timer (void) {} + ~ACE_Profile_Timer (void) {} + int start (void) { errno = ENOTSUP; return -1; } + int stop (void) { errno = ENOTSUP; return -1; } + int elapsed_time (ACE_Elapsed_Time &et) { errno = ENOTSUP; return -1; } +}; +#else +class ACE_Export ACE_Profile_Timer + // = TITLE + // A C++ wrapper for UNIX interval timers. +{ +public: + struct ACE_Elapsed_Time + { + double real_time; + double user_time; + double system_time; + }; + +#if defined (ACE_HAS_PRUSAGE_T) + typedef prusage_t Rusage; +#elif defined (ACE_HAS_GETRUSAGE) + typedef rusage Rusage; +#endif /* ACE_HAS_PRUSAGE_T */ + + // = Initialization and termination methods. + ACE_Profile_Timer (void); + // Default constructor. + + ~ACE_Profile_Timer (void); + // Shutdown the timer. + + // = Timer methods. + int start (void); + // Activate the timer. + + int stop (void); + // Stop the timer. + + // = Resource utilization methods. + int elapsed_time (ACE_Elapsed_Time &et); + // Compute the time elapsed since . + + void elapsed_rusage (ACE_Profile_Timer::Rusage &rusage); + // Compute the amount of resource utilization since the start time. + + void get_rusage (ACE_Profile_Timer::Rusage &rusage); + // Return the resource utilization (don't recompute it). + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + void compute_times (ACE_Elapsed_Time &et); + // Compute how much time has elapsed. + + ACE_Profile_Timer::Rusage begin_usage_; + // Keep track of the starting resource utilization. + + ACE_Profile_Timer::Rusage end_usage_; + // Keep track of the ending resource utilization. + + ACE_Profile_Timer::Rusage last_usage_; + // Keep track of the last rusage for incremental timing. + +#if defined (ACE_HAS_PRUSAGE_T) + void subtract (timestruc_t &tdiff, timestruc_t &t0, timestruc_t &t1); + // Substract two timestructs and store their difference. + + ACE_HANDLE proc_handle_; + // I/O handle for /proc file system. + +#elif defined (ACE_HAS_GETRUSAGE) + void subtract (timeval &tdiff, timeval &t0, timeval &t1); + // Substract two timestructs and store their difference. + + timeval begin_time_; + // Keep track of the beginning time. + + timeval end_time_; + // Keep track of the ending time. + + timeval last_time_; + // Keep track of the last time for incremental timing. +#elif defined (ACE_WIN32) + ACE_Time_Value begin_time_; + // Keep track of the beginning time. + + ACE_Time_Value end_time_; + // Keep track of the ending time. + + ACE_Time_Value last_time_; + // Keep track of the last time for incremental timing. + +#endif /* ACE_HAS_PRUSAGE_T */ +}; + +#if defined (__ACE_INLINE__) +#include "ace/Profile_Timer.i" +#endif /* __ACE_INLINE__ */ + +#endif /* defined (ACE_HAS_PRUSAGE_T) || defined (ACE_HAS_GETRUSAGE) */ +#endif /* ACE_PROFILE_TIMER_H */ + diff --git a/ace/Profile_Timer.i b/ace/Profile_Timer.i new file mode 100644 index 00000000000..8ff9feec5a8 --- /dev/null +++ b/ace/Profile_Timer.i @@ -0,0 +1,48 @@ +/* -*- C++ -*- */ +// $Id$ + +// Profile_Timer.i + +#if defined (ACE_HAS_PRUSAGE_T) || defined (ACE_HAS_GETRUSAGE) + +#if defined (ACE_HAS_PRUSAGE_T) +ACE_INLINE int +ACE_Profile_Timer::start (void) +{ + ACE_TRACE ("ACE_Profile_Timer::start"); + return ACE_OS::ioctl (this->proc_handle_, + PIOCUSAGE, + &this->begin_usage_); +} + +ACE_INLINE int +ACE_Profile_Timer::stop (void) +{ + ACE_TRACE ("ACE_Profile_Timer::stop"); + this->last_usage_ = this->end_usage_; + return ACE_OS::ioctl (this->proc_handle_, + PIOCUSAGE, + &this->end_usage_); +} +#elif defined (ACE_HAS_GETRUSAGE) +ACE_INLINE int +ACE_Profile_Timer::start (void) +{ + ACE_TRACE ("ACE_Profile_Timer::start"); + this->begin_time_ = ACE_OS::gettimeofday (); + ACE_OS::getrusage (RUSAGE_SELF, &this->begin_usage_); + return 0; +} + +ACE_INLINE int +ACE_Profile_Timer::stop (void) +{ + ACE_TRACE ("ACE_Profile_Timer::stop"); + this->last_time_ = this->end_time_; + this->end_time_ = ACE_OS::gettimeofday (); + this->last_usage_ = this->end_usage_; + ACE_OS::getrusage (RUSAGE_SELF, &this->end_usage_); + return 0; +} +#endif /* ACE_HAS_PRUSAGE_T */ +#endif /* defined (ACE_HAS_PRUSAGE_T) || defined (ACE_HAS_GETRUSAGE) */ diff --git a/ace/README b/ace/README new file mode 100644 index 00000000000..e39bd7a633c --- /dev/null +++ b/ace/README @@ -0,0 +1,784 @@ +ACE DEFINES +----------------------------------------------------------------------------- + +The following describes the meaning of the C++ compiler macros that +may be set in the DEFFLAGS Makefile macro. When you port ACE to a new +platform and/or C++ compiler, make sure that you check to see which of +these need to be defined. Eventually, most of this information should +be auto-discovered via GNU autoconf or Larry Wall's metaconfig... + +Macro Description +----- ----------- + +ACE_HAS_64BIT_LONGS Platform has 64bit longs and 32bit ints... +ACE_HAS_ALLOCA Compiler/platform supports alloca() +ACE_HAS_ALLOCA_H Compiler/platform has +ACE_HAS_AUTOMATIC_INIT_FINI Compiler/platform correctly calls init()/fini() for shared libraries +ACE_HAS_BROKEN_BITSHIFT Compiler has integer overflow problem with bit-shift operations. +ACE_HAS_BROKEN_CTIME Compiler/platform uses macro for ctime (e.g., MVS) +ACE_HAS_BROKEN_MSG_H Platform headers don't support prototypes +ACE_HAS_BROKEN_MMAP_H HP/UX does not wrap the mmap(2) header files with extern "C". +ACE_HAS_BROKEN_POSIX_TIME Platform defines struct timespec in +ACE_HAS_BROKEN_RANDR OS/compiler's header files are inconsistent with libC definition of rand_r(). +ACE_HAS_BROKEN_SENDMSG OS/compiler omits the const from the sendmsg() prototype. +ACE_HAS_BROKEN_SETRLIMIT OS/compiler omits the const from the rlimit parameter in the setrlimit() prototype. +ACE_HAS_BROKEN_WRITEV OS/compiler omits the const from the iovec parameter in the writev() prototype. +ACE_HAS_BSTRING Platform has (which contains bzero() prototype) +ACE_HAS_CHARPTR_DL OS/platform uses char * for dlopen/dlsym args, rather than const char *. +ACE_HAS_CHARPTR_SOCKOPT OS/platform uses char * for sockopt, rather than const char * +ACE_HAS_COMPLEX_LOCK Platform supports non-standard readers/writer locks... +ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES Prototypes for both signal() and struct sigaction are consistent. +ACE_HAS_CPLUSPLUS_HEADERS Compiler/platform has correctly prototyped header files +ACE_HAS_DLL Build ACE using the frigging PC DLL nonsense... +ACE_HAS_GETRUSAGE Platform supports the getrusage() system call. +ACE_HAS_GNU_CSTRING_H Denotes that GNU has cstring.h as standard which redefines memchr() +ACE_HAS_GREENHILLS_SOCKETS Platform is using GreenHills compiler with its weird socket headers. +ACE_HAS_HI_RES_TIMER Compiler/platform supports SunOS high resolution timers +ACE_HAS_INLINED_OSCALLS Inline all the static class OS methods to remove call overhead +ACE_HAS_IP_MULTICAST Platform supports IP multicast +ACE_HAS_IRIX_GETTIMEOFDAY Denotes that IRIX 5.3 has second argument to gettimeofday() which is variable ... +ACE_HAS_IRIX62_THREADS Platform supports the very odd IRIX 6.2 threads... +ACE_HAS_LIMITED_RUSAGE_T The rusage_t structure has only two fields. +ACE_HAS_LONGLONG_T Compiler/platform supports the "long long" datatype. +ACE_HAS_LONG_MAP_FAILED Platform defines MAP_FAILED as a long constant. +ACE_HAS_MFC Platform supports Microsoft Foundation Classes +ACE_HAS_MSG Platform supports recvmsg and sendmsg +ACE_HAS_MT_SAFE_SOCKETS Sockets may be called in multi-threaded programs +ACE_HAS_NONCONST_GETBY Platform uses non-const char * in calls to gethostbyaddr, gethostbyname, getservbyname +ACE_HAS_OLD_MALLOC Compiler/platform uses old malloc()/free() prototypes (ugh) +ACE_HAS_ONEARG_SIGWAIT sigwait() takes only one argument. +ACE_HAS_ORBIX Platform has Orbix CORBA implementation +ACE_HAS_OSF_TIMOD_H Platform supports the OSF TLI timod STREAMS module +ACE_HAS_POLL Platform contains +ACE_HAS_POSIX_NONBLOCK Platform supports POSIX O_NONBLOCK semantics +ACE_HAS_POSIX_SEM Platform supports POSIX real-time semaphores (e.g., VxWorks and Solaris) +ACE_HAS_POSIX_TIME Platform supports the POSIX timespec_t type +ACE_HAS_PROC_FS Platform supports the /proc file system and defines tid_t in +ACE_HAS_PRUSAGE_T Platform supports the prusage_t struct +ACE_HAS_PTHREADS Platform supports POSIX Pthreads +ACE_HAS_PTHREAD_ATTR_INIT Platform requires pthread_*attr_init() rather than pthread_*attr_create() +ACE_HAS_PTHREAD_ATTR_DESTROY Platform requires pthread_*attr_destroy() rather than pthread_*attr_delete() +ACE_HAS_PTHREAD_CONDATTR_SETKIND_NP Platform has pthread_condattr_setkind_np(). +ACE_HAS_PTHREAD_DSTATE_PTR pthread_attr_setdetachstate() takes pointer to 2nd arg. +ACE_HAS_PTHREAD_EQUAL Platform has pthread_equal(). +ACE_HAS_PTHREAD_GETSPECIFIC_DATAPTR pthread_getspecific() takes a data pointer for 2nd arg. +ACE_HAS_PTHREAD_MUTEXATTR_SETKIND_NP Platform has pthread_mutexattr_setkind_np(). +ACE_HAS_PTHREAD_T Platform has pthread_t defined. +ACE_HAS_PTHREAD_YIELD_VOIDPTR pthread_yield() takes a void pointer arg. +ACE_HAS_REENTRANT_FUNCTIONS Platform supports reentrant functions (i.e., all the POSIX *_r functions). +ACE_HAS_REGEX Platform supports the POSIX regular expression library +ACE_HAS_RTLD_LAZY_V Explicit dynamic linking permits "lazy" symbol resolution +ACE_HAS_SELECT_H Platform has special header for select(). +ACE_HAS_SEMUN Compiler/platform defines a union semun for SysV shared memory +ACE_HAS_SIGINFO_T Platform supports SVR4 extended signals +ACE_HAS_SIGWAIT Platform/compiler has the sigwait(2) prototype +ACE_HAS_SIG_ATOMIC_T Compiler/platform defines the sig_atomic_t typedef +ACE_HAS_SIN_LEN Platform supports new BSD inet_addr len field. +ACE_HAS_SIZET_SOCKET_LEN OS/compiler uses size_t * rather than int * for socket lengths +ACE_HAS_SOCKIO_H Compiler/platform provides the sockio.h file +ACE_HAS_SPARCWORKS_401_SIGNALS Compiler has brain-damaged SPARCwork SunOS 4.x signal prototype... +ACE_HAS_SSIZE_T Compiler supports the ssize_t typedef +ACE_HAS_STHREADS Platform supports Solaris threads +ACE_HAS_STRBUF_T Compiler/platform supports struct strbuf +ACE_HAS_STREAMS Platform supports STREAMS +ACE_HAS_STREAM_PIPES Platform supports STREAM pipes +ACE_HAS_STRERROR Compiler/platform supports strerror () +ACE_HAS_STRUCT_NETDB_DATA Compiler/platform has strange hostent API for socket *_r() calls +ACE_HAS_STRUCT_PROTOENT_DATA Compiler/platform has strange protoent API for socket *_r() calls +ACE_HAS_SUNOS4_GETTIMEOFDAY SunOS 4 style prototype. +ACE_HAS_SUNOS4_SIGNAL_T Compiler has horrible SunOS 4.x signal handlers... +ACE_HAS_SVR4_DYNAMIC_LINKING Compiler/platform supports SVR4 dynamic linking semantics +ACE_HAS_SVR4_GETTIMEOFDAY Compiler/platform supports SVR4 gettimeofday() prototype +ACE_HAS_SVR4_SIGNAL_T Compiler/platform supports SVR4 signal typedef +ACE_HAS_SVR4_TIME Platform supports the SVR4 timestruc_t type +ACE_HAS_SVR4_TLI Compiler/platform supports SVR4 TLI (in particular, T_GETNAME stuff)... +ACE_HAS_SYSCALL_GETRUSAGE HP/UX has an undefined syscall for GETRUSAGE... +ACE_HAS_SYSCALL_H Compiler/platform contains the file. +ACE_HAS_SYSENT_H Platform provides header +ACE_HAS_SYSINFO Platform supports system configuration information +ACE_HAS_SYSV_IPC Platform supports System V IPC (most versions of UNIX, but not Win32) +ACE_HAS_SYS_ERRLIST Platform/compiler supports _sys_errlist symbol +ACE_HAS_SYS_FILIO_H Platform provides header +ACE_HAS_SYS_SIGLIST Compiler/platform supports sys_siglist array +ACE_HAS_TEMPLATE_TYPEDEFS Compiler implements templates that support typedefs inside of classes used as formal arguments to a template class. +ACE_HAS_TERM_IOCTLS Platform has terminal ioctl flags like TCGETS and TCSETS. +ACE_HAS_THREADS Platform supports threads +ACE_HAS_THREAD_SPECIFIC_STORAGE Compiler/platform has thread-specific storage +ACE_HAS_TID_T Platform supports the tid_t type (e.g., AIX) +ACE_HAS_TIMEZONE_GETTIMEOFDAY Platform/compiler supports timezone * as second parameter to gettimeofday() +ACE_HAS_TIMOD_H Platform supports TLI timod STREAMS module +ACE_HAS_TIUSER_H Platform supports TLI tiuser header +ACE_HAS_TLI Platform supports TLI +ACE_HAS_TLI_PROTOTYPES Platform provides TLI function prototypes +ACE_HAS_UCONTEXT_T Platform supports ucontext_t (which is used in the extended signal API). +ACE_HAS_UNION_WAIT The wait() system call takes a (union wait *) rather than int * +ACE_HAS_UNIXWARE_SVR4_SIGNAL_T Has inconsistent SVR4 signal stuff, but not the same as the other platforms +ACE_HAS_UNICODE Platform/compiler supports UNICODE +ACE_HAS_VOIDPTR_MMAP Platform requires void * for mmap(). +ACE_HAS_VOIDPTR_SOCKOPT OS/compiler uses void * arg 4 setsockopt() rather than const char * +ACE_HAS_WIN32_TRYLOCK The Win32 platform support TryEnterCriticalSection() +ACE_HAS_XLI Platform has the XLI version of TLI +ACE_HAS_XT Platform has Xt and Motif +ACE_HAS_YIELD_VOID_PTR Platform requires pthread_yield() to take a NULL. +ACE_LACKS_CONDATTR_PSHARED Platform has no implementation of pthread_condattr_setpshared(), even though it supports pthreads! +ACE_LACKS_MADVISE Platform lacks madvise() (e.g., Linux) +ACE_LACKS_MALLOC_H Platform lacks malloc.h +ACE_LACKS_MKTEMP ACE has no mktemp() +ACE_LACKS_MMAP The platform doesn't have mmap(2) (e.g., SCO UNIX). +ACE_LACKS_MODE_MASKS Platform/compiler doesn't have open() mode masks. +ACE_LACKS_MSGBUF_T Platform lacks struct msgbuf (e.g., NT and MSV). +ACE_LACKS_MSYNC Platform lacks msync() (e.g., Linux) +ACE_LACKS_PARAM_H Platform lacks (e.g., MVS) +ACE_LACKS_POSIX_PROTO Platform lacks POSIX prototypes for certain System V functions like shared memory and message queues. +ACE_LACKS_RECVMSG Platform lacks recvmsg() (e.g., Linux) +ACE_LACKS_RPC_H Platform lacks the ONC RPC header files. +ACE_LACKS_SBRK Platform lacks a working sbrk() (e.g., Win32 and VxWorks) +ACE_LACKS_SEMBUF_T Platform lacks struct sembuf (e.g., Win32 and VxWorks) +ACE_LACKS_SETDETACH Platform lacks pthread_attr_setdetachstate() (e.g., HP/UX 10.x) +ACE_LACKS_KEYDELETE Platform lacks TSS keydelete (e.g., HP/UX) +ACE_LACKS_SENDMSG Platform lacks sendmsg() (e.g., Linux) +ACE_LACKS_SI_ADDR Platform lacks the si_addr field of siginfo_t (e.g., VxWorks and HP/UX 10.x) +ACE_LACKS_SYSV_SHMEM Platform lacks System V shared memory (e.g., Win32 and VxWorks) +ACE_LACKS_SIGINFO_H Platform lacks the siginfo.h include file (e.g., MVS) +ACE_LACKS_SOCKETPAIR Platform lacks the socketpair() call (e.g., SCO UNIX) +ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES Compiler doesn't support static data member templates +ACE_LACKS_STRRECVFD Platform doesn't define struct strrecvfd. +ACE_LACKS_SYSCALL Platform doesn't have syscall() prototype +ACE_LACKS_SYSV_MSQ_PROTOS Platform doesn't have prototypes for Sys V msg()* queues. +ACE_LACKS_T_ERRNO Header files lack t_errno for TLI +ACE_LACKS_UCONTEXT_H Platform lacks the ucontext.h file +ACE_LACKS_UNIX_DOMAIN_SOCKETS ACE platform has no UNIX domain sockets +ACE_LACKS_UTSNAME_T Platform lacks struct utsname (e.g., Win32 and VxWorks) +ACE_MT_SAFE Compile using multi-thread libraries +ACE_NDEBUG Turns off debugging features +ACE_NEEDS_READV Platform doesn't define readv, so use our own +ACE_NEEDS_SYSTIME_H doesn't automatically #include +ACE_NEEDS_WRITEV Platform doesn't define writev, so use our own +ACE_NLOGGING Turns off the LM_DEBUG and LM_ERROR logging macros... +ACE_NTRACE Turns off the tracing feature. +ACE_PAGE_SIZE Defines the page size of the system +ACE_REDEFINES_XTI_FUNCTIONS Platform redefines the t_... names (UnixWare) +ACE_SELECT_USES_INT Platform uses int for select() rather than fd_set +ACE_TEMPLATES_REQUIRE_PRAGMA Compiler's template mechanism must use a pragma This is used for AIX's C++ compiler. +ACE_TEMPLATES_REQUIRE_SOURCE Compiler's template mechanim must see source code (i.e., .cpp files). This is used for GNU G++. +ACE_TEMPLATES_REQUIRE_SPECIALIZATION Compiler's template mechanism requires the use of explicit C++ specializations for all used templates. This is also used for GNU G++ if you don't use the "repo" patches. +ACE_USE_POLL Use the poll() event demultiplexor rather than select(). +ACE_WSOCK_VERSION A parameter list indicating the version of WinSock (e.g., "1, 1" is version 1.1). +---------------------------------------- + +The following is a partial list of where some of these macros are used +in the code. This list was originally compiled by Jam Hamidi +(jh1@core01.osi.com). It is now hopelessly out of date. I hope +someone will come along and update it. + +ACE_HAS_ALLOCA: +--------------- + + Used in: + libsrc/IPC_SAP/SOCK_SAP/SOCK_Connect.C + for allocation of iovp + libsrc/IPC_SAP/SPIPE_SAP/SPIPE_Msg.C + for alocation of iovp + + In solaris: + alloca() allocates size bytes of space in the stack frame of + the caller, and returns a pointer to the allocated block. + This temporary space is automatically freed when the caller + returns. Note: if the allocated block is beyond the current + stack limit, the resulting behavior is undefined. + + In HPUX: + no equivalent. + + Notes: + in HPUX it has to do new and delete. Affects performance. + + +ACE_HAS_AUTOMATIC_INIT_FINI: +---------------------------- + + Used in: + libsrc/Service_Configurator/Service_Repository.i + libsrc/Service_Configurator/Parse_Node.i + include/Parse_Node.i + include/Service_Repository.i + + In solaris: + _init() initializes a loadable module. It is called before + any other routine in a loadable module. + _info() returns information about a loadable module. + _fini() should return the return value from mod_remove(9F). + This flag if set, doesn't do anything. If not set, forces + _init() and _fini() to be executed as is: + dlsym ((char *) handle, "_fini"). + + In HPUX: + don't set. + Maybe have to look into shl_load( ), shl_definesym( ), + shl_findsym( ), shl_gethandle( ), shl_getsymbols( ), + shl_unload( ), shl_get( )(3X) - explicit load of shared libraries + Means Service Configurator won't be available. + TBA. + + +ACE_HAS_CPLUSPLUS_HEADERS: +-------------------------- + + Used In: + ace/OS.h + + HPUX: + set it. + + Notes: + If this is not defined, libc.h and osfcn.h get included. + Only needed for older compiler/OS platforms that don't + provide standard C++ header files in /usr/include. + +ACE_HAS_HI_RES_TIMER: +--------------------- + + Used In: + libsrc/Misc/High_Res_Timer.h + libsrc/Misc/High_Res_Timer.C + include/High_Res_Timer.h + + In Solaris, + C++ wrapper around gethrtime(), which returns a long long. + gethrtime() returns the current high-resolution real time. + Time is expressed as nanoseconds since some arbitrary time + in the past; it is not correlated in any way to the time of + day, and thus is not subject to resetting, drifting, etc. + + In HPUX + look into: getclock(), reltimer(), getitimer() + maybe even vtimes structure vm_utime, vm_stime ? + + Notes: + TBA + + +ACE_HAS_LONGLONG_T: +------------------- + + Used In: + libsrc/Misc/High_Res_Timer.i + libsrc/Misc/High_Res_Timer.C + include/High_Res_Timer.i + + Solaris: + has long long + + HPUX: + doesn't. + + +ACE_LACKS_T_ERRNO: +------------------- + + Used In: + ace/OS.h + + HPUX: + set it. + + Notes: + if set, adds: + extern int t_errno; + + +ACE_HAS_POSIX_NONBLOCK: +----------------------- + + Used in: + ace/OS.h + + HPUX: + set it. + + Notes: + if defined, sets ACE_NONBLOCK and O_NONBLOCK + O_NONBLOCK is used in libsrc/Misc/misc.C to do a + fcntl (fd, F_SETFL, opt) + ACE_NONBLOCK is used in libsrc/IPC_SAP/FIFO_SAP/FIFO_Recv.C in the + disable member function and options passed to the open function + in libsrc/IPC_SAP/FIFO_SAP/FIFO.C + + +ACE_HAS_PROC_FS: +---------------- + + Used in: + ace/OS.h + libsrc/Misc/Profile_Timer.i + + Notes: + if set, includes + the PIOCUSAGE define is used in Profile_Timer. + + Solaris: + procfs.h defines things for the prpsinfo structure (basically to + do a "ps" from inside a program). + + HPUX: + don't set: obviously a different mechanism. + Look into /usr/include/sys/proc.h. The structure is proc. The + pointer to the kernel's proc table may be obtained by + extern struct proc *proc, *procNPROC; + extern int nproc; + + +ACE_HAS_PRUSAGE_T: +------------------ + + Used in: + libsrc/Misc/Profile_Timer.h + libsrc/Misc/Profile_Timer.C + + Notes: + If defined, declares the Profile_Timer class that does start(), + stop() and basically gets real_time, user_time, system_time for + an interval. + This stuff is highly non-portable. + + HPUX: + don't set + + +ACE_HAS_RTLD_LAZY_V: +-------------------- + + Used in: + ace/OS.h + + Notes: + if not defined, does a: + #defines RTLD_LAZY 1. + This is the mode argument passed to dlopen(path,mode), used in + libsrc/Service_Configurator/Parse_Node.i + + Solaris: + dlopen() is one of a family of routines that give the user + direct access to the dynamic linking facilities. (SEE + SunOS 5.3 Linker and Libraries Manual ). These routines are + made available via the library loaded when the option -ldl + is passed to the link-editor. + + These routines are available to dynamically linked execut- + ables ONLY. + + HPUX: + don't set. + look into: + shl_load( ), shl_definesym( ), shl_findsym( ), shl_gethandle( ), + shl_getsymbols( ), shl_unload( ), shl_get( )(3X) + - explicit load of shared libraries + + +ACE_HAS_SEMUN: +-------------- + + Used in: + libsrc/Semaphores/Semaphore_Simple.h + + Notes: + if not defined, defines semun as: + union semun { + int val; /* value for SETVAL */ + struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */ + ushort *array; /* array for GETALL & SETALL */ + }; + + HPUX: + don't set. + in /usr/include/sem.h: + /* The fourth argument to semctl() varies depending on the value of + its first argument. If desired, "union semun" can be declared + by the user, but this is not necessary since the individual + member can just be passed as the argument. */ + + +ACE_HAS_SIG_ATOMIC_T: +--------------------- + + Used in: + ace/OS.h + + Notes: + if not defined, does a: + typedef int sig_atomic_t; + This is used in the Reactor and service configurator. + + HPUX: + set it. + in /usr/include/sys/signal.h: + typedef unsigned int sig_atomic_t; + + +ACE_HAS_SSIZE_T: +---------------- + + Used in: + ace/OS.h + + Notes: + if not defined, does a + typedef int ssize_t; + used mostly in IPC_SAP. (don't confuse with size_t). + + HPUX: + set it. + in /usr/include/sys/types.h + + +ACE_HAS_STRBUF_T: +----------------- + + Used in: + include/Str_Buf.h + + Notes: + if not defined, declares the strbuf structure as: + struct strbuf + { + int maxlen; /* no. of bytes in buffer */ + int len; /* no. of bytes returned */ + void *buf; /* pointer to data */ + }; + + Solaris: + defined in /usr/include/sys/stropts.h + Sys V.4 Streams. + uses strbuf as parameter to putmsg, putpmsg: + int putmsg(int fildes, const struct strbuf *ctlptr, + const struct strbuf *dataptr, int flags); + + HPUX: + don't set. + no SYS V.4 streams. + + +ACE_HAS_STREAMS: +---------------- + + Used In: + ace/OS.h + libsrc/IPC_SAP/SOCK_SAP/LSOCK.C + + Notes: + if defined, includes + + HPUX: + don't set. + no SYS V.4 streams. + + +ACE_HAS_STREAM_PIPES: +--------------------- + + Used in: + libsrc/IPC_SAP/SPIPE_SAP/SPIPE_Msg.h + libsrc/IPC_SAP/SPIPE_SAP/SPIPE_Msg.C + libsrc/IPC_SAP/SPIPE_SAP/SPIPE_Listener.h + libsrc/IPC_SAP/SPIPE_SAP/SPIPE_Listener.C + libsrc/IPC_SAP/SPIPE_SAP/SPIPE.h + libsrc/IPC_SAP/SPIPE_SAP/SPIPE.C + libsrc/IPC_SAP/FIFO_SAP/FIFO_Send_Msg.h + libsrc/IPC_SAP/FIFO_SAP/FIFO_Send_Msg.C + libsrc/IPC_SAP/FIFO_SAP/FIFO_Send_Msg.i + libsrc/IPC_SAP/FIFO_SAP/FIFO_Recv_Msg.h + libsrc/IPC_SAP/FIFO_SAP/FIFO_Recv_Msg.C + libsrc/IPC_SAP/FIFO_SAP/FIFO_Recv_Msg.i + + Notes: + if not set, won't be able to use the SPIPE class (IPC_SAP) with + rendezvous handles. + + HPUX: + don't set. + No sysV.4 streams. + + +ACE_HAS_STRERROR: +----------------- + + Used in: + ace/OS.h + + Notes: + if not defined, does a: + #define strerror(err) sys_errlist[err] + + Solaris: + /usr/include/string.h + + HPUX: + set it. + in /usr/include/sys/errno.h and string.h + extern char *strerror (int); + + +ACE_HAS_SVR4_DYNAMIC_LINKING: +----------------------------- + + Used in: + ace/OS.h + tests/Service_Configurator/CCM_App.C + + Notes: + if defined, includes + with dlopen(), dlsym(), etc.. + + HPUX: + don't set. + has its own: + shl_findsym( ), shl_gethandle( ), shl_getsymbols( ), + shl_unload( ), shl_get( )(3X) - explicit load of shared libraries + + +ACE_HAS_SVR4_GETTIMEOFDAY: +-------------------------- + + Used in: + ace/OS.h + libsrc/Reactor/Timer_Queue.i + + Notes: + has to do with gettimeofday (). + + Solaris: + gettimeofday (struct timeval *tp) + + HPUX: + don't set. + it has gettimeofday (struct timeval *tp, struct timezone *tzp); + most calls do a: + #if defined (ACE_HAS_SVR4_GETTIMEOFDAY) + ::gettimeofday (&cur_time); + #else + ::gettimeofday (&cur_time, 0); + #endif /* ACE_HAS_SVR4_GETTIMEOFDAY */ + + +ACE_HAS_POLL: +------------ + Used in: + ace/OS.h + + Notes: + #if defined (ACE_HAS_POLL) + #include + #endif /* ACE_HAS_POLL */ + +ACE_USE_POLL_IMPLEMENTATION: +------------------ + + Used in: + ace/OS.h + + Notes: + Use the poll() event demultiplexor rather than select(). + + HPUX: + set it. + + +ACE_HAS_SVR4_SIGNAL_T: +---------------------- + + Used in: + ace/OS.h + + Notes: + #if defined (ACE_HAS_SVR4_SIGNAL_T) + typedef void (*SignalHandler)(int); + typedef void (*SignalHandlerV)(void); + #elif defined (ACE_HAS_SIGNALHANDLERV_INT_ARG) + typedef void (*SignalHandler)(int); + typedef void (*SignalHandlerV)(int); + #else + #define SignalHandler SIG_PF + typedef void (*SignalHandlerV)(...); + #endif /* ACE_HAS_SVR4_SIGNAL_T */ + + HPUX: + set it. + + +ACE_HAS_SVR4_TLI: +----------------- + + Used in: + libsrc/IPC_SAP/TLI_SAP/TLI.C + libsrc/IPC_SAP/TLI_SAP/TLI.h + libsrc/IPC_SAP/TLI_SAP/TLI_Stream.C + + Notes: + TLI is the transport layer calls as in: t_bind(), t_open(), t_unbind(), + t_optmgmt(), ... in SunOS and Solaris. + + HPUX: + don't set. + Not supported. + + +ACE_HAS_SYS_FILIO_H: +-------------------- + + Used in: + ace/OS.h + + Notes: + if not defined, includes . + didn't find any reference to anything in this file in the ACE code. + + Solaris: + filio.h defines FIOCLEX, FIOASYNC, ... as _IO('f', 1), .. + for FIOLFS,.. solaris has this to say: + /* + * ioctl's for Online: DiskSuite. + * WARNING - the support for these ioctls may be withdrawn + * in the future OS releases. + */ + + HPUX: + defines FIOASYNC and some other ones, + defines some like FIOCLEX. + some are never defined. + use #ifdef HP-UX to modify sysincludes.h + + +ACE_HAS_SYS_SIGLIST: +-------------------- + + Used in: + ace/OS.h + libsrc/Log_Msg/Log_Msg.C + + Notes: + if not defined, does a: + extern const char **_sys_siglist; + + Solaris: + This is an array holding signal descriptions. + + HPUX: + don't set. + Some additional work is required. In libsrc/Log_Msg/Log_Msg.C, + sys_siglist is used regardless of ACE_HAS_SYS_SIGLIST. + have to add #ifdefs to remove them. + + +ACE_HAS_TEMPLATE_TYPEDEFS: +-------------------------- + + Used in: + libsrc/ASX/*.[Chi] + + Notes: + cfront-based C++ compilers don't implement templates that support + classes with typedefs of other types as formal arguments. This + typedef uses the C++ preprocessor to work around this problem. + +ACE_HAS_THREADS: +---------------- + + Used in: + libsrc/Service_Configurator/Service_Record.i + libsrc/Service_Configurator/Svc_Conf.y.C + libsrc/Service_Configurator/Thread_Spawn.i + libsrc/Threads/Synch.C + libsrc/Threads/Synch.i + libsrc/Threads/Thr_Manager.i + libsrc/ASX/STREAM.C + libsrc/ASX/Queue.C + libsrc/ASX/Module.C + libsrc/ASX/Stream_Modules.C + libsrc/ASX/Multiplexor.C + libsrc/ASX/Message_List.C + include/Message_List.h + include/Module.h + include/Multiplexor.h + include/Queue.h + include/STREAM.h + include/Stream_Modules.h + include/Service_Record.h + include/Thread_Spawn.h + include/Synch.h + include/Thr_Manager.h + + Notes: + We use Message_List.h even in a non-threaded environment. + our XOMessageList.h does this by #ifdefs around Threaded things. + + HPUX: + not until 10.0. + + +ACE_HAS_THREAD_T: +----------------- + + Used in: + ace/OS.h + + Notes: + #if !defined (ACE_HAS_THREAD_T) + typedef int thread_t; + #endif /* !ACE_HAS_THREAD_T */ + + HPUX: + don't set. + + +ACE_HAS_TIMOD_H: +---------------- + + Used in: + ace/OS.h + + Notes: + if defined, include + + Solaris: + timod is a STREAMS module for use with the Transport Inter- + face (TI) functions of the Network Services library. The + timod module converts a set of ioctl(2) calls into STREAMS + messages that may be consumed by a transport protocol pro- + vider that supports the Transport Interface. This allows a + user to initiate certain TI functions as atomic operations. + + HPUX: + don't set. + + +ACE_HAS_TIUSER_H: +----------------- + + Used in: + ace/OS.h + + Notes: + if set, includes + + Solaris: + in conjunction with t_bind, t_accept, etc.. transport layer. + + HPUX: + don't set. + + +ACE_USE_POLL_IMPLEMENTATION: +---------------------------- + + Used in: + libsrc/Reactor/Reactor.i + include/Event_Handler.h + ace/OS.h + include/Reactor.h + + Notes: + in the reactor, use poll instead of select. In general, + good thing to have set. + + Don't set this, it will get set by ACE_HAS_SVR4_POLL + diff --git a/ace/Reactor.cpp b/ace/Reactor.cpp new file mode 100644 index 00000000000..524e9cc434a --- /dev/null +++ b/ace/Reactor.cpp @@ -0,0 +1,1614 @@ +// Reactor.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Synch_T.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/SOCK_Connector.h" +#include "ace/Reactor.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_Reactor) + +struct ACE_Notification_Buffer +{ + ACE_Notification_Buffer (void); + + ACE_Notification_Buffer (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask); + + ACE_Event_Handler *eh_; + // Pointer to the Event_Handler that will be dispatched + // by the main event loop. + + ACE_Reactor_Mask mask_; + // Mask that indicates which method to call. +}; + +ACE_Notification_Buffer::ACE_Notification_Buffer (void) {} + +ACE_Notification_Buffer::ACE_Notification_Buffer (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask) + : eh_ (eh), + mask_ (mask) +{ +} + +// Performs sanity checking on the ACE_HANDLE. + +int +ACE_Handler_Repository::invalid_handle (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_Handler_Repository::invalid_handle"); +#if defined (ACE_WIN32) + return handle == ACE_INVALID_HANDLE; +#else /* !ACE_WIN32 */ + return handle < 0 || handle >= this->max_size_; +#endif /* ACE_WIN32 */ +} + +size_t +ACE_Handler_Repository::max_handlep1 (void) +{ + ACE_TRACE ("ACE_Handler_Repository::max_handlep1"); + +#if defined (ACE_WIN32) + return this->cur_size_; +#else + return this->max_handlep1_; +#endif /* ACE_WIN32 */ +} + +int +ACE_Handler_Repository::open (size_t size) +{ + ACE_TRACE ("ACE_Handler_Repository::open"); + this->max_size_ = size; + +#if defined (ACE_WIN32) + this->cur_size_ = 0; + + // Try to allocate the memory. + ACE_NEW_RETURN (this->event_handlers_, ACE_NT_EH_Record[size], -1); + + // Initialize the ACE_Event_Handler * to ACE_INVALID_HANDLE; + for (size_t h = 0; h < size; h++) + { + this->event_handlers_[h].handle_ = ACE_INVALID_HANDLE; + this->event_handlers_[h].event_handler_ = 0; + } +#else + this->max_handlep1_ = 0; + + // Try to allocate the memory. + ACE_NEW_RETURN (this->event_handlers_, ACE_Event_Handler *[size], -1); + + // Initialize the ACE_Event_Handler * to NULL. + for (size_t h = 0; h < size; h++) + this->event_handlers_[h] = 0; + +#endif /* ACE_WIN32 */ + return 0; +} + +// Initialize a repository of the appropriate . + +ACE_Handler_Repository::ACE_Handler_Repository (void) + : event_handlers_ (0), + max_size_ (0), +#if defined (ACE_WIN32) + cur_size_ (0) +#else + max_handlep1_ (ACE_INVALID_HANDLE) +#endif /* ACE_WIN32 */ +{ + ACE_TRACE ("ACE_Handler_Repository::ACE_Handler_Repository"); +} + +int +ACE_Handler_Repository::close (ACE_Reactor *reactor) +{ + ACE_TRACE ("ACE_Handler_Repository::close"); + + if (this->event_handlers_ != 0) + { +#if defined(ACE_WIN32) + for (ssize_t i = 0; + i < this->cur_size_; + i++) + reactor->detach (this->event_handlers_[i].handle_, + ACE_Event_Handler::RWE_MASK); + + delete [] this->event_handlers_; + this->event_handlers_ = 0; +#else + for (ACE_HANDLE h = 0; + h < this->max_handlep1_; + h++) + reactor->detach (h, ACE_Event_Handler::RWE_MASK); + + delete [] this->event_handlers_; + this->event_handlers_ = 0; +#endif /* !ACE_WIN32 */ + } + return 0; +} + +// Return the associated with . + +ACE_Event_Handler * +ACE_Handler_Repository::find (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_Handler_Repository::find"); +#if defined (ACE_WIN32) + for (ssize_t i = 0; i < this->cur_size_; i++) + if (this->event_handlers_[i].handle_ == handle) + return this->event_handlers_[i].event_handler_; + + return 0; +#else + if (handle < 0 || handle >= this->max_handlep1_) + return 0; + else + return this->event_handlers_[handle]; +#endif /* ACE_WIN32 */ +} + +// Bind the to the . + +int +ACE_Handler_Repository::bind (ACE_HANDLE handle, + ACE_Event_Handler *event_handler) +{ + ACE_TRACE ("ACE_Handler_Repository::bind"); +#if defined (ACE_WIN32) + int first_free = -1; + + for (ssize_t i = 0; i < this->cur_size_; i++) + if (this->event_handlers_[i].handle_ == handle) + { + // If the HANDLE is already here just reassign the + // Event_Handler. + this->event_handlers_[i].event_handler_ = event_handler; + return 0; + } + else if (this->event_handlers_[i].handle_ == ACE_INVALID_HANDLE + && first_free == -1) + first_free = i; + + if (first_free > -1) + // We found a free spot, let's reuse it (and the comments ;-)). + { + this->event_handlers_[first_free].handle_ = handle; + this->event_handlers_[first_free].event_handler_ = event_handler; + return 0; + } + else if (this->cur_size_ < this->max_size_) + { + // Insert at the end of the active portion. + this->event_handlers_[this->cur_size_].handle_ = handle; + this->event_handlers_[this->cur_size_].event_handler_ = event_handler; + this->cur_size_++; + return 0; + } + else + { + // No more room! + errno = ENOMEM; + return -1; + } +#else + this->event_handlers_[handle] = event_handler; + + if (this->max_handlep1_ < handle + 1) + this->max_handlep1_ = handle + 1; + return 0; +#endif /* ACE_WIN32 */ +} + +// Remove the binding of . + +int +ACE_Handler_Repository::unbind (ACE_HANDLE handle, + ACE_Handle_Set &rd_mask, + ACE_Handle_Set &wr_mask, + ACE_Handle_Set &ex_mask) +{ + ACE_TRACE ("ACE_Handler_Repository::unbind"); +#if defined (ACE_WIN32) + // If all the events were cleared then totally shut down Event + // Handler. + + if (rd_mask.is_set (handle) == 0 + && wr_mask.is_set (handle) == 0 + && ex_mask.is_set (handle) == 0) + { + for (ssize_t i = 0; i < this->cur_size_; i++) + if (this->event_handlers_[i].handle_ == handle) + { + this->event_handlers_[i].handle_ = ACE_INVALID_HANDLE; + this->event_handlers_[i].event_handler_ = 0; + + if (this->cur_size_ == i + 1) + { + // We've deleted the last entry (i.e., i + 1 == the + // current size of the array), so we need to figure + // out the last valid place in the array that is worth + // looking at. + + for (int i = this->cur_size_ - 1; + i >= 0 && this->event_handlers_[i].handle_ == ACE_INVALID_HANDLE; + i--) + continue; + + this->cur_size_ = i + 1; + } + break; + } + } + + return 0; +#else + // If all the events were cleared then totally shut down Event + // Handler. + + if (handle < 0 || handle >= this->max_handlep1_) + return -1; + + if (rd_mask.is_set (handle) == 0 + && wr_mask.is_set (handle) == 0 + && ex_mask.is_set (handle) == 0) + { + this->event_handlers_[handle] = 0; + + if (this->max_handlep1_ == handle + 1) + { + // We've deleted the last entry, so we need to figure out + // the last valid place in the array that is worth looking + // at. + ACE_HANDLE rd_max = rd_mask.max_set (); + ACE_HANDLE wr_max = wr_mask.max_set (); + ACE_HANDLE ex_max = ex_mask.max_set (); + + // Compute the maximum of three values. + this->max_handlep1_ = rd_max < wr_max ? wr_max : rd_max; + if (this->max_handlep1_ < ex_max) + this->max_handlep1_ = ex_max; + + this->max_handlep1_++; + } + } + return 0; +#endif /* ACE_WIN32 */ +} + +ACE_Handler_Repository_Iterator::ACE_Handler_Repository_Iterator (const ACE_Handler_Repository &s) + : rep_ (s), + current_ (-1) +{ + this->advance (); +} + +// Pass back the that hasn't been seen in the Set. +// Returns 0 when all items have been seen, else 1. + +int +ACE_Handler_Repository_Iterator::next (ACE_Event_Handler *&next_item) +{ +#if defined (ACE_WIN32) + if (this->current_ >= this->rep_.cur_size_) + return 0; + else + { + next_item = this->rep_.event_handlers_[this->current_].event_handler_; + return 1; + } + +#else + if (this->current_ >= this->rep_.max_handlep1_) + return 0; + else + { + next_item = this->rep_.event_handlers_[this->current_]; + return 1; + } +#endif /* ACE_WIN32 */ +} + +// Move forward by one element in the set. + +int +ACE_Handler_Repository_Iterator::advance (void) +{ +#if defined (ACE_WIN32) + if (this->current_ < this->rep_.cur_size_) + this->current_++; + + while (this->current_ < this->rep_.cur_size_) + if (this->rep_.event_handlers_[this->current_].handle_ != ACE_INVALID_HANDLE) + return 1; + else + this->current_++; + + return 0; +#else + if (this->current_ < this->rep_.max_handlep1_) + this->current_++; + + while (this->current_ < this->rep_.max_handlep1_) + if (this->rep_.event_handlers_[this->current_] != 0) + return 1; + else + this->current_++; + + return 0; +#endif /* ACE_WIN32 */ +} + +// Dump the state of an object. + +void +ACE_Handler_Repository_Iterator::dump (void) const +{ + ACE_TRACE ("ACE_Handler_Repository_Iterator::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "current_ = %d", this->current_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +void +ACE_Handler_Repository::dump (void) const +{ + ACE_TRACE ("ACE_Handler_Repository::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); +#if defined (ACE_WIN32) + ACE_DEBUG ((LM_DEBUG, + "(%t) cur_size_ = %d, max_size_ = %d\n", + this->cur_size_, this->max_size_)); +#else + ACE_DEBUG ((LM_DEBUG, + "(%t) max_handlep1_ = %d, max_size_ = %d\n", + this->max_handlep1_, this->max_size_)); +#endif /* ACE_WIN32 */ + + ACE_DEBUG ((LM_DEBUG, "[")); + + ACE_Event_Handler *eh = 0; + + for (ACE_Handler_Repository_Iterator iter (*this); + iter.next (eh) != 0; + iter.advance ()) + ACE_DEBUG ((LM_DEBUG, " (eh = %x, eh->handle_ = %d)", eh, eh->get_handle ())); + + ACE_DEBUG ((LM_DEBUG, " ]")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Handler_Repository_Iterator) + +void +ACE_Reactor::dump (void) const +{ + ACE_TRACE ("ACE_Reactor::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + + this->timer_queue_->dump (); + this->handler_rep_.dump (); + this->signal_handler_->dump (); + ACE_DEBUG ((LM_DEBUG, "delete_signal_handler_ = %d\n", this->delete_signal_handler_)); + + ACE_HANDLE h; + + for (ACE_Handle_Set_Iterator handle_iter_wr (this->wr_handle_mask_); + (h = handle_iter_wr ()) != ACE_INVALID_HANDLE; + ++handle_iter_wr) + ACE_DEBUG ((LM_DEBUG, "write_handle = %d\n", h)); + + for (ACE_Handle_Set_Iterator handle_iter_rd (this->rd_handle_mask_); + (h = handle_iter_rd ()) != ACE_INVALID_HANDLE; + ++handle_iter_rd) + ACE_DEBUG ((LM_DEBUG, "read_handle = %d\n", h)); + + for (ACE_Handle_Set_Iterator handle_iter_ex (this->ex_handle_mask_); + (h = handle_iter_ex ()) != ACE_INVALID_HANDLE; + ++handle_iter_ex) + ACE_DEBUG ((LM_DEBUG, "except_handle = %d\n", h)); + + for (ACE_Handle_Set_Iterator handle_iter_wr_ready (this->wr_handle_mask_ready_); + (h = handle_iter_wr_ready ()) != ACE_INVALID_HANDLE; + ++handle_iter_wr_ready) + ACE_DEBUG ((LM_DEBUG, "write_handle_ready = %d\n", h)); + + for (ACE_Handle_Set_Iterator handle_iter_rd_ready (this->rd_handle_mask_ready_); + (h = handle_iter_rd_ready ()) != ACE_INVALID_HANDLE; + ++handle_iter_rd_ready) + ACE_DEBUG ((LM_DEBUG, "read_handle_ready = %d\n", h)); + + for (ACE_Handle_Set_Iterator handle_iter_ex_ready (this->ex_handle_mask_ready_); + (h = handle_iter_ex_ready ()) != ACE_INVALID_HANDLE; + ++handle_iter_ex_ready) + ACE_DEBUG ((LM_DEBUG, "except_handle_ready = %d\n", h)); + + ACE_DEBUG ((LM_DEBUG, "restart_ = %d\n", this->restart_)); + ACE_DEBUG ((LM_DEBUG, "\nrequeue_position_ = %d\n", this->requeue_position_)); + ACE_DEBUG ((LM_DEBUG, "\ninitialized_ = %d\n", this->initialized_)); + ACE_DEBUG ((LM_DEBUG, "\nowner_ = %d\n", this->owner_)); + +#if defined (ACE_MT_SAFE) + this->notification_handler_.dump (); + this->token_.dump (); +#endif /* ACE_MT_SAFE */ + + this->timer_skew_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +int +ACE_Reactor::handler_i (int signum, ACE_Event_Handler **eh) +{ + ACE_TRACE ("ACE_Reactor::handler_i"); + ACE_Event_Handler *handler = this->signal_handler_->handler (signum); + + if (handler == 0) + return -1; + else if (*eh != 0) + *eh = handler; + return 0; +} + +void +ACE_Reactor::owner (ACE_thread_t tid, ACE_thread_t *o_id) +{ + ACE_TRACE ("ACE_Reactor::owner"); + ACE_MT (ACE_GUARD (ACE_REACTOR_MUTEX, ace_mon, this->token_)); + + if (o_id) + *o_id = this->owner_; + + this->owner_ = tid; +} + +int +ACE_Reactor::owner (ACE_thread_t *t_id) +{ + ACE_TRACE ("ACE_Reactor::owner"); + ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1)); + *t_id = this->owner_; + return 0; +} + +void +ACE_Reactor::requeue_position (int rp) +{ + ACE_TRACE ("ACE_Reactor::requeue_position"); + ACE_MT (ACE_GUARD (ACE_REACTOR_MUTEX, ace_mon, this->token_)); + this->requeue_position_ = rp; +} + +int +ACE_Reactor::requeue_position (void) +{ + ACE_TRACE ("ACE_Reactor::requeue_position"); + ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1)); + return this->requeue_position_; +} + +#if defined (ACE_MT_SAFE) +// Enqueue ourselves into the list of waiting threads. +void +ACE_Reactor::renew (void) +{ + ACE_TRACE ("ACE_Reactor::renew"); + this->token_.renew (this->requeue_position_); +} + +void +ACE_Reactor_Token::dump (void) const +{ + ACE_TRACE ("ACE_Reactor_Token::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Reactor_Token::ACE_Reactor_Token (ACE_Reactor &r) + : reactor_ (r) +#if defined (ACE_REACTOR_HAS_DEADLOCK_DETECTION) + , ACE_Local_Mutex (0) // Triggers unique name by stringifying "this"... +#endif /* ACE_REACTOR_HAS_DEADLOCK_DETECTION */ +{ + ACE_TRACE ("ACE_Reactor_Token::ACE_Reactor_Token"); +} + +// Used to wakeup the Reactor. + +void +ACE_Reactor_Token::sleep_hook (void) +{ + ACE_TRACE ("ACE_Reactor_Token::sleep_hook"); + if (this->reactor_.notify () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "sleep_hook failed")); +} + +void +ACE_Notification_Handler::dump (void) const +{ + ACE_TRACE ("ACE_Notification_Handler::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "reactor_ = %x", this->reactor_)); + this->notification_pipe_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +int +ACE_Notification_Handler::open (ACE_Reactor *r) +{ + ACE_TRACE ("ACE_Notification_Handler::open"); + + this->reactor_ = r; + this->notification_pipe_.open (); + +#if !defined (ACE_WIN32) // There seems to be a Win32 bug with this... + // Set this into non-blocking mode. + if (ACE::set_flags (this->notification_pipe_.read_handle (), + ACE_NONBLOCK) == -1) + return -1; + else +#endif /* !ACE_WIN32 */ + if (this->reactor_->register_handler (this->notification_pipe_.read_handle (), + this, + ACE_Event_Handler::READ_MASK) == -1) + return -1; + return 0; +} + +int +ACE_Notification_Handler::close (void) +{ + ACE_TRACE ("ACE_Notification_Handler::close"); + return this->notification_pipe_.close (); +} + +ssize_t +ACE_Notification_Handler::notify (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Notification_Handler::notify"); + ACE_Notification_Buffer buffer (eh, mask); + + ssize_t n = ACE::send (this->notification_pipe_.write_handle (), + (char *) &buffer, + sizeof buffer); + if (n == -1) + return -1; + return 0; +} + +// Handles pending threads (if any) that are waiting to unblock the +// Reactor. + +int +ACE_Notification_Handler::handle_notifications (ACE_Handle_Set &rmask) +{ + ACE_TRACE ("ACE_Notification_Handler::handle_notification"); + + ACE_HANDLE read_handle = this->notification_pipe_.read_handle (); + + if (rmask.is_set (read_handle)) + { + this->reactor_->notify_handle + (read_handle, ACE_Event_Handler::READ_MASK, + this->reactor_->rd_handle_mask_ready_, + this->reactor_->handler_rep_.find (read_handle), + &ACE_Event_Handler::handle_input); + return 1; + } + else + return 0; +} + +// Special trick to unblock select() or poll() when updates occur in +// somewhere other than the main ACE_Reactor thread. All we do is +// write data to a pipe that the ACE_Reactor is listening on. Thanks +// to Paul Stephenson at Ericsson for suggesting this approach. + +int +ACE_Notification_Handler::handle_input (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_Notification_Handler::handle_input"); + // Precondition: this->reactor_.token_.current_owner () == + // ACE_Thread::self (); + + ACE_ASSERT (this->notification_pipe_.read_handle () == handle); + + ACE_Notification_Buffer buffer; + ssize_t n; + +#if defined (ACE_WIN32) + if ((n = ACE::recv (handle, (char *) &buffer, sizeof buffer)) == -1) + return -1; + // Put ourselves at the head of the queue. + this->reactor_->requeue_position (0); +#else + while ((n = ACE::recv (handle, (char *) &buffer, sizeof buffer)) != -1) +#endif /* ACE_WIN32 */ + { + // If eh == 0 then another thread is unblocking the ACE_Reactor + // to update the ACE_Reactor's internal structures. Otherwise, + // we need to dispatch the appropriate handle_* method on the + // ACE_Event_Handler pointer we've been passed. + if (buffer.eh_ != 0) + { + int result = 0; + + switch (buffer.mask_) + { + case ACE_Event_Handler::READ_MASK: + result = buffer.eh_->handle_input (ACE_INVALID_HANDLE); + break; + case ACE_Event_Handler::WRITE_MASK: + result = buffer.eh_->handle_output (ACE_INVALID_HANDLE); + break; + case ACE_Event_Handler::EXCEPT_MASK: + result = buffer.eh_->handle_exception (ACE_INVALID_HANDLE); + break; + default: + ACE_ERROR ((LM_ERROR, "invalid mask = %d\n", buffer.mask_)); + break; + } + if (result == -1) + buffer.eh_->handle_close (ACE_INVALID_HANDLE, + ACE_Event_Handler::EXCEPT_MASK); + } + } + + // Enqueue ourselves into the list of waiting threads. When we + // reacquire the token we'll be off and running again with ownership + // of the token. + this->reactor_->renew (); + + // Postcondition: this->reactor_.token_.current_owner () == + // ACE_Thread::self (); + return n == -1 && errno != EWOULDBLOCK ? -1 : 0; +} +#endif /* ACE_MT_SAFE */ + +int +ACE_Reactor::notify (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Reactor::notify"); + + ssize_t n = 0; +#if defined (ACE_MT_SAFE) + // Pass over both the Event_Handler *and* the mask in order to allow + // the caller to dictate which Event_Handler method the receiver + // invokes. + + n = this->notification_handler_.notify (eh, mask); +#else + eh = eh; + mask = mask; +#endif /* ACE_MT_SAFE */ + return n == -1 ? -1 : 0; +} + +int +ACE_Reactor::resume_handler (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_Reactor::resume_handler"); + ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1)); + return this->resume (handle); +} + +int +ACE_Reactor::suspend_handler (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_Reactor::suspend_handler"); + ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1)); + return this->suspend (handle); +} + +int +ACE_Reactor::suspend_handlers (void) +{ + ACE_TRACE ("ACE_Reactor::suspend_handlers"); + ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1)); + + ACE_Event_Handler *eh = 0; + + for (ACE_Handler_Repository_Iterator iter (this->handler_rep_); + iter.next (eh) != 0; + iter.advance ()) + this->suspend (eh->get_handle ()); + + return 0; +} + +int +ACE_Reactor::resume_handlers (void) +{ + ACE_TRACE ("ACE_Reactor::resume_handlers"); + ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1)); + + ACE_Event_Handler *eh = 0; + + for (ACE_Handler_Repository_Iterator iter (this->handler_rep_); + iter.next (eh) != 0; + iter.advance ()) + this->resume (eh->get_handle ()); + + return 0; +} + +int +ACE_Reactor::register_handler (ACE_Event_Handler *handler, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Reactor::register_handler"); + ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1)); + return this->attach (handler->get_handle (), handler, mask); +} + +int +ACE_Reactor::register_handler (ACE_HANDLE handle, + ACE_Event_Handler *handler, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Reactor::register_handler"); + ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1)); + return this->attach (handle, handler, mask); +} + +int +ACE_Reactor::register_handler (const ACE_Handle_Set &handles, + ACE_Event_Handler *handler, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Reactor::register_handler"); + ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1)); + return this->register_handlers (handles, handler, mask); +} + +int +ACE_Reactor::handler (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + ACE_Event_Handler **handler) +{ + ACE_TRACE ("ACE_Reactor::handler"); + ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1)); + return this->handler_i (handle, mask, handler); +} + +int +ACE_Reactor::remove_handler (const ACE_Handle_Set &handles, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Reactor::remove_handler"); + ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1)); + return this->remove_handlers (handles, mask); +} + +int +ACE_Reactor::remove_handler (ACE_Event_Handler *handler, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Reactor::remove_handler"); + ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1)); + return this->detach (handler->get_handle (), mask); +} + +int +ACE_Reactor::remove_handler (ACE_HANDLE handle, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Reactor::remove_handler"); + ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1)); + return this->detach (handle, mask); +} + +// Performs operations on the "ready" bits. + +int +ACE_Reactor::ready_ops (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + int ops) +{ + ACE_TRACE ("ACE_Reactor::ready_ops"); + ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1)); + return this->bit_ops (handle, mask, + this->rd_handle_mask_ready_, + this->wr_handle_mask_ready_, + this->ex_handle_mask_ready_, + ops); +} + +// Initialize the ACE_Reactor + +int +ACE_Reactor::open (size_t size, + int restart, + ACE_Sig_Handler *sh) +{ + ACE_TRACE ("ACE_Reactor::open"); + ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1)); + + if (this->initialized_ != 0) + return -1; + else + this->initialized_ = 1; + + this->owner_ = ACE_Thread::self (); + this->restart_ = restart; + + // Allows the signal handler to be overridden. + if (sh == 0) + { + ACE_NEW_RETURN (this->signal_handler_, ACE_Sig_Handler, -1); + this->delete_signal_handler_ = 1; + } + else + { + this->signal_handler_ = sh; + this->delete_signal_handler_ = 0; + } + + if (this->handler_rep_.open (size) == -1) + return -1; +#if defined (ACE_MT_SAFE) + else if (this->notification_handler_.open (this) == -1) + { + // Make sure to release resources. + this->handler_rep_.close (this); + return -1; + } +#endif /* ACE_MT_SAFE */ + + ACE_NEW_RETURN (this->timer_queue_, ACE_Timer_Queue, -1); + +#if defined (ACE_USE_POLL) + ACE_NEW_RETURN (this->poll_h_, pollfd[size], -1); + + for (size_t h = 0; h < size; h++) + { + this->poll_h_[h].fd = -1; + this->poll_h_[h].events = 0; + this->poll_h_[h].revents = 0; + } +#endif /* ACE_USE_POLL */ + + return 0; +} + +ACE_Reactor::ACE_Reactor (ACE_Sig_Handler *sh) + : timer_skew_ (0, ACE_TIMER_SKEW), + initialized_ (0), + timer_queue_ (0), + requeue_position_ (-1) // Requeue at end of waiters by default. +#if defined (ACE_MT_SAFE) + , token_ (*this) +#endif /* ACE_MT_SAFE */ +{ + ACE_TRACE ("ACE_Reactor::ACE_Reactor"); + if (this->open (ACE_Reactor::DEFAULT_SIZE, 0, sh)) + ACE_ERROR ((LM_ERROR, "%p\n", "open failed")); +} + +// Initialize the new ACE_Reactor. + +ACE_Reactor::ACE_Reactor (size_t size, int rs, ACE_Sig_Handler *sh) + : timer_skew_ (0, ACE_TIMER_SKEW), + initialized_ (0), + timer_queue_ (0), + requeue_position_ (-1) // Requeue at end of waiters by default. +#if defined (ACE_MT_SAFE) + , token_ (*this) +#endif /* ACE_MT_SAFE */ +{ + ACE_TRACE ("ACE_Reactor::ACE_Reactor"); + if (this->open (size, rs, sh) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "open failed")); +} + +// Close down the ACE_Reactor instance, detaching any remaining +// Event_Handers. This had better be called from the main event loop +// thread... + +void +ACE_Reactor::close (void) +{ + ACE_TRACE ("ACE_Reactor::close"); + ACE_MT (ACE_GUARD (ACE_REACTOR_MUTEX, ace_mon, this->token_)); + + if (this->timer_queue_ != 0) + { + this->handler_rep_.close (this); + + if (this->delete_signal_handler_) + delete this->signal_handler_; + this->signal_handler_ = 0; + + delete this->timer_queue_; + this->timer_queue_ = 0; + +#if defined (ACE_MT_SAFE) + this->notification_handler_.close (); +#endif /* ACE_MT_SAFE */ + +#if defined (ACE_USE_POLL) + delete [] this->poll_h_; +#endif /* ACE_USE_POLL */ + } +} + +ACE_Reactor::~ACE_Reactor (void) +{ + ACE_TRACE ("ACE_Reactor::~ACE_Reactor"); + this->close (); +} + +int +ACE_Reactor::remove_handlers (const ACE_Handle_Set &handles, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Reactor::remove_handlers"); + ACE_HANDLE h; + + for (ACE_Handle_Set_Iterator handle_iter (handles); + (h = handle_iter ()) != ACE_INVALID_HANDLE; + ++handle_iter) + if (this->detach (h, mask) == -1) + return -1; + + return 0; +} + +int +ACE_Reactor::register_handlers (const ACE_Handle_Set &handles, + ACE_Event_Handler *handler, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Reactor::register_handlers"); + ACE_HANDLE h; + + for (ACE_Handle_Set_Iterator handle_iter (handles); + (h = handle_iter ()) != ACE_INVALID_HANDLE; + ++handle_iter) + if (this->attach (h, handler, mask) == -1) + return -1; + + return 0; +} + +int +ACE_Reactor::register_handler (const ACE_Sig_Set &sigset, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp) +{ + ACE_TRACE ("ACE_Reactor::register_handler"); + int result = 0; + + for (int s = 1; s < NSIG; s++) + if (sigset.is_member (s) + && this->signal_handler_->register_handler (s, new_sh, new_disp) == -1) + result = -1; + + return result; +} + +int +ACE_Reactor::remove_handler (const ACE_Sig_Set &sigset) +{ + ACE_TRACE ("ACE_Reactor::remove_handler"); + int result = 0; + + for (int s = 1; s < NSIG; s++) + if (sigset.is_member (s) + && this->signal_handler_->remove_handler (s) == -1) + result = -1; + + return result; +} + +// Note the queue handles its own locking. + +int +ACE_Reactor::schedule_timer (ACE_Event_Handler *handler, + const void *arg, + const ACE_Time_Value &delta_time, + const ACE_Time_Value &interval) +{ + ACE_TRACE ("ACE_Reactor::schedule_timer"); + ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1)); + + return this->timer_queue_->schedule + (handler, arg, ACE_OS::gettimeofday () + delta_time, interval); +} + +// Main event loop driver that blocks for before returning +// (will return earlier if I/O or signal events occur). + +int +ACE_Reactor::handle_events (ACE_Time_Value &max_wait_time) +{ + ACE_TRACE ("ACE_Reactor::handle_events"); + + // Stash the current time. + ACE_Time_Value prev_time = ACE_OS::gettimeofday (); + + int result = this->handle_events (&max_wait_time); + + // Compute the time while the Reactor is processing. + ACE_Time_Value elapsed_time = ACE_OS::gettimeofday () - prev_time; + + if (max_wait_time > elapsed_time) + max_wait_time = max_wait_time - elapsed_time; + else + { + max_wait_time = ACE_Time_Value::zero; // Used all of timeout. + errno = ETIME; + } + return result; +} + +int +ACE_Reactor::handle_error (void) +{ + ACE_TRACE ("ACE_Reactor::handle_error"); + if (errno == EINTR) + return this->restart_; + else if (errno == EBADF) + return this->check_handles (); + else + return -1; +} + +void +ACE_Reactor::notify_handle (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + ACE_Handle_Set &ready_mask, + ACE_Event_Handler *iop, + ACE_EH_PTMF ptmf) +{ + ACE_TRACE ("ACE_Reactor::notify_handle"); + if (iop == 0) + return; + + int status = (iop->*ptmf) (handle); + + if (status < 0) + this->detach (handle, mask); + else if (status > 0) + ready_mask.set_bit (handle); +} + +// Perform GET, CLR, SET, and ADD operations on the Handle_Sets. +// +// GET = 1, Retrieve current value +// SET = 2, Set value of bits to new mask (changes the entire mask) +// ADD = 3, Bitwise "or" the value into the mask (only changes +// enabled bits) +// CLR = 4 Bitwise "and" the negation of the value out of the mask +// (only changes enabled bits) +// +// Returns the original mask. Must be called with locks held. + +int +ACE_Reactor::bit_ops (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + ACE_Handle_Set &rd, + ACE_Handle_Set &wr, + ACE_Handle_Set &ex, + int ops) +{ + ACE_TRACE ("ACE_Reactor::bit_ops"); + if (this->handler_rep_.invalid_handle (handle)) + return -1; + + ACE_Sig_Guard sb; // Block out all signals until method returns. + + ACE_FDS_PTMF ptmf = &ACE_Handle_Set::set_bit; + u_long omask = ACE_Event_Handler::NULL_MASK; + + switch (ops) + { + case ACE_Reactor::GET_MASK: + if (rd.is_set (handle)) + ACE_SET_BITS (omask, ACE_Event_Handler::READ_MASK); + if (wr.is_set (handle)) + ACE_SET_BITS (omask, ACE_Event_Handler::WRITE_MASK); + if (ex.is_set (handle)) + ACE_SET_BITS (omask, ACE_Event_Handler::EXCEPT_MASK); + break; + + case ACE_Reactor::CLR_MASK: + ptmf = &ACE_Handle_Set::clr_bit; + /* FALLTHRU */ + case ACE_Reactor::SET_MASK: + /* FALLTHRU */ + case ACE_Reactor::ADD_MASK: + + // The following code is rather subtle... Note that if we are + // doing a ACE_Reactor::SET_MASK then if the bit is not enabled + // in the mask we need to clear the bit from the ACE_Handle_Set. + // On the other hand, f we are doing a ACE_Reactor::CLR_MASK or + // a ACE_Reactor::ADD_MASK we just carry out the operations + // specified by the mask. + + if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK)) + { + (rd.*ptmf) (handle); + ACE_SET_BITS (omask, ACE_Event_Handler::READ_MASK); + } + else if (ops == ACE_Reactor::SET_MASK) + rd.clr_bit (handle); + + if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK)) + { + (wr.*ptmf) (handle); + ACE_SET_BITS (omask, ACE_Event_Handler::WRITE_MASK); + } + else if (ops == ACE_Reactor::SET_MASK) + wr.clr_bit (handle); + + if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::EXCEPT_MASK)) + { + (ex.*ptmf) (handle); + ACE_SET_BITS (omask, ACE_Event_Handler::EXCEPT_MASK); + } + else if (ops == ACE_Reactor::SET_MASK) + ex.clr_bit (handle); + break; + default: + return -1; + } + return omask; +} + +// Perform GET, CLR, SET, and ADD operations on the select() +// Handle_Sets. +// +// GET = 1, Retrieve current value +// SET = 2, Set value of bits to new mask (changes the entire mask) +// ADD = 3, Bitwise "or" the value into the mask (only changes +// enabled bits) +// CLR = 4 Bitwise "and" the negation of the value out of the mask +// (only changes enabled bits) +// +// Returns the original mask. + +int +ACE_Reactor::mask_ops (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + int ops) +{ + ACE_TRACE ("ACE_Reactor::mask_ops"); + ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1)); + return this->bit_ops (handle, mask, + this->rd_handle_mask_, + this->wr_handle_mask_, + this->ex_handle_mask_, + ops); +} + +// Must be called with locks held + +int +ACE_Reactor::handler_i (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + ACE_Event_Handler **handler) +{ + ACE_TRACE ("ACE_Reactor::handler_i"); + if (this->handler_rep_.invalid_handle (handle) + || this->handler_rep_.find (handle) == 0) + return -1; + else + { + if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK) + && this->rd_handle_mask_.is_set (handle) == 0) + return -1; + if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK) + && this->wr_handle_mask_.is_set (handle) == 0) + return -1; + if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::EXCEPT_MASK) + && this->ex_handle_mask_.is_set (handle) == 0) + return -1; + } + + if (handler != 0) + *handler = this->handler_rep_.find (handle); + return 0; +} + +// Must be called with locks held + +int +ACE_Reactor::resume (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_Reactor::resume"); + if (this->handler_rep_.invalid_handle (handle) + || this->handler_rep_.find (handle) == 0) + return -1; + + this->rd_handle_mask_.set_bit (handle); + this->wr_handle_mask_.set_bit (handle); + this->ex_handle_mask_.set_bit (handle); + return 0; +} + +// Must be called with locks held + +int +ACE_Reactor::suspend (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_Reactor::suspend"); + if (this->handler_rep_.invalid_handle (handle) + || this->handler_rep_.find (handle) == 0) + return -1; + + this->rd_handle_mask_.clr_bit (handle); + this->wr_handle_mask_.clr_bit (handle); + this->ex_handle_mask_.clr_bit (handle); + return 0; +} + +// Must be called with locks held + +int +ACE_Reactor::attach (ACE_HANDLE handle, + ACE_Event_Handler *handler, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Reactor::attach"); + + if (this->handler_rep_.invalid_handle (handle)) + return -1; + + this->handler_rep_.bind (handle, handler); + + this->bit_ops (handle, mask, + this->rd_handle_mask_, + this->wr_handle_mask_, + this->ex_handle_mask_, + ACE_Reactor::ADD_MASK); + return 0; +} + +int +ACE_Reactor::detach (ACE_HANDLE handle, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Reactor::detach"); + if (this->handler_rep_.invalid_handle (handle) + || this->handler_rep_.find (handle) == 0) + return -1; + + ACE_Event_Handler *eh = this->handler_rep_.find (handle); + + this->bit_ops (handle, mask, + this->rd_handle_mask_, + this->wr_handle_mask_, + this->ex_handle_mask_, + ACE_Reactor::CLR_MASK); + + if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::DONT_CALL) == 0) + eh->handle_close (handle, mask); + + // See if we can unbind this handle. + this->handler_rep_.unbind (handle, + this->rd_handle_mask_, + this->wr_handle_mask_, + this->ex_handle_mask_); + return 0; +} + +#if defined (ACE_USE_POLL) +// Transforms the select() data structures into a data structure +// suitable for use with poll(). + +pollfd * +ACE_Reactor::handle_sets_to_poll_fds (ACE_HANDLE &width) +{ + ACE_TRACE ("ACE_Reactor::handle_sets_to_poll_fds"); + + for (ACE_HANDLE h = 0; h < this->handler_rep_.max_handlep1 (); h++) + { + if (this->wr_handle_mask_.is_set (h)) + { + this->poll_h_[width].fd = h; + ACE_SET_BITS (this->poll_h_[width].events, ACE_Event_Handler::WRITE_MASK); + } + if (this->rd_handle_mask_.is_set (h)) + { + this->poll_h_[width].fd = h; + ACE_SET_BITS (this->poll_h_[width].events, ACE_Event_Handler::READ_MASK); + } + if (this->ex_handle_mask_.is_set (h)) + { + this->poll_h_[width].fd = h; + ACE_SET_BITS (this->poll_h_[width].events, ACE_Event_Handler::EXCEPT_MASK); + } + if (this->poll_h_[width].fd != -1) + width++; + } + + return this->poll_h_; + return 0; +} + +// Transforms the poll() data structures into data structures +// suitable for use with select(). + +void +ACE_Reactor::poll_fds_to_handle_sets (ACE_HANDLE width, + ACE_Handle_Set &rmask, + ACE_Handle_Set &wmask, + ACE_Handle_Set &emask, + int nfound) +{ + ACE_TRACE ("ACE_Reactor::poll_fds_to_handle_sets"); + + for (ACE_HANDLE h = 0; nfound > 0 && h < width; h++) + { + int found = 0; + pollfd &p_fd = this->poll_h_[h]; + + if (p_fd.revents & POLLOUT) + { + wmask.set_bit (p_fd.fd); + found = 1; + } + + if (p_fd.revents & POLLPRI) + { + emask.set_bit (p_fd.fd); + found = 1; + } + + if ((p_fd.revents & POLLIN) + || (p_fd.revents & POLLHUP) + || (p_fd.revents & POLLERR)) + { + rmask.set_bit (p_fd.fd); + found = 1; + } + + p_fd.revents = 0; + p_fd.events = 0; + p_fd.fd = -1; + + if (found) + nfound--; + } +} +#endif /* ACE_USE_POLL */ + +// Must be called with lock held + +int +ACE_Reactor::wait_for_multiple_events (ACE_Handle_Set &rmask, + ACE_Handle_Set &wmask, + ACE_Handle_Set &emask, + ACE_Time_Value *max_wait_time) +{ + ACE_TRACE ("ACE_Reactor::wait_for_multiple_events"); +#if defined (ACE_USE_POLL) + u_long width = 0; +#endif /* ACE_USE_POLL */ + int nfound; + + do + { + max_wait_time = this->timer_queue_->calculate_timeout (max_wait_time); + +#if defined (ACE_USE_POLL) + pollfd *phandles = this->handle_sets_to_poll_fds (width); + nfound = ACE_OS::poll (phandles, width, max_wait_time); +#else /* USE SELECT */ + size_t width = this->handler_rep_.max_handlep1 (); + rmask = this->rd_handle_mask_; + wmask = this->wr_handle_mask_; + emask = this->ex_handle_mask_; + nfound = ACE_OS::select (int (width), rmask, wmask, emask, max_wait_time); +#endif /* ACE_USE_POLL */ + } + while (nfound == -1 && this->handle_error () > 0); + +#if defined (ACE_USE_POLL) + this->poll_fds_to_handle_sets (width, rmask, wmask, emask, nfound); +#endif /* ACE_USE_POLL */ + + if (nfound > 0) + { +#if !defined (ACE_WIN32) + rmask.sync (this->handler_rep_.max_handlep1 ()); + wmask.sync (this->handler_rep_.max_handlep1 ()); + emask.sync (this->handler_rep_.max_handlep1 ()); +#endif /* ACE_REACTOR_ALTERANTIVE_IMPL */ + } + return nfound; // Timed out or input available +} + +void +ACE_Reactor::dispatch (int nfound, + ACE_Handle_Set &rmask, + ACE_Handle_Set &wmask, + ACE_Handle_Set &emask) +{ + ACE_TRACE ("ACE_Reactor::dispatch"); + // Handle timers first since they may have higher latency + // constraints... + + if (!this->timer_queue_->is_empty ()) + // Fudge factor accounts for problems with Solaris timers... + this->timer_queue_->expire (ACE_OS::gettimeofday () + this->timer_skew_); + +#if defined (ACE_MT_SAFE) + // Check to see if the notify ACE_HANDLE is enabled. If so, it + // means that one or more other threads are trying to update the + // ACE_Reactor's internal tables. We'll handle all these threads + // and then break out to continue the event loop. + + if (this->notification_handler_.handle_notifications (rmask) == 0) +#endif /* ACE_MT_SAFE */ + { + ACE_HANDLE h; + + if (nfound > 0) + { + // Handle output conditions (this code needs to come first to + // handle the obscure case of piggy-backed data coming along + // with the final handshake message of a nonblocking + // connection). + + for (ACE_Handle_Set_Iterator handle_iter_wr (wmask); + (h = handle_iter_wr ()) != ACE_INVALID_HANDLE && --nfound >= 0; + ++handle_iter_wr) + this->notify_handle (h, ACE_Event_Handler::WRITE_MASK, + this->wr_handle_mask_ready_, + this->handler_rep_.find (h), + &ACE_Event_Handler::handle_output); + } + + if (nfound > 0) + { + // Handle "exceptional" conditions. + for (ACE_Handle_Set_Iterator handle_iter_ex (emask); + (h = handle_iter_ex ()) != ACE_INVALID_HANDLE && --nfound >= 0; + ++handle_iter_ex) + this->notify_handle (h, ACE_Event_Handler::EXCEPT_MASK, + this->ex_handle_mask_ready_, + this->handler_rep_.find (h), + &ACE_Event_Handler::handle_exception); + } + if (nfound > 0) + { + // Handle input and shutdown conditions. + for (ACE_Handle_Set_Iterator handle_iter_rd (rmask); + (h = handle_iter_rd ()) != ACE_INVALID_HANDLE && --nfound >= 0; + ++handle_iter_rd) + this->notify_handle (h, ACE_Event_Handler::READ_MASK, + this->rd_handle_mask_ready_, + this->handler_rep_.find (h), + &ACE_Event_Handler::handle_input); + } + } +} + +int +ACE_Reactor::fill_in_ready (ACE_Handle_Set &rmask, + ACE_Handle_Set &wmask, + ACE_Handle_Set &emask) +{ + ACE_TRACE ("ACE_Reactor::fill_in_ready"); + ACE_Sig_Guard sb; + + rmask = this->rd_handle_mask_ready_; + wmask = this->wr_handle_mask_ready_; + emask = this->ex_handle_mask_ready_; + + this->rd_handle_mask_ready_.reset (); + this->wr_handle_mask_ready_.reset (); + this->ex_handle_mask_ready_.reset (); + + return rmask.num_set () + wmask.num_set () + emask.num_set (); +} + +int +ACE_Reactor::handle_events (ACE_Time_Value *max_wait_time) +{ + ACE_TRACE ("ACE_Reactor::handle_events"); +#if defined (ACE_MT_SAFE) + ACE_MT (ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1)); + if (ACE_OS::thr_equal (ACE_Thread::self (), this->owner_) == 0) + return -1; +#endif /* ACE_MT_SAFE */ + + ACE_Handle_Set rmask; + ACE_Handle_Set wmask; + ACE_Handle_Set emask; + int nfound; + + if (this->any_ready ()) + nfound = this->fill_in_ready (rmask, wmask, emask); + else + nfound = this->wait_for_multiple_events (rmask, wmask, emask, max_wait_time); + + for (;;) + { + this->dispatch (nfound, rmask, wmask, emask); + + if (ACE_Sig_Handler::sig_pending () != 0) + { + ACE_Sig_Handler::sig_pending (0); + + // Dispatch any HANDLES that are activated + // as a result of signals since they may be + // time critical... + + if (this->any_ready ()) + { + nfound = this->fill_in_ready (rmask, wmask, emask); + continue; + } + } + break; + } + + return nfound; +} + +int +ACE_Reactor::check_handles (void) +{ + ACE_TRACE ("ACE_Reactor::check_handles"); + +#if defined (ACE_USE_POLL) + pollfd p_handle; + p_handle.events = POLLIN; +#else + ACE_Time_Value time_poll = ACE_Time_Value::zero; + ACE_Handle_Set rmask; +#endif /* ACE_USE_POLL */ + + ACE_Event_Handler *eh = 0; + int result = 0; + + for (ACE_Handler_Repository_Iterator iter (this->handler_rep_); + iter.next (eh) != 0; + iter.advance ()) + { + ACE_HANDLE handle = eh->get_handle (); + + // Skip back to the beginning of the loop if the HANDLE is + // invalid. + if (handle == ACE_INVALID_HANDLE) + continue; + +#if defined (ACE_USE_POLL) + p_handle.fd = handle; + if (ACE_OS::poll (&p_handle, 1, 0) == -1) + { + result = 1; + this->detach (handle, ACE_Event_Handler::RWE_MASK); + } +#else + rmask.set_bit (handle); + if (ACE_OS::select (int (handle) + 1, + rmask, 0, 0, + &time_poll) < 0) + { + result = 1; + this->detach (handle, ACE_Event_Handler::RWE_MASK); + } + rmask.clr_bit (handle); +#endif /* ACE_USE_POLL */ + } + + return result; +} diff --git a/ace/Reactor.h b/ace/Reactor.h new file mode 100644 index 00000000000..fe178877950 --- /dev/null +++ b/ace/Reactor.h @@ -0,0 +1,642 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Reactor.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_REACTOR_H) +#define ACE_REACTOR_H + +#include "ace/Handle_Set.h" +#include "ace/Timer_Queue.h" +#include "ace/Signal.h" +#include "ace/Thread.h" +#include "ace/Token.h" +#include "ace/Pipe.h" +#include "ace/SOCK_Stream.h" + +// Add useful typedefs to simplify the following code. +typedef void (ACE_Handle_Set::*ACE_FDS_PTMF) (ACE_HANDLE); +typedef int (ACE_Event_Handler::*ACE_EH_PTMF) (ACE_HANDLE); + +// Forward declaration. +class ACE_Reactor; + +#if defined (ACE_MT_SAFE) + +// The following two classes have to be moved out here to keep the SGI +// C++ compiler happy (it doesn't like nested classes). + +class ACE_Export ACE_Notification_Handler : public ACE_Event_Handler + // = TITLE + // Callback and unblock the ACE_Reactor if it's sleeping. + // + // = DESCRIPTION + // This implementation is necessary for cases where the Reactor + // is being run in a multi-threaded program. In this case, we + // need a special trick to unblock select() or poll() when + // updates occur in somewhere other than the main ACE_Reactor + // thread. All we do is write data to a pipe or socket that the + // ACE_Reactor is listening on. +{ +public: + // = Initialization and termination methods. + int open (ACE_Reactor *); + int close (void); + + int handle_notifications (ACE_Handle_Set &rmask); + // Handles pending threads (if any) that are waiting to unblock the + // Reactor. + + ssize_t notify (ACE_Event_Handler * = 0, + ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK); + // Called by a thread when it wants to unblock the Reactor. + + virtual int handle_input (ACE_HANDLE handle); + // Called back by the Reactor when a thread wants to unblock us. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Reactor *reactor_; + // Keep a back pointer to the Reactor. + + ACE_Pipe notification_pipe_; + // Contains the HANDLE the Reactor is listening on, as well as the + // HANDLE that threads wanting the attention of the Reactor will + // write to. +}; + +#if defined (ACE_REACTOR_HAS_DEADLOCK_DETECTION) +#include "ace/Local_Tokens.h" +typedef ACE_Local_Mutex ACE_REACTOR_MUTEX; +#else +typedef ACE_Token ACE_REACTOR_MUTEX; +#endif /* ACE_REACTOR_HAS_DEADLOCK_DETECTION */ + +class ACE_Export ACE_Reactor_Token : public ACE_REACTOR_MUTEX + // = TITLE + // Used as a synchronization mechanism to coordinate concurrent + // access to a Reactor object. +{ +public: + ACE_Reactor_Token (ACE_Reactor &r); + + virtual void sleep_hook (void); + // Called just before the ACE_Event_Handler goes to sleep. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Reactor &reactor_; +}; + +#endif /* ACE_MT_SAFE */ + +class ACE_Export ACE_Handler_Repository +{ + // = TITLE + // Used to map ACE_HANDLEs onto the appropriate ACE_Event_Handler *. + // + // = DESCRIPTION + // This class is necessary to shield differences between UNIX + // and WIN32. In UNIX, ACE_HANDLE is an int, whereas in WIN32 + // it's a void *. This class hides all these details from the + // bulk of the Reactor code. +public: + friend class ACE_Handler_Repository_Iterator; + + // = Initialization and termination methods. + ACE_Handler_Repository (void); + // Default "do-nothing" constructor. + + int open (size_t size); + // Initialize a repository of the appropriate . + + int close (ACE_Reactor *); + // Destroy the handler and cleanup the Reactor. + + // = Search structure operations. + + ACE_Event_Handler *find (ACE_HANDLE); + // Return the associated with . + + int bind (ACE_HANDLE, ACE_Event_Handler *); + // Bind the to the . + + int unbind (ACE_HANDLE, ACE_Handle_Set &rd_mask, + ACE_Handle_Set &wr_mask, ACE_Handle_Set &ex_mask); + // Remove the binding of . + + // Performs sanity checking on the ACE_HANDLE. + int invalid_handle (ACE_HANDLE); + + size_t max_handlep1 (void); + // Maximum ACE_HANDLE value, plus 1. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ssize_t max_size_; + // Maximum number of handles. + +#if defined (ACE_WIN32) + ssize_t cur_size_; + // The highest currently active handle, plus 1. + + // = This structure maps to . + struct ACE_NT_EH_Record + { + ACE_HANDLE handle_; + ACE_Event_Handler *event_handler_; + }; + + ACE_NT_EH_Record *event_handlers_; + // The NT version implements this via a dynamically allocated + // array of . Since NT implements ACE_HANDLE + // as a void * we can't directly index into this array. Therefore, + // we just do a linear search (for now). Next, we'll modify + // things to use hashing or something faster... +#else + ACE_HANDLE max_handlep1_; + // The highest currently active handle, plus 1. + + ACE_Event_Handler **event_handlers_; + // The UNIX version implements this via a dynamically allocated + // array of that is indexed directly using + // the ACE_HANDLE value. +#endif /* ACE_WIN32 */ +}; + +class ACE_Export ACE_Handler_Repository_Iterator +{ +public: + // = Initialization method. + ACE_Handler_Repository_Iterator (const ACE_Handler_Repository &s); + + // = Iteration methods. + + int next (ACE_Event_Handler *&next_item); + // Pass back the that hasn't been seen in the Set. + // Returns 0 when all items have been seen, else 1. + + int advance (void); + // Move forward by one element in the set. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + const ACE_Handler_Repository &rep_; + // Reference to the Handler_Repository we are iterating over. + + ssize_t current_; + // Pointer to the current iteration level. +}; + +class ACE_Export ACE_Reactor + // = TITLE + // An object oriented event demultiplexor and event handler + // dispatcher. + // + // = DESCRIPTION + // The ACE_Reactor is an object-oriented event demultiplexor + // and event handler dispatcher. The sources of events that the + // ACE_Reactor waits for and dispatches includes I/O events, + // signals, and timer events. +{ +public: + enum + { + DEFAULT_SIZE = ACE_DEFAULT_REACTOR_SIZE, + // Default size of the Reactor's handle table. + + // = Operations on the "ready" mask and the "dispatch" mask. + GET_MASK = 1, + // Retrieve current value of the the "ready" mask or the "dispatch" mask. + SET_MASK = 2, + // Set value of bits to new mask (changes the entire mask). + ADD_MASK = 3, + // Bitwise "or" the value into the mask (only changes enabled bits). + CLR_MASK = 4 + // Bitwise "and" the negation of the value out of the mask (only changes enabled bits). + }; + + // = Initialization and termination methods. + + ACE_Reactor (ACE_Sig_Handler * = 0); + // Initialize the new ACE_Reactor with the default size. + + ACE_Reactor (size_t size, + int restart = 0, + ACE_Sig_Handler * = 0); + // Initialize the new ACE_Reactor of size . + + virtual int open (size_t size = DEFAULT_SIZE, + int restart = 0, + ACE_Sig_Handler * = 0); + // Initialize the new ACE_Reactor of size . + + virtual void close (void); + // Close down the reactor and release all of its resources. + + virtual ~ACE_Reactor (void); + // Close down the reactor and release all of its resources. + + // = Timer management. + virtual int schedule_timer (ACE_Event_Handler *, + const void *arg, + const ACE_Time_Value &delta, + const ACE_Time_Value &interval = ACE_Time_Value::zero); + // Schedule an that will expire after amount + // of time. If it expires then is passed in as the value to + // the 's callback method. If + // is != to then it is used to + // reschedule the automatically. This method + // returns a timer handle that uniquely identifies the + // in an internal list. This timer handle can be + // used to cancel an before it expires. The + // cancellation ensures that timer_ids are unique up to values of + // greater than 2 billion timers. As long as timers don't stay + // around longer than this there should be no problems with + // accidentally deleting the wrong timer. + + virtual int cancel_timer (ACE_Event_Handler *event_handler); + // Cancel all that match the address of + // . + + virtual int cancel_timer (int timer_id, const void **arg = 0); + // Cancel the single that matches the + // value (which was returned from the method). If arg is + // non-NULL then it will be set to point to the ``magic cookie'' + // argument passed in when the was registered. This + // makes it possible to free up the memory and avoid memory leaks. + + // = Event loop drivers. + virtual int handle_events (ACE_Time_Value *how_long = 0); + // Main event loop driver that blocks for before + // returning (will return earlier if I/O or signal events occur). + // Note that can be 0, in which case this method blocks + // until I/O events or signals occur. + + virtual int handle_events (ACE_Time_Value &how_long); + // Main event loop driver that blocks for before + // returning (will return earlier if I/O or signal events occur). + + // = Register and remove Handlers. + virtual int register_handler (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask); + // Register an Event_Handler with a particular . Note + // that the Reactor will call eh->get_handle() to extract the + // underlying I/O handle). + + virtual int register_handler (ACE_HANDLE handle, + ACE_Event_Handler *eh, + ACE_Reactor_Mask mask); + // Register an Event_Handler with a particular . Note + // that since the is given the Reactor will *not* call + // eh->get_handle() to extract the underlying I/O handle). + + virtual int register_handler (const ACE_Handle_Set &handles, + ACE_Event_Handler *eh, + ACE_Reactor_Mask mask); + // Register with all the in the . + + virtual int register_handler (int signum, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp = 0, + ACE_Event_Handler **old_sh = 0, + ACE_Sig_Action *old_disp = 0); + // Register to handle the signal using the + // . Returns the that was previously registered + // (if any), along with the of the signal handler. + + virtual int register_handler (const ACE_Sig_Set &sigset, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp = 0); + // Registers to handle a set of signals using the + // . + + virtual int remove_handler (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask); + // Removes the binding of from the Reactor. If there + // are no more bindings for this then it is removed from the + // Reactor. Note that the Reactor will call eh->get_handle() to + // extract the underlying I/O handle. + + virtual int remove_handler (ACE_HANDLE handle, + ACE_Reactor_Mask); + // Removes the bind of whose handle is + // from the Reactor. If there are no more bindings for + // this then it is removed from the Reactor. + + virtual int remove_handler (const ACE_Handle_Set &handle_set, + ACE_Reactor_Mask); + // Removes all the bindings for handles in the + // bind of . If there are no more bindings for any + // of these handlers then they are removed from the Reactor. + + virtual int remove_handler (int signum, + ACE_Sig_Action *new_disp, + ACE_Sig_Action *old_disp = 0, + int sigkey = -1); + // Remove the ACE_Event_Handler currently associated with . + // is ignored in this implementation since there is only + // one instance of a signal handler. Install the new disposition + // (if given) and return the previous disposition (if desired by the + // caller). Returns 0 on success and -1 if is invalid. + + virtual int remove_handler (const ACE_Sig_Set &sigset); + // Calls for every signal in . + + // = Suspend and resume Handlers. + + virtual int suspend_handler (ACE_Event_Handler *eh); + // Temporarily suspend the associated with . + + virtual int suspend_handler (ACE_HANDLE handle); + // Temporarily suspend the associated with . + + virtual int resume_handler (ACE_Event_Handler *eh); + // Resume a temporarily suspend associated with + // . + + virtual int resume_handler (ACE_HANDLE handle); + // Resume a temporarily suspended associated with + // . + + virtual int suspend_handlers (void); + // Suspend all the in the Reactor. + + virtual int resume_handlers (void); + // Resume all the in the Reactor. + + // = Misc. Handler operations. + virtual int handler (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + ACE_Event_Handler **eh = 0); + // Check to see if is associated with a valid Event_Handler + // bound to . Return the associated with this + // if != 0. + + virtual int handler (int signum, + ACE_Event_Handler ** = 0); + // Check to see if is associated with a valid Event_Handler + // bound to a signal. Return the associated with this + // if != 0. + + // = High-level Event_Handler scheduling operations + + virtual int schedule_wakeup (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask); + // ADD the dispatch MASK "bit" bound with the and the . + + virtual int schedule_wakeup (ACE_HANDLE handle, + ACE_Reactor_Mask mask); + // ADD the dispatch MASK "bit" bound with the and the . + + virtual int cancel_wakeup (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask); + // CLR the dispatch MASK "bit" bound with the and the . + + virtual int cancel_wakeup (ACE_HANDLE handle, + ACE_Reactor_Mask mask); + // CLR the dispatch MASK "bit" bound with the and the . + + // = Low-level dispatch mask manipulation methods. + virtual int mask_ops (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask, + int ops); + // GET/SET/ADD/CLR the dispatch MASK "bit" bound with the and + // . + + virtual int mask_ops (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + int ops); + // GET/SET/ADD/CLR the dispatch MASK "bit" bound with the + // and . + + // = Ready bit manipulation methods. + virtual int ready_ops (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask, + int ops); + // GET/SET/ADD/CLR the ready "bit" bound with the and . + + virtual int ready_ops (ACE_HANDLE handle, + ACE_Reactor_Mask, + int ops); + // GET/SET/ADD/CLR the ready "bit" bound with the and . + + virtual int notify (ACE_Event_Handler * = 0, + ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK); + // Wakeup ACE_Reactor if currently blocked in select()/poll(). Pass + // over both the Event_Handler *and* the mask in order to allow the + // caller to dictate which Event_Handler method the receiver + // invokes. + + // = Get/set position that the main ACE_Reactor thread is requeued + // in the list of waiters during a notify() callback. + void requeue_position (int); + int requeue_position (void); + + // = Get/set the current "owner" of the thread (i.e., the only + // thread that can perform a handle_events()). + void owner (ACE_thread_t n_id, ACE_thread_t *o_id = 0); + // Set the new owner of the thread and return the old owner. + + int owner (ACE_thread_t *); + // Return the current owner of the thread. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + // = Internal methods that do the actual work (most of these + // assume that locks are held). + + virtual int attach (ACE_HANDLE handle, + ACE_Event_Handler *eh, + ACE_Reactor_Mask mask); + // Do the work of actually binding the and with the + // . + + virtual int detach (ACE_HANDLE handle, + ACE_Reactor_Mask); + // Do the work of actually unbinding the and with the + // . + + virtual int suspend (ACE_HANDLE handle); + // Suspend the associated with + virtual int resume (ACE_HANDLE handle); + // Resume the associated with + + virtual int remove_handlers (const ACE_Handle_Set &handles, + ACE_Reactor_Mask); + // Remove a set of . + + virtual int register_handlers (const ACE_Handle_Set &handles, + ACE_Event_Handler *handler, + ACE_Reactor_Mask mask); + // Register a set of . + + virtual int handler_i (ACE_HANDLE handle, + ACE_Reactor_Mask, + ACE_Event_Handler ** = 0); + // Implement the public method. + + virtual int handler_i (int signum, ACE_Event_Handler ** = 0); + // Implement the public method. + + virtual int any_ready (void) const; + + virtual int handle_error (void); + // Take corrective action when errors occur. + + virtual int check_handles (void); + // Make sure the handles are all valid. + + virtual int bit_ops (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + ACE_Handle_Set &rd, + ACE_Handle_Set &wr, + ACE_Handle_Set &ex, + int ops); + // Allow manipulation of the dispatch mask and ready ops mask. + + virtual int fill_in_ready (ACE_Handle_Set &, + ACE_Handle_Set &, + ACE_Handle_Set &); + // Check if there are any bits enabled in the ready_ops set. + + virtual int wait_for_multiple_events (ACE_Handle_Set &, + ACE_Handle_Set &, + ACE_Handle_Set &, + ACE_Time_Value *); + // Wait for events to occur. + + virtual void dispatch (int, + ACE_Handle_Set &, + ACE_Handle_Set &, + ACE_Handle_Set &); + // Dispatch timers and I/O event handlers once events have occurred. + + virtual void notify_handle (ACE_HANDLE handle, + ACE_Reactor_Mask mask, + ACE_Handle_Set &, + ACE_Event_Handler *eh, + ACE_EH_PTMF callback); + // Notify the appropriate in the context of the + // associated with that a particular event has occurred. + + ACE_Timer_Queue *timer_queue_; + // Defined as a pointer to allow overriding by derived classes... + + ACE_Handler_Repository handler_rep_; + // Pointer to an array of s used to keep track + // of the user-defined callbacks. + + ACE_Sig_Handler *signal_handler_; + // Handle signals without requiring global/static variables. + + int delete_signal_handler_; + // Keeps track of whether we should delete the signal handler. + + // = Track which handles we are interested + // for various types of (reading, writing, and exception) events. + // The following three are waited for by poll() or + // select(). + ACE_Handle_Set rd_handle_mask_; + ACE_Handle_Set wr_handle_mask_; + ACE_Handle_Set ex_handle_mask_; + + // = Keep track of events that we'd like to have dispatched + // *without* requiring poll() or select() to wait... + ACE_Handle_Set rd_handle_mask_ready_; + ACE_Handle_Set wr_handle_mask_ready_; + ACE_Handle_Set ex_handle_mask_ready_; + + int restart_; + // Restart automatically when interrupted + + int requeue_position_; + // Position that the main ACE_Reactor thread is requeued in the list + // of waiters during a notify() callback. If this value == -1 we + // are requeued at the end of the list. Else if it's 0 then we are + // requeued at the front of the list. Else if it's > 1 then that + // indicates the number of waiters to skip over. + + int initialized_; + // True if we've been initialized yet... + + ACE_thread_t owner_; + // The original thread that created this Reactor. + +#if defined (ACE_MT_SAFE) + ACE_Notification_Handler notification_handler_; + // Callback object that unblocks the ACE_Reactor if it's sleeping. + + ACE_Reactor_Token token_; + // Synchronization token for the MT_SAFE ACE_Reactor. + + void renew (void); + // Enqueue ourselves into the list of waiting threads at the + // appropriate point specified by . + + friend class ACE_Notification_Handler; +#endif /* ACE_MT_SAFE */ + + friend class ACE_Handler_Repository; + +#if defined (ACE_USE_POLL) + // = Convert to and from the select() to poll() types. + pollfd *handle_sets_to_poll_fds (ACE_HANDLE &width); + void poll_fds_to_handle_sets (ACE_HANDLE width, + ACE_Handle_Set &, + ACE_Handle_Set &, + ACE_Handle_Set &, + int nfound); + pollfd *poll_h_; + // Pointer to the array of pollfd handles for poll() version. +#endif /* ACE_USE_POLL */ + +private: + ACE_Time_Value timer_skew_; + // Adjusts for skew that occurs in certain OS timers (e.g., + // Solaris). + + // Deny access since member-wise won't work... + ACE_Reactor (const ACE_Reactor &); + ACE_Reactor &operator = (const ACE_Reactor &); +}; + +#include "ace/Reactor.i" +#endif /* ACE_REACTOR_H */ diff --git a/ace/Reactor.i b/ace/Reactor.i new file mode 100644 index 00000000000..519b3fadccf --- /dev/null +++ b/ace/Reactor.i @@ -0,0 +1,135 @@ +/* -*- C++ -*- */ +// $Id$ + +// Reactor.i + +#include "ace/Log_Msg.h" + +inline int +ACE_Reactor::resume_handler (ACE_Event_Handler *h) +{ + ACE_TRACE ("ACE_Reactor::resume_handler"); + return this->resume (h->get_handle ()); +} + +inline int +ACE_Reactor::suspend_handler (ACE_Event_Handler *h) +{ + ACE_TRACE ("ACE_Reactor::suspend_handler"); + return this->suspend (h->get_handle ()); +} + +inline int +ACE_Reactor::register_handler (int signum, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp, + ACE_Event_Handler **old_sh, + ACE_Sig_Action *old_disp) +{ + ACE_TRACE ("ACE_Reactor::register_handler"); + return this->signal_handler_->register_handler (signum, + new_sh, new_disp, + old_sh, old_disp); +} + +inline int +ACE_Reactor::handler (int signum, ACE_Event_Handler **handler) +{ + ACE_TRACE ("ACE_Reactor::handler"); + return this->handler_i (signum, handler); +} + +inline int +ACE_Reactor::remove_handler (int signum, + ACE_Sig_Action *new_disp, + ACE_Sig_Action *old_disp, + int sigkey) +{ + ACE_TRACE ("ACE_Reactor::remove_handler"); + return this->signal_handler_->remove_handler (signum, new_disp, old_disp, sigkey); +} + +// The remaining methods in this file must be called with locks held + +// Note the queue handles its own locking. + +inline int +ACE_Reactor::cancel_timer (ACE_Event_Handler *handler) +{ + ACE_TRACE ("ACE_Reactor::cancel_timer"); + return this->timer_queue_->cancel (handler); +} + +inline int +ACE_Reactor::cancel_timer (int timer_id, const void **arg) +{ + ACE_TRACE ("ACE_Reactor::cancel_timer"); + return this->timer_queue_->cancel (timer_id, arg); +} + +// Performs operations on the "ready" bits. + +inline int +ACE_Reactor::ready_ops (ACE_Event_Handler *handler, + ACE_Reactor_Mask mask, + int ops) +{ + ACE_TRACE ("ACE_Reactor::ready_ops"); + return this->ready_ops (handler->get_handle (), mask, ops); +} + +// Performs operations on the "dispatch" masks. + +inline int +ACE_Reactor::mask_ops (ACE_Event_Handler *handler, + ACE_Reactor_Mask mask, + int ops) +{ + ACE_TRACE ("ACE_Reactor::mask_ops"); + return this->mask_ops (handler->get_handle (), mask, ops); +} + +inline int +ACE_Reactor::any_ready (void) const +{ + ACE_TRACE ("ACE_Reactor::any_ready"); + ACE_Sig_Guard sb; + + int result = this->rd_handle_mask_ready_.num_set () > 0 + || this->wr_handle_mask_ready_.num_set () > 0 + || this->ex_handle_mask_ready_.num_set () > 0; + + return result; +} + +inline int +ACE_Reactor::schedule_wakeup (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Reactor::schedule_wakeup"); + return this->mask_ops (eh->get_handle (), mask, ACE_Reactor::ADD_MASK); +} + +inline int +ACE_Reactor::cancel_wakeup (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Reactor::cancel_wakeup"); + return this->mask_ops (eh->get_handle (), mask, ACE_Reactor::CLR_MASK); +} + +inline int +ACE_Reactor::schedule_wakeup (ACE_HANDLE handle, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Reactor::schedule_wakeup"); + return this->mask_ops (handle, mask, ACE_Reactor::ADD_MASK); +} + +inline int +ACE_Reactor::cancel_wakeup (ACE_HANDLE handle, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_Reactor::cancel_wakeup"); + return this->mask_ops (handle, mask, ACE_Reactor::CLR_MASK); +} diff --git a/ace/ReactorEx.cpp b/ace/ReactorEx.cpp new file mode 100644 index 00000000000..6a55493a11b --- /dev/null +++ b/ace/ReactorEx.cpp @@ -0,0 +1,282 @@ +// ReactorEx.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/ReactorEx.h" + +#if defined (ACE_WIN32) + +#if !defined (__ACE_INLINE__) +#include "ace/ReactorEx.i" +#endif /* __ACE_INLINE__ */ + +ACE_ReactorEx::ACE_ReactorEx (void) + : active_handles_ (0), + timer_skew_ (0, ACE_TIMER_SKEW), + token_ (*this) +{ + if (this->register_handler (&this->notify_handler_) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "registering notify handler")); +} + +ACE_ReactorEx::~ACE_ReactorEx (void) +{ +} + +int +ACE_ReactorEx::notify (void) +{ + ACE_GUARD_RETURN (ACE_ReactorEx_Token, ace_mon, this->token_, -1); + + return notify_handler_.notify (); +} + +int +ACE_ReactorEx::register_handler (ACE_Event_Handler *eh, + ACE_HANDLE handle) +{ + ACE_GUARD_RETURN (ACE_ReactorEx_Token, ace_mon, this->token_, -1); + + if (this->active_handles_ >= ACE_ReactorEx::MAX_SIZE) + return -1; + + if (handle == ACE_INVALID_HANDLE) + handle = eh->get_handle (); + this->handles_[this->active_handles_] = handle; + this->handlers_[this->active_handles_] = eh; + this->active_handles_++; + return 0; +} + +// Removes -eh- from the ReactorEx. Note that the ReactorEx will call +// eh->get_handle() to extract the underlying I/O handle. + +int +ACE_ReactorEx::remove_handler (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask) +{ + ACE_GUARD_RETURN (ACE_ReactorEx_Token, ace_mon, this->token_, -1); + + ACE_HANDLE handle = eh->get_handle (); + + // Go through all the handles looking for -handle-. Even if we find + // it, we continue through the rest of the list. -handle- could + // appear multiple times. + for (size_t index = 0; index < this->active_handles_; index++) + { + if (this->handles_[index] == handle) + { + if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::DONT_CALL) == 0) + handlers_[index]->handle_close (handle, + ACE_Event_Handler::NULL_MASK); + + // If there was only one handle, reset the pointer to 0. + if (this->active_handles_ == 1) + { + // This is logically correct, but probably should never + // happen. This means that ACE_ReactorEx_Notify is + // being removed! We'll do it anyway and print out a + // warning. + this->active_handles_ = 0; + ACE_ERROR ((LM_ERROR, "ReactorEx: ReactorEx_Notify was" + "just removed!\n")); + } + // Otherwise, take the handle and handler from the back and + // overwrite the ones being removed. + else + { + this->handles_[index] = this->handles_[--this->active_handles_]; + this->handlers_[index] = this->handlers_[this->active_handles_]; + } + } + } + + return 0; +} + +int +ACE_ReactorEx::schedule_timer (ACE_Event_Handler *handler, + const void *arg, + const ACE_Time_Value &delta_time, + const ACE_Time_Value &interval) +{ + ACE_TRACE ("ACE_ReactorEx::schedule_timer"); + + return this->timer_queue_.schedule + (handler, arg, ACE_OS::gettimeofday () + delta_time, interval); +} + +int +ACE_ReactorEx::handle_events (ACE_Time_Value *how_long, + int wait_all) +{ + // @@ Need to implement -wait_all-. + + DWORD wait_status; + int handles_skipped = 0; + // These relative_things are moved through the handles_ each time + // handle_events is called. Set relative index = -1 so we can check + // in case of timeouts. + int relative_index = -1; + ACE_HANDLE *relative_handles = this->handles_; + ACE_Event_Handler **relative_handlers = this->handlers_; + + // Stash the current time. + ACE_Time_Value prev_time = ACE_OS::gettimeofday (); + // Check for pending timeout events. + how_long = timer_queue_.calculate_timeout (how_long); + // Translate into Win32 time value. + int timeout = how_long == 0 ? INFINITE : how_long->msec (); + + int active_handles = this->active_handles_; + + while (active_handles > 0) + { + wait_status = ::WaitForMultipleObjects (active_handles, + relative_handles, + wait_all, + timeout); + if (!this->timer_queue_.is_empty ()) + // Fudge factor accounts for problems with Solaris timers... + this->timer_queue_.expire (ACE_OS::gettimeofday () + this->timer_skew_); + + // Compute the time while the ReactorEx was processing. + ACE_Time_Value elapsed_time = ACE_OS::gettimeofday () - prev_time; + + // Update -how_long- to reflect the amount of time since + // handle_events was called. This is computed in case we return + // from the switch. + if (how_long != 0) + { + if (*how_long > elapsed_time) + *how_long = *how_long - elapsed_time; + else + *how_long = ACE_Time_Value::zero; // Used all of timeout. + } + + switch (wait_status) + { + case WAIT_TIMEOUT: + errno = ETIME; + // If we timed out on the first call, return 0, otherwise + // an event must have occured; return 1. + return relative_index == -1 ? 0 : 1; + case WAIT_FAILED: + errno = ::GetLastError (); + return -1; + default: + { + // @@ Need to implement WAIT_ABANDONED_0 stuff. + relative_index = wait_status - WAIT_OBJECT_0; + + if (relative_handlers[relative_index]->handle_signal (0) == -1) + // If we remove a handler, then the index should stay + // the same, since it may have been replaced with the + // end handle by remove_handler. + this->remove_handler (relative_handlers[relative_index]); + else + // If we did not remove the handler, then move the index + // up one so that we skip this handler on the next + // iteration. + relative_index++; + + // Update the relative pointers. + relative_handles = &relative_handles[relative_index]; + relative_handlers = &relative_handlers[relative_index]; + + // The number of remaining active handles is + // active_handles_ less the number of handles we skipped + // over. + handles_skipped += relative_index; + active_handles = this->active_handles_ - handles_skipped; + + // Make the timeout be zero so that we don't block on any + // subsequent calls to WaitForMultipleObjects. Rather, we + // just poll through the rest looking for signaled handles. + timeout = 0; + } + } + } + + // Compute the time while the ReactorEx was processing. Note that + // this is recomputed to reflect time spent dispatching handlers. + ACE_Time_Value elapsed_time = ACE_OS::gettimeofday () - prev_time; + + // Update how_long to reflect the amount of time since handle_events + // was called. + if (how_long != 0) + { + if (*how_long > elapsed_time) + *how_long = *how_long - elapsed_time; + else + *how_long = ACE_Time_Value::zero; // Used all of timeout. + } + + return 0; +} + +// ************************************************************ + +void +ACE_ReactorEx_Token::dump (void) const +{ + ACE_TRACE ("ACE_ReactorEx_Token::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_ReactorEx_Token::ACE_ReactorEx_Token (ACE_ReactorEx &r) + : reactorEx_ (r) +#if defined (ACE_ReactorEx_HAS_DEADLOCK_DETECTION) + , ACE_Local_Mutex (0) // Triggers unique name by stringifying "this"... +#endif /* ACE_ReactorEx_HAS_DEADLOCK_DETECTION */ +{ + ACE_TRACE ("ACE_ReactorEx_Token::ACE_ReactorEx_Token"); +} + +// Used to wakeup the Reactor. + +void +ACE_ReactorEx_Token::sleep_hook (void) +{ + ACE_TRACE ("ACE_ReactorEx_Token::sleep_hook"); + if (this->reactorEx_.notify () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "sleep_hook failed")); +} + +// ************************************************************ + +ACE_ReactorEx_Notify::ACE_ReactorEx_Notify (void) +{ + // Create an "auto-reset" event that is used to unblock the + // ReactorEx. + handle_ = ::CreateEvent (NULL, FALSE, FALSE, NULL); +} + +ACE_ReactorEx_Notify::~ACE_ReactorEx_Notify (void) +{ + ACE_OS::close (handle_); +} + +ACE_HANDLE +ACE_ReactorEx_Notify::get_handle (void) const +{ + return this->handle_; +} + +int +ACE_ReactorEx_Notify::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + // Do nothing. + return 0; +} + +int +ACE_ReactorEx_Notify::notify (void) +{ + return ::SetEvent (handle_) ? 0 : -1; +} + +#endif /* ACE_WIN32 */ diff --git a/ace/ReactorEx.h b/ace/ReactorEx.h new file mode 100644 index 00000000000..3b1bcc84a4b --- /dev/null +++ b/ace/ReactorEx.h @@ -0,0 +1,231 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// ReactorEx.h +// +// = AUTHOR +// Tim Harrison and Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_ReactorEx_H) +#define ACE_ReactorEx_H + +#include "ace/Timer_Queue.h" +#include "ace/Time_Value.h" +#include "ace/Event_Handler.h" +#include "ace/Token.h" + +#if defined (ACE_MT_SAFE) + +#if defined (ACE_REACTOREX_HAS_DEADLOCK_DETECTION) +#include "ace/Local_Tokens.h" +typedef ACE_Local_Mutex ACE_REACTOREX_MUTEX; +#else +typedef ACE_Token ACE_REACTOREX_MUTEX; +#endif /* ACE_REACTOR_HAS_DEADLOCK_DETECTION */ + +// Forward decl. +class ACE_ReactorEx; + +class ACE_Export ACE_ReactorEx_Token : public ACE_REACTOREX_MUTEX +{ +public: + ACE_ReactorEx_Token (ACE_ReactorEx &r); + + virtual void sleep_hook (void); + // Called just before the ACE_Event_Handler goes to sleep. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_ReactorEx &reactorEx_; +}; + +#endif /* ACE_MT_SAFE */ + +#if defined (ACE_WIN32) +// ************************************************************ + +class ACE_Export ACE_ReactorEx_Notify : public ACE_Event_Handler +// = TITLE +// ReactorEx Notify +// +// = DESCRIPTION +// A "do-nothing" class that is called when ReactorEx::notify is +// called. +{ +public: + ACE_ReactorEx_Notify (void); + // Creates a handle. + + ~ACE_ReactorEx_Notify (void); + // Destroys a handle. + + int notify (void); + // Signals a handle. + +private: + virtual ACE_HANDLE get_handle (void) const; + // Returns a handle. + + virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); + // Does nothing with a handle. + + ACE_HANDLE handle_; + // A handle. +}; + +class ACE_Export ACE_ReactorEx + // = TITLE + // An object oriented event demultiplexor and event handler + // ReactorEx for Win32 WaitForMultipleObjects + // + // = DESCRIPTION + + // The ACE_ReactorEx is an object-oriented event demultiplexor + // and event handler ReactorEx. The sources of events that the + // ACE_ReactorEx waits for and dispatches includes I/O events, + // general Win32 synchronization events (such as mutexes, + // semaphores, threads, etc.) and timer events. +{ +public: + enum + { + MAX_SIZE = MAXIMUM_WAIT_OBJECTS, + // Default size of the ReactorEx's handle table. + }; + + // = Initialization and termination methods. + + ACE_ReactorEx (void); + // Initialize the new ACE_ReactorEx with the default size. + + virtual ~ACE_ReactorEx (void); + // Close down the ReactorEx and release all of its resources. + + // = Event loop drivers. + // Main event loop driver that blocks for -how_long- before + // returning (will return earlier if I/O or signal events occur). + // Note that -how_long- can be 0, in which case this method blocks + // until I/O events or signals occur. Returns 0 if timed out, 1 if + // an event occurred, and -1 if an error occured. + virtual int handle_events (ACE_Time_Value *how_long = 0, + int wait_all = 0); + virtual int handle_events (ACE_Time_Value &how_long, + int wait_all = 0); + + + // = Register and remove Handlers. + virtual int register_handler (ACE_Event_Handler *eh, + ACE_HANDLE handle = ACE_INVALID_HANDLE); + // Register an Event_Handler -eh-. If handle == ACE_INVALID_HANDLE + // the ReactorEx will call eh->get_handle() to extract the + // underlying I/O handle). + + virtual int remove_handler (ACE_Event_Handler *eh, + ACE_Reactor_Mask mask = 0); + // Removes -eh- from the ReactorEx. Note that the ReactorEx will + // call eh->get_handle() to extract the underlying I/O handle. If + // -mask- == ACE_Event_Handler::DONT_CALL then the -handle_close- + // method of the -eh- is not invoked. + + virtual int notify (void); + // Wakeup ACE_ReactorEx if currently blocked + // WaitForMultipleObjects. + + // = Timer management. + virtual int schedule_timer (ACE_Event_Handler *eh, + const void *arg, + const ACE_Time_Value &delta, + const ACE_Time_Value &interval = ACE_Time_Value::zero); + // Schedule an Event Handler -eh- that will expire after -delta- + // amount of time. If it expires then -arg- is passed in as the + // value to eh->handle_timeout. If -interval- is != to + // ACE_Time_Value::zero then it is used to reschedule -eh- + // automatically. This method returns a timer handle that uniquely + // identifies the -eh- in an internal list. This timer handle can + // be used to cancel an Event_Handler before it expires. The + // cancellation ensures that timer_ids are unique up to values of + // greater than 2 billion timers. As long as timers don't stay + // around longer than this there should be no problems with + // accidentally deleting the wrong timer. + + virtual int cancel_timer (ACE_Event_Handler *event_handler); + // Cancel all Event_Handlers that match the address of + // -event_handler-. + + virtual int cancel_timer (int timer_id, const void **arg = 0); + // Cancel the single Event_Handler that matches the -timer_id- value + // (which was returned from the schedule method). If arg is + // non-NULL then it will be set to point to the ``magic cookie'' + // argument passed in when the Event_Handler was registered. This + // makes it possible to free up the memory and avoid memory leaks. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + int handle_notification (void); + // Handle the case where some thread has awakened us via our + // notification event. + + ACE_Timer_Queue timer_queue_; + // Defined as a pointer to allow overriding by derived classes... + + ACE_Time_Value timer_skew_; + // Adjusts for timer skew in various clocks. + + ACE_HANDLE handles_[MAX_SIZE]; + // Array of handles passed to WaitForMultipleObjects. + + ACE_Event_Handler *handlers_[MAX_SIZE]; + // Array of Event_Handler pointers that store the handlers to + // dispatch when the corresponding handles_ entry becomes signaled. + + size_t active_handles_; + // Number of handles that are currently active (ranges between 0 and + // MAX_SIZE). + + ACE_ReactorEx_Token token_; + // Synchronization token for the MT_SAFE ACE_Reactor. + +private: + + // Deny access since member-wise won't work... + ACE_ReactorEx (const ACE_ReactorEx &); + ACE_ReactorEx &operator = (const ACE_ReactorEx &); + + ACE_ReactorEx_Notify notify_handler_; + // Called when notify is called. +}; + +#else /* NOT win32 */ +class ACE_Export ACE_ReactorEx +{ +public: + virtual int handle_events (void) { return -1; } + virtual int handle_events (ACE_Time_Value &) { return -1; } + virtual int notify (void) { return 0; } +}; + +#endif /* ACE_WIN32 */ + +#if defined (__ACE_INLINE__) +#include "ace/ReactorEx.i" +#endif /* __ACE_INLINE__ */ +#endif /* ACE_ReactorEx_H */ diff --git a/ace/ReactorEx.i b/ace/ReactorEx.i new file mode 100644 index 00000000000..8ee3423cd22 --- /dev/null +++ b/ace/ReactorEx.i @@ -0,0 +1,28 @@ +/* -*- C++ -*- */ +// $Id$ + +#if defined (ACE_WIN32) + +ACE_INLINE int +ACE_ReactorEx::cancel_timer (ACE_Event_Handler *handler) +{ + ACE_TRACE ("ACE_ReactorEx::cancel_timer"); + return this->timer_queue_.cancel (handler); +} + +ACE_INLINE int +ACE_ReactorEx::cancel_timer (int timer_id, + const void **arg) +{ + ACE_TRACE ("ACE_ReactorEx::cancel_timer"); + return this->timer_queue_.cancel (timer_id, arg); +} + +ACE_INLINE int +ACE_ReactorEx::handle_events (ACE_Time_Value &how_long, + int wait_all) +{ + return this->handle_events (&how_long, wait_all); +} + +#endif /* ACE_WIN32 */ diff --git a/ace/Read_Buffer.cpp b/ace/Read_Buffer.cpp new file mode 100644 index 00000000000..9f49b7c7405 --- /dev/null +++ b/ace/Read_Buffer.cpp @@ -0,0 +1,155 @@ +// Read_Buffer.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Read_Buffer.h" +#include "ace/Service_Config.h" + +void +ACE_Read_Buffer::dump (void) const +{ + ACE_TRACE ("ACE_Read_Buffer::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "size_ = %d", this->size_)); + ACE_DEBUG ((LM_DEBUG, "\noccurrences_ = %d", this->occurrences_)); + ACE_DEBUG ((LM_DEBUG, "\nstream_ = %x", this->stream_)); + ACE_DEBUG ((LM_DEBUG, "\nallocator_ = %x", this->allocator_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Read_Buffer::ACE_Read_Buffer (FILE *fp, + int close_on_delete, + ACE_Allocator *allocator) + : stream_ (fp), + close_on_delete_ (close_on_delete), + allocator_ (allocator) +{ + ACE_TRACE ("ACE_Read_Buffer::ACE_Read_Buffer"); + if (this->allocator_ == 0) + this->allocator_ = ACE_Service_Config::allocator (); +} + +ACE_Read_Buffer::ACE_Read_Buffer (int handle, + int close_on_delete, + ACE_Allocator *allocator) + : stream_ (::fdopen (handle, "r")), + close_on_delete_ (close_on_delete), + allocator_ (allocator) +{ + ACE_TRACE ("ACE_Read_Buffer::ACE_Read_Buffer"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Service_Config::allocator (); +} + +ACE_Read_Buffer::~ACE_Read_Buffer (void) +{ + ACE_TRACE ("ACE_Read_Buffer::~ACE_Read_Buffer"); + + if (this->close_on_delete_) + ::fclose (this->stream_); +} + +// Input: term the character to terminate on +// search the character to search for +// replace the character with which to replace search +// Output: a buffer containing the contents of stream +// Method: call the recursive helper function read_helper + +char * +ACE_Read_Buffer::read (int term, int search, int replace) +{ + ACE_TRACE ("ACE_Read_Buffer::read"); + this->occurrences_ = 0; + this->size_ = 0; + return this->rec_read (term, search, replace); +} + +// Input: term the termination character +// search the character to search for +// replace the character with which to replace search +// Purpose: read in a file to a buffer using only a single dynamic +// allocation. +// Method: read until the local buffer is full and then recurse. +// Must continue until the termination character is reached. +// Allocate the final buffer based on the number of local +// buffers read and as the recursive calls bottom out, +// copy them in reverse order into the allocated buffer. + +char * +ACE_Read_Buffer::rec_read (int term, int search, int replace) +{ + ACE_TRACE ("ACE_Read_Buffer::rec_read"); + // This is our temporary workspace. + char buf[BUFSIZ]; + + int c; + size_t index = 0; + int done = 0; + + // Read in the file char by char + while (index < BUFSIZ) + { + c = getc (this->stream_); + + // Don't insert EOF into the buffer... + if (c == EOF) + { + if (index == 0) + return 0; + else + { + ungetc (c, this->stream_); + break; + } + } + else if (c == term) + done = 1; + + // Check for possible substitutions. + if (c == search) + { + this->occurrences_++; + + if (replace >= 0) + c = replace; + } + + buf[index++] = c; + + // Substitutions must be made before checking for termination. + if (done) + break; + } + + // Increment the number of bytes. + this->size_ += index; + + char *result; + + // Recurse, when the recursion bottoms out, allocate the result + // buffer. + if (done || c == EOF) + { + // Use the allocator to acquire the memory. + result = (char *) this->allocator_->malloc (this->size_ * sizeof (char)); + + if (result == 0) + { + errno = ENOMEM; + return 0; + } + result += this->size_; + } + else if ((result = this->rec_read (term, search, replace)) == 0) + return 0; + + // Copy buf into the appropriate location starting from end of + // buffer. Peter says this is confusing and that we should use + // memcpy() ;-) + + for (size_t j = index; j > 0; j--) + *--result = buf[j - 1]; + + return result; +} diff --git a/ace/Read_Buffer.h b/ace/Read_Buffer.h new file mode 100644 index 00000000000..ff932925b60 --- /dev/null +++ b/ace/Read_Buffer.h @@ -0,0 +1,93 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Read_Buffer.h +// +// = AUTHOR +// Doug Schmidt and Seth Widoff +// +// ============================================================================ + +#if !defined (ACE_READ_BUFFER_H) +#define ACE_READ_BUFFER_H + +#include "ace/ACE.h" +#include "ace/Malloc.h" + +class ACE_Export ACE_Read_Buffer + // = TITLE + // Efficiently reads an artibrarily large buffer from an input + // stream up to an including a termination character. Also + // performs search/replace on single occurrences a character in + // the buffer using the priniciples of Integrated Layer + // Processing. + // + // = DESCRIPTION + // This implementation is optimized to do a single dynamic + // allocation and make only one copy of the data. It uses + // recursion and the run-time stack to accomplish this + // efficiently. +{ +public: + // = Initialization and termination methods. + ACE_Read_Buffer (FILE *fp, int close_on_delete = 0, ACE_Allocator * = 0); + // Read from a FILE *. + + ACE_Read_Buffer (int handle, int close_on_delete = 0, ACE_Allocator * = 0); + // Read from an open HANDLE. + + ~ACE_Read_Buffer (void); + // Closes the FILE *. + + // Returns a dynamically allocated pointer to n bytes of data from + // the input stream up to (and including) the . If + // is >= 0 then all occurrences of the value are + // substituted with the value. + char *read (int terminator = EOF, + int search = '\n', + int replace = '\0'); + + size_t replaced (void) const; + // Returns the number of characters replaced during a . + + size_t size (void) const; + // Returns the size of the allocated buffer obtained during a . + + void dump (void) const; + // Dump the state of the object. + +private: + char *rec_read (int term, int search, int replace); + // Recursive helper method that does the work... + + size_t size_; + // The total number of characters in the buffer. + + size_t occurrences_; + // The total number of characters replaced. + + FILE *stream_; + // The stream we are reading from. + + int close_on_delete_; + // Keeps track of whether we should close the FILE in the + // destructor. + + ACE_Allocator *allocator_; + // Pointer to the allocator. + + // = Disallow copying and assignment... + void operator= (const ACE_Read_Buffer &); + ACE_Read_Buffer (const ACE_Read_Buffer &); +}; + +#include "ace/Read_Buffer.i" + +#endif /* ACE_READ_BUFFER_H */ diff --git a/ace/Read_Buffer.i b/ace/Read_Buffer.i new file mode 100644 index 00000000000..fc8be70166c --- /dev/null +++ b/ace/Read_Buffer.i @@ -0,0 +1,23 @@ +/* -*- C++ -*- */ +// $Id$ + +// Read_Buffer.i + +// Accessor to the number of bytes in the buffer. + +inline size_t +ACE_Read_Buffer::size (void) const +{ + ACE_TRACE ("ACE_Read_Buffer::size"); + return this->size_; +} + +// The total number of characters replaced. + +inline size_t +ACE_Read_Buffer::replaced (void) const +{ + ACE_TRACE ("ACE_Read_Buffer::replaced"); + return this->occurrences_; +} + diff --git a/ace/Remote_Name_Space.cpp b/ace/Remote_Name_Space.cpp new file mode 100644 index 00000000000..9125b4e47a7 --- /dev/null +++ b/ace/Remote_Name_Space.cpp @@ -0,0 +1,312 @@ +// Remote_Name_Space.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Remote_Name_Space.h" + +int +ACE_Remote_Name_Space::open (const char *servername, int port) +{ + ACE_TRACE ("ACE_Remote_Name_Space::open"); + ACE_INET_Addr servaddr; + + // Initialize Addr + if (servaddr.set (port, servername) == -1) + return -1; + + // Connect to Name Server process. + if (this->ns_proxy_.open (servaddr) == -1) + return -1; + + return 0; +} + +ACE_Remote_Name_Space::ACE_Remote_Name_Space (void) +{ + ACE_TRACE ("ACE_Remote_Name_Space::ACE_Remote_Name_Space"); +} + +ACE_Remote_Name_Space::ACE_Remote_Name_Space (const char *hostname, int port) +{ + ACE_TRACE ("ACE_Remote_Name_Space::ACE_Remote_Name_Space"); + if (this->open (hostname, port) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Remote_Name_Space::ACE_Remote_Name_Space")); +} + +int +ACE_Remote_Name_Space::bind (const ACE_WString &name, + const ACE_WString &value, + const char *type) +{ + ACE_TRACE ("ACE_Remote_Name_Space::bind"); + ACE_Name_Request request (ACE_Name_Request::BIND, name.rep (), + name.length () * sizeof (ACE_USHORT16), + value.rep (), + value.length () * sizeof (ACE_USHORT16), + type, strlen (type)); + int result = this->ns_proxy_.request_reply (request); + return result == ACE_Name_Reply::SUCCESS ? 0 : result; +} + +int +ACE_Remote_Name_Space::rebind (const ACE_WString &name, + const ACE_WString &value, + const char *type) +{ + ACE_TRACE ("ACE_Remote_Name_Space::rebind"); + ACE_Name_Request request (ACE_Name_Request::REBIND, name.rep (), + name.length () * sizeof (ACE_USHORT16), + value.rep (), + value.length () * sizeof (ACE_USHORT16), + type, strlen (type)); + int result = this->ns_proxy_.request_reply (request); + return result == ACE_Name_Reply::SUCCESS ? 0 : result; +} + +int +ACE_Remote_Name_Space::resolve (const ACE_WString &name, + ACE_WString &value, + char *&type) +{ + ACE_TRACE ("ACE_Remote_Name_Space::resolve"); + ACE_Name_Request request (ACE_Name_Request::RESOLVE, name.rep (), + name.length () * sizeof (ACE_USHORT16), + NULL, 0, NULL, 0); + + if (this->ns_proxy_.send_request (request) == -1) + return -1; + + ACE_Name_Request reply; + + if (this->ns_proxy_.recv_reply (reply) == -1) + return -1; + + ACE_WString temp (reply.value (), reply.value_len () / sizeof (ACE_USHORT16)); + value = temp; + ACE_NEW_RETURN (type, char[reply.type_len ()], -1); + ACE_OS::strcpy (type, reply.type ()); + + return 0; +} + +int +ACE_Remote_Name_Space::unbind (const ACE_WString &name) +{ + ACE_TRACE ("ACE_Remote_Name_Space::unbind"); + ACE_Name_Request request (ACE_Name_Request::UNBIND, name.rep (), + name.length () * sizeof (ACE_USHORT16), + NULL, 0, NULL, 0); + + int result = this->ns_proxy_.request_reply (request); + return result == ACE_Name_Reply::SUCCESS ? 0 : result; +} + +int +ACE_Remote_Name_Space::list_names (ACE_WSTRING_SET &set, + const ACE_WString &pattern) +{ + ACE_TRACE ("ACE_Remote_Name_Space::list_names"); + ACE_Name_Request request (ACE_Name_Request::LIST_NAMES, pattern.rep (), + pattern.length () * sizeof (ACE_USHORT16), + NULL, 0, NULL, 0); + + if (this->ns_proxy_.send_request (request) == -1) + return -1; + + ACE_Name_Request reply (0, NULL, 0, NULL, 0, NULL, 0, 0); + + while (reply.msg_type () != ACE_Name_Request::MAX_ENUM) + { + if (this->ns_proxy_.recv_reply (reply) == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Remote_Name_Space::list_names")); + return -1; + } + if (reply.msg_type () != ACE_Name_Request::MAX_ENUM) + { + ACE_WString name (reply.name (), reply.name_len () / sizeof (ACE_USHORT16)); + set.insert (name); + } + } + return 0; +} + +int +ACE_Remote_Name_Space::list_values (ACE_WSTRING_SET &set, + const ACE_WString &pattern) +{ + ACE_TRACE ("ACE_Remote_Name_Space::list_values"); + ACE_Name_Request request (ACE_Name_Request::LIST_VALUES, pattern.rep (), + pattern.length () * sizeof (ACE_USHORT16), + NULL, 0, NULL, 0); + + if (this->ns_proxy_.send_request (request) == -1) + return -1; + + ACE_Name_Request reply (0, NULL, 0, NULL, 0, NULL, 0, 0); + + while (reply.msg_type () != ACE_Name_Request::MAX_ENUM) + { + if (this->ns_proxy_.recv_reply (reply) == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Remote_Name_Space::list_values")); + return -1; + } + if (reply.msg_type () != ACE_Name_Request::MAX_ENUM) + { + ACE_WString value (reply.value (), reply.value_len () / sizeof (ACE_USHORT16)); + set.insert (value); + } + } + return 0; +} + +int +ACE_Remote_Name_Space::list_types (ACE_WSTRING_SET &set, + const ACE_WString &pattern) +{ + ACE_TRACE ("ACE_Remote_Name_Space::list_types"); + ACE_Name_Request request (ACE_Name_Request::LIST_TYPES, pattern.rep (), + pattern.length () * sizeof (ACE_USHORT16), + NULL, 0, NULL, 0); + + if (this->ns_proxy_.send_request (request) == -1) + return -1; + + ACE_Name_Request reply (0, NULL, 0, NULL, 0, NULL, 0, 0); + + while (reply.msg_type () != ACE_Name_Request::MAX_ENUM) + { + if (this->ns_proxy_.recv_reply (reply) == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Remote_Name_Space::list_values")); + return -1; + } + if (reply.msg_type () != ACE_Name_Request::MAX_ENUM) + { + ACE_WString type (reply.type ()); + set.insert (type); + } + } + return 0; +} + +int +ACE_Remote_Name_Space::list_name_entries (ACE_BINDING_SET &set, + const ACE_WString &pattern) +{ + ACE_TRACE ("ACE_Remote_Name_Space::list_names"); + ACE_Name_Request request (ACE_Name_Request::LIST_NAME_ENTRIES, pattern.rep (), + pattern.length () * sizeof (ACE_USHORT16), + NULL, 0, NULL, 0); + + if (this->ns_proxy_.send_request (request) == -1) + return -1; + + ACE_Name_Request reply (0, NULL, 0, NULL, 0, NULL, 0, 0); + + while (reply.msg_type () != ACE_Name_Request::MAX_ENUM) + { + if (this->ns_proxy_.recv_reply (reply) == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Remote_Name_Space::list_names")); + return -1; + } + if (reply.msg_type () != ACE_Name_Request::MAX_ENUM) + { + ACE_WString name (reply.name (), reply.name_len () / sizeof (ACE_USHORT16)); + ACE_WString value (reply.value (), reply.value_len () / sizeof (ACE_USHORT16)); + ACE_Name_Binding entry (name, value, reply.type ()); + + if (set.insert (entry) == -1) + return -1; + } + } + return 0; +} + +int +ACE_Remote_Name_Space::list_value_entries (ACE_BINDING_SET &set, + const ACE_WString &pattern) +{ + ACE_TRACE ("ACE_Remote_Name_Space::list_values"); + ACE_Name_Request request (ACE_Name_Request::LIST_VALUE_ENTRIES, pattern.rep (), + pattern.length () * sizeof (ACE_USHORT16), + NULL, 0, NULL, 0); + + if (this->ns_proxy_.send_request (request) == -1) + return -1; + + ACE_Name_Request reply (0, NULL, 0, NULL, 0, NULL, 0, 0); + + while (reply.msg_type () != ACE_Name_Request::MAX_ENUM) + { + if (this->ns_proxy_.recv_reply (reply) == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Remote_Name_Space::list_values")); + return -1; + } + if (reply.msg_type () != ACE_Name_Request::MAX_ENUM) + { + ACE_WString name (reply.name (), reply.name_len () / sizeof (ACE_USHORT16)); + ACE_WString value (reply.value (), reply.value_len () / sizeof (ACE_USHORT16)); + ACE_Name_Binding entry (name, value, reply.type()); + + if (set.insert (entry) == -1) + return -1; + } + } + return 0; +} + +int +ACE_Remote_Name_Space::list_type_entries (ACE_BINDING_SET &set, + const ACE_WString &pattern) +{ + ACE_TRACE ("ACE_Remote_Name_Space::list_types"); + ACE_Name_Request request (ACE_Name_Request::LIST_TYPE_ENTRIES, pattern.rep (), + pattern.length () * sizeof (ACE_USHORT16), + NULL, 0, NULL, 0); + + if (this->ns_proxy_.send_request (request) == -1) + return -1; + + ACE_Name_Request reply (0, NULL, 0, NULL, 0, NULL, 0, 0); + + while (reply.msg_type () != ACE_Name_Request::MAX_ENUM) + { + if (this->ns_proxy_.recv_reply (reply) == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Remote_Name_Space::list_values")); + return -1; + } + if (reply.msg_type () != ACE_Name_Request::MAX_ENUM) + { + ACE_WString name (reply.name (), reply.name_len () / sizeof (ACE_USHORT16)); + ACE_WString value (reply.value (), reply.value_len () / sizeof (ACE_USHORT16)); + ACE_Name_Binding entry (name, value, reply.type()); + + if (set.insert (entry) == -1) + return -1; + } + } + return 0; +} + + +ACE_Remote_Name_Space::~ACE_Remote_Name_Space (void) +{ + ACE_TRACE ("ACE_Remote_Name_Space::~ACE_Remote_Name_Space"); +} + +void +ACE_Remote_Name_Space::dump (void) const +{ + ACE_TRACE ("ACE_Remote_Name_Space::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->ns_proxy_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + diff --git a/ace/Remote_Name_Space.h b/ace/Remote_Name_Space.h new file mode 100644 index 00000000000..a81c15b6bbb --- /dev/null +++ b/ace/Remote_Name_Space.h @@ -0,0 +1,126 @@ +/* -*- C++ -*- */ +// $Id$ + +/*-*- C++ -*- */ + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// ACE_Remote_Name_Space +// +// = AUTHOR +// Prashant Jain +// +// ============================================================================ + +#if !defined (ACE_REMOTE_NAME_SPACE_H) +#define ACE_REMOTE_NAME_SPACE_H + +#include "ace/ACE.h" +#include "ace/SString.h" +#include "ace/Set.h" +#include "ace/Name_Proxy.h" +#include "ace/Name_Space.h" + +typedef ACE_Unbounded_Set ACE_WSTRING_SET; + +class ACE_Export ACE_Remote_Name_Space : public ACE_Name_Space + // = TITLE + // Maintaining accesses Remote Name Server Database. Allows to + // add NameBindings, change them, remove them and resolve + // NameBindings. + // + // = DESCRIPTION + // Manages a Naming Service for a remote name space which includes + // bindings for net_local naming context. + // All strings are stored in wide character format. + // A Name Binding consists of a name (that's the key), a value + // string and an optional type string (no wide chars). +{ +public: + // = Initialization and termination methods. + ACE_Remote_Name_Space (void); + // "Do-nothing" constructor. + + ACE_Remote_Name_Space (const char *hostname, int port); + // Specifies the scope of this namespace, opens and memory-maps the + // associated file (if accessible) or contacts the dedicated name + // server process for NET_LOCAL namespace. + + int open (const char *servername, int port); + // Specifies the scope of this namespace, opens and memory-maps the + // associated file (if accessible) or contacts the dedicated name + // server process for NET_LOCAL namespace. + + ~ACE_Remote_Name_Space (void); + // destructor, do some cleanup :TBD: last dtor should "compress" + // file + + virtual int bind (const ACE_WString &name_in, + const ACE_WString &value_in, + const char *type_in = ""); + // Bind a new name to a naming context (Wide character strings). + + virtual int rebind (const ACE_WString &name_in, + const ACE_WString &value_in, + const char *type_in = ""); + // Overwrite the value or type of an existing name in a + // ACE_Remote_Name_Space or bind a new name to the context, if it + // didn't exist yet. (Wide charcter strings interface). + + virtual int unbind (const ACE_WString &name_in); + // Delete a name from a ACE_Remote_Name_Space (Wide charcter strings + // Interface). + + virtual int resolve (const ACE_WString &name_in, + ACE_WString &value_out, + char *&type_out); + // Get value and type of a given name binding (Wide chars). The + // caller is responsible for deleting both and ! + + virtual int list_names (ACE_WSTRING_SET &set_out, + const ACE_WString &pattern_in); + // Get a set of names matching a specified pattern (wchars). Matching + // means the names must begin with the pattern string. + + virtual int list_values (ACE_WSTRING_SET &set_out, + const ACE_WString &pattern_in); + // Get a set of values matching a specified pattern (wchars). Matching + // means the values must begin with the pattern string. + + virtual int list_types (ACE_WSTRING_SET &set_out, + const ACE_WString &pattern_in); + // Get a set of types matching a specified pattern (wchars). Matching + // means the types must begin with the pattern string. + + virtual int list_name_entries (ACE_BINDING_SET &set, + const ACE_WString &pattern); + // Get a set of names matching a specified pattern (wchars). Matching + // means the names must begin with the pattern string. Returns the + // complete binding associated each pattern match. + + virtual int list_value_entries (ACE_BINDING_SET &set, + const ACE_WString &pattern); + // Get a set of values matching a specified pattern (wchars). Matching + // means the values must begin with the pattern string. Returns the + // complete binding associated each pattern match. + + virtual int list_type_entries (ACE_BINDING_SET &set, + const ACE_WString &pattern); + // Get a set of types matching a specified pattern (wchars). Matching + // means the types must begin with the pattern string. Returns the + // complete binding associated each pattern match. + + virtual void dump (void) const; + // Dump the state of the object. + +private: + + ACE_Name_Proxy ns_proxy_; + // Interface to Name server process for NET_LOCAL namespace. +}; + +#endif /* ACE_REMOTE_NAME_SPACE_H */ diff --git a/ace/Remote_Tokens.cpp b/ace/Remote_Tokens.cpp new file mode 100644 index 00000000000..e07b91a70ca --- /dev/null +++ b/ace/Remote_Tokens.cpp @@ -0,0 +1,445 @@ +// Remote_Tokens.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Remote_Tokens.h" +#include "ace/Singleton.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Remote_Tokens.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_MT_SAFE) +typedef ACE_Thread_Mutex ACE_TSS_CONNECTION_MUTEX; +#else +typedef ACE_Null_Mutex ACE_TSS_CONNECTION_MUTEX; +#endif /* ACE_MT_SAFE */ + +// Make a typedef to simplify access to the Singleton below. +typedef ACE_Singleton + ACE_Token_Connections; + +// Initialize the statics from ACE_TSS_Connection; +ACE_INET_Addr ACE_TSS_Connection::server_address_; + +// ************************************************************ + +void +ACE_TSS_Connection::set_server_address (const ACE_INET_Addr &server_address) +{ + ACE_TRACE ("ACE_TSS_Connection::set_server_address"); + server_address_ = server_address; +} + +// Necessary to make some compilers work... +ACE_TSS_Connection::ACE_TSS_Connection (void) +{ + ACE_TRACE ("ACE_TSS_Connection::ACE_TSS_Connection"); +} + +ACE_TSS_Connection::~ACE_TSS_Connection (void) +{ + ACE_TRACE ("ACE_TSS_Connection::~ACE_TSS_Connection"); +} + +ACE_SOCK_Stream * +ACE_TSS_Connection::get_connection (void) +{ + return ACE_TSS::operator-> (); +} + +ACE_SOCK_Stream * +ACE_TSS_Connection::make_TSS_TYPE (void) const +{ + ACE_TRACE ("ACE_TSS_Connection::make_TSS_TYPE"); + + ACE_SOCK_Connector connector; + ACE_SOCK_Stream *stream = 0; + + ACE_NEW_RETURN (stream, ACE_SOCK_Stream, 0); + + if (connector.connect (*stream, server_address_) == -1) + { + delete stream; + errno = ECONNREFUSED; + return 0; + } + + ACE_DEBUG ((LM_DEBUG, "ACE_TSS_Connection new connection\n")); + return stream; +} + +ACE_TSS_Connection::operator ACE_SOCK_Stream *(void) +{ + return this->get_connection (); +} + + +void +ACE_TSS_Connection::dump (void) const +{ + ACE_TRACE ("ACE_TSS_Connection::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "ACE_TSS_Connection::dump:\n")); + ACE_DEBUG ((LM_DEBUG, "server_address_\n")); + server_address_.dump (); + ACE_DEBUG ((LM_DEBUG, "base:\n")); + ACE_TSS::dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// ************************************************************ +// ************************************************************ +// ************************************************************ + +ACE_Remote_Token_Proxy::ACE_Remote_Token_Proxy (void) +{ + ACE_TRACE ("ACE_Remote_Token_Proxy::ACE_Remote_Token_Proxy"); +} + +ACE_Remote_Token_Proxy::~ACE_Remote_Token_Proxy (void) +{ + ACE_TRACE ("ACE_Remote_Token_Proxy::~ACE_Remote_Token_Proxy"); +} + +int +ACE_Remote_Token_Proxy::open (const char *name, + int ignore_deadlock, + int debug) +{ + ACE_TRACE ("ACE_Remote_Token_Proxy::open"); + ignore_shadow_deadlock_ = ignore_deadlock; + return ACE_Token_Proxy::open (name, 0, debug); +} + +void +ACE_Remote_Token_Proxy::set_server_address (const ACE_INET_Addr &server_address) +{ + ACE_TRACE ("ACE_Remote_Token_Proxy::set_server_address"); + ACE_Token_Connections::instance ()->set_server_address (server_address); +} + +int +ACE_Remote_Token_Proxy::initiate_connection (void) +{ + ACE_TRACE ("ACE_Remote_Token_Proxy::initiate_connection"); + if (token_ == 0) + { + errno = ENOENT; + ACE_ERROR_RETURN ((LM_ERROR, "ACE_Remote_Token_Proxy not open.\n"), -1); + } + + ACE_SOCK_Stream *peer = ACE_Token_Connections::instance ()->get_connection (); + return peer == 0 ? 0 : 1; +} + +// Do the work of sending a request and getting a reply. + +int +ACE_Remote_Token_Proxy::request_reply (ACE_Token_Request &request, + ACE_Synch_Options &options) +{ + ACE_TRACE ("ACE_Remote_Token_Proxy::request_reply"); + void *buffer; + ssize_t length; + +// request.dump (); + + if ((length = request.encode (buffer)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "encode failed"), -1); + + ACE_SOCK_Stream *peer = ACE_Token_Connections::instance ()->get_connection (); + + if (peer == 0) + return -1; + + // Transmit request via a blocking send. + + if (peer->send_n (buffer, length) != length) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send_n failed"), -1); + else + { + ACE_Token_Reply reply; + + // Receive reply via blocking read. + + if (peer->recv (&reply, sizeof reply) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv failed"), -1); + + if (reply.decode () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "decode failed"), -1); + + errno = int (reply.errnum ()); + if (errno != 0) + ACE_RETURN (-1); + else + return 0; + } +} + +int +ACE_Remote_Token_Proxy::acquire (int notify, + void (*sleep_hook)(void *), + ACE_Synch_Options &options) +{ + ACE_TRACE ("ACE_Remote_Token_Proxy::acquire"); + + // First grab the local shadow mutex. + if (ACE_Token_Proxy::acquire (notify, + sleep_hook, + ACE_Synch_Options::asynch) == -1) + { + // Acquire failed, deal with it... + switch (errno) + { + case EWOULDBLOCK : + // Whoah, we detected wouldblock via the shadow mutex! + if (debug_) + ACE_DEBUG ((LM_DEBUG, "(%t) shadow: acquire will block, owner is %s\n", + this->token_->owner_id ())); + // No error, but would block, + break; + + case EDEADLK : + if (debug_) + ACE_DEBUG ((LM_DEBUG, "(%t) shadow: deadlock detected\n")); + + if (ignore_shadow_deadlock_) + break; + else + { + errno = EDEADLK; + ACE_RETURN (-1); + } + + default : + ACE_ERROR_RETURN ((LM_ERROR, + "(%t) %p shadow acquire failed\n", + "ACE_Remote_Token_Proxy"), + -1); + } + } + + ACE_Token_Request request (token_->type (), + this->type (), + ACE_Token_Request::ACQUIRE, + this->name (), + this->client_id (), + options); + + request.notify (notify); + + int result = this->request_reply (request, options); + + if (result == -1) + { + // Update the local shadow copy. + ACE_DEBUG ((LM_DEBUG, "error on remote acquire, releasing shadow mutex.\n")); + ACE_Token_Proxy::release (); + } + else + { + ACE_DEBUG ((LM_DEBUG, "(%t) acquired %s remotely.\n", this->name ())); + // Our shadow call may have failed. However, it's still a race + // to the remote server. If we beat the client which holds the + // local token, we need to fix things locally to reflect the + // actual ownership. All that should happen is that our waiter + // is moved to the front of the waiter list. + token_->make_owner (waiter_); + } + + return result; +} + +int +ACE_Remote_Token_Proxy::tryacquire (void (*sleep_hook)(void *)) +{ + ACE_TRACE ("ACE_Remote_Token_Proxy::tryacquire"); + + // If we can detect locally that the tryacquire will fail, there is + // no need to go remote. + if (ACE_Token_Proxy::tryacquire (sleep_hook) == -1) + { + if (debug_) + { + int error = errno; + ACE_DEBUG ((LM_DEBUG, "shadow try acquire failed\n")); + errno = error; + } + + return -1; + } + + ACE_Token_Request request (token_->type (), + this->type (), + ACE_Token_Request::RELEASE, + this->name (), + this->client_id (), + ACE_Synch_Options::synch); + + return this->request_reply (request, + ACE_Synch_Options::synch); +} + +int +ACE_Remote_Token_Proxy::renew (int requeue_position, + ACE_Synch_Options &options) +{ + ACE_TRACE ("ACE_Remote_Token_Proxy::renew"); + + if (ACE_Token_Proxy::renew (requeue_position, + ACE_Synch_Options::asynch) == -1) + { + // Check for error. + if (errno != EWOULDBLOCK) + return -1; + else if (debug_) + ACE_DEBUG ((LM_DEBUG, + "(%t) shadow: renew would block. owner %s.\n", + this->token_->owner_id ())); + } + + ACE_Token_Request request (token_->type (), + this->type (), + ACE_Token_Request::RENEW, + this->name (), + this->client_id (), + options); + + request.requeue_position (requeue_position); + + int result = this->request_reply (request, options); + + if (result == -1) + { + int error = errno; + ACE_Token_Proxy::release (); + errno = error; + ACE_ERROR_RETURN ((LM_ERROR, "%p error on remote renew, releasing shadow mutex.\n", + "ACE_Remote_Token_Proxy"), -1); + } + else + { + if (debug_) + ACE_DEBUG ((LM_DEBUG, "(%t) renewed %s remotely.\n", this->name ())); + // Make sure that the local shadow reflects our new ownership. + token_->make_owner (waiter_); + return result; + } +} + +int +ACE_Remote_Token_Proxy::release (ACE_Synch_Options &options) +{ + ACE_TRACE ("ACE_Remote_Token_Proxy::release"); + + ACE_Token_Request request (token_->type (), + this->type (), + ACE_Token_Request::RELEASE, + this->name (), + this->client_id (), + options); + + int result = this->request_reply (request, options); + if (result == 0) + ACE_DEBUG ((LM_DEBUG, "(%t) released %s remotely.\n", this->name ())); + + // whether success or failure, we're going to release the shadow. + // If race conditions exist such that we are no longer the owner, + // this release will perform a remove. + if (ACE_Token_Proxy::release () == -1) + ACE_ERROR ((LM_ERROR, "(%t) shadow: release failed\n")); + + return result; +} + +int +ACE_Remote_Token_Proxy::remove (ACE_Synch_Options &options) +{ + ACE_TRACE ("ACE_Remote_Token_Proxy::remove"); + return 0; +} + +void +ACE_Remote_Token_Proxy::token_acquired (ACE_TPQ_Entry *e) +{ + ACE_TRACE ("ACE_Remote_Token_Proxy::token_acquired"); + ACE_DEBUG ((LM_DEBUG, "(%t) shadow token %s acquired\n", + this->client_id (), + this->name ())); + // ACE_Token_Proxy::token_acquired (vp); +} + +const char* +ACE_Remote_Token_Proxy::owner_id (void) +{ + ACE_TRACE ("ACE_Remote_Token_Proxy::owner_id"); + ACE_DEBUG ((LM_DEBUG, "owner_id called\n")); + // @@ special operation + return 0; +} + +void +ACE_Remote_Token_Proxy::dump (void) const +{ + ACE_TRACE ("ACE_Remote_Token_Proxy::owner_id"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "ACE_Tokens::dump:\n" + " ignore_shadow_deadlock_ = %d\n", + ignore_shadow_deadlock_)); + ACE_DEBUG ((LM_DEBUG, "base:\n")); + ACE_Token_Proxy::dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// ************************************************************ +// ************************************************************ +// ************************************************************ + +void +ACE_Remote_Mutex::dump (void) const +{ + ACE_TRACE ("ACE_Remote_Mutex::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "ACE_Remote_Mutex::dump:\n")); + ACE_DEBUG ((LM_DEBUG, "base:\n")); + ACE_Remote_Token_Proxy::dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// ************************************************************ +// ************************************************************ +// ************************************************************ + +void +ACE_Remote_RLock::dump (void) const +{ + ACE_TRACE ("ACE_Remote_RLock::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "ACE_Remote_RLock::dump:\n")); + ACE_DEBUG ((LM_DEBUG, "base:\n")); + ACE_Remote_Token_Proxy::dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// ************************************************************ +// ************************************************************ +// ************************************************************ + +void +ACE_Remote_WLock::dump (void) const +{ + ACE_TRACE ("ACE_Remote_WLock::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "ACE_Remote_WLock::dump:\n")); + ACE_DEBUG ((LM_DEBUG, "base:\n")); + ACE_Remote_Token_Proxy::dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_TSS ; +template class ACE_Singleton ; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/ace/Remote_Tokens.h b/ace/Remote_Tokens.h new file mode 100644 index 00000000000..63217c54390 --- /dev/null +++ b/ace/Remote_Tokens.h @@ -0,0 +1,283 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// Remote_Tokens.h +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) and +// Tim Harrison (harrison@cs.wustl.edu) +// +// ============================================================================ + +#if !defined (ACE_REMOTE_MUTEX_H) +#define ACE_REMOTE_MUTEX_H + +#include "ace/INET_Addr.h" +#include "ace/SOCK_Connector.h" +#include "ace/SOCK_Stream.h" +#include "ace/Synch_Options.h" +#include "ace/Local_Tokens.h" +#include "ace/Token_Request_Reply.h" +#include "ace/Synch.h" + +class ACE_Export ACE_Remote_Token_Proxy : public ACE_Token_Proxy + // = TITLE + // Proxy for acquiring, renewing, and releasing a distributed + // synchronization token. + // + // = DESCRIPTION + // The Remote_Token_Proxy class implements the mechanisms for + // distributed token operations. It is similar to the + // ACE_Token_Proxy. + // + // = BUGS + // Distributed sleep_hooks have not been implemented. owner_id () + // is not implemented. +{ +public: + ACE_Remote_Token_Proxy (void); + // Null construction. + + virtual ~ACE_Remote_Token_Proxy (void); + // Death. + + int open (const char *name, + int ignore_deadlock = 0, + int debug = 0); + // Same as Token_Proxy. is the string uniquely identifying + // the token. can be 1 to disable deadlock + // notifications. prints debug messages. + + + int initiate_connection (void); + // Open a connection with the token server. This only need be used + // when the user wishes to explicitly open a connection to check if + // the server exists. Connections are stored in the + // ACE_Token_Connections singleton as thread-specific data. That + // is, every thread has only one connection that is used for all + // remote tokens. + + virtual int acquire (int notify = 0, + void (*sleep_hook)(void *) = 0, + ACE_Synch_Options &options = + ACE_Synch_Options::synch); + // Acquire the distributed token. If notify is specified and the + // token is already held, the owner is notified. options contains + // the timeout value for the acquire call. The timer is kept at the + // token server. Asynchronous operations are not supported. + // Returns 0 on success, -1 on failure with == problem. + + virtual int tryacquire (void (*sleep_hook)(void *) = 0); + // Try to acquire the distributed token. If the token is already + // held, the call returns without queueing the caller as a waiter. + // Returns 0 on success (the token was acquired), and -1 with + // EWOULDBLOCK if the token was already held. + + virtual int renew (int requeue_position = 0, + ACE_Synch_Options &options = + ACE_Synch_Options::synch); + // Renew the token by offering to release it if there are any other + // waiters, otherwise get the token back immediately. This renew + // has the same semantics as ACE_Local_Mutex release. It is + // semantically equivalent to release()> followed by + // acquire()>, but it is faster. options contains the + // timeout value used if renew blocks. As with acquire, the timer + // is maintained at the token server. If there are waiters and + // requeue_position == -1, the caller is queued at the rear of the + // waiter list. Otherwise, requeue_position specifies the number of + // waiters to "let by" before reacquiring the token (effectively, + // the position in the waiter list.) + + virtual int release (ACE_Synch_Options &options = + ACE_Synch_Options::synch); + // Release the distributed token. Similar to ACE_Local_Mutex, if the + // caller is not the owner, it is removed from the waiter list (if + // applicable.) Returns 0 on success, -1 on failure with == + // problem. + + virtual int remove (ACE_Synch_Options &options = + ACE_Synch_Options::synch); + // Become interface compliant for ACE_Guard<>. This has no + // functionality. + + virtual void token_acquired (ACE_TPQ_Entry *); + // Override the default to do nothing. + + virtual const char* owner_id (void); + // the client id of the current token holder + + static void set_server_address (const ACE_INET_Addr &server_address); + // sets the server address for all instances of ACE_Remote_Token_Proxy + // If this isn't called, the environment variable TOKEN_SERVER is + // checked for the server address. If that is not specified, all + // ACE_Remote_** operations will fail. + + void dump (void) const; + // Dump the state of the class. + +protected: + + int ignore_shadow_deadlock_; + // if shadows report deadlock, go remote anyway + + int request_reply (ACE_Token_Request &request, + ACE_Synch_Options &options); + // Perform the request and wait for the reply. +}; + +class ACE_Export ACE_Remote_Mutex : public ACE_Remote_Token_Proxy +// = TITLE +// Proxy for acquiring, renewing, and releasing a distributed +// mutex. +// +// = DESCRIPTION +// This is the remote equivalent to ACE_Local_Mutex. The +// Remote_Mutex class offers methods for acquiring, renewing, and +// releasing a distributed synchronization mutex. Similar to +// ACE_Local_Mutex, ACE_Remote_Token_Proxy offers recursive +// acquisition, FIFO waiter ordering, and deadlock detection. It +// depends on the Token Server for its distributed synchronization +// semantics. +{ +public: + ACE_Remote_Mutex (void); + // Null creation. Remote_Token_Proxy::open must be called. + + ACE_Remote_Mutex (const char *token_name, + int ignore_deadlock = 0, + int debug = 0); + // Calls Remote_Token_Proxy::open for you. + + void dump (void) const; + // Dump the state of the class. + + virtual ACE_Token_Proxy *clone (void) const; + // Return deep copy. + +protected: + virtual ACE_Tokens *create_token (const char *name); + // Make the correct type of ACE_Tokens. This is called by the Token + // Manager. +}; + +class ACE_Export ACE_Remote_RLock : public ACE_Remote_Token_Proxy +// = TITLE +// Proxy for acquiring, renewing, and releasing a distributed +// readers lock. +// +// = DESCRIPTION +// This is the remote equivalent to ACE_Local_RLock. Multiple +// readers can hold the lock simultaneously when no writers have +// the lock. Alternatively, when a writer holds the lock, no other +// participants (readers or writers) may hold the lock. +// ACE_Remote_RLock depends on the ACE Token Server for its +// distributed synchronization semantics. +{ +public: + ACE_Remote_RLock (void); + + ACE_Remote_RLock (const char *token_name, + int ignore_deadlock = 0, + int debug = 0); + + ACE_Remote_RLock (const ACE_Remote_RLock &mutex); + + void dump (void) const; + // Dump the state of the class. + + virtual int type (void) const; + // Returns ACE_RW_Token::RLOCK; + + virtual ACE_Token_Proxy *clone (void) const; + // Return deep copy. + +protected: + virtual ACE_Tokens *create_token (const char *name); + // Make the correct type of ACE_Tokens. This is called by the Token + // Manager. +}; + +class ACE_Export ACE_Remote_WLock : public ACE_Remote_Token_Proxy + // = TITLE + // Proxy for acquiring, renewing, and releasing a distributed + // writers lock. + // + // = DESCRIPTION + // Shields applications from details of interacting with the + // ACE_Token_Server. The token_name_ is just the string that the + // Token Server uses to identify the token. The client_id_ (also + // used by the Token Server,) identifies the owner of the token and + // is used for deadlock detection. +{ +public: + ACE_Remote_WLock (void); + + ACE_Remote_WLock (const char *token_name, + int ignore_deadlock = 0, + int debug = 0); + + ACE_Remote_WLock (const ACE_Remote_WLock &mutex); + + void dump (void) const; + // Dump the state of the class. + + virtual int type (void) const; + // Returns ACE_RW_Token::WLOCK; + + virtual ACE_Token_Proxy *clone (void) const; + // Return deep copy. + +protected: + virtual ACE_Tokens *create_token (const char *name); + // Make the correct type of ACE_Tokens. This is called by the Token + // Manager. +}; + +class ACE_Export ACE_TSS_Connection : public ACE_TSS + // = TITLE + // Class for providing a connection per thread. + // + // = DESCRIPTION + // ACE_TSS_Connection provides a single access point for all + // threads to access thread-specific connections. This prevents + // resource-sharing problems such as thread serialization. +{ +public: + // Necessary to make some compilers work... + ACE_TSS_Connection (void); + ~ACE_TSS_Connection (void); + + ACE_SOCK_Stream *get_connection (void); + // retrieve the thread's connection + + virtual ACE_SOCK_Stream *make_TSS_TYPE (void) const; + // Factory Method that creates a new SOCK Stream. + + operator ACE_SOCK_Stream *(void); + // inheritence and operator overloading don't mix. Redefine this + // from ACE_TSS so that we can use it. + + static void set_server_address (const ACE_INET_Addr &server_address); + // Set the server address. + + void dump (void) const; + // Dump the state of the class. + +protected: + static ACE_INET_Addr server_address_; + // The address of the Token Server used by all instances of + // Token_Proxy. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Remote_Tokens.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_REMOTE_TOKEN_H */ diff --git a/ace/Remote_Tokens.i b/ace/Remote_Tokens.i new file mode 100644 index 00000000000..2a87bf30919 --- /dev/null +++ b/ace/Remote_Tokens.i @@ -0,0 +1,98 @@ +/* -*- C++ -*- */ +// $Id$ + +// Remote_Tokens.i + +ACE_INLINE +ACE_Remote_Mutex::ACE_Remote_Mutex (void) +{ + ACE_TRACE ("ACE_Remote_Mutex::ACE_Remote_Mutex"); +} + +ACE_INLINE +ACE_Remote_Mutex::ACE_Remote_Mutex (const char *token_name, + int ignore_deadlock, + int debug) +{ + ACE_TRACE ("ACE_Remote_Mutex::ACE_Remote_Mutex"); + this->open (token_name, ignore_deadlock, debug); +} + +ACE_INLINE ACE_Token_Proxy * +ACE_Remote_Mutex::clone (void) const +{ + return new ACE_Remote_Mutex (this->name (), + ignore_deadlock_, + debug_); +} + +ACE_INLINE ACE_Tokens * +ACE_Remote_Mutex::create_token (const char *name) +{ + return new ACE_Mutex_Token (name); +} + +// ************************************************************ + +ACE_INLINE +ACE_Remote_RLock::ACE_Remote_RLock (const char *token_name, + int ignore_deadlock, + int debug) +{ + ACE_TRACE ("ACE_Remote_RLock::ACE_Remote_RLock"); + this->open (token_name, ignore_deadlock, debug); +} + +ACE_INLINE ACE_Tokens * +ACE_Remote_RLock::create_token (const char *name) +{ + return new ACE_RW_Token (name); +} + +ACE_INLINE int +ACE_Remote_RLock::type (void) const +{ + return ACE_RW_Token::READER; +} + +ACE_INLINE ACE_Token_Proxy * +ACE_Remote_RLock::clone (void) const +{ + return new ACE_Remote_RLock (this->name (), + ignore_deadlock_, + debug_); +} + +// ************************************************************ + +ACE_INLINE +ACE_Remote_WLock::ACE_Remote_WLock (const char *token_name, + int ignore_deadlock, + int debug) +{ + ACE_TRACE ("ACE_Remote_WLock::ACE_Remote_WLock"); + this->open (token_name, ignore_deadlock, debug); +} + + +ACE_INLINE ACE_Tokens * +ACE_Remote_WLock::create_token (const char *name) +{ + return new ACE_RW_Token (name); +} + +ACE_INLINE int +ACE_Remote_WLock::type (void) const +{ + return ACE_RW_Token::WRITER; +} + +ACE_INLINE ACE_Token_Proxy * +ACE_Remote_WLock::clone (void) const +{ + return new ACE_Remote_WLock (this->name (), + ignore_deadlock_, + debug_); +} + + diff --git a/ace/SOCK.cpp b/ace/SOCK.cpp new file mode 100644 index 00000000000..251e9e71eac --- /dev/null +++ b/ace/SOCK.cpp @@ -0,0 +1,97 @@ +// SOCK.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/SOCK.h" +#include "ace/Log_Msg.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_SOCK) + +#if defined (ACE_WIN32) +// Static used to initialize WinSock. +ACE_SOCK ACE_SOCK::dummy_; +#endif /* ACE_WIN32 */ + +void +ACE_SOCK::dump (void) const +{ + ACE_TRACE ("ACE_SOCK::dump"); +} + +ACE_SOCK::ACE_SOCK (void) +{ + ACE_TRACE ("ACE_SOCK::ACE_SOCK"); + + // Make sure that we've initialized the WinSock library before using + // sockets! + ACE_OS::socket_init (ACE_WSOCK_VERSION); +} + +// Returns information about the remote peer endpoint (if there is +// one). + +int +ACE_SOCK::get_remote_addr (ACE_Addr &sa) const +{ + ACE_TRACE ("ACE_SOCK::get_remote_addr"); + int len = sa.get_size (); + sockaddr *addr = (sockaddr *) sa.get_addr (); + + if (ACE_OS::getpeername (this->get_handle (), addr, &len) == -1) + return -1; + + sa.set_size (len); + return 0; +} + +int +ACE_SOCK::get_local_addr (ACE_Addr &sa) const +{ + ACE_TRACE ("ACE_SOCK::get_local_addr"); + int len = sa.get_size (); + sockaddr *addr = (sockaddr *) sa.get_addr (); + + if (ACE_OS::getsockname (this->get_handle (), addr, &len) == -1) + return -1; + + sa.set_size ((int)len); + return 0; +} + +int +ACE_SOCK::open (int type, + int protocol_family, + int protocol) +{ + ACE_TRACE ("ACE_SOCK::open"); + this->set_handle (ACE_OS::socket (protocol_family, type, protocol)); + return this->get_handle () == ACE_INVALID_HANDLE ? -1 : 0; +} + +// Close down a ACE_SOCK. + +int +ACE_SOCK::close (void) +{ + ACE_TRACE ("ACE_SOCK::close"); + int result = 0; + + if (this->get_handle () != ACE_INVALID_HANDLE) + { + result = ACE_OS::closesocket (this->get_handle ()); + this->set_handle (ACE_INVALID_HANDLE); + } + return result; +} + +// General purpose constructor for performing server ACE_SOCK +// creation. + +ACE_SOCK::ACE_SOCK (int type, + int protocol_family, + int protocol) +{ + ACE_TRACE ("ACE_SOCK::ACE_SOCK"); + if (this->open (type, protocol_family, protocol) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_SOCK::ACE_SOCK")); +} diff --git a/ace/SOCK.h b/ace/SOCK.h new file mode 100644 index 00000000000..25f2b580cfe --- /dev/null +++ b/ace/SOCK.h @@ -0,0 +1,95 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// SOCK.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SOCK_H) +#define ACE_SOCK_H + +#include "ace/ACE.h" +#include "ace/Addr.h" +#include "ace/IPC_SAP.h" + +// The following is necessary since many C++ compilers don't support +// typedef'd types inside of classes used as formal template +// arguments... ;-(. Luckily, using the C++ preprocessor I can hide +// most of this nastiness! + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) +#define ACE_SOCK_ACCEPTOR ACE_SOCK_Acceptor +#define ACE_SOCK_CONNECTOR ACE_SOCK_Connector +#define ACE_SOCK_STREAM ACE_SOCK_Stream +#else /* TEMPLATES are broken (must be a cfront-based compiler...) */ +#define ACE_SOCK_ACCEPTOR ACE_SOCK_Acceptor, ACE_INET_Addr +#define ACE_SOCK_CONNECTOR ACE_SOCK_Connector, ACE_INET_Addr +#define ACE_SOCK_STREAM ACE_SOCK_Stream, ACE_INET_Addr +#endif /* ACE_TEMPLATE_TYPEDEFS */ + +class ACE_Export ACE_SOCK : public ACE_IPC_SAP + // = TITLE + // Defines the member functions for the base class of the + // ACE_SOCK abstraction. +{ +public: + int open (int type, + int protocol_family, + int protocol); + // Wrapper around the socket() system call. + + int set_option (int level, + int option, + void *optval, + int optlen) const; + // Wrapper around the setsockopt() system call. + + int get_option (int level, + int option, + void *optval, + int *optlen) const; + // Wrapper around the getsockopt() system call. + + int close (void); + // Close down the socket. + + int get_local_addr (ACE_Addr &) const; + // Return the local endpoint address. + + int get_remote_addr (ACE_Addr &) const; + // Return the address of the remotely connected peer (if there is + // one). + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + // = Make this an abstract class. + ACE_SOCK (void); + // Default constructor. + + ACE_SOCK (int type, int protocol_family, int protocol = 0); + // Wrapper around the socket() system call. + +#if defined (ACE_WIN32) + static ACE_SOCK dummy_; + // Used to ensure we initialize WinSock! +#endif /* ACE_WIN32 */ +}; + +#include "ace/SOCK.i" + +#endif /* ACE_SOCK_H */ diff --git a/ace/SOCK.i b/ace/SOCK.i new file mode 100644 index 00000000000..bbf4794a8af --- /dev/null +++ b/ace/SOCK.i @@ -0,0 +1,28 @@ +/* -*- C++ -*- */ +// $Id$ + +// SOCK.i + +inline int +ACE_SOCK::set_option (int level, + int option, + void *optval, + int optlen) const +{ + ACE_TRACE ("ACE_SOCK::set_option"); + return ACE_OS::setsockopt (this->get_handle (), level, + option, (char *) optval, optlen); +} + +// Provides access to the ACE_OS::getsockopt system call. + +inline int +ACE_SOCK::get_option (int level, + int option, + void *optval, + int *optlen) const +{ + ACE_TRACE ("ACE_SOCK::get_option"); + return ACE_OS::getsockopt (this->get_handle (), level, + option, (char *) optval, optlen); +} diff --git a/ace/SOCK_Acceptor.cpp b/ace/SOCK_Acceptor.cpp new file mode 100644 index 00000000000..1a1e05fe536 --- /dev/null +++ b/ace/SOCK_Acceptor.cpp @@ -0,0 +1,125 @@ +// SOCK_Acceptor.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/SOCK_Acceptor.h" +#include "ace/Log_Msg.h" + +#if !defined (__ACE_INLINE__) +#include "ace/SOCK_Acceptor.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Acceptor) + +// Do nothing routine for constructor. + +ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (void) +{ + ACE_TRACE ("ACE_SOCK_Acceptor::ACE_SOCK_Acceptor"); +} + +// General purpose routine for accepting new connections. + +int +ACE_SOCK_Acceptor::accept (ACE_SOCK_Stream &new_stream, ACE_Addr *remote_addr, + ACE_Time_Value *timeout, int restart) const +{ + ACE_TRACE ("ACE_SOCK_Acceptor::accept"); + ACE_HANDLE new_handle = this->shared_accept (remote_addr, timeout, restart); + new_stream.set_handle (new_handle); + return new_handle == ACE_INVALID_HANDLE ? -1 : 0; +} + +// General purpose routine for performing server ACE_SOCK creation. + +ACE_SOCK_Acceptor::ACE_SOCK_Acceptor (const ACE_Addr &local_sap, + int reuse_addr, + int protocol_family, + int backlog, + int protocol) +{ + ACE_TRACE ("ACE_SOCK_Acceptor::ACE_SOCK_Acceptor"); + if (this->open (local_sap, reuse_addr, protocol_family, + backlog, protocol) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_SOCK_Acceptor")); +} + +void +ACE_SOCK_Acceptor::dump (void) const +{ + ACE_TRACE ("ACE_SOCK_Acceptor::dump"); +} + +// General purpose routine for performing server ACE_SOCK creation. + +int +ACE_SOCK_Acceptor::open (const ACE_Addr &local_sap, int reuse_addr, + int protocol_family, int backlog, + int protocol) +{ + ACE_TRACE ("ACE_SOCK_Acceptor::open"); + int one = 1; + int error = 0; + + if (ACE_SOCK::open (SOCK_STREAM, protocol_family, protocol) + == -1) + error = 1; + else if (reuse_addr && + this->set_option (SOL_SOCKET, SO_REUSEADDR, + &one, sizeof one) == -1) + error = 1; + else if (&local_sap == &ACE_Addr::sap_any + && protocol_family == PF_INET) + { + if (ACE::bind_port (this->get_handle ()) == -1) + error = 1; + } + else if (ACE_OS::bind (this->get_handle (), (sockaddr *) local_sap.get_addr (), + local_sap.get_size ()) == -1) + error = 1; + + if (error || ACE_OS::listen (this->get_handle (), backlog) == -1) + this->close (); + + return error ? -1 : 0; +} + +// Performs the timed accept operation. + +ACE_HANDLE +ACE_SOCK_Acceptor::shared_accept (ACE_Addr *remote_addr, + ACE_Time_Value *timeout, + int restart) const +{ + ACE_TRACE ("ACE_SOCK_Acceptor::shared_accept"); + sockaddr *addr = 0; + int *len_ptr = 0; + int len; + ACE_HANDLE new_handle; + + if (remote_addr != 0) + { + len = remote_addr->get_size (); + len_ptr = &len; + addr = (sockaddr *) remote_addr->get_addr (); + } + + // Handle the timeout case. + if (timeout != 0 && ACE::handle_timed_accept (this->get_handle (), timeout, restart) == -1) + return ACE_INVALID_HANDLE; + else + { + // Perform a blocking accept. + + do + new_handle = ACE_OS::accept (this->get_handle (), addr, len_ptr); + while (new_handle == ACE_INVALID_HANDLE && restart && errno == EINTR); + + // Reset the size of the addr (really only necessary for the + // UNIX domain sockets). + if (new_handle != ACE_INVALID_HANDLE && remote_addr != 0) + remote_addr->set_size (*len_ptr); + + return new_handle; + } +} diff --git a/ace/SOCK_Acceptor.h b/ace/SOCK_Acceptor.h new file mode 100644 index 00000000000..fd3c2534a92 --- /dev/null +++ b/ace/SOCK_Acceptor.h @@ -0,0 +1,81 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// SOCK_Acceptor.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SOCK_ACCEPTOR_H) +#define ACE_SOCK_ACCEPTOR_H + +#include "ace/SOCK_Stream.h" +#include "ace/Time_Value.h" + +class ACE_Export ACE_SOCK_Acceptor : public ACE_SOCK + // = TITLE + // Defines the format and interface for an ACE_SOCK ACE_Stream acceptor. +{ +public: + // = Initialization methods. + ACE_SOCK_Acceptor (void); + // Default constructor. + + ACE_SOCK_Acceptor (const ACE_Addr &local_sap, + int reuse_addr = 0, + int protocol_family = PF_INET, + int backlog = 5, + int protocol = 0); + // Initiate a passive mode socket. + + int open (const ACE_Addr &local_sap, + int reuse_addr = 0, + int protocol_family = PF_INET, + int backlog = 5, + int protocol = 0); + // Initiate a passive mode socket. + + // = Passive connection acceptance method. + int accept (ACE_SOCK_Stream &new_stream, + ACE_Addr *remote_addr = 0, + ACE_Time_Value *timeout = 0, + int restart = 1) const; + // Accept a new data transfer connection. A of 0 means + // block forever, a of {0, 0} means poll. == 1 + // means "restart if interrupted." + + // = Meta-type info + typedef ACE_INET_Addr PEER_ADDR; + typedef ACE_SOCK_Stream PEER_STREAM; + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + ACE_HANDLE shared_accept (ACE_Addr *remote_addr, + ACE_Time_Value *, + int restart) const; + // Shared by both the ACE_LSOCK_Acceptor and ACE_SOCK_Acceptor. + +private: + int get_remote_addr (ACE_Addr &) const; + // Do not allow this function to percolate up to this interface... +}; + +#if defined (__ACE_INLINE__) +#include "ace/SOCK_Acceptor.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_SOCK_ACCEPTOR_H */ diff --git a/ace/SOCK_Acceptor.i b/ace/SOCK_Acceptor.i new file mode 100644 index 00000000000..06b6b01401c --- /dev/null +++ b/ace/SOCK_Acceptor.i @@ -0,0 +1,8 @@ +/* -*- C++ -*- */ +// $Id$ + +// SOCK_Acceptor.i + +#include "ace/Log_Msg.h" + + diff --git a/ace/SOCK_CODgram.cpp b/ace/SOCK_CODgram.cpp new file mode 100644 index 00000000000..c8c4d88a6f7 --- /dev/null +++ b/ace/SOCK_CODgram.cpp @@ -0,0 +1,100 @@ +// SOCK_CODgram.cpp +// $Id$ + +/* Contains the definitions for the ACE_SOCK connection-oriented + datagram abstraction. */ + +#define ACE_BUILD_DLL +#include "ace/SOCK_CODgram.h" +#include "ace/Log_Msg.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_CODgram) + +void +ACE_SOCK_CODgram::dump (void) const +{ + ACE_TRACE ("ACE_SOCK_CODgram::dump"); +} + +/* Here's the general-purpose constructor. */ + +ACE_SOCK_CODgram::ACE_SOCK_CODgram (const ACE_Addr &remote, const ACE_Addr &local, + int protocol_family, int protocol) +{ + ACE_TRACE ("ACE_SOCK_CODgram::ACE_SOCK_CODgram"); + if (this->open (remote, local, protocol_family, protocol) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_SOCK_CODgram")); +} + +/* This is the general-purpose open routine. Note that it performs + a different set of functions depending on the LOCAL and REMOTE + addresses passed to it. Here's the basic logic: + + 1. remote == ACE_Addr::sap_any && local == ACE_Addr::sap_any + if protocol_family == PF_INET then + bind the local address to a randomly generated port number... + + 2. remote == ACE_Addr::sap_any && local != ACE_Addr::sap_any + we are just binding the local address + (used primarily by servers) + + 3. remote != ACE_Addr::sap_any && local == ACE_Addr::sap_any + we are connecting to the remote address + (used primarily by clients) + + 4. remote != ACE_Addr::sap_any && local != ACE_Addr::sap_any + we are binding to the local address + and connecting to the remote address +*/ + +int +ACE_SOCK_CODgram::open (const ACE_Addr &remote, const ACE_Addr &local, + int protocol_family, int protocol) +{ + ACE_TRACE ("ACE_SOCK_CODgram::open"); + if (ACE_SOCK::open (SOCK_DGRAM, protocol_family, protocol) == -1) + return -1; + else + { + int error = 0; + + if (&local == &ACE_Addr::sap_any && &remote == &ACE_Addr::sap_any) + { + /* Assign an arbitrary port number from the transient range!! */ + + if (protocol_family == PF_INET + && ACE::bind_port (this->get_handle ()) == -1) + error = 1; + } + /* We are binding just the local address. */ + else if (&local != &ACE_Addr::sap_any && &remote == &ACE_Addr::sap_any) + { + if (ACE_OS::bind (this->get_handle (), (sockaddr *) local.get_addr (), + local.get_size ()) == -1) + error = 1; + } + /* We are connecting to the remote address. */ + else if (&local == &ACE_Addr::sap_any && &remote != &ACE_Addr::sap_any) + { + if (ACE_OS::connect (this->get_handle (), (sockaddr *) remote.get_addr (), + remote.get_size ()) == -1) + error = 1; + } + /* We are binding to the local address and connecting to the + remote addresses. */ + else + { + if (ACE_OS::bind (this->get_handle (), (sockaddr *) local.get_addr (), + local.get_size ()) == -1 + || ACE_OS::connect (this->get_handle (), (sockaddr *) remote.get_addr (), + remote.get_size ()) == -1) + error = 1; + } + if (error) + { + this->close (); + this->set_handle (ACE_INVALID_HANDLE); + } + return error ? -1 : 0; + } +} diff --git a/ace/SOCK_CODgram.h b/ace/SOCK_CODgram.h new file mode 100644 index 00000000000..008a5a6f60e --- /dev/null +++ b/ace/SOCK_CODgram.h @@ -0,0 +1,55 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// SOCK_CODgram.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SOCK_CODGRAM_H) +#define ACE_SOCK_CODGRAM_H + +#include "ace/SOCK_IO.h" +#include "ace/Addr.h" + +class ACE_Export ACE_SOCK_CODgram : public ACE_SOCK_IO + // = TITLE + // Defines the member functions for the ACE_SOCK connected + // datagram abstraction. +{ +public: + // = Initialization methods. + ACE_SOCK_CODgram (void); + // Default constructor. + + ACE_SOCK_CODgram (const ACE_Addr &remote_sap, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int protocol_family = PF_INET, + int protocol = 0); + // Initiate a connected dgram. + + int open (const ACE_Addr &remote_sap, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int protocol_family = PF_INET, + int protocol = 0); + // Initiate a connected dgram. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#include "ace/SOCK_CODgram.i" + +#endif /* ACE_SOCK_CODGRAM_H */ diff --git a/ace/SOCK_CODgram.i b/ace/SOCK_CODgram.i new file mode 100644 index 00000000000..8f72a5b117c --- /dev/null +++ b/ace/SOCK_CODgram.i @@ -0,0 +1,12 @@ +/* -*- C++ -*- */ +// $Id$ + +// SOCK_CODgram.i + +inline +ACE_SOCK_CODgram::ACE_SOCK_CODgram (void) +{ + ACE_TRACE ("ACE_SOCK_CODgram::ACE_SOCK_CODgram"); +} + + diff --git a/ace/SOCK_Connector.cpp b/ace/SOCK_Connector.cpp new file mode 100644 index 00000000000..ad904cd6c19 --- /dev/null +++ b/ace/SOCK_Connector.cpp @@ -0,0 +1,152 @@ +// SOCK_Connector.cpp +// $Id$ + + +#define ACE_BUILD_DLL +#include "ace/SOCK_Connector.h" +#include "ace/Handle_Set.h" +#include "ace/INET_Addr.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Connector) + +void +ACE_SOCK_Connector::dump (void) const +{ + ACE_TRACE ("ACE_SOCK_Connector::dump"); +} + +// Actively connect and produce a new ACE_SOCK_Stream if things go well... + +int +ACE_SOCK_Connector::connect (ACE_SOCK_Stream &new_stream, + const ACE_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms, + int protocol_family, + int protocol) +{ + ACE_TRACE ("ACE_SOCK_Connector::connect"); + int result = 0; + + // Only open a new socket if we don't already have a valid handle. + if (new_stream.get_handle () == ACE_INVALID_HANDLE) + { + if (ACE_SOCK::open (SOCK_STREAM, protocol_family, protocol) == -1) + return -1; + } + else // Borrow the handle from the NEW_STREAM. + this->set_handle (new_stream.get_handle ()); + + sockaddr *raddr = (sockaddr *) remote_sap.get_addr (); + size_t rsize = remote_sap.get_size (); + + if (&local_sap != &ACE_Addr::sap_any) + { + // Bind the local endpoint to a specific addr. + + int one = 1; + if (reuse_addr && this->set_option (SOL_SOCKET, SO_REUSEADDR, + &one, sizeof one) == -1) + result = -1; + else + { + sockaddr *laddr = (sockaddr *) local_sap.get_addr (); + size_t size = local_sap.get_size (); + result = ACE_OS::bind (this->get_handle (), laddr, size); + } + if (result == -1) + { + this->close (); + return -1; + } + } + + // Enable non-blocking, if required. + if (timeout != 0) + { + if (this->enable (ACE_NONBLOCK) == -1) + result = -1; + + if (ACE_OS::connect (this->get_handle (), raddr, rsize) == -1) + { + result = -1; + + // Check whether the connection is in progress. + if (errno == EINPROGRESS || errno == EWOULDBLOCK) + { + // This expression checks if we were polling. + if (timeout->sec () == 0 && timeout->usec () == 0) + errno = EWOULDBLOCK; + // Wait synchronously + else if (this->complete (new_stream, 0, timeout) != -1) + return 0; + } + } + } + // Do a blocking connect. + else if (ACE_OS::connect (this->get_handle (), raddr, rsize) == -1) + result = -1; + + // EISCONN is treated specially since this routine may be used to check + // if we are already connected. + if (result != -1 || errno == EISCONN) + { + // If everything succeeded transfer ownership to . + new_stream.set_handle (this->get_handle ()); + this->set_handle (ACE_INVALID_HANDLE); + } + else if (!(errno == EWOULDBLOCK || errno == ETIMEDOUT)) + { + // If things have gone wrong, close down and return an error. + this->close (); + new_stream.set_handle (ACE_INVALID_HANDLE); + } + return result; +} + +// Try to complete a non-blocking connection. + +int +ACE_SOCK_Connector::complete (ACE_SOCK_Stream &new_stream, + ACE_Addr *remote_sap, + ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_SOCK_Connector::complete"); + ACE_HANDLE h = ACE::handle_timed_complete (this->get_handle (), tv); + + if (h == ACE_INVALID_HANDLE) + { + this->close (); + return -1; + } + else // We've successfully connected! + { + if (remote_sap != 0) + { + int len; + + len = remote_sap->get_size (); + sockaddr *addr = (sockaddr *) remote_sap->get_addr (); + + if (ACE_OS::getpeername (h, addr, &len) == -1) + { + this->close (); + return -1; + } + } + + // Transfer ownership. + new_stream.set_handle (this->get_handle ()); + + // Start out with non-blocking disabled on the . + new_stream.disable (ACE_NONBLOCK); + + this->set_handle (ACE_INVALID_HANDLE); + return 0; + } +} + + diff --git a/ace/SOCK_Connector.h b/ace/SOCK_Connector.h new file mode 100644 index 00000000000..226e862cb44 --- /dev/null +++ b/ace/SOCK_Connector.h @@ -0,0 +1,101 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// SOCK_Connector.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SOCK_CONNECTOR_H) +#define ACE_SOCK_CONNECTOR_H + +#include "ace/SOCK_Stream.h" +#include "ace/Time_Value.h" + +class ACE_Export ACE_SOCK_Connector : public ACE_SOCK + // = TITLE + // Defines an active connection factory for the socket wrappers. +{ +public: + // = Initialization routines. + ACE_SOCK_Connector (void); + // Default constructor. + + ACE_SOCK_Connector (ACE_SOCK_Stream &new_stream, + const ACE_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = 0, + int perms = 0, + int protocol_family = PF_INET, + int protocol = 0); + // Actively connect and produce a if things go well. + // The is the address that we are trying to connect + // with. The is the amount of time to wait to connect. + // If it's 0 then we block indefinitely. If *timeout == {0, 0} then + // the connection is done using non-blocking mode. In this case, if + // the connection can't be made immediately the value of -1 is + // returned with . If *timeout > {0, 0} then + // this is the amount of time to wait before timing out. If the + // time expires before the connection is made . + // The is the value of local address to bind to. If + // it's the default value of then the user is + // letting the OS do the binding. If == 1 then the + // is reused, even if it hasn't been cleanedup yet. + + int connect (ACE_SOCK_Stream &new_stream, + const ACE_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = 0, + int perms = 0, + int protcol_family = PF_INET, + int protocol = 0); + // Actively connect and produce a if things go well. + // The is the address that we are trying to connect + // with. The is the amount of time to wait to connect. + // If it's 0 then we block indefinitely. If *timeout == {0, 0} then + // the connection is done using non-blocking mode. In this case, if + // the connection can't be made immediately the value of -1 is + // returned with . If *timeout > {0, 0} then + // this is the amount of time to wait before timing out. If the + // time expires before the connection is made . + // The is the value of local address to bind to. If + // it's the default value of then the user is + // letting the OS do the binding. If == 1 then the + // is reused, even if it hasn't been cleanedup yet. + + // = Completion routine. + int complete (ACE_SOCK_Stream &new_stream, + ACE_Addr *remote_sap = 0, + ACE_Time_Value *timeout = 0); + // Try to complete a non-blocking connection. + // If connection completion is successful then contains + // the connected ACE_SOCK_Stream. If is non-NULL then it + // will contain the address of the connected peer. + + // = Meta-type info + typedef ACE_INET_Addr PEER_ADDR; + typedef ACE_SOCK_Stream PEER_STREAM; + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#include "ace/SOCK_Connector.i" + +#endif /* ACE_SOCK_CONNECTOR_H */ diff --git a/ace/SOCK_Connector.i b/ace/SOCK_Connector.i new file mode 100644 index 00000000000..391e2146e14 --- /dev/null +++ b/ace/SOCK_Connector.i @@ -0,0 +1,35 @@ +/* -*- C++ -*- */ +// $Id$ + +// SOCK_Connector.i + +#include "ace/Log_Msg.h" + +// This constructor is used by a client when it wants to connect to +// the specified REMOTE_SAP address using a blocking open. + +inline +ACE_SOCK_Connector::ACE_SOCK_Connector (ACE_SOCK_Stream &new_stream, + const ACE_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms, + int protocol_family, + int protocol) +{ + ACE_TRACE ("ACE_SOCK_Connector::ACE_SOCK_Connector"); + if (this->connect (new_stream, remote_sap, timeout, local_sap, + reuse_addr, flags, perms, protocol_family, protocol) == -1 + && timeout != 0 && !(errno == EWOULDBLOCK || errno == ETIMEDOUT)) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_SOCK_Connector::ACE_SOCK_Connector")); +} + +// Do-nothing constructor... + +inline +ACE_SOCK_Connector::ACE_SOCK_Connector (void) +{ + ACE_TRACE ("ACE_SOCK_Connector::ACE_SOCK_Connector"); +} diff --git a/ace/SOCK_Dgram.cpp b/ace/SOCK_Dgram.cpp new file mode 100644 index 00000000000..e6ccde3b011 --- /dev/null +++ b/ace/SOCK_Dgram.cpp @@ -0,0 +1,118 @@ +// SOCK_Dgram.cpp +// $Id$ + + +#define ACE_BUILD_DLL +#include "ace/SOCK_Dgram.h" +#include "ace/Log_Msg.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Dgram) + +void +ACE_SOCK_Dgram::dump (void) const +{ + ACE_TRACE ("ACE_SOCK_Dgram::dump"); +} + +// Here's the shared open function. Note that if we are using the +// PF_INET protocol family and the address of LOCAL == the address of +// the special variable SAP_ANY then we are going to arbitrarily bind +// to a portnumber. + +int +ACE_SOCK_Dgram::shared_open (const ACE_Addr &local, int protocol_family) +{ + ACE_TRACE ("ACE_SOCK_Dgram::shared_open"); + int error = 0; + + if (&local == &ACE_Addr::sap_any && protocol_family == PF_INET) + { + if (ACE::bind_port (this->get_handle ()) == -1) + error = 1; + } + else if (ACE_OS::bind (this->get_handle (), (sockaddr *) local.get_addr (), + local.get_size ()) == -1) + error = 1; + + if (error) + this->close (); + + return error ? -1 : 0; +} + +// Here's the general-purpose constructor used by a connectionless +// datagram ``server''... + +ACE_SOCK_Dgram::ACE_SOCK_Dgram (const ACE_Addr &local, + int protocol_family, + int protocol) + : ACE_SOCK (SOCK_DGRAM, protocol_family, protocol) +{ + ACE_TRACE ("ACE_SOCK_Dgram::ACE_SOCK_Dgram"); + if (this->shared_open (local, protocol_family) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_SOCK_Dgram")); +} + +// Here's the general-purpose open routine. + +int +ACE_SOCK_Dgram::open (const ACE_Addr &local, + int protocol_family, + int protocol) +{ + ACE_TRACE ("ACE_SOCK_Dgram::open"); + if (ACE_SOCK::open (SOCK_DGRAM, protocol_family, + protocol) == -1) + return -1; + else + return this->shared_open (local, protocol_family); +} + +#if defined (ACE_HAS_MSG) +// Send an iovec of size N to ADDR as a datagram (connectionless +// version). + +ssize_t +ACE_SOCK_Dgram::send (const iovec iov[], + size_t n, + const ACE_Addr &addr, + int flags) const +{ + ACE_TRACE ("ACE_SOCK_Dgram::send"); + msghdr send_msg; + + send_msg.msg_iov = (iovec *) iov; + send_msg.msg_iovlen = n; + send_msg.msg_name = (char *) addr.get_addr (); + send_msg.msg_namelen = addr.get_size (); + send_msg.msg_accrights = 0; + send_msg.msg_accrightslen = 0; + return ACE_OS::sendmsg (this->get_handle (), &send_msg, flags); +} + +// Recv an iovec of size N to ADDR as a datagram (connectionless +// version). + +ssize_t +ACE_SOCK_Dgram::recv (iovec iov[], + size_t n, + ACE_Addr &addr, + int flags) const +{ + ACE_TRACE ("ACE_SOCK_Dgram::recv"); + msghdr recv_msg; + + recv_msg.msg_iov = (iovec *) iov; + recv_msg.msg_iovlen = n; + recv_msg.msg_name = (char *) addr.get_addr (); + recv_msg.msg_namelen = addr.get_size (); + recv_msg.msg_accrights = 0; + recv_msg.msg_accrightslen = 0; + + ssize_t status = ACE_OS::recvmsg (this->get_handle (), + &recv_msg, flags); + addr.set_size (recv_msg.msg_namelen); + return status; +} + +#endif /* ACE_HAS_MSG */ diff --git a/ace/SOCK_Dgram.h b/ace/SOCK_Dgram.h new file mode 100644 index 00000000000..7760a9e6356 --- /dev/null +++ b/ace/SOCK_Dgram.h @@ -0,0 +1,92 @@ +/* -*- C++ -*- */ +// $Id$ + + +// =========================================================================== +// +// = LIBRARY +// ace +// +// = FILENAME +// SOCK_Dgram.h +// +// = AUTHOR +// Doug Schmidt +// +// =========================================================================== + +#if !defined (ACE_SOCK_DGRAM_H) +#define ACE_SOCK_DGRAM_H + +#include "ace/SOCK.h" +#include "ace/Addr.h" + +class ACE_Export ACE_SOCK_Dgram : public ACE_SOCK + // = TITLE + // Defines the member functions for the ACE_SOCK datagram + // abstraction. +{ +public: + // = Initialization routines. + ACE_SOCK_Dgram (void); + // Default constructor. + + ACE_SOCK_Dgram (const ACE_Addr &local, + int protocol_family = PF_INET, + int protocol = 0); + // Initiate a socket dgram. + + int open (const ACE_Addr &local, + int protocol_family = PF_INET, + int protocol = 0); + // Initiate a socket dgram. + + // = Data transfer routines. + ssize_t send (const void *buf, + size_t n, + const ACE_Addr &addr, + int flags = 0) const; + // Send an byte to the datagram socket (uses sendto(3)). + + ssize_t recv (void *buf, + size_t n, + ACE_Addr &addr, + int flags = 0) const; + // Receive an byte from the datagram socket (uses + // recvfrom(3)). + +#if defined (ACE_HAS_MSG) + ssize_t send (const iovec iov[], + size_t n, + const ACE_Addr &addr, + int flags = 0) const; + // Send an of size to the datagram socket (uses + // sendmsg(3)). + + ssize_t recv (iovec iov[], + size_t n, + ACE_Addr &addr, + int flags = 0) const; + // Recv an of size to the datagram socket (uses + // recvmsg(3)). +#endif /* ACE_HAS_MSG */ + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + int shared_open (const ACE_Addr &local, + int protocol_family); + // Open is shared by this and by . + +private: + int get_remote_addr (ACE_Addr &) const; + // Do not allow this function to percolate up to this interface... +}; + +#include "ace/SOCK_Dgram.i" + +#endif /* ACE_SOCK_DGRAM_H */ diff --git a/ace/SOCK_Dgram.i b/ace/SOCK_Dgram.i new file mode 100644 index 00000000000..e88d3906f4c --- /dev/null +++ b/ace/SOCK_Dgram.i @@ -0,0 +1,45 @@ +/* -*- C++ -*- */ +// $Id$ + +// SOCK_Dgram.i + +// Here's the simple-minded constructor. + +inline +ACE_SOCK_Dgram::ACE_SOCK_Dgram (void) +{ + ACE_TRACE ("ACE_SOCK_Dgram::ACE_SOCK_Dgram"); +} + +// Send an N byte datagram to ADDR (connectionless version). + +inline ssize_t +ACE_SOCK_Dgram::send (const void *buf, + size_t n, + const ACE_Addr &addr, + int flags) const +{ + ACE_TRACE ("ACE_SOCK_Dgram::send"); + sockaddr *saddr = (sockaddr *) addr.get_addr (); + size_t len = addr.get_size (); + return ACE_OS::sendto (this->get_handle (), (const char *) buf, n, flags, + (struct sockaddr *) saddr, len); +} + +// Recv an n byte datagram to ADDR (connectionless version). + +inline ssize_t +ACE_SOCK_Dgram::recv (void *buf, + size_t n, + ACE_Addr &addr, + int flags) const +{ + ACE_TRACE ("ACE_SOCK_Dgram::recv"); + sockaddr *saddr = (sockaddr *) addr.get_addr (); + int addr_len = addr.get_size (); + + ssize_t status = ACE_OS::recvfrom (this->get_handle (), (char *) buf, n, flags, + (sockaddr *) saddr, &addr_len); + addr.set_size (addr_len); + return status; +} diff --git a/ace/SOCK_Dgram_Bcast.cpp b/ace/SOCK_Dgram_Bcast.cpp new file mode 100644 index 00000000000..b38fe768e6f --- /dev/null +++ b/ace/SOCK_Dgram_Bcast.cpp @@ -0,0 +1,243 @@ +// SOCK_Dgram_Bcast.cpp +// $Id$ + + +#define ACE_BUILD_DLL +#include "ace/SOCK_Dgram_Bcast.h" +#include "ace/Log_Msg.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Dgram_Bcast) + +ACE_Bcast_Node::ACE_Bcast_Node (ACE_INET_Addr &addr, + ACE_Bcast_Node *next) + : bcast_addr_ (addr), + next_ (next) +{ + ACE_TRACE ("ACE_Bcast_Node::ACE_Bcast_Node"); +} + +void +ACE_SOCK_Dgram_Bcast::dump (void) const +{ + ACE_TRACE ("ACE_SOCK_Dgram_Bcast::dump"); +} + +// Close up and release resources. + +int +ACE_SOCK_Dgram_Bcast::close (void) +{ + ACE_TRACE ("ACE_SOCK_Dgram_Bcast::close"); + + ACE_Bcast_Node *temp = this->if_list_; + + // Release the dynamically allocated memory. + while (temp != 0) + { + ACE_Bcast_Node *hold = temp->next_; + delete temp; + temp = hold; + } + + // Shut down the descriptor. + return ACE_SOCK::close (); +} + +// Here's the simple-minded constructor. + +ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast (void) + : if_list_ (0) +{ + ACE_TRACE ("ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast"); +} + +// Here's the general-purpose constructor used by a connectionless +// datagram ``server''... + +ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast (const ACE_Addr &local, + int protocol_family, + int protocol) + : ACE_SOCK_Dgram (local, protocol_family, protocol), + if_list_ (0) +{ + ACE_TRACE ("ACE_SOCK_Dgram_Bcast::ACE_SOCK_Dgram_Bcast"); + + if (this->mk_broadcast () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_SOCK_Dgram_Bcast")); +} + +// Here's the general-purpose open routine. + +int +ACE_SOCK_Dgram_Bcast::open (const ACE_Addr &local, + int protocol_family, + int protocol) +{ + ACE_TRACE ("ACE_SOCK_Dgram_Bcast::open"); + if (this->ACE_SOCK_Dgram::open (local, protocol_family, + protocol) == -1) + return -1; + + return this->mk_broadcast (); +} + +// Make broadcast available for Datagram socket. + +int +ACE_SOCK_Dgram_Bcast::mk_broadcast (void) +{ + ACE_TRACE ("ACE_SOCK_Dgram_Bcast::mk_broadcast"); + + int one = 1; + + if (ACE_OS::setsockopt (this->get_handle (), SOL_SOCKET, SO_BROADCAST, + (char *) &one, sizeof one) == -1) + return -1; + +#if !defined(ACE_WIN32) + char buf[BUFSIZ]; + struct ifconf ifc; + struct ifreq *ifr; + + struct ifreq flags; + struct ifreq if_req; + + int s = this->get_handle (); + + ifc.ifc_len = sizeof buf; + ifc.ifc_buf = buf; + + // Get interface structure and initialize the addresses using UNIX techniques. + if (ACE_OS::ioctl (s, SIOCGIFCONF, (char *) &ifc) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", + "ACE_SOCK_Dgram_Bcast::mk_broadcast: ioctl (get interface configuration)"), + ACE_INVALID_HANDLE); + + ifr = ifc.ifc_req; + + for (int n = ifc.ifc_len / sizeof (struct ifreq) ; n > 0; n--, ifr++) + { + + if (ifr->ifr_addr.sa_family != AF_INET) + { + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_SOCK_Dgram_Bcast::mk_broadcast: Not AF_INET")); + continue; + } + + flags = if_req = *ifr; + + if (ACE_OS::ioctl (s, SIOCGIFFLAGS, (char *) &flags) == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", + "ACE_SOCK_Dgram_Bcast::mk_broadcast: ioctl (get interface flags)")); + continue; + } + + if (ACE_BIT_ENABLED (flags.ifr_flags, IFF_UP) == 0) + { + ACE_ERROR ((LM_ERROR, "%p\n", + "ACE_SOCK_Dgram_Bcast::mk_broadcast: Network interface is not up")); + continue; + } + + if (ACE_BIT_ENABLED (flags.ifr_flags, IFF_LOOPBACK)) + continue; + + if (ACE_BIT_ENABLED (flags.ifr_flags, IFF_BROADCAST)) + { + if (ACE_OS::ioctl (s, SIOCGIFBRDADDR, (char *) &if_req) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", + "ACE_SOCK_Dgram_Bcast::mk_broadcast: ioctl (get broadaddr)")); + else + { + ACE_INET_Addr addr ((sockaddr_in *) &if_req.ifr_broadaddr, + sizeof if_req.ifr_broadaddr); + ACE_NEW_RETURN (this->if_list_, ACE_Bcast_Node (addr, this->if_list_), -1); + } + } + else + ACE_ERROR ((LM_ERROR, "%p\n", + "ACE_SOCK_Dgram_Bcast::mk_broadcast: Broadcast is not enable for this interface.")); + } +#else + ACE_INET_Addr addr (u_short (0), ACE_UINT32 (INADDR_BROADCAST)); + ACE_NEW_RETURN (this->if_list_, ACE_Bcast_Node (addr, this->if_list_), -1); +#endif /* !ACE_WIN32 */ + return this->if_list_ == 0 ? -1 : 0; +} + +// Broadcast the datagram to every interface. Returns the average +// number of bytes sent. + +ssize_t +ACE_SOCK_Dgram_Bcast::send (const void *buf, + size_t n, + u_short port_number, + int flags) const +{ + ACE_TRACE ("ACE_SOCK_Dgram_Bcast::send"); + size_t iterations = 0; + ssize_t total_bytes = 0; + + if (this->if_list_ == 0) + return -1; + + for (ACE_Bcast_Node *temp = this->if_list_; + temp != 0; + temp = temp->next_) + { + temp->bcast_addr_.set_port_number (port_number); + + ssize_t bytes_sent = ACE_SOCK_Dgram::send (buf, n, + temp->bcast_addr_, + flags); + + if (bytes_sent == -1) + return -1; + else + total_bytes += bytes_sent; + + iterations++; + } + + return iterations == 0 ? 0 : total_bytes / iterations; +} + +#if defined (ACE_HAS_MSG) +// Broadcast datagram to every interfaces. + +ssize_t +ACE_SOCK_Dgram_Bcast::send (const iovec iov[], + size_t n, + u_short port_number, + int flags) const +{ + ACE_TRACE ("ACE_SOCK_Dgram_Bcast::send"); + + if (this->if_list_ == 0) + return -1; + + // Send the message to every interface. + + for (ACE_Bcast_Node *temp = this->if_list_; temp != 0; temp++) + if (ACE_SOCK_Dgram::send (iov, n, temp->bcast_addr_, flags) == -1) + return -1; + + return 0; +} + +// Broadcast an ACE_IO_Vector of size N to ADDR as a datagram (note +// that addr must be preassigned to the broadcast address of the +// subnet...). + +ssize_t +ACE_SOCK_Dgram_Bcast::send (const iovec iov[], + size_t n, + const ACE_Addr &addr, + int flags) const +{ + ACE_TRACE ("ACE_SOCK_Dgram_Bcast::send"); + + return ACE_SOCK_Dgram::send (iov, n, addr, flags); +} +#endif /* ACE_HAS_MSG */ diff --git a/ace/SOCK_Dgram_Bcast.h b/ace/SOCK_Dgram_Bcast.h new file mode 100644 index 00000000000..f44270a37a9 --- /dev/null +++ b/ace/SOCK_Dgram_Bcast.h @@ -0,0 +1,106 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ + +// = LIBRARY +// ace +// +// = FILENAME +// SOCK_Dgram_Bcast.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SOCK_DGRAM_BCAST_H) +#define ACE_SOCK_DGRAM_BCAST_H + +#include "ace/INET_Addr.h" +#include "ace/SOCK_Dgram.h" + +struct ACE_Bcast_Node +{ + ACE_Bcast_Node (ACE_INET_Addr &, ACE_Bcast_Node *); + + ACE_INET_Addr bcast_addr_; + // Broadcast address for the interface. + + ACE_Bcast_Node *next_; + // Pointer to the next interface in the chain. +}; + +class ACE_Export ACE_SOCK_Dgram_Bcast : public ACE_SOCK_Dgram + // = TITLE + // Defines the member functions for the ACE_SOCK datagram + // abstraction. +{ +public: + // = Initialization and termination methods. + ACE_SOCK_Dgram_Bcast (void); + // Default constructor. + + ACE_SOCK_Dgram_Bcast (const ACE_Addr &local, + int protocol_family = PF_INET, + int protocol = 0); + // Initiate a connectionless datagram broadcast endpoint. + + int open (const ACE_Addr &local, + int protocol_family = PF_INET, + int protocol = 0); + // Initiate a connectionless datagram broadcast endpoint. + + int close (void); + // Close up and release dynamically allocated resources. + + ssize_t send (const void *buf, + size_t n, + u_short portnum, + int flags = 0) const; + // Broadcast the datagram to every interface. Returns the average + // number of bytes sent. + + ssize_t send (const iovec iov[], + size_t n, + u_short portnum, + int flags = 0) const; + // Broadcast the datagrams to every interface. Returns the + // average number of bytes sent. + + ssize_t send (const void *buf, + size_t n, + const ACE_Addr &addr, + int flags = 0) const; + // Broadcast an N byte datagram to ADDR (note that addr must be + // preassigned to the broadcast address of the subnet...). + + ssize_t send (const iovec iov[], + size_t n, + const ACE_Addr &addr, + int flags = 0) const; + // Broadcast an of size to as a datagram (note + // that addr must be preassigned to the broadcast address of the + // subnet...) */ + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + int mk_broadcast (void); + // Make broadcast available for Datagram socket. + + ACE_Bcast_Node *if_list_; + // Points to the head of the list of broadcast interfaces. + + int get_remote_addr (ACE_Addr &) const; + // Do not allow this function to percolate up to this interface... +}; + +#include "ace/SOCK_Dgram_Bcast.i" + +#endif /* ACE_SOCK_DGRAM_BCAST_H */ diff --git a/ace/SOCK_Dgram_Bcast.i b/ace/SOCK_Dgram_Bcast.i new file mode 100644 index 00000000000..8029354e2ae --- /dev/null +++ b/ace/SOCK_Dgram_Bcast.i @@ -0,0 +1,23 @@ +/* -*- C++ -*- */ +// $Id$ + +// SOCK_Dgram_Bcast.i + +// Broadcast an N byte datagram to ADDR (note that addr must be +// preassigned to the broadcast address of the subnet...) + +inline ssize_t +ACE_SOCK_Dgram_Bcast::send (const void *buf, + size_t n, + const ACE_Addr &addr, + int flags) const +{ + ACE_TRACE ("ACE_SOCK_Dgram_Bcast::send"); + + sockaddr *saddr = (sockaddr *) addr.get_addr (); + size_t len = addr.get_size (); + return ACE_OS::sendto (this->get_handle (), (const char *) buf, n, flags, + (struct sockaddr *) saddr, len); +} + + diff --git a/ace/SOCK_Dgram_Mcast.cpp b/ace/SOCK_Dgram_Mcast.cpp new file mode 100644 index 00000000000..9401653edc1 --- /dev/null +++ b/ace/SOCK_Dgram_Mcast.cpp @@ -0,0 +1,108 @@ +// SOCK_Dgram_Mcast.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/SOCK_Dgram_Mcast.h" +#include "ace/INET_Addr.h" + +#if defined (ACE_HAS_IP_MULTICAST) + +ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Dgram_Mcast) + +void +ACE_SOCK_Dgram_Mcast::dump (void) const +{ + ACE_TRACE ("ACE_SOCK_Dgram_Mcast::dump"); +} + +// Dummy default constructor... + +ACE_SOCK_Dgram_Mcast::ACE_SOCK_Dgram_Mcast (void) +{ + ACE_TRACE ("ACE_SOCK_Dgram_Mcast::ACE_SOCK_Dgram_Mcast"); +} + +int +ACE_SOCK_Dgram_Mcast::subscribe (const ACE_INET_Addr &mcast_addr, + int reuse_addr, + const char *net_if, + int protocol_family, + int protocol) +{ + ACE_TRACE ("ACE_SOCK_Dgram_Mcast::subscribe"); + // make a local copy of address to use in sends + this->mcast_addr_.set (mcast_addr); + + if (this->ACE_SOCK::open (SOCK_DGRAM, protocol_family, protocol) == -1) + return -1; + + // Create multicast request. + if (this->make_multicast_address (this->mcast_addr_, net_if) == -1) + return -1; + + int one = 1; + if (reuse_addr + && this->ACE_SOCK::set_option (SOL_SOCKET, + SO_REUSEADDR, + &one, + sizeof one) == -1) + return -1; + + // Create an address to bind the socket to. + + ACE_INET_Addr local; + + if (local.set (this->mcast_addr_.get_port_number ()) == -1) + return -1; + else if (ACE_SOCK_Dgram::shared_open (local, protocol_family) == -1) + return -1; + + // Tell network device driver to read datagrams with a + // multicast_address address. + else if (this->ACE_SOCK::set_option (IPPROTO_IP, + IP_ADD_MEMBERSHIP, + &multicast_address_, + sizeof multicast_address_) == -1) + return -1; + return 0; +} + +int +ACE_SOCK_Dgram_Mcast::unsubscribe (void) +{ + ACE_TRACE ("ACE_SOCK_Dgram_Mcast::unsubscribe"); + return this->ACE_SOCK::set_option (IPPROTO_IP, + IP_DROP_MEMBERSHIP, + &multicast_address_, + sizeof multicast_address_); +} + +int +ACE_SOCK_Dgram_Mcast::make_multicast_address (const ACE_INET_Addr &mcast_addr, + const char *net_if) +{ + ACE_TRACE ("ACE_SOCK_Dgram_Mcast::make_multicast_address"); + +#if !defined (ACE_WIN32) + if (net_if != 0) + { + struct ifreq if_address; + + ACE_OS::strcpy (if_address.ifr_name, net_if); + + if (ACE_OS::ioctl (this->get_handle (), SIOCGIFADDR, &if_address) < 0) + return -1; + + struct sockaddr_in *socket_address; + socket_address = (sockaddr_in *) &if_address.ifr_addr; + multicast_address_.imr_interface.s_addr = socket_address->sin_addr.s_addr; + } + else +#endif /* ACE_WIN32 */ + multicast_address_.imr_interface.s_addr = INADDR_ANY; + + multicast_address_.imr_multiaddr.s_addr = htonl (mcast_addr.get_ip_address ()); + // multicast_address_.imr_multiaddr.s_addr = mcast_addr.get_ip_address (); + return 0; +} +#endif /* ACE_HAS_IP_MULTICAST */ diff --git a/ace/SOCK_Dgram_Mcast.h b/ace/SOCK_Dgram_Mcast.h new file mode 100644 index 00000000000..586627e8a12 --- /dev/null +++ b/ace/SOCK_Dgram_Mcast.h @@ -0,0 +1,112 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// SOCK_Dgram_Mcast.h +// +// = AUTHORS +// Irfan Pyrali (ip1@cs.wustl.edu) +// Tim Harrison (harrison@cs.wustl.edu) +// +// ============================================================================ + +#if !defined (ACE_SOCK_DGRAM_MCAST_H) +#define ACE_SOCK_DGRAM_MCAST_H + +#include "ace/SOCK_Dgram.h" +#include "ace/INET_Addr.h" + +#if defined (ACE_HAS_IP_MULTICAST) +class ACE_Export ACE_SOCK_Dgram_Mcast : public ACE_SOCK_Dgram + // = TITLE + // Defines the member functions for the ACE_SOCK multicast abstraction. +{ +public: + // = Initialization routine. + ACE_SOCK_Dgram_Mcast (void); + // Note that there is no open (). This cannot be used unless you + // subscribe to the multicast group. If you just want to send (and + // not listen) to the multicast group, use ACE_SOCK_Dgram or + // ACE_SOCK_CODgram. + + // = Multicast group management routines. + + int subscribe (const ACE_INET_Addr &mcast_addr, + int reuse_addr = 1, + const char *net_if = 0, + int protocol_family = PF_INET, + int protocol = 0); + // Join a multicast group by telling the network interface device + // driver to accept datagrams with ACE_INET_Addr &mcast_addr + // multicast addresses. + // + // If you have called open already, subscribe closes the socket and + // opens a new socket bound to the mcast_addr. + // + // Interface is hardware specific. use netstat -i to find whether + // your interface is, say, le0 or something else. If net_if == 0, + // subscribe uses the default mcast interface. + // Returns: -1 on error, else 0. + + int unsubscribe (void); + // Unsubscribe from a multicast group. Returns 0 on success, -1 on + // failure. + + // = Data transfer routines. + ssize_t send (const void *buf, size_t n, int flags = 0) const; + // Send bytes in . + + ssize_t send (const iovec iov[], size_t n, int flags = 0) const; + // Send . + + // = Options. + int set_option (int option, char optval); + // Set an ip option that takes a char as input. + // e.g. IP_MULTICAST_LOOP. This is just a nice interface to a + // subset of possible setsockopt/ACE_SOCK::set_option calls Returns + // 0 on success, -1 on failure. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_HANDLE open (const ACE_Addr &local, + int protocol_family = PF_INET, + int protocol = 0); + // disable public use of ACE_SOCK_Dgram::open () + + // = Disable public use of ACE_SOCK_Dgram::sends and force + // ACE_SOCK_Dgram_Mcast::sends inline + ssize_t send (const void *buf, + size_t n, + const ACE_Addr &addr, + int flags = 0) const; + ssize_t send (const iovec iov[], + size_t n, + const ACE_Addr &addr, + int flags = 0) const; + + int make_multicast_address (const ACE_INET_Addr &mcast_addr, + const char *net_if = "le0"); + // Initialize a multicast address. + + ACE_INET_Addr mcast_addr_; + // Multicast group address. + + struct ip_mreq multicast_address_; + // IP address. +}; + +#include "ace/SOCK_Dgram_Mcast.i" + +#endif /* ACE_HAS_IP_MULTICAST */ +#endif /* ACE_SOCK_DGRAM_MCAST_H */ diff --git a/ace/SOCK_Dgram_Mcast.i b/ace/SOCK_Dgram_Mcast.i new file mode 100644 index 00000000000..835a3bbd135 --- /dev/null +++ b/ace/SOCK_Dgram_Mcast.i @@ -0,0 +1,31 @@ +/* -*- C++ -*- */ +// $Id$ + +// SOCK_Dgram_Mcast.i + +inline int +ACE_SOCK_Dgram_Mcast::set_option (int option, + char optval) +{ + ACE_TRACE ("ACE_SOCK_Dgram_Mcast::set_option"); + return this->ACE_SOCK::set_option (IPPROTO_IP, option, + &optval, sizeof (char)); +} + +inline ssize_t +ACE_SOCK_Dgram_Mcast::send (const void *buf, + size_t n, int flags) const +{ + ACE_TRACE ("ACE_SOCK_Dgram_Mcast::send"); + return this->ACE_SOCK_Dgram::send (buf, n, + this->mcast_addr_, flags); +} + +inline ssize_t +ACE_SOCK_Dgram_Mcast::send (const iovec iov[], + size_t n, int flags) const +{ + ACE_TRACE ("ACE_SOCK_Dgram_Mcast::send"); + return this->ACE_SOCK_Dgram::send (iov, n, + this->mcast_addr_, flags); +} diff --git a/ace/SOCK_IO.cpp b/ace/SOCK_IO.cpp new file mode 100644 index 00000000000..a09be6ce5a6 --- /dev/null +++ b/ace/SOCK_IO.cpp @@ -0,0 +1,114 @@ +// SOCK_IO.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/SOCK_IO.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_IO) + +void +ACE_SOCK_IO::dump (void) const +{ + ACE_TRACE ("ACE_SOCK_IO::dump"); +} + +// Allows a client to read from a socket without having to provide +// a buffer to read. This method determines how much data is in the +// socket, allocates a buffer of this size, reads in the data, and +// returns the number of bytes read. + +ssize_t +ACE_SOCK_IO::recv (iovec *io_vec) +{ +#if defined (FIONREAD) + u_long inlen; + + if (ACE_OS::ioctl (this->get_handle (), FIONREAD, + (u_long *) &inlen) == -1) + return -1; + else if (inlen > 0) + { + io_vec->iov_base = new char[inlen]; + io_vec->iov_len = this->recv (io_vec->iov_base, inlen); + return io_vec->iov_len; + } + else +#endif /* FIONREAD */ + // Could return ACE_NOTSUP_RETURN + return 0; +} + +// Send N char *ptrs and int lengths. Note that the char *'s precede +// the ints (basically, an varargs version of writev). The count N is +// the *total* number of trailing arguments, *not* a couple of the +// number of tuple pairs! + +ssize_t +ACE_SOCK_IO::send (size_t n, ...) const +{ + ACE_TRACE ("ACE_SOCK_IO::send"); + + va_list argp; + size_t total_tuples = n / 2; + ssize_t result; +#if defined (ACE_HAS_ALLOCA) + iovec *iovp = (iovec *) alloca (total_tuples * sizeof (iovec)); +#else + iovec *iovp; + ACE_NEW_RETURN (iovp, iovec[total_tuples], -1); +#endif /* !defined (ACE_HAS_ALLOCA) */ + + va_start (argp, n); + + for (size_t i = 0; i < total_tuples; i++) + { + iovp[i].iov_base = va_arg (argp, char *); + iovp[i].iov_len = va_arg (argp, int); + } + + result = ACE_OS::writev (this->get_handle (), iovp, total_tuples); +#if !defined (ACE_HAS_ALLOCA) + delete [] iovp; +#endif /* !defined (ACE_HAS_ALLOCA) */ + va_end (argp); + return result; +} + +// This is basically an interface to ACE_OS::readv, that doesn't use +// the struct iovec explicitly. The ... can be passed as an arbitrary +// number of (char *ptr, int len) tuples. However, the count N is the +// *total* number of trailing arguments, *not* a couple of the number +// of tuple pairs! + +ssize_t +ACE_SOCK_IO::recv (size_t n, ...) const +{ + ACE_TRACE ("ACE_SOCK_IO::recv"); + + va_list argp; + size_t total_tuples = n / 2; + ssize_t result; +#if defined (ACE_HAS_ALLOCA) + iovec *iovp = (iovec *) alloca (total_tuples * sizeof (iovec)); +#else + iovec *iovp; + + ACE_NEW_RETURN (iovp, iovec[total_tuples], -1); +#endif /* !defined (ACE_HAS_ALLOCA) */ + + va_start (argp, n); + + for (size_t i = 0; i < total_tuples; i++) + { + iovp[i].iov_base = va_arg (argp, char *); + iovp[i].iov_len = va_arg (argp, int); + } + + result = ACE_OS::readv (this->get_handle (), iovp, total_tuples); +#if !defined (ACE_HAS_ALLOCA) + delete [] iovp; +#endif /* !defined (ACE_HAS_ALLOCA) */ + va_end (argp); + return result; +} + diff --git a/ace/SOCK_IO.h b/ace/SOCK_IO.h new file mode 100644 index 00000000000..bc60e050a64 --- /dev/null +++ b/ace/SOCK_IO.h @@ -0,0 +1,74 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// SOCK_IO.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SOCK_IO_H) +#define ACE_SOCK_IO_H + +#include "ace/SOCK.h" + +class ACE_Export ACE_SOCK_IO : public ACE_SOCK + // = TITLE + // Defines the methods for the ACE_SOCK I/O routines (i.e., send/recv). +{ +public: + ssize_t send (const void *buf, size_t n, int flags) const; + // Send an n byte buffer to the connected socket (uses send(3)). + + ssize_t recv (void *buf, size_t n, int flags) const; + // Recv an n byte buffer from the connected socket (uses recv(3)). + + ssize_t send (const void *buf, size_t n) const; + // Send an n byte buffer to the connected socket (uses write(2)). + + ssize_t recv (void *buf, size_t n) const; + // Recv an n byte buffer from the connected socket (uses read(2)). + + ssize_t send (const iovec iov[], size_t n) const; + // Send a vector of n byte messages to the connected socket. + + ssize_t recv (iovec iov[], size_t n) const; + // Recv a vector of n byte messages to the connected socket. + + ssize_t send (size_t n, ...) const; + // Send varargs messages to the connected socket. + + ssize_t recv (size_t n, ...) const; + // Recv varargs messages to the connected socket. + + ssize_t send (const void *buf, size_t n, ACE_OVERLAPPED *overlapped) const; + // Send bytes via Win32 WriteFile using overlapped I/O. + + ssize_t recv (void *buf, size_t n, ACE_OVERLAPPED *overlapped) const; + // Recv bytes via Win32 ReadFile using overlapped I/O. + + ssize_t recv (iovec *io_vec); + // Allows a client to read from a socket without having to provide a + // buffer to read. This method determines how much data is in the + // socket, allocates a buffer of this size, reads in the data, and + // returns the number of bytes read. The caller is responsible for + // deleting the memory. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#include "ace/SOCK_IO.i" + +#endif /* ACE_SOCK_IO_H */ diff --git a/ace/SOCK_IO.i b/ace/SOCK_IO.i new file mode 100644 index 00000000000..bfc6450d286 --- /dev/null +++ b/ace/SOCK_IO.i @@ -0,0 +1,85 @@ +/* -*- C++ -*- */ +// $Id$ + +// SOCK_IO.i + +// Send an n byte message to the connected socket. + +inline ssize_t +ACE_SOCK_IO::send (const void *buf, size_t n, int flags) const +{ + ACE_TRACE ("ACE_SOCK_IO::send"); + return ACE_OS::send (this->get_handle (), (const char *) buf, n, flags); +} + +// Recv an n byte message from the connected socket. + +inline ssize_t +ACE_SOCK_IO::recv (void *buf, size_t n, int flags) const +{ + ACE_TRACE ("ACE_SOCK_IO::recv"); + return ACE_OS::recv (this->get_handle (), (char *) buf, n, flags); +} + +// Send an n byte message to the connected socket. + +inline ssize_t +ACE_SOCK_IO::send (const void *buf, size_t n) const +{ + ACE_TRACE ("ACE_SOCK_IO::send"); +#if defined (ACE_WIN32) + return ACE_OS::send (this->get_handle (), (const char *) buf, n, 0); +#else + return ACE_OS::write (this->get_handle (), (const char *) buf, n); +#endif /* ACE_WIN32 */ +} + +// Recv an n byte message from the connected socket. + +inline ssize_t +ACE_SOCK_IO::recv (void *buf, size_t n) const +{ + ACE_TRACE ("ACE_SOCK_IO::recv"); +#if defined (ACE_WIN32) + return ACE_OS::recv (this->get_handle (), (char *) buf, n, 0); +#else + return ACE_OS::read (this->get_handle (), (char *) buf, n); +#endif /* ACE_WIN32 */ +} + +// Send a vector of n byte messages to the connected socket. + +inline ssize_t +ACE_SOCK_IO::send (const iovec iov[], size_t n) const +{ + ACE_TRACE ("ACE_SOCK_IO::send"); + return ACE_OS::writev (this->get_handle (), (iovec *) iov, n); +} + +// Recv an n byte message from the connected socket. + +inline ssize_t +ACE_SOCK_IO::recv (iovec iov[], size_t n) const +{ + ACE_TRACE ("ACE_SOCK_IO::recv"); + return ACE_OS::readv (this->get_handle (), (iovec *) iov, n); +} + +inline ssize_t +ACE_SOCK_IO::send (const void *buf, size_t n, + ACE_OVERLAPPED *overlapped) const +{ + ACE_TRACE ("ACE_SOCK_IO::send"); + return ACE_OS::write (this->get_handle (), + (const char *) buf, n, + overlapped); +} + +inline ssize_t +ACE_SOCK_IO::recv (void *buf, size_t n, + ACE_OVERLAPPED *overlapped) const +{ + ACE_TRACE ("ACE_SOCK_IO::recv"); + return ACE_OS::read (this->get_handle (), (char *) buf, n, + overlapped); +} diff --git a/ace/SOCK_Stream.cpp b/ace/SOCK_Stream.cpp new file mode 100644 index 00000000000..0dc237200a9 --- /dev/null +++ b/ace/SOCK_Stream.cpp @@ -0,0 +1,16 @@ +// SOCK_Stream.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/SOCK_Stream.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_SOCK_Stream) + +void +ACE_SOCK_Stream::dump (void) const +{ + ACE_TRACE ("ACE_SOCK_Stream::dump"); +} + + + diff --git a/ace/SOCK_Stream.h b/ace/SOCK_Stream.h new file mode 100644 index 00000000000..3eceece50c2 --- /dev/null +++ b/ace/SOCK_Stream.h @@ -0,0 +1,69 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// SOCK_Stream.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SOCK_STREAM_H) +#define ACE_SOCK_STREAM_H + +#include "ace/SOCK_IO.h" +#include "ace/INET_Addr.h" + +class ACE_Export ACE_SOCK_Stream : public ACE_SOCK_IO + // = TITLE + // Defines the methods in the abstraction. + // + // = DESCRIPTION + // This adds additional wrapper methods atop the class. +{ +public: + //= The following two methods use write and read system calls, + //= which are faster than the send and recv library functions + //= used by the following two methods. + ssize_t send_n (const void *buf, int n) const; + // Send n bytes, keep trying until n are sent. + ssize_t recv_n (void *buf, int n) const; + // Recv n bytes, keep trying until n are received. + + // = The following two methods use the send and recv system + // = calls. + ssize_t send_n (const void *buf, int n, int flags) const; + // Send n bytes, keep trying until n are sent. + ssize_t recv_n (void *buf, int n, int flags) const; + // Recv n bytes, keep trying until n are received. + + // = Send/receive an ``urgent'' character (see TCP specs...). + ssize_t send_urg (void *ptr, int len = sizeof (char)); + ssize_t recv_urg (void *ptr, int len = sizeof (char)); + + // = Selectively close endpoints. + int close_reader (void); + // Close down the reader. + int close_writer (void); + // Close down the writer. + + // = Meta-type info + typedef ACE_INET_Addr PEER_ADDR; + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#include "ace/SOCK_Stream.i" + +#endif /* ACE_SOCK_STREAM_H */ diff --git a/ace/SOCK_Stream.i b/ace/SOCK_Stream.i new file mode 100644 index 00000000000..cd703bb834c --- /dev/null +++ b/ace/SOCK_Stream.i @@ -0,0 +1,81 @@ +/* -*- C++ -*- */ +// $Id$ + +// SOCK_Stream.i + +#include "ace/SOCK_Stream.h" + +// Shut down just the reading end of a ACE_SOCK. + +inline int +ACE_SOCK_Stream::close_reader (void) +{ + ACE_TRACE ("ACE_SOCK_Stream::close_reader"); + int result = ACE_OS::shutdown (this->get_handle (), 0); + return result; +} + +// Shut down just the writing end of a ACE_SOCK. + +inline int +ACE_SOCK_Stream::close_writer (void) +{ + ACE_TRACE ("ACE_SOCK_Stream::close_writer"); + int result = ACE_OS::shutdown (this->get_handle (), 1); + return result; +} + +// Receive exactly BUF_SIZE bytes from file descriptor this->handle +// into . Keep trying until this many bytes are received. + +inline ssize_t +ACE_SOCK_Stream::recv_n (void *buf, int buf_size, int flags) const +{ + ACE_TRACE ("ACE_SOCK_Stream::recv_n"); + return ACE::recv_n (this->get_handle (), buf, buf_size, flags); +} + +// Send exactly N bytes from to . Keeping trying +// until this many bytes are sent. + +inline ssize_t +ACE_SOCK_Stream::send_n (const void *buf, int buf_size, int flags) const +{ + ACE_TRACE ("ACE_SOCK_Stream::send_n"); + return ACE::send_n (this->get_handle (), buf, buf_size, flags); +} + +// Receive exactly BUF_SIZE bytes from file descriptor +// into BUF. Keep trying until this many bytes are received. + +inline ssize_t +ACE_SOCK_Stream::recv_n (void *buf, int buf_size) const +{ + ACE_TRACE ("ACE_SOCK_Stream::recv_n"); + return ACE::recv_n (this->get_handle (), buf, buf_size); +} + +// Send exactly N bytes from BUF to THIS->SOK_FD. Keeping trying +// until this many bytes are sent. + +inline ssize_t +ACE_SOCK_Stream::send_n (const void *buf, int buf_size) const +{ + ACE_TRACE ("ACE_SOCK_Stream::send_n"); + return ACE::send_n (this->get_handle (), buf, buf_size); +} + +inline ssize_t +ACE_SOCK_Stream::send_urg (void *ptr, int len) +{ + ACE_TRACE ("ACE_SOCK_Stream::send_urg"); + return ACE_OS::send (this->get_handle (), (char *) ptr, len, MSG_OOB); +} + +inline ssize_t +ACE_SOCK_Stream::recv_urg (void *ptr, int len) +{ + ACE_TRACE ("ACE_SOCK_Stream::recv_urg"); + return ACE_OS::recv (this->get_handle (), (char *) ptr, len, MSG_OOB); +} + diff --git a/ace/SPIPE.cpp b/ace/SPIPE.cpp new file mode 100644 index 00000000000..ff52532a8e6 --- /dev/null +++ b/ace/SPIPE.cpp @@ -0,0 +1,58 @@ +// SPIPE.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/SPIPE.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_SPIPE) + +// This is the do-nothing constructor. + +ACE_SPIPE::ACE_SPIPE (void) +{ + ACE_TRACE ("ACE_SPIPE::ACE_SPIPE"); +} + +void +ACE_SPIPE::dump (void) const +{ + ACE_TRACE ("ACE_SPIPE::dump"); +} + +// Close down a ACE_SPIPE. + +int +ACE_SPIPE::get_local_addr (ACE_SPIPE_Addr &local_sap) const +{ + ACE_TRACE ("ACE_SPIPE::get_local_addr"); + local_sap = this->local_addr_; + return 0; +} + +// Close down the STREAM pipe without removing the rendezvous point. + +int +ACE_SPIPE::close (void) +{ + ACE_TRACE ("ACE_SPIPE::close"); + int result = 0; + + if (this->get_handle () != ACE_INVALID_HANDLE) + { + result = ACE_OS::close (this->get_handle ()); + this->set_handle (ACE_INVALID_HANDLE); + } + return result; +} + +// Close down the STREAM pipe and remove the rendezvous point from the +// file system. + +int +ACE_SPIPE::remove (void) +{ + ACE_TRACE ("ACE_SPIPE::remove"); + int result = this->close (); + return ACE_OS::unlink (this->local_addr_.get_path_name ()) == -1 || result == -1 ? -1 : 0; +} + diff --git a/ace/SPIPE.h b/ace/SPIPE.h new file mode 100644 index 00000000000..527e5388616 --- /dev/null +++ b/ace/SPIPE.h @@ -0,0 +1,76 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// SPIPE.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SPIPE_H) +#define ACE_SPIPE_H + +#include "ace/IPC_SAP.h" +#include "ace/SPIPE_Addr.h" + +// The following is necessary since many C++ compilers don't support +// typedef'd types inside of classes used as formal template +// arguments... ;-(. Luckily, using the C++ preprocessor I can hide +// most of this nastiness! + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) +#define ACE_SPIPE_ACCEPTOR ACE_SPIPE_Acceptor +#define ACE_SPIPE_CONNECTOR ACE_SPIPE_Connector +#define ACE_SPIPE_STREAM ACE_SPIPE_Stream +#define ACE_UPIPE_ACCEPTOR ACE_UPIPE_Acceptor +#define ACE_UPIPE_CONNECTOR ACE_UPIPE_Connector +#define ACE_UPIPE_STREAM ACE_UPIPE_Stream +#else /* TEMPLATES are broken (must be a cfront-based compiler...) */ +#define ACE_SPIPE_ACCEPTOR ACE_SPIPE_Acceptor, ACE_SPIPE_Addr +#define ACE_SPIPE_CONNECTOR ACE_SPIPE_Connector, ACE_SPIPE_Addr +#define ACE_SPIPE_STREAM ACE_SPIPE_Stream, ACE_SPIPE_Addr +#define ACE_UPIPE_ACCEPTOR ACE_UPIPE_Acceptor, ACE_SPIPE_Addr +#define ACE_UPIPE_CONNECTOR ACE_UPIPE_Connector, ACE_SPIPE_Addr +#define ACE_UPIPE_STREAM ACE_UPIPE_Stream, ACE_SPIPE_Addr +#endif /* ACE_TEMPLATE_TYPEDEFS */ + +class ACE_Export ACE_SPIPE : public ACE_IPC_SAP + // = TITLE + // Defines the member functions for the base class of the + // ACE_SPIPE abstraction. +{ +public: + int close (void); + // Close down the STREAM pipe without removing the rendezvous point. + + int remove (void); + // Close down the STREAM pipe and remove the rendezvous point from + // the file system. + + int get_local_addr (ACE_SPIPE_Addr &) const; + // Return the local address of this endpoint. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + ACE_SPIPE (void); + // Ensure that this class is an abstract base class + + ACE_SPIPE_Addr local_addr_; + // Our local address. +}; + +#include "ace/SPIPE.i" +#endif /* ACE_SPIPE_H */ diff --git a/ace/SPIPE.i b/ace/SPIPE.i new file mode 100644 index 00000000000..d2db9a084c8 --- /dev/null +++ b/ace/SPIPE.i @@ -0,0 +1,6 @@ +/* -*- C++ -*- */ +// $Id$ + +// SPIPE.i + + diff --git a/ace/SPIPE_Acceptor.cpp b/ace/SPIPE_Acceptor.cpp new file mode 100644 index 00000000000..c3d7458257d --- /dev/null +++ b/ace/SPIPE_Acceptor.cpp @@ -0,0 +1,212 @@ +// SPIPE_Acceptor.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/SPIPE_Acceptor.h" +#include "ace/Log_Msg.h" + +ACE_SPIPE_Acceptor::ACE_SPIPE_Acceptor (void) +{ + ACE_TRACE ("ACE_SPIPE_Acceptor::ACE_SPIPE_Acceptor"); +} + +int +ACE_SPIPE_Acceptor::remove (void) +{ + ACE_TRACE ("ACE_SPIPE_Acceptor::remove"); + int result = this->close (); +#if defined (ACE_HAS_STREAM_PIPES) + // Remove the underlying file. + return ACE_OS::unlink (this->local_addr_.get_path_name ()) == -1 + || result == -1 ? -1 : 0; +#else + return 0; +#endif +} + +ACE_ALLOC_HOOK_DEFINE(ACE_SPIPE_Acceptor) + +void +ACE_SPIPE_Acceptor::dump (void) const +{ + ACE_TRACE ("ACE_SPIPE_Acceptor::dump"); +} + +// General purpose routine for performing server ACE_SPIPE creation. + +int +ACE_SPIPE_Acceptor::open (const ACE_SPIPE_Addr &local_sap, + int reuse_addr, + int perms) +{ + ACE_TRACE ("ACE_SPIPE_Acceptor::open"); + + this->local_addr_ = local_sap; + this->set_handle (ACE_INVALID_HANDLE); + + return this->create_new_instance (perms); +} + +int +ACE_SPIPE_Acceptor::create_new_instance (int perms) +{ +#if defined (ACE_HAS_STREAM_PIPES) + ACE_HANDLE handle; + ACE_HANDLE spipe[2]; + + handle = ACE_OS::creat (this->local_addr_.get_path_name (), perms); + + if (handle == ACE_INVALID_HANDLE) + return -1; + else if (ACE_OS::close (handle) == -1) + return -1; + else if (ACE_OS::pipe (spipe) == -1) + return -1; + else if (ACE_OS::ioctl (spipe[0], I_PUSH, "connld") == -1) + return -1; + else if (ACE_OS::fattach (spipe[0], this->local_addr_.get_path_name ()) == -1) + return -1; + + this->set_handle (spipe[1]); + return 0; +#elif defined (ACE_WIN32) + // Create a new instance of the Named Pipe (WIN32). A new instance + // of the named pipe must be created for every client process. If an + // instance of the named pipe that is already connected to a client + // process is reused with a new client process, ::ConnectNamedPipe() + // would fail. + + ACE_TRACE ("ACE_SPIPE_Acceptor::create_new_instance"); + + // Create a new instance of the named pipe + ACE_HANDLE handle = ::CreateNamedPipe (this->local_addr_.get_path_name (), + PIPE_ACCESS_DUPLEX | + FILE_FLAG_OVERLAPPED, + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, + MAX_PIPE_INSTANCES, + 1024*10, + 1024*10, + ACE_DEFAULT_TIMEOUT, + NULL); + if (handle == ACE_INVALID_HANDLE) + return -1; + else + this->set_handle (handle); + return 0; +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STREAM_PIPES */ +} + +int +ACE_SPIPE_Acceptor::close (void) +{ + ACE_TRACE ("ACE_SPIPE_Acceptor::close"); + + // This behavior is shared by UNIX and Win32... + int result = this->ACE_SPIPE::close (); + this->set_handle (ACE_INVALID_HANDLE); + +#if defined (ACE_HAS_STREAM_PIPES) + ACE_OS::fdetach (this->local_addr_.get_path_name ()); +#endif /* ACE_HAS_STREAM_PIPES */ + return result; +} + +ACE_INLINE +ACE_SPIPE_Acceptor::ACE_SPIPE_Acceptor (const ACE_SPIPE_Addr &local_sap, + int reuse_addr, + int perms) +{ + ACE_TRACE ("ACE_SPIPE_Acceptor::ACE_SPIPE_Acceptor"); + + if (this->open (local_sap, reuse_addr, perms) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_SPIPE_Acceptor")); +} + +// General purpose routine for accepting new connections. + +int +ACE_SPIPE_Acceptor::accept (ACE_SPIPE_Stream &new_io, + ACE_SPIPE_Addr *remote_addr, + ACE_Time_Value *timeout, + int restart) +{ + ACE_TRACE ("ACE_SPIPE_Acceptor::accept"); +#if defined (ACE_HAS_STREAM_PIPES) + strrecvfd r_handle; + + // Note that if THIS->MILLI_SECOND_DELAY == -1 we block on + // ACE_OS::ioctl(). Otherwise, we will wait for the desired number + // of milli seconds using ACE_OS::poll. + + if (timeout != 0 && + ACE::handle_timed_accept (this->get_handle (), timeout, restart) == -1) + return -1; + else if (ACE_OS::ioctl (this->get_handle (), I_RECVFD, &r_handle) == -1) + return -1; + + new_io.set_handle (r_handle.fd); + new_io.local_addr_ = this->local_addr_; + new_io.remote_addr_.set_size (sizeof r_handle.gid + sizeof r_handle.uid); + new_io.remote_addr_.group_id (r_handle.gid); + new_io.remote_addr_.user_id (r_handle.uid); + + // This is for compatibility with ACE_SOCK_Acceptor and + // ACE_TLI_Acceptor. + if (remote_addr != 0) + *remote_addr = new_io.remote_addr_; + + return 0; +#elif defined (ACE_WIN32) + // Check to see if we have a valid pipe + if (this->get_handle () == ACE_INVALID_HANDLE) + return -1; + + // Accept connection on the current instance of the named pipe Note + // that the connection is done synchronously, by specifying a NULL + // OVERLAPPED structure pointer. + + int attempts = 0; + + for (;;) + { + attempts++; + + if (::ConnectNamedPipe (this->get_handle (), NULL) != 0) + break; + + DWORD error = ::GetLastError (); + + if (error == ERROR_NO_DATA) + { + // A client connected and disconnected in the interval + // between the creation of the named pipe instance and the + // call to ::ConnectNamedPipe (). The named pipe handle + // must be disconnected from this fleeting client before it + // can be reconnected to new client. + + if (attempts > MAX_ACCEPT_ATTEMPTS) + return -1; + else if (::DisconnectNamedPipe (this->get_handle ()) != 0) + return -1; + // Loop and make another connection attempt. + } + else if (error == ERROR_PIPE_CONNECTED) + // A client connected in the interval between the creation of + // the named pipe instance and the call to ::ConnectNamedPipe + // (). However, the connection is alright. + break; + else // Unrecoverable connection failure, so let's bail out... + return -1; + } + + new_io.set_handle (this->get_handle ()); + new_io.local_addr_ = this->local_addr_; + + // Create a new instance of the pipe for the next connection. + return this->create_new_instance (); +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STREAM_PIPES */ +} diff --git a/ace/SPIPE_Acceptor.h b/ace/SPIPE_Acceptor.h new file mode 100644 index 00000000000..a5d45aa3b42 --- /dev/null +++ b/ace/SPIPE_Acceptor.h @@ -0,0 +1,78 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// SPIPE_Acceptor.h +// +// = AUTHOR +// Doug Schmidt and Prashant Jain +// +// ============================================================================ + +#if !defined (ACE_SPIPE_ACCEPTOR_H) +#define ACE_SPIPE_ACCEPTOR_H + +#include "ace/SPIPE_Stream.h" + +class ACE_Export ACE_SPIPE_Acceptor : public ACE_SPIPE + // = TITLE + // Defines the format and interface for the listener side of the + // ACE_SPIPE_Stream. +{ +public: +#if defined (ACE_WIN32) + // = Maximum number of attempts to accept a connection + enum + { + MAX_PIPE_INSTANCES = PIPE_UNLIMITED_INSTANCES, + MAX_ACCEPT_ATTEMPTS = 3 + }; +#endif + + // = Initialization and termination methods. + ACE_SPIPE_Acceptor (void); + // Default constructor. + + ACE_SPIPE_Acceptor (const ACE_SPIPE_Addr &local_sap, + int reuse_addr = 1, + int perms = ACE_DEFAULT_PERMS); + // Initiate a passive-mode STREAM pipe listener. + + int open (const ACE_SPIPE_Addr &local_sap, + int reuse_addr = 1, + int perms = ACE_DEFAULT_PERMS); + // Initiate a passive-mode STREAM pipe listener. + + int close (void); + // Close down the passive-mode STREAM pipe listener. + + int remove (void); + // Remove the underlying mounted pipe from the file system. + + // = Passive connection acceptance method. + int accept (ACE_SPIPE_Stream &ipc_sap_spipe, + ACE_SPIPE_Addr *remote_addr = 0, + ACE_Time_Value *timeout = 0, + int restart = 1); + // Accept a new data transfer connection. A of 0 means + // block forever, a of {0, 0} means poll. == 1 + // means "restart if interrupted." + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +private: + + int create_new_instance (int perms = 0); + // Create a new instance of an SPIPE. +}; + +#endif /* ACE_SPIPE_ACCEPTOR_H */ diff --git a/ace/SPIPE_Acceptor.i b/ace/SPIPE_Acceptor.i new file mode 100644 index 00000000000..441ff5a6232 --- /dev/null +++ b/ace/SPIPE_Acceptor.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// $Id$ + +// SPIPE_Acceptor.i diff --git a/ace/SPIPE_Addr.cpp b/ace/SPIPE_Addr.cpp new file mode 100644 index 00000000000..09bbc573c7a --- /dev/null +++ b/ace/SPIPE_Addr.cpp @@ -0,0 +1,110 @@ +// SPIPE_Addr.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/SPIPE_Addr.h" + +#if !defined (__ACE_INLINE__) +#include "ace/SPIPE_Addr.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_SPIPE_Addr) + +void +ACE_SPIPE_Addr::dump (void) const +{ +} + +// Set a pointer to the address. +void +ACE_SPIPE_Addr::set_addr (void *addr, int len) +{ + ACE_TRACE ("ACE_SPIPE_Addr::set_addr"); + + this->ACE_Addr::base_set (AF_SPIPE, len); + ACE_OS::memcpy ((void *) &this->SPIPE_addr_, + (void *) addr, + len); +} + +// Do nothing constructor. + +ACE_SPIPE_Addr::ACE_SPIPE_Addr (void) + : ACE_Addr (AF_SPIPE, sizeof this->SPIPE_addr_) +{ + (void) ACE_OS::memset ((void *) &this->SPIPE_addr_, 0, + sizeof this->SPIPE_addr_); +} + +// Transform the string into the current addressing format. + +int +ACE_SPIPE_Addr::string_to_addr (LPCTSTR addr) +{ + return this->set (addr); +} + +/* Copy constructor. */ + +ACE_SPIPE_Addr::ACE_SPIPE_Addr (const ACE_SPIPE_Addr &sa) + : ACE_Addr (AF_SPIPE, + sizeof this->SPIPE_addr_.gid_ + sizeof this->SPIPE_addr_.uid_ + + ACE_OS::strlen (this->SPIPE_addr_.rendezvous_) + 1) +{ + (void) ACE_OS::memcpy ((void *) &this->SPIPE_addr_, (void *) + &sa.SPIPE_addr_, sa.get_size ()); +} + +int +ACE_SPIPE_Addr::set (LPCTSTR addr, + gid_t gid, + uid_t uid) +{ + int len = sizeof (this->SPIPE_addr_.uid_); + len += sizeof(this->SPIPE_addr_.gid_); + +#if defined (ACE_WIN32) + char *colonp = ACE_OS::strchr (addr, ':'); + char temp[BUFSIZ] ; + + if (colonp == 0) // Assume it's a port number. + { + ACE_OS::strcpy(temp, "\\\\.\\pipe\\") ; + ACE_OS::strcat(temp, addr) ; + } + else + { + ACE_OS::strcpy(temp, "\\\\") ; + *colonp = '\0'; + if (ACE_OS::strcmp(addr, "localhost") == 0) + ACE_OS::strcat(temp, ".") ; // change localhost to . + else + ACE_OS::strcat(temp, addr) ; + ACE_OS::strcat(temp, "\\pipe\\" ) ; + ACE_OS::strcat(temp, colonp+1) ; + } + + this->ACE_Addr::base_set (AF_SPIPE, + ACE_OS::strlen (temp) + len); + ACE_OS::strcpy(this->SPIPE_addr_.rendezvous_, temp) ; + +#else + this->ACE_Addr::base_set (AF_SPIPE, ACE_OS::strlen (addr) + len); + ACE_OS::strncpy (this->SPIPE_addr_.rendezvous_, addr, + sizeof this->SPIPE_addr_.rendezvous_); +#endif + + this->SPIPE_addr_.gid_ = gid == 0 ? ACE_OS::getgid () : gid; + this->SPIPE_addr_.uid_ = uid == 0 ? ACE_OS::getuid () : uid; + return 0; +} + +// Create a ACE_Addr from a ACE_SPIPE pathname. + +ACE_SPIPE_Addr::ACE_SPIPE_Addr (LPCTSTR addr, + gid_t gid, + uid_t uid) +{ + this->set (addr, gid, uid); +} + diff --git a/ace/SPIPE_Addr.h b/ace/SPIPE_Addr.h new file mode 100644 index 00000000000..142e754c322 --- /dev/null +++ b/ace/SPIPE_Addr.h @@ -0,0 +1,101 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// SPIPE_Addr.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SPIPE_ADDR_H) +#define ACE_SPIPE_ADDR_H +#include "ace/Addr.h" +#include "ace/ACE.h" + +class ACE_Export ACE_SPIPE_Addr : public ACE_Addr + // = TITLE + // Defines the SVR4 STREAM pipe address family address format. +{ +public: + // = Initialization methods. + ACE_SPIPE_Addr (void); + // Default constructor. + + ACE_SPIPE_Addr (const ACE_SPIPE_Addr &sa); + // Copy constructor. + + ACE_SPIPE_Addr (LPCTSTR rendezvous_point, gid_t = 0, uid_t = 0); + // Create a ACE_SPIPE_Addr from a rendezvous point in the file system. + + int set (LPCTSTR rendezvous_point, gid_t = 0, uid_t = 0); + // Create a ACE_SPIPE_Addr from a rendezvous point in the file system. + + virtual void *get_addr (void) const; + // Return a pointer to the address. + + virtual void set_addr (void *addr, int len); + // Set a pointer to the underlying network address. + + virtual int addr_to_string (char addr[], size_t) const; + // Transform the current address into string format. + + virtual int string_to_addr (LPCTSTR addr); + // Transform the string into the current addressing format. + + // = Equality/inequality tests + virtual int operator == (const ACE_Addr &SAP) const; + // Check for equality. + + virtual int operator != (const ACE_Addr &SAP) const; + // Check for inequality + + // = SPIPE-specific address operations + LPCTSTR get_path_name (void) const; + // Pathname of rendezvous point in file system. + + uid_t user_id (void) const; + // Get user id. + void user_id (uid_t uid); + // Set user id. + + void group_id (gid_t gid); + // Set group ids. + gid_t group_id (void) const; + // Get group ids. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + // = This struct contains security attributes. + struct + { + gid_t gid_; + // Group id. + + uid_t uid_; + // User id. + + TCHAR rendezvous_[MAXNAMLEN + 1]; + // Pathname in the file system. + + } SPIPE_addr_; + // Contents of an SPIPE address. +}; + +#if defined (__ACE_INLINE__) +#include "ace/SPIPE_Addr.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_SPIPE_ADDR_H */ diff --git a/ace/SPIPE_Addr.i b/ace/SPIPE_Addr.i new file mode 100644 index 00000000000..358fbc29cfd --- /dev/null +++ b/ace/SPIPE_Addr.i @@ -0,0 +1,70 @@ +/* -*- C++ -*- */ +// $Id$ + +// SPIPE_Addr.i + +// Transform the current address into string format. + +ACE_INLINE int +ACE_SPIPE_Addr::addr_to_string (char s[], size_t len) const +{ + ACE_OS::strncpy (s, this->SPIPE_addr_.rendezvous_, len); + return 0; +} + +// Return the address. + +ACE_INLINE void * +ACE_SPIPE_Addr::get_addr (void) const +{ + return (void *) &this->SPIPE_addr_; +} + +// Compare two addresses for equality. + +ACE_INLINE int +ACE_SPIPE_Addr::operator == (const ACE_Addr &sap) const +{ + return ACE_OS::strcmp (this->SPIPE_addr_.rendezvous_, + ((ACE_SPIPE_Addr &) sap).SPIPE_addr_.rendezvous_) == 0; +} + +// Compare two addresses for inequality. + +ACE_INLINE int +ACE_SPIPE_Addr::operator != (const ACE_Addr &sap) const +{ + return !((*this) == sap); // This is lazy, of course... ;-) +} + +// Return the path name used for the rendezvous point. + +ACE_INLINE LPCTSTR +ACE_SPIPE_Addr::get_path_name (void) const +{ + return this->SPIPE_addr_.rendezvous_; +} + +ACE_INLINE uid_t +ACE_SPIPE_Addr::user_id (void) const +{ + return this->SPIPE_addr_.uid_; +} + +ACE_INLINE void +ACE_SPIPE_Addr::user_id (uid_t uid) +{ + this->SPIPE_addr_.uid_ = uid; +} + +ACE_INLINE gid_t +ACE_SPIPE_Addr::group_id (void) const +{ + return this->SPIPE_addr_.gid_; +} + +ACE_INLINE void +ACE_SPIPE_Addr::group_id (gid_t gid) +{ + this->SPIPE_addr_.gid_ = gid; +} diff --git a/ace/SPIPE_Connector.cpp b/ace/SPIPE_Connector.cpp new file mode 100644 index 00000000000..5d8a7e34f5f --- /dev/null +++ b/ace/SPIPE_Connector.cpp @@ -0,0 +1,68 @@ +// SPIPE_Connector.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/SPIPE_Connector.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_SPIPE_Connector) + +// Creates a Local ACE_SPIPE. + +ACE_SPIPE_Connector::ACE_SPIPE_Connector (ACE_SPIPE_Stream &new_io, + const ACE_SPIPE_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_SPIPE_Connector::ACE_SPIPE_Connector"); + if (this->connect (new_io, remote_sap, timeout, local_sap, + reuse_addr, flags, perms) == -1 + && timeout != 0 && !(errno == EWOULDBLOCK || errno == ETIMEDOUT)) + ACE_ERROR ((LM_ERROR, "address %s, %p\n", + remote_sap.get_path_name (), "ACE_SPIPE_Connector")); +} + +void +ACE_SPIPE_Connector::dump (void) const +{ + ACE_TRACE ("ACE_SPIPE_Connector::dump"); +} + +ACE_SPIPE_Connector::ACE_SPIPE_Connector (void) +{ + ACE_TRACE ("ACE_SPIPE_Connector::ACE_SPIPE_Connector"); +} + +int +ACE_SPIPE_Connector::connect (ACE_SPIPE_Stream &new_io, + const ACE_SPIPE_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_SPIPE_Connector::connect"); + + // Make darn sure that the O_CREAT flag is not set! + ACE_CLR_BITS (flags, O_CREAT); + ACE_HANDLE handle = ACE::handle_timed_open (timeout, + remote_sap.get_path_name (), + flags, perms); + new_io.set_handle (handle); + new_io.remote_addr_ = remote_sap; // class copy. + +#if defined (ACE_WIN32) + DWORD pipe_mode = PIPE_READMODE_MESSAGE | PIPE_WAIT; + + // Set named pipe mode and buffering characteristics. + if (handle != ACE_INVALID_HANDLE) + return ::SetNamedPipeHandleState (handle, + &pipe_mode, + NULL, + NULL); +#endif + return handle == ACE_INVALID_HANDLE ? -1 : 0; +} diff --git a/ace/SPIPE_Connector.h b/ace/SPIPE_Connector.h new file mode 100644 index 00000000000..bc659f9ae8e --- /dev/null +++ b/ace/SPIPE_Connector.h @@ -0,0 +1,88 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// SPIPE_Connector.h +// +// = AUTHOR +// Doug Schmidt and Prashant Jain +// +// ============================================================================ + +#if !defined (ACE_SPIPE_CONNECTOR_H) +#define ACE_SPIPE_CONNECTOR_H + +#include "ace/SPIPE_Stream.h" + +class ACE_Export ACE_SPIPE_Connector : public ACE_SPIPE + // = TITLE + // Defines an active connection factory for the STREAM pipe + // wrappers. +{ +public: + // = Initialization method. + ACE_SPIPE_Connector (void); + // Default constructor. + + ACE_SPIPE_Connector (ACE_SPIPE_Stream &new_io, + const ACE_SPIPE_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0); + // Actively connect and produce a if things go well. + // The is the address that we are trying to connect + // with. The is the amount of time to wait to connect. + // If it's 0 then we block indefinitely. If *timeout == {0, 0} then + // the connection is done using non-blocking mode. In this case, if + // the connection can't be made immediately the value of -1 is + // returned with . If *timeout > {0, 0} then + // this is the amount of time to wait before timing out. If the + // time expires before the connection is made . + // The is the value of local address to bind to. If + // it's the default value of then the user is + // letting the OS do the binding. If == 1 then the + // is reused, even if it hasn't been cleanedup yet. + // The and arguments are passed down to the open() + // method. + + int connect (ACE_SPIPE_Stream &new_io, + const ACE_SPIPE_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0); + // Actively connect and produce a if things go well. + // The is the address that we are trying to connect + // with. The is the amount of time to wait to connect. + // If it's 0 then we block indefinitely. If *timeout == {0, 0} then + // the connection is done using non-blocking mode. In this case, if + // the connection can't be made immediately the value of -1 is + // returned with . If *timeout > {0, 0} then + // this is the amount of time to wait before timing out. If the + // time expires before the connection is made . + // The is the value of local address to bind to. If + // it's the default value of then the user is + // letting the OS do the binding. If == 1 then the + // is reused, even if it hasn't been cleanedup yet. + // The and arguments are passed down to the open() + // method. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#include "ace/SPIPE_Connector.i" + +#endif /* ACE_SPIPE_CONNECTOR_H */ diff --git a/ace/SPIPE_Connector.i b/ace/SPIPE_Connector.i new file mode 100644 index 00000000000..cdbc69f06b2 --- /dev/null +++ b/ace/SPIPE_Connector.i @@ -0,0 +1,7 @@ +/* -*- C++ -*- */ +// $Id$ + +// SPIPE_Connector.i + +#include "ace/Log_Msg.h" + diff --git a/ace/SPIPE_Stream.cpp b/ace/SPIPE_Stream.cpp new file mode 100644 index 00000000000..ab38d87e666 --- /dev/null +++ b/ace/SPIPE_Stream.cpp @@ -0,0 +1,93 @@ +// SPIPE_Stream.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/SPIPE_Stream.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_SPIPE_Stream) + +void +ACE_SPIPE_Stream::dump (void) const +{ + ACE_TRACE ("ACE_SPIPE_Stream::dump"); +} + +// Simple-minded do nothing constructor. + +ACE_SPIPE_Stream::ACE_SPIPE_Stream (void) +{ + ACE_TRACE ("ACE_SPIPE_Stream::ACE_SPIPE_Stream"); +} + +// Send N char *ptrs and int lengths. Note that the char *'s precede +// the ints (basically, an varargs version of writev). The count N is +// the *total* number of trailing arguments, *not* a couple of the +// number of tuple pairs! + +ssize_t +ACE_SPIPE_Stream::send (size_t n, ...) const +{ + ACE_TRACE ("ACE_SPIPE_Stream::send"); + va_list argp; + size_t total_tuples = n / 2; + ssize_t result; +#if defined (ACE_HAS_ALLOCA) + iovec *iovp = (iovec *) alloca (total_tuples * sizeof (iovec)); +#else + iovec *iovp; + + ACE_NEW_RETURN (iovp, iovec[total_tuples], -1); +#endif /* !defined (ACE_HAS_ALLOCA) */ + + va_start (argp, n); + + for (size_t i = 0; i < total_tuples; i++) + { + iovp[i].iov_base = va_arg (argp, char *); + iovp[i].iov_len = va_arg (argp, int); + } + + result = ACE_OS::writev (this->get_handle (), iovp, total_tuples); +#if !defined (ACE_HAS_ALLOCA) + delete [] iovp; +#endif /* !defined (ACE_HAS_ALLOCA) */ + va_end (argp); + return result; +} + +// This is basically an interface to ACE_OS::readv, that doesn't use +// the struct iovec explicitly. The ... can be passed as an arbitrary +// number of (char *ptr, int len) tuples. However, the count N is the +// *total* number of trailing arguments, *not* a couple of the number +// of tuple pairs! + +ssize_t +ACE_SPIPE_Stream::recv (size_t n, ...) const +{ + ACE_TRACE ("ACE_SPIPE_Stream::recv"); + va_list argp; + size_t total_tuples = n / 2; + ssize_t result; +#if defined (ACE_HAS_ALLOCA) + iovec *iovp = (iovec *) alloca (total_tuples * sizeof (iovec)); +#else + iovec *iovp; + + ACE_NEW_RETURN (iovp, iovec[total_tuples], -1); +#endif /* !defined (ACE_HAS_ALLOCA) */ + + va_start (argp, n); + + for (size_t i = 0; i < total_tuples; i++) + { + iovp[i].iov_base = va_arg (argp, char *); + iovp[i].iov_len = va_arg (argp, int); + } + + result = ACE_OS::readv (this->get_handle (), iovp, total_tuples); +#if !defined (ACE_HAS_ALLOCA) + delete [] iovp; +#endif /* !defined (ACE_HAS_ALLOCA) */ + va_end (argp); + return result; +} diff --git a/ace/SPIPE_Stream.h b/ace/SPIPE_Stream.h new file mode 100644 index 00000000000..5b78bd1e148 --- /dev/null +++ b/ace/SPIPE_Stream.h @@ -0,0 +1,117 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// SPIPE_Stream.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SPIPE_STREAM_H) +#define ACE_SPIPE_STREAM_H + +#include "ace/SPIPE.h" +#include "ace/SPIPE_Addr.h" + +class ACE_Export ACE_SPIPE_Stream : public ACE_SPIPE + // = TITLE + // Define an ACE_SPIPE_Stream. +{ +friend class ACE_SPIPE_Acceptor; +friend class ACE_SPIPE_Connector; +public: + // = Initialization method. + ACE_SPIPE_Stream (void); + // Default constructor. + + int get_remote_addr (ACE_SPIPE_Addr &remote_sap) const; + // Obtain the address of whom we are connected with. + + int send_handle (ACE_HANDLE handle) const; + // Send an open FD to another process. + + int recv_handle (ACE_HANDLE &handle) const; + // Recv an open FD from another process. + + int recv_handle (strrecvfd &recvfd) const; + // Recv an open FD from another process. + + ssize_t send_n (const void *buf, size_t n) const; + // Send n bytes, keep trying until n are sent. + + ssize_t recv_n (void *buf, size_t n) const; + // Recv n bytes, keep trying until n are received. + + ssize_t send (const void *buf, size_t n) const; + // Send bytes via STREAM pipes using "band" mode. + + ssize_t recv (void *buf, size_t n) const; + // Recv bytes via STREAM pipes using "band" mode. + + ssize_t send (const ACE_Str_Buf *cntl, + const ACE_Str_Buf *data, + int flags = 0) const; + // Send and via STREAM pipes. + + ssize_t recv (ACE_Str_Buf *cntl, + ACE_Str_Buf *data, + int *flags) const; + // Recv and via STREAM pipes. + + ssize_t send (const ACE_Str_Buf *cntl, + const ACE_Str_Buf *data, + int band, + int flags = 0) const; + // Send bytes via STREAM pipes using "band" mode. + + ssize_t recv (ACE_Str_Buf *cntl, + ACE_Str_Buf *data, + int *band, + int *flags) const; + // Recv bytes via STREAM pipes using "band" mode. + + ssize_t send (const iovec iov[], size_t n) const; + // Send iovecs via <::writev>. + + ssize_t recv (iovec iov[], size_t n) const; + // Recv iovecs via <::readv>. + + ssize_t send (size_t n, ...) const; + // Send N char *ptrs and int lengths. Note that the char *'s + // precede the ints (basically, an varargs version of writev). The + // count N is the *total* number of trailing arguments, *not* a + // couple of the number of tuple pairs! + + ssize_t recv (size_t n, ...) const; + // This is an interface to ::readv, that doesn't use the struct + // iovec explicitly. The ... can be passed as an arbitrary number + // of (char *ptr, int len) tuples. However, the count N is the + // *total* number of trailing arguments, *not* a couple of the + // number of tuple pairs! + + ssize_t send (const void *buf, size_t n, ACE_OVERLAPPED *overlapped) const; + // Send bytes via Win32 WriteFile using overlapped I/O. + + ssize_t recv (void *buf, size_t n, ACE_OVERLAPPED *overlapped) const; + // Recv bytes via Win32 ReadFile using overlapped I/O. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_SPIPE_Addr remote_addr_; +}; + +#include "ace/SPIPE_Stream.i" +#endif /* ACE_SPIPE_STREAM_H */ diff --git a/ace/SPIPE_Stream.i b/ace/SPIPE_Stream.i new file mode 100644 index 00000000000..7018068e8d7 --- /dev/null +++ b/ace/SPIPE_Stream.i @@ -0,0 +1,160 @@ +/* -*- C++ -*- */ +// $Id$ + +// SPIPE_Stream.i + +// Create an ACE_SPIPE_Stream. + +inline int +ACE_SPIPE_Stream::get_remote_addr (ACE_SPIPE_Addr &remote_sap) const +{ + ACE_TRACE ("ACE_SPIPE_Stream::get_remote_addr"); + remote_sap = this->remote_addr_; + return 0; +} + +// Send exactly N bytes from BUF to this socket. Keeping trying until +// this many bytes are sent. + +inline ssize_t +ACE_SPIPE_Stream::send_n (const void *buf, size_t n) const +{ + ACE_TRACE ("ACE_SPIPE_Stream::send_n"); + return ACE::send_n (this->get_handle (), buf, n); +} + +// Receive exactly N bytes from this socket into BUF. Keep trying +// until this many bytes are received. + +inline ssize_t +ACE_SPIPE_Stream::recv_n (void *buf, size_t n) const +{ + ACE_TRACE ("ACE_SPIPE_Stream::recv_n"); + return ACE::recv_n (this->get_handle (), buf, n); +} + +inline ssize_t +ACE_SPIPE_Stream::send (const void *buf, size_t n) const +{ + ACE_TRACE ("ACE_SPIPE_Stream::send"); + return ACE_OS::write (this->get_handle (), (const char *) buf, n); +} + +inline ssize_t +ACE_SPIPE_Stream::recv (void *buf, size_t n) const +{ + ACE_TRACE ("ACE_SPIPE_Stream::recv"); + return ACE_OS::read (this->get_handle (), (char *) buf, n); +} + +inline ssize_t +ACE_SPIPE_Stream::send (const ACE_Str_Buf *cntl, const ACE_Str_Buf *data, int flags) const +{ + ACE_TRACE ("ACE_SPIPE_Stream::send"); + return ACE_OS::putmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, flags); +} + +inline ssize_t +ACE_SPIPE_Stream::recv (ACE_Str_Buf *cntl, ACE_Str_Buf *data, int *flags) const +{ + ACE_TRACE ("ACE_SPIPE_Stream::recv"); + return ACE_OS::getmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, flags); +} + +inline ssize_t +ACE_SPIPE_Stream::send (const ACE_Str_Buf *cntl, const ACE_Str_Buf *data, int band, int flags) const +{ + ACE_TRACE ("ACE_SPIPE_Stream::send"); + return ACE_OS::putpmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, band, flags); +} + +inline ssize_t +ACE_SPIPE_Stream::recv (ACE_Str_Buf *cntl, ACE_Str_Buf *data, int *band, int *flags) const +{ + ACE_TRACE ("ACE_SPIPE_Stream::recv"); + return ACE_OS::getpmsg (this->get_handle (), (strbuf *) cntl, (strbuf *) data, band, flags); +} + +inline ssize_t +ACE_SPIPE_Stream::send (const iovec iov[], size_t n) const +{ + ACE_TRACE ("ACE_SPIPE_Stream::send"); + return ACE_OS::writev (this->get_handle (), (iovec *) iov, n); +} + +inline ssize_t +ACE_SPIPE_Stream::recv (iovec iov[], size_t n) const +{ + ACE_TRACE ("ACE_SPIPE_Stream::recv"); + return ACE_OS::readv (this->get_handle (), (iovec *) iov, n); +} + +// This routine sends an open file descriptor to this socket. + +inline int +ACE_SPIPE_Stream::send_handle (ACE_HANDLE handle) const +{ + ACE_TRACE ("ACE_SPIPE_Stream::send_handle"); +#if defined (ACE_HAS_STREAM_PIPES) + return ACE_OS::ioctl (this->get_handle (), I_SENDFD, (void *) handle); +#else + handle = handle; + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STREAM_PIPES */ +} + +// This file receives an open file descriptor from this socket. + +inline int +ACE_SPIPE_Stream::recv_handle (ACE_HANDLE &handle) const +{ + ACE_TRACE ("ACE_SPIPE_Stream::recv_handle"); +#if defined (ACE_HAS_STREAM_PIPES) + strrecvfd recvfd; + + if (ACE_OS::ioctl (this->get_handle (), I_RECVFD, (void *) &recvfd) == -1) + return -1; + else + { + handle = recvfd.fd; + return 0; + } +#else + handle = handle; + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STREAM_PIPES */ +} + +// This file receives an open file descriptor from this socket and +// also passes back the information about the address... + +inline int +ACE_SPIPE_Stream::recv_handle (strrecvfd &recvfd) const +{ + ACE_TRACE ("ACE_SPIPE_Stream::recv_handle"); +#if defined (ACE_HAS_STREAM_PIPES) + return ACE_OS::ioctl (this->get_handle (), I_RECVFD, (void *) &recvfd); +#else + recvfd = recvfd; + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_STREAM_PIPES */ +} + +inline ssize_t +ACE_SPIPE_Stream::send (const void *buf, size_t n, + ACE_OVERLAPPED *overlapped) const +{ + ACE_TRACE ("ACE_SPIPE_Stream::send"); + return ACE_OS::write (this->get_handle (), + (const char *) buf, n, + overlapped); +} + +inline ssize_t +ACE_SPIPE_Stream::recv (void *buf, size_t n, + ACE_OVERLAPPED *overlapped) const +{ + ACE_TRACE ("ACE_SPIPE_Stream::recv"); + return ACE_OS::read (this->get_handle (), (char *) buf, n, + overlapped); +} diff --git a/ace/SString.cpp b/ace/SString.cpp new file mode 100644 index 00000000000..82889f8fa7a --- /dev/null +++ b/ace/SString.cpp @@ -0,0 +1,596 @@ +// SString.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Malloc.h" +#include "ace/Service_Config.h" +#include "ace/SString.h" + +#if !defined (__ACE_INLINE__) +#include "ace/SString.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_CString) + +// Copy constructor. + +ACE_CString::ACE_CString (const ACE_CString &s) + : len_ (s.len_), + allocator_ (s.allocator_) + +{ + ACE_TRACE ("ACE_CString::ACE_CString"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Service_Config::allocator (); + + this->rep_ = (char *) this->allocator_->malloc (s.len_ + 1); + ACE_OS::memcpy ((void *) this->rep_, (const void *) s.rep_, this->len_); + this->rep_[this->len_] = 0; +} + +void +ACE_CString::dump (void) const +{ + ACE_TRACE ("ACE_CString::dump"); +} + +ACE_CString::~ACE_CString (void) +{ + ACE_TRACE ("ACE_CString::~ACE_CString"); + this->allocator_->free (this->rep_); +} + +size_t +ACE_CString::length (void) const +{ + ACE_TRACE ("ACE_CString::length"); + return this->len_; +} + +// Default constructor. + +ACE_CString::ACE_CString (ACE_Allocator *allocator) + : len_ (0), rep_ (0), + allocator_ (allocator) +{ + ACE_TRACE ("ACE_CString::ACE_CString"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Service_Config::allocator (); +} + +// Constructor that actually copies memory. + +ACE_CString::ACE_CString (const char *s, ACE_Allocator *allocator) + : allocator_ (allocator) +{ + ACE_TRACE ("ACE_CString::ACE_CString"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Service_Config::allocator (); + + if (s == 0) + { + this->len_ = 0; + this->rep_ = 0; + } + else + { + this->len_ = ACE_OS::strlen (s); + this->rep_ = (char *) this->allocator_->malloc (this->len_ + 1); + ACE_OS::strcpy (this->rep_, s); + } +} + +// Constructor that actually copies memory. + +ACE_CString::ACE_CString (const char *s, + size_t len, + ACE_Allocator *allocator) + : allocator_ (allocator) +{ + ACE_TRACE ("ACE_CString::ACE_CString"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Service_Config::allocator (); + + if (s == 0) + { + this->len_ = 0; + this->rep_ = 0; + } + else + { + this->len_ = len; + this->rep_ = (char *) this->allocator_->malloc (this->len_ + 1); + ACE_OS::strncpy (this->rep_, s, len); + this->rep_[len] = '\0'; // Make sure to NUL terminate this! + } +} + +// Assignment operator (does copy memory). + +void +ACE_CString::operator = (const ACE_CString &s) +{ + ACE_TRACE ("ACE_CString::operator ="); + // Check for identify. + + if (this != &s) + { + // Only reallocate if we don't have enough space... + if (this->len_ < s.len_) + { + this->allocator_->free (this->rep_); + this->rep_ = (char *) this->allocator_->malloc (s.len_ + 1); + } + this->len_ = s.len_; + ACE_OS::strcpy (this->rep_, s.rep_); + } +} + +int +ACE_CString::strstr (const ACE_CString &s) const +{ + ACE_TRACE ("ACE_CString::strstr"); + + if (this->len_ < s.len_) + // If they're larger than we are they can't be a substring of us! + return -1; + else if (this->len_ == s.len_) + // Check if we're equal. + return *this == s ? 0 : -1; + else + { + // They're smaller than we are... + size_t len = this->len_ - s.len_; + + for (size_t i = 0; i < len; i++) + { + size_t j; + + for (j = 0; j < s.len_; j++) + if (this->rep_[i + j] != s.rep_[j]) + break; + + if (j == s.len_) + // Found a match! Return the index. + return i; + } + + return -1; + } +} + +// Concat operator (does copy memory). + +void +ACE_CString::operator += (const ACE_CString &s) +{ + ACE_TRACE ("ACE_CString::operator +="); + + char *t = (char *) this->allocator_->malloc (this->len_ + s.len_ + 1); + ACE_OS::memcpy (t, this->rep_, this->len_); + ACE_OS::memcpy (t + this->len_, s.rep_, s.len_); + this->len_ += s.len_; + t[this->len_] = '\0'; + this->allocator_->free (this->rep_); + this->rep_ = t; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_SString) + +void +ACE_SString::dump (void) const +{ + ACE_TRACE ("ACE_SString::dump"); +} + +size_t +ACE_SString::length (void) const +{ + ACE_TRACE ("ACE_SString::length"); + return this->len_; +} + +// Copy constructor. + +ACE_SString::ACE_SString (const ACE_SString &s) + : len_ (s.len_), + allocator_ (s.allocator_) +{ + ACE_TRACE ("ACE_SString::ACE_SString"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Service_Config::allocator (); + + this->rep_ = (char *) this->allocator_->malloc (s.len_ + 1); + ACE_OS::memcpy ((void *) this->rep_, (const void *) s.rep_, this->len_); + this->rep_[this->len_] = 0; +} + +// Default constructor. + +ACE_SString::ACE_SString (ACE_Allocator *allocator) + : allocator_ (allocator), + len_ (0), rep_ (0) +{ + ACE_TRACE ("ACE_SString::ACE_SString"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Service_Config::allocator (); +} + +int +ACE_SString::strstr (const ACE_SString &s) const +{ + ACE_TRACE ("ACE_SString::strstr"); + + if (this->len_ < s.len_) + // If they're larger than we are they can't be a substring of us! + return -1; + else if (this->len_ == s.len_) + // Check if we're equal. + return *this == s ? 0 : -1; + else + { + // They're smaller than we are... + size_t len = this->len_ - s.len_; + + for (size_t i = 0; i < len; i++) + { + size_t j; + + for (j = 0; j < s.len_; j++) + { + if (this->rep_[i + j] != s.rep_[j]) + break; + } + + if (j == s.len_) + // Found a match! Return the index. + return i; + } + + return -1; + } +} + +// Set the underlying pointer (does not copy memory). + +void +ACE_SString::rep (char *s) +{ + ACE_TRACE ("ACE_SString::rep"); + + this->rep_ = s; + + if (s == 0) + this->len_ = 0; + else + this->len_ = ACE_OS::strlen (s); +} + +// Constructor that actually copies memory. + +ACE_SString::ACE_SString (const char *s, + ACE_Allocator *allocator) + : allocator_ (allocator) +{ + ACE_TRACE ("ACE_SString::ACE_SString"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Service_Config::allocator (); + + if (s == 0) + { + this->len_ = 0; + this->rep_ = 0; + } + else + { + this->len_ = ACE_OS::strlen (s); + this->rep_ = (char *) this->allocator_->malloc (this->len_ + 1); + ACE_OS::strcpy (this->rep_, s); + } +} + +// Constructor that actually copies memory. + +ACE_SString::ACE_SString (const char *s, + size_t len, + ACE_Allocator *allocator) + : allocator_ (allocator) +{ + ACE_TRACE ("ACE_SString::ACE_SString"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Service_Config::allocator (); + + if (s == 0) + { + this->len_ = 0; + this->rep_ = 0; + } + else + { + this->len_ = len; + this->rep_ = (char *) this->allocator_->malloc (this->len_ + 1); + ACE_OS::strncpy (this->rep_, s, len); + this->rep_[len] = '\0'; // Make sure to NUL terminate this! + } +} + +// Assignment operator (does copy memory). + +void +ACE_SString::operator = (const ACE_SString &s) +{ + ACE_TRACE ("ACE_SString::operator ="); + // Check for identify. + + if (this != &s) + { + // Only reallocate if we don't have enough space... + if (this->len_ < s.len_) + { + this->allocator_->free (this->rep_); + this->rep_ = (char *) this->allocator_->malloc (s.len_ + 1); + } + this->len_ = s.len_; + ACE_OS::strcpy (this->rep_, s.rep_); + } +} + +ACE_ALLOC_HOOK_DEFINE(ACE_WString) + +void +ACE_WString::dump (void) const +{ + ACE_TRACE ("ACE_WString::dump"); +} + +// Default constructor. + +ACE_WString::ACE_WString (ACE_Allocator *allocator) + : len_ (0), + rep_ (0), + allocator_ (allocator) +{ + ACE_TRACE ("ACE_WString::ACE_WString"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Service_Config::allocator (); +} + +size_t +ACE_WString::wstrlen (const ACE_USHORT16 *s) +{ + ACE_TRACE ("ACE_WString::wstrlen"); + int i; + + for (i = 0; s[i] != 0; i++) + continue; + + return i; +} + +// Get the underlying pointer as an ASCII char. + +char * +ACE_WString::char_rep (void) const +{ + ACE_TRACE ("ACE_WString::char_rep"); + if (this->len_ <= 0) + return 0; + else + { + char *t; + + ACE_NEW_RETURN (t, char[this->len_ + 1], 0); + + for (size_t i = 0; i < this->len_; i++) + // Note that this cast may lose data if wide chars are + // actually used! + t[i] = char (this->rep_[i]); + + t[this->len_] = '\0'; + return t; + } +} + +// Constructor that actually copies memory. + +ACE_WString::ACE_WString (const char *s, + ACE_Allocator *allocator) + : allocator_ (allocator) +{ + ACE_TRACE ("ACE_WString::ACE_WString"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Service_Config::allocator (); + + if (s == 0) + { + this->len_ = 0; + this->rep_ = 0; + } + else + { + this->len_ = ACE_OS::strlen (s); + this->rep_ = (ACE_USHORT16 *) this->allocator_->malloc ((this->len_ + 1) * sizeof (ACE_USHORT16)); + + // Copy the char * string byte-by-byte into the ACE_USHORT16 * + // string. + for (size_t i = 0; i < this->len_; i++) + this->rep_[i] = s[i]; + + // null terminate + this->rep_[this->len_] = 0; + } +} + +// Constructor that actually copies memory. + +ACE_WString::ACE_WString (const ACE_USHORT16 *s, ACE_Allocator *allocator) + : allocator_ (allocator) +{ + ACE_TRACE ("ACE_WString::ACE_WString"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Service_Config::allocator (); + + if (s == 0) + { + this->len_ = 0; + this->rep_ = 0; + } + else + { + this->len_ = this->wstrlen (s); + this->rep_ = (ACE_USHORT16 *) this->allocator_->malloc ((this->len_ + 1) * sizeof (ACE_USHORT16)); + + ACE_OS::memcpy (this->rep_, s, this->len_ * sizeof (ACE_USHORT16)); + + // null terminate + this->rep_[this->len_] = 0; + } +} + +// Constructor that actually copies memory. + +ACE_WString::ACE_WString (const ACE_USHORT16 *s, + size_t len, + ACE_Allocator *allocator) + : allocator_ (allocator) +{ + ACE_TRACE ("ACE_WString::ACE_WString"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Service_Config::allocator (); + + if (s == 0) + { + this->len_ = 0; + this->rep_ = 0; + } + else + { + this->len_ = len; + this->rep_ = (ACE_USHORT16 *) this->allocator_->malloc ((this->len_ + 1) * sizeof (ACE_USHORT16)); + + ACE_OS::memcpy (this->rep_, s, len * sizeof (ACE_USHORT16)); + + // null terminate + this->rep_[this->len_] = 0; + } +} + +size_t +ACE_WString::length (void) const +{ + ACE_TRACE ("ACE_WString::length"); + return this->len_; +} + +// Copy constructor. + +ACE_WString::ACE_WString (const ACE_WString &s) +: len_ (s.len_), + allocator_ (s.allocator_) +{ + ACE_TRACE ("ACE_WString::ACE_WString"); + + if (this->allocator_ == 0) + this->allocator_ = ACE_Service_Config::allocator (); + + this->rep_ = (ACE_USHORT16 *) this->allocator_->malloc ((s.len_ + 1) * sizeof (ACE_USHORT16)); + ACE_OS::memcpy ((void *) this->rep_, (const void *) s.rep_, + this->len_ * sizeof (ACE_USHORT16)); + this->rep_[this->len_] = 0; +} + +// Assignment operator (does copy memory). + +void +ACE_WString::operator = (const ACE_WString &s) +{ + ACE_TRACE ("ACE_WString::operator ="); + // Check for identify. + + if (this != &s) + { + // Only reallocate if we don't have enough space... + if (this->len_ < s.len_) + { + this->allocator_->free (this->rep_); + this->rep_ = (ACE_USHORT16 *) this->allocator_->malloc ((s.len_ + 1) * sizeof (ACE_USHORT16)); + // null terminate + this->rep_[s.len_] = 0; + } + + this->len_ = s.len_; + ACE_OS::memcpy ((void *) this->rep_, (const void *) s.rep_, + this->len_ * sizeof (ACE_USHORT16)); + } +} + +// Concat operator (does copy memory). + +void +ACE_WString::operator += (const ACE_WString &s) +{ + ACE_TRACE ("ACE_WString::operator +="); + ACE_USHORT16 *t = (ACE_USHORT16 *) this->allocator_->malloc ((this->len_ + s.len_ + 1) * sizeof (ACE_USHORT16)); + + ACE_OS::memcpy ((void *) t, (const void *) this->rep_, this->len_ * sizeof (ACE_USHORT16)); + ACE_OS::memcpy ((void *) (t + this->len_ * sizeof (ACE_USHORT16)), + (const void *) s.rep_, s.len_ * sizeof (ACE_USHORT16)); + this->len_ += s.len_; + + // null terminate + t[this->len_] = 0; + + this->allocator_->free (this->rep_); + this->rep_ = t; +} + +ACE_WString::~ACE_WString (void) +{ + ACE_TRACE ("ACE_WString::~ACE_WString"); + this->allocator_->free (this->rep_); +} + +int +ACE_WString::strstr (const ACE_WString &s) const +{ + ACE_TRACE ("ACE_WString::strstr"); + + if (this->len_ < s.len_) + // If they're larger than we are they can't be a substring of us! + return -1; + else if (this->len_ == s.len_) + // Check if we're equal. + return *this == s ? 0 : -1; + else + { + // They're smaller than we are... + size_t len = this->len_ - s.len_; + + for (size_t i = 0; i < len; i++) + { + size_t j; + + for (j = 0; j < s.len_; j++) + if (this->rep_[i + j] != s.rep_[j]) + break; + + if (j == s.len_) + // Found a match! Return the index. + return i; + } + + return -1; + } +} diff --git a/ace/SString.h b/ace/SString.h new file mode 100644 index 00000000000..c6e906ec73a --- /dev/null +++ b/ace/SString.h @@ -0,0 +1,265 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// SString.h +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) +// +// ============================================================================ + +#if !defined (ACE_SSTRING_H) +#define ACE_SSTRING_H + +#include "ace/ACE.h" + +// Forward decl. +class ACE_Allocator; + +class ACE_Export ACE_CString + // = TITLE + // A simple "C String" (ACE_CString) class. + // + // = DESCRIPTION + // This is a place holder until all compilers implement the + // ANSI/ISO C++ standard String class. Note that we need to use + // this class since the ACE ACE_Map_Manager requires an object + // that supports the operator== and operator!=. + // This class uses an ACE_Allocator to allocate memory + // The user can make this a persistant class by providing an + // ACE_Allocator with a persistable memory pool +{ +public: + ACE_CString (ACE_Allocator *allocator = 0); + // Default constructor. + + ACE_CString (const char *s, ACE_Allocator *allocator = 0); + // Constructor that copies into dynamically allocated memory. + + ACE_CString (const ACE_CString &); + // Copy constructor. + + ~ACE_CString (void); + // Deletes the memory... + + ACE_CString (const char *s, size_t len, ACE_Allocator *allocator = 0); + // Constructor that copies chars of into dynamically + // allocated memory (will NUL terminate the result). + + void operator= (const ACE_CString &); + // Assignment operator (does copy memory). + + size_t length (void) const; + // Return the length of the string. + + char *rep (void) const; + // Get a copy of the underlying pointer. + + void operator += (const ACE_CString &); + // Concat operator (copies memory). + + int strstr (const ACE_CString &s) const; + // Comparison operator that will match substrings. Returns the + // index of the first location that matches, else -1. + + char operator[] (size_t index) const; + // Return the character in the string (doesn't perform + // bounds checking). + + int operator== (const ACE_CString &s) const; + // Comparison operator (must match entire string). + + int operator!= (const ACE_CString &s) const; + // Comparison operator. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Allocator *allocator_; + // Pointer to a memory allocator. + + size_t len_; + // Length of the ACE_CString (not counting the trailing '\0'). + + char *rep_; + // Pointer to data. +}; + +class ACE_Export ACE_SString + // = TITLE + // A very "Simple String" (ACE_SString) class. + // + // = DESCRIPTION + // This is *not* a general-purpose string class. It is only + // intended for use with applications that understand how it + // works. In particular, it has no destructor... Note that we + // need to use this class since the ACE ACE_Map_Manager requires + // an object that supports the operator== and operator!=. + // This class uses an ACE_Allocator to allocate memory + // The user can make this a persistant class by providing an + // ACE_Allocator with a persistable memory pool +{ +public: + ACE_SString (ACE_Allocator *allocator = 0); + // Default constructor. + + ACE_SString (const char *s, ACE_Allocator *allocator = 0); + // Constructor that copies into dynamically allocated memory. + + ACE_SString (const char *s, size_t len, ACE_Allocator *allocator = 0); + // Constructor that copies chars of into dynamically + // allocated memory (will NUL terminate the result). + + ACE_SString (const ACE_SString &); + // Copy constructor. + + void operator= (const ACE_SString &); + // Assignment operator (does copy memory). + + size_t length (void) const; + // Return the length of the string. + + void rep (char *s); + // Set the underlying pointer. Since this does not copy memory or + // delete existing memory use with extreme caution!!! + + char *rep (void) const; + // Get the underlying pointer. + + void operator += (const ACE_SString &); + // Concat operator (does copy memory). + + int strstr (const ACE_SString &s) const; + // Comparison operator that will match substrings. Returns the + // index of the first location that matches, else -1. + + char operator[] (size_t index) const; + // Return the character in the string (doesn't perform + // bounds checking). + + int operator== (const ACE_SString &s) const; + // Comparison operator (must match entire string). + + int operator!= (const ACE_SString &s) const; + // Comparison operator. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + + ACE_Allocator *allocator_; + // Pointer to a memory allocator. + + size_t len_; + // Length of the ACE_SString (not counting the trailing '\0'). + + char *rep_; + // Pointer to data. +}; + +class ACE_Export ACE_WString + // = TITLE + // A persistent wide string class. + // + // = DESCRIPTION + // This is *not* a general-purpose string class. It is only + // intended for use with applications that understand how it + // works. Note that we need to use this class since the ACE + // ACE_Map_Manager requires an object that supports the operator== + // and operator!=. + // This class uses an ACE_Allocator to allocate memory + // The user can make this a persistant class by providing an + // ACE_Allocator with a persistable memory pool +{ +public: + ACE_WString (ACE_Allocator *allocator = 0); + // Default constructor. + + ACE_WString (const char *s, ACE_Allocator *allocator = 0); + // Constructor that copies into dynamically allocated memory. + + ACE_WString (const ACE_USHORT16 *s, ACE_Allocator *allocator = 0); + // Constructor that copies into dynamically allocated memory. + + ACE_WString (const ACE_USHORT16 *s, size_t len, ACE_Allocator *allocator = 0); + // Constructor that copies ACE_USHORT16's of into dynamically + // allocated memory (will NUL terminate the result). + + ACE_WString (const ACE_WString &s); + // Copy constructor. + + ~ACE_WString (void); + // Deletes the memory... + + ACE_USHORT16 operator[] (size_t index) const; + // Return the character in the string (doesn't perform + // bounds checking). + + void operator= (const ACE_WString &); + // Assignment operator (does copy memory). + + void operator += (const ACE_WString &); + // Concat operator (does copy memory). + + size_t length (void) const; + // Return the length of the string. + + ACE_USHORT16 *rep (void) const; + // Gets a copy of the underlying pointer. + + char *char_rep (void) const; + // Transform into a copy of the ASCII character representation. + + ACE_USHORT16 *fast_rep (void) const; + // Get at the underlying representation directly! + + int strstr (const ACE_WString &s) const; + // Comparison operator that will match substrings. Returns the + // index of the first location that matches, else -1. + + int operator== (const ACE_WString &s) const; + // Comparison operator (must match entire string). + + int operator!= (const ACE_WString &s) const; + // Comparison operator. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Allocator *allocator_; + // Pointer to a memory allocator. + + size_t wstrlen (const ACE_USHORT16 *); + // Computes the length of a "0" terminated ACE_USHORT16 *. + + size_t len_; + // Length of the ACE_WString. + + ACE_USHORT16 *rep_; + // Pointer to data. +}; + +#if defined (__ACE_INLINE__) +#include "ace/SString.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_SSTRING_H */ diff --git a/ace/SString.i b/ace/SString.i new file mode 100644 index 00000000000..c628f6d42ec --- /dev/null +++ b/ace/SString.i @@ -0,0 +1,141 @@ +/* -*- C++ -*- */ +// $Id$ + +// SString.i + +// Return the character in the string. + +ACE_INLINE char +ACE_CString::operator[] (size_t index) const +{ + ACE_TRACE ("ACE_CString::operator[]"); + return this->rep_[index]; +} + +// Get a copy of the underlying representation. + +ACE_INLINE char * +ACE_CString::rep (void) const +{ + ACE_TRACE ("ACE_CString::rep"); + + char *new_string; + ACE_NEW_RETURN (new_string, char[this->len_ + 1], 0); + ACE_OS::strcpy (new_string, this->rep_); + + return new_string; +} + +// Comparison operator. + +ACE_INLINE int +ACE_CString::operator== (const ACE_CString &s) const +{ + ACE_TRACE ("ACE_CString::operator=="); + return this->len_ == s.len_ + && ACE_OS::strcmp (this->rep_, s.rep_) == 0; +} + +// Comparison operator. + +ACE_INLINE int +ACE_CString::operator!= (const ACE_CString &s) const +{ + ACE_TRACE ("ACE_CString::operator!="); + return !(*this == s); +} + +// Return the character in the string. + +ACE_INLINE char +ACE_SString::operator[] (size_t index) const +{ + ACE_TRACE ("ACE_SString::operator[]"); + return this->rep_[index]; +} + +// Get the underlying pointer (does not make a copy, so beware!). + +ACE_INLINE char * +ACE_SString::rep (void) const +{ + ACE_TRACE ("ACE_SString::rep"); + return this->rep_; +} + +// Comparison operator. + +ACE_INLINE int +ACE_SString::operator== (const ACE_SString &s) const +{ + ACE_TRACE ("ACE_SString::operator=="); + return this->len_ == s.len_ + && ACE_OS::strcmp (this->rep_, s.rep_) == 0; +} + +// Comparison operator. + +ACE_INLINE int +ACE_SString::operator!= (const ACE_SString &s) const +{ + ACE_TRACE ("ACE_SString::operator!="); + return !(*this == s); +} + +// Get a copy of the underlying representation. + +ACE_INLINE ACE_USHORT16 * +ACE_WString::rep (void) const +{ + ACE_TRACE ("ACE_WString::rep"); + if (this->len_ <= 0) + return 0; + else + { + ACE_USHORT16 *t; + ACE_NEW_RETURN (t, ACE_USHORT16[this->len_ + 1], 0); + ACE_OS::memcpy (t, this->rep_, this->len_ * sizeof (ACE_USHORT16)); + + // null terminate + t[this->len_] = 0; + + return t; + } +} + +// Get at the underlying representation directly! + +ACE_INLINE ACE_USHORT16 * +ACE_WString::fast_rep (void) const +{ + return this->rep_; +} + +// Comparison operator. + +ACE_INLINE int +ACE_WString::operator== (const ACE_WString &s) const +{ + ACE_TRACE ("ACE_WString::operator=="); + return this->len_ == s.len_ + && ACE_OS::memcmp ((const void *) this->rep_, (const void *) s.rep_, + this->len_ * sizeof (ACE_USHORT16)) == 0; +} + +// Comparison operator. + +ACE_INLINE int +ACE_WString::operator!= (const ACE_WString &s) const +{ + ACE_TRACE ("ACE_WString::operator!="); + return !(*this == s); +} + +// Return the character in the string. + +ACE_INLINE ACE_USHORT16 +ACE_WString::operator[] (size_t index) const +{ + ACE_TRACE ("ACE_WString::operator[]"); + return this->rep_[index]; +} diff --git a/ace/SV_Message.cpp b/ace/SV_Message.cpp new file mode 100644 index 00000000000..dc2e8413b18 --- /dev/null +++ b/ace/SV_Message.cpp @@ -0,0 +1,18 @@ +// SV_Message.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/SV_Message.h" + +#if !defined (__ACE_INLINE__) +#include "ace/SV_Message.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_SV_Message) + +void +ACE_SV_Message::dump (void) const +{ + ACE_TRACE ("ACE_SV_Message::dump"); +} + diff --git a/ace/SV_Message.h b/ace/SV_Message.h new file mode 100644 index 00000000000..7ee965520ae --- /dev/null +++ b/ace/SV_Message.h @@ -0,0 +1,51 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// SV_Message.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SV_MESSAGE_H) +#define ACE_SV_MESSAGE_H + +#include "ace/ACE.h" + +class ACE_Export ACE_SV_Message + // = TITLE + // Defines the header file for the C++ wrapper for message queues. */ +{ +public: + // = Initialization and termination methods. + ACE_SV_Message (long type = 0); + ~ACE_SV_Message (void); + + // = Get/set the message type. + long type (void) const; + void type (long); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + long type_; + // Type of the message. +}; + +#if defined (__ACE_INLINE__) +#include "ace/SV_Message.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_SV_MESSAGE_H */ diff --git a/ace/SV_Message.i b/ace/SV_Message.i new file mode 100644 index 00000000000..8c08e41d151 --- /dev/null +++ b/ace/SV_Message.i @@ -0,0 +1,31 @@ +/* -*- C++ -*- */ +// $Id$ + +// SV_Message.i + +ACE_INLINE +ACE_SV_Message::ACE_SV_Message (long t) + : type_ (t) +{ + ACE_TRACE ("ACE_SV_Message::ACE_SV_Message"); +} + +ACE_INLINE +ACE_SV_Message::~ACE_SV_Message (void) +{ + ACE_TRACE ("ACE_SV_Message::~ACE_SV_Message"); +} + +ACE_INLINE long +ACE_SV_Message::type (void) const +{ + ACE_TRACE ("ACE_SV_Message::type"); + return this->type_; +} + +ACE_INLINE void +ACE_SV_Message::type (long t) +{ + ACE_TRACE ("ACE_SV_Message::type"); + this->type_ = t; +} diff --git a/ace/SV_Message_Queue.cpp b/ace/SV_Message_Queue.cpp new file mode 100644 index 00000000000..0350904392b --- /dev/null +++ b/ace/SV_Message_Queue.cpp @@ -0,0 +1,34 @@ +// SV_Message_Queue.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/SV_Message_Queue.h" +#include "ace/Log_Msg.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_SV_Message_Queue) + +void +ACE_SV_Message_Queue::dump (void) const +{ + ACE_TRACE ("ACE_SV_Message_Queue::dump"); +} + +ACE_SV_Message_Queue::ACE_SV_Message_Queue (void) +{ + ACE_TRACE ("ACE_SV_Message_Queue::ACE_SV_Message_Queue"); +} + +ACE_SV_Message_Queue::~ACE_SV_Message_Queue (void) +{ + ACE_TRACE ("ACE_SV_Message_Queue::~ACE_SV_Message_Queue"); +} + +ACE_SV_Message_Queue::ACE_SV_Message_Queue (key_t external_id, + int create, + int perms) +{ + ACE_TRACE ("ACE_SV_Message_Queue::ACE_SV_Message_Queue"); + if (this->open (external_id, create, perms) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", + "ACE_SV_Message_Queue::ACE_SV_Message_Queue")); +} diff --git a/ace/SV_Message_Queue.h b/ace/SV_Message_Queue.h new file mode 100644 index 00000000000..cd9c85f82e8 --- /dev/null +++ b/ace/SV_Message_Queue.h @@ -0,0 +1,86 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// SV_Message_Queue.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_MESSAGE_QUEUE_H) +#define ACE_MESSAGE_QUEUE_H + +#include "ace/ACE.h" +#include "ace/SV_Message.h" + +class ACE_Export ACE_SV_Message_Queue + // = TITLE + // Defines the header file for the C++ wrapper for System V IPC + // message queues. +{ +public: + // = Useful symbolic constants. + enum + { + ACE_CREATE = IPC_CREAT, + ACE_OPEN = 0, + ACE_NOWAIT = IPC_NOWAIT + }; + + // = Initialization and termination methods. + ACE_SV_Message_Queue (void); + ACE_SV_Message_Queue (key_t external_id, + int create = ACE_SV_Message_Queue::ACE_OPEN, + int perms = ACE_DEFAULT_PERMS); + int open (key_t external_id, + int create = ACE_SV_Message_Queue::ACE_OPEN, + int perms = ACE_DEFAULT_PERMS); + // Open a message queue using the . + + ~ACE_SV_Message_Queue (void); + + int close (void); + // Close down this instance of the message queue without removing it + // from the system. + + int remove (void); + // Close down and remove the message queue from the system. + + + // = Message transfer methods. + int recv (ACE_SV_Message &mb, + int length, + long mtype = 0, + int mflags = 0); + + int send (const ACE_SV_Message &mb, + int length, + int mflags = 0); + + int control (int option, void *arg = 0); + // Access the underlying control operations. + + // = Get/set the underly internal id. + int get_id (void); + void set_id (int); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + int internal_id_; + // Returned from the underlying msgget() system call. +}; + +#include "ace/SV_Message_Queue.i" +#endif /* ACE_MESSAGE_QUEUE_H */ diff --git a/ace/SV_Message_Queue.i b/ace/SV_Message_Queue.i new file mode 100644 index 00000000000..f896388232e --- /dev/null +++ b/ace/SV_Message_Queue.i @@ -0,0 +1,78 @@ +/* -*- C++ -*- */ +// $Id$ + +// SV_Message_Queue.i + +#include "ace/SV_Message_Queue.h" + +// Open a message queue using the . + +inline int +ACE_SV_Message_Queue::open (key_t external_id, int create, int perms) +{ + ACE_TRACE ("ACE_SV_Message_Queue::open"); + return this->internal_id_ = ACE_OS::msgget (external_id, create | perms); +} + +// What does it mean to close a message queue?! + +inline int +ACE_SV_Message_Queue::close (void) +{ + ACE_TRACE ("ACE_SV_Message_Queue::close"); + this->internal_id_ = -1; + return 1; +} + +inline int +ACE_SV_Message_Queue::control (int option, void *arg) +{ + ACE_TRACE ("ACE_SV_Message_Queue::control"); + return ACE_OS::msgctl (this->internal_id_, option, + (msqid_ds *) arg); +} + +inline int +ACE_SV_Message_Queue::remove (void) +{ + ACE_TRACE ("ACE_SV_Message_Queue::remove"); + int result = this->control (IPC_RMID); + this->internal_id_ = -1; + return result; +} + +inline int +ACE_SV_Message_Queue::get_id (void) +{ + ACE_TRACE ("ACE_SV_Message_Queue::get_id"); + return this->internal_id_; +} + +inline void +ACE_SV_Message_Queue::set_id (int id) +{ + ACE_TRACE ("ACE_SV_Message_Queue::set_id"); + this->internal_id_ = id; +} + +inline int +ACE_SV_Message_Queue::recv (ACE_SV_Message &mb, + int length, + long type, + int mflags) +{ + ACE_TRACE ("ACE_SV_Message_Queue::recv"); + return ACE_OS::msgrcv (this->internal_id_, (void *) &mb, + length, type, mflags); +} + +inline int +ACE_SV_Message_Queue::send (const ACE_SV_Message &mb, + int length, + int mflags) +{ + ACE_TRACE ("ACE_SV_Message_Queue::send"); + return ACE_OS::msgsnd (this->internal_id_, (void *) &mb, + length, mflags); +} + diff --git a/ace/SV_Semaphore_Complex.cpp b/ace/SV_Semaphore_Complex.cpp new file mode 100644 index 00000000000..1586c7fb8a9 --- /dev/null +++ b/ace/SV_Semaphore_Complex.cpp @@ -0,0 +1,240 @@ +// SV_Semaphore_Complex.cpp +// $Id$ + +/* -*- C++ -*- */ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/SV_Semaphore_Complex.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_SV_Semaphore_Complex) + +void +ACE_SV_Semaphore_Complex::dump (void) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Complex::dump"); +} + +// initial value of process +const int ACE_SV_Semaphore_Complex::BIGCOUNT_ = 10000; + +// Define the ACE_SV_Semaphore operation arrays for the semop() calls. +sembuf ACE_SV_Semaphore_Complex::op_lock_[2] = +{ + {0, 0, 0}, // Wait for [0] (lock) to equal 0 + {0, 1, SEM_UNDO}, // then increment [0] to 1 - this locks it. + // UNDO to release the lock if processes exit + // before explicitly unlocking. +}; + +sembuf ACE_SV_Semaphore_Complex::op_endcreate_[2] = +{ + {1, -1, SEM_UNDO}, // Decrement [1] (proc counter) with undo on + // exit, UNDO to adjust proc counter if + // process exits before explicitly calling close() + {0, -1, SEM_UNDO}, // the decrement [0] (lock) back to 0 +}; + +sembuf ACE_SV_Semaphore_Complex::op_open_[1] = +{ + {1, -1, SEM_UNDO}, // Decrement [1] (proc counter) with undo on + // exit. +}; + +sembuf ACE_SV_Semaphore_Complex::op_close_[3] = +{ + {0, 0, 0}, // Wait for [0] (lock) to equal 0 + {0, 1, SEM_UNDO}, // then increment [0] to 1 - this lock it + {1, 1, SEM_UNDO}, // then increment [1] (proc counter) +}; + +sembuf ACE_SV_Semaphore_Complex::op_unlock_[1] = +{ + {0, -1, SEM_UNDO}, // Decrement [0] (lock) back to 0 +}; + +// Open or create an array of SV_Semaphores. We return 0 if all is OK, else -1. + +int +ACE_SV_Semaphore_Complex::open (key_t k, + int create, + int initial_value, + int nsems, + int perms) +{ + ACE_TRACE ("ACE_SV_Semaphore_Complex::open"); + if (k == IPC_PRIVATE) + return -1; + + this->key_ = k; + + if (create == ACE_SV_Semaphore_Complex::ACE_CREATE) + { + int result; + + do + { + this->internal_id_ = ACE_OS::semget + (this->key_, 2 + nsems, perms | ACE_SV_Semaphore_Complex::ACE_CREATE); + + if (this->internal_id_ == -1) + return -1; // permission problem or tables full + + // When the ACE_SV_Semaphore is created, we know that the + // value of all 3 members is 0. Get a lock on the + // ACE_SV_Semaphore by waiting for [0] to equal 0, then + // increment it. + + // There is a race condition here. There is the possibility + // that between the semget() above and the semop() below, + // another process can call out close() function which can + // remove the ACE_SV_Semaphore if that process is the last + // one using it. Therefor we handle the error condition of + // an invalid ACE_SV_Semaphore ID specifically below, and if + // it does happen, we just go back and create it again. + result = ACE_OS::semop (this->internal_id_, + &ACE_SV_Semaphore_Complex::op_lock_[0], + 2); + } + while (result == -1 && (errno == EINVAL || errno == EIDRM)); + + if (result == -1) + return -1; + + // Get the value of the process counter. If it equals 0, then no + // one has initialized the ACE_SV_Semaphore yet. + + int semval; + + if ((semval = ACE_SV_Semaphore_Simple::control (GETVAL, 0, 1)) < 0) + return this->init (); + + if (semval == 0) + { + // We should initialize by doing a SETALL, but that would + // clear the adjust value that we set when we locked the + // ACE_SV_Semaphore above. Instead we do system calls to + // initialize [1], as well as all the nsems SV_Semaphores. + + if (ACE_SV_Semaphore_Simple::control (SETVAL, + ACE_SV_Semaphore_Complex::BIGCOUNT_, + 1) == -1) + return -1; + else + for (int i = 0; i < nsems; i++) + if (this->control (SETVAL, initial_value, i) == -1) + return -1; + } + + // Decrement the process counter and then release the lock. + return ACE_OS::semop (this->internal_id_, + &ACE_SV_Semaphore_Complex::op_endcreate_[0], + 2); + } + else + { + this->internal_id_ = ACE_OS::semget (this->key_, 2 + nsems, 0); + if (this->internal_id_ == -1) + return -1; // doesn't exist or tables full + + // Decrement the process counter. We don't need a lock to do this. + if (ACE_OS::semop (this->internal_id_, + &ACE_SV_Semaphore_Complex::op_open_[0], 1) < 0) + return this->init (); + return 0; + } +} + +int +ACE_SV_Semaphore_Complex::open (const char *name, + int flags, + int initial_value, + int nsems, + int perms) +{ + ACE_TRACE ("ACE_SV_Semaphore_Complex::open"); + return this->open (ACE_SV_Semaphore_Simple::name_2_key (name), + flags, initial_value, nsems, perms); +} + +// Close a ACE_SV_Semaphore. Unlike the remove above, this function is +// for a process to call before it exits, when it is done with the +// ACE_SV_Semaphore. We "decrement" the counter of processes using the +// ACE_SV_Semaphore, and if this was the last one, we can remove the +// ACE_SV_Semaphore. + +int +ACE_SV_Semaphore_Complex::close (void) +{ + ACE_TRACE ("ACE_SV_Semaphore_Complex::close"); + int semval; + + if (this->key_ <= (key_t) - 1 || this->internal_id_ == -1) + return -1; + + // The following semop() first gets a lock on the ACE_SV_Semaphore, + // then increments [1] - the process number. + + if (ACE_OS::semop (this->internal_id_, + &ACE_SV_Semaphore_Complex::op_close_[0], + 3) == -1) + return -1; + + // Now that we have a lock, read the value of the process counter to + // see if this is the last reference to the ACE_SV_Semaphore. There + // is a race condition here - see the comments in create (). + + if ((semval = ACE_SV_Semaphore_Simple::control (GETVAL, 0, 1)) == -1) + return -1; + + if (semval > ACE_SV_Semaphore_Complex::BIGCOUNT_) + return -1; + else if (semval == ACE_SV_Semaphore_Complex::BIGCOUNT_) + return this->remove (); + else + { + int result = ACE_OS::semop (this->internal_id_, + &ACE_SV_Semaphore_Complex::op_unlock_[0], 1); + + this->init (); + + return result; + } +} + +ACE_SV_Semaphore_Complex::ACE_SV_Semaphore_Complex (key_t k, + int flags, + int initial_value, + int nsems, + int perms) +{ + ACE_TRACE ("ACE_SV_Semaphore_Complex::ACE_SV_Semaphore_Complex"); + if (this->open (k, flags, initial_value, nsems, perms) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_SV_Semaphore_Complex")); +} + +ACE_SV_Semaphore_Complex::ACE_SV_Semaphore_Complex (const char *name, + int flags, + int initial_value, + int nsems, + int perms) +{ + ACE_TRACE ("ACE_SV_Semaphore_Complex::ACE_SV_Semaphore_Complex"); + if (this->open (ACE_SV_Semaphore_Simple::name_2_key (name), + flags, initial_value, nsems, perms) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_SV_Semaphore_Complex")); +} + +ACE_SV_Semaphore_Complex::~ACE_SV_Semaphore_Complex (void) +{ + ACE_TRACE ("ACE_SV_Semaphore_Complex::~ACE_SV_Semaphore_Complex"); + if (this->internal_id_ >= 0) + this->close (); +} + +ACE_SV_Semaphore_Complex::ACE_SV_Semaphore_Complex (void) +{ + ACE_TRACE ("ACE_SV_Semaphore_Complex::ACE_SV_Semaphore_Complex"); + this->init (); +} + diff --git a/ace/SV_Semaphore_Complex.h b/ace/SV_Semaphore_Complex.h new file mode 100644 index 00000000000..42cf1480830 --- /dev/null +++ b/ace/SV_Semaphore_Complex.h @@ -0,0 +1,149 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// ACE_SV_Semaphore_Complex.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SV_SEMAPHORE_COMPLEX_H) +#define ACE_SV_SEMAPHORE_COMPLEX_H + +#include "ace/SV_Semaphore_Simple.h" + +class ACE_Export ACE_SV_Semaphore_Complex : private ACE_SV_Semaphore_Simple + // = TITLE + // This is a more complex semaphore wrapper that handles race + // conditions for initialization correctly... + // + // = DESCRIPTION + // This code is a port to C++, inspired by: W. Richard Stevens + // from his book: UNIX Network Programming (Prentice Hall, ISBN + // 0-13-949876-1 - 1990) ACE_SV_Semaphore Interface: we provide + // a simpler and easier to understand interface to the System V + // ACE_SV_Semaphore calls. We create and use a 2 + n-member + // set for the requested ACE_SV_Semaphore. The first member, + // [0], is a counter used to know when all processes have + // finished with the ACE_SV_Semaphore. The counter is + // initialized to a large number, decremented on every create + // or open and incremented on every close. This way we can use + // the "adjust" feature provided by System V so that any + // process that exit's without calling close() is accounted + // for. It doesn't help us if the last process does this (as we + // have no way of getting control to remove the + // ACE_SV_Semaphore) but it will work if any process other than + // the last does an exit (intentional or unintentional). + // + // The second member, [1], of the ACE_SV_Semaphore is used as a + // lock variable to avoid any race conditions in the create() + // and close() functions. + // + // The members beyond [1] are actual ACE_SV_Semaphore values in + // the array of SV_Semaphores (which may be sized by the user + // in the constructor). +{ +public: + enum + { + ACE_CREATE = IPC_CREAT, + ACE_OPEN = 0 + }; + + // = Initialization and termination methods. + ACE_SV_Semaphore_Complex (void); + ACE_SV_Semaphore_Complex (key_t key, + int create = ACE_SV_Semaphore_Complex::ACE_CREATE, + int initial_value = 1, + int nsems = 1, + int perms = ACE_DEFAULT_PERMS); + ACE_SV_Semaphore_Complex (const char *name, + int create = ACE_SV_Semaphore_Complex::ACE_CREATE, + int initial_value = 1, + int nsems = 1, + int perms = ACE_DEFAULT_PERMS); + ~ACE_SV_Semaphore_Complex (void); + + int open (const char *name, + int flags = ACE_SV_Semaphore_Simple::ACE_CREATE, + int initial_value = 1, + int nsems = 1, + int perms = ACE_DEFAULT_PERMS); + // Open or create an array of SV_Semaphores. We return 0 if all is + // OK, else -1. + + int open (key_t key, + int flags = ACE_SV_Semaphore_Simple::ACE_CREATE, + int initial_value = 1, + int nsems = 1, + int perms = ACE_DEFAULT_PERMS); + // Open or create an array of SV_Semaphores. We return 0 if all is + // OK, else -1. + + int close (void); + // Close an ACE_SV_Semaphore. Unlike the method, this + // method is for a process to call before it exits, when it is done + // with the ACE_SV_Semaphore. We "decrement" the counter of + // processes using the ACE_SV_Semaphore, and if this was the last + // one, we can remove the ACE_SV_Semaphore. + + // = Semaphore acquire and release methods. + + int acquire (int n = 0, int flags = 0) const; + // Acquire the semaphore. + + int acquire_read (int n = 0, int flags = 0) const; + // Acquire a semaphore for reading. + + int acquire_write (int n = 0, int flags = 0) const; + // Acquire a semaphore for writing + + int tryacquire (int n = 0, int flags = 0) const; + // Try to acquire the semaphore. + + int tryacquire_read (int n = 0, int flags = 0) const; + // Try to acquire the semaphore for reading. + + int tryacquire_write (int n = 0, int flags = 0) const; + // Try to acquire the semaphore for writing. + + int release (int n = 0, int flags = 0) const; + // Release the semaphore. + + // = Semaphore operation methods. + int op (int val, int n = 0, int flags = 0) const; + int op (sembuf op_vec[], int n) const; + + // = Semaphore control methods. + int control (int cmd, semun arg, int n = 0) const; + int control (int cmd, int value = 0, int n = 0) const; + + // = Upgrade access control... + ACE_SV_Semaphore_Simple::get_id; + ACE_SV_Semaphore_Simple::remove; + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + static const int BIGCOUNT_; + static sembuf op_lock_[2]; + static sembuf op_endcreate_[2]; + static sembuf op_open_[1]; + static sembuf op_close_[3]; + static sembuf op_unlock_[1]; +}; + +#include "ace/SV_Semaphore_Complex.i" +#endif /* ACE_SV_SEMAPHORE_COMPLEX_H */ diff --git a/ace/SV_Semaphore_Complex.i b/ace/SV_Semaphore_Complex.i new file mode 100644 index 00000000000..b85fd09ec6d --- /dev/null +++ b/ace/SV_Semaphore_Complex.i @@ -0,0 +1,83 @@ +/* -*- C++ -*- */ +// $Id$ + +// SV_Semaphore_Complex.i + +#include "ace/Trace.h" + +inline int +ACE_SV_Semaphore_Complex::acquire (int n, int flags) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Complex::acquire"); + return ACE_SV_Semaphore_Simple::acquire (n + 2, flags); +} + +inline int +ACE_SV_Semaphore_Complex::acquire_read (int n, int flags) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Complex::acquire_read"); + return this->acquire (n, flags); +} + +inline int +ACE_SV_Semaphore_Complex::acquire_write (int n, int flags) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Complex::acquire_write"); + return this->acquire (n, flags); +} + +inline int +ACE_SV_Semaphore_Complex::tryacquire (int n, int flags) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Complex::tryacquire"); + return ACE_SV_Semaphore_Simple::tryacquire (n + 2, flags); +} + +inline int +ACE_SV_Semaphore_Complex::tryacquire_read (int n, int flags) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Complex::tryacquire_read"); + return this->tryacquire (n, flags); +} + +inline int +ACE_SV_Semaphore_Complex::tryacquire_write (int n, int flags) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Complex::tryacquire_write"); + return this->tryacquire (n, flags); +} + +inline int +ACE_SV_Semaphore_Complex::release (int n, int flags) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Complex::release"); + return ACE_SV_Semaphore_Simple::release (n + 2, flags); +} + +inline int +ACE_SV_Semaphore_Complex::op (int val, int n, int flags) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Complex::op"); + return ACE_SV_Semaphore_Simple::op (val, n + 2, flags); +} + +inline int +ACE_SV_Semaphore_Complex::op (sembuf op_vec[], int n) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Complex::op"); + return ACE_SV_Semaphore_Simple::op (op_vec, n + 2); +} + +inline int +ACE_SV_Semaphore_Complex::control (int cmd, semun arg, int n) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Complex::control"); + return ACE_SV_Semaphore_Simple::control (cmd, arg, n + 2); +} + +inline int +ACE_SV_Semaphore_Complex::control (int cmd, int value, int n) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Complex::control"); + return ACE_SV_Semaphore_Simple::control (cmd, value, n + 2); +} diff --git a/ace/SV_Semaphore_Simple.cpp b/ace/SV_Semaphore_Simple.cpp new file mode 100644 index 00000000000..6ae67ea116d --- /dev/null +++ b/ace/SV_Semaphore_Simple.cpp @@ -0,0 +1,179 @@ +// SV_Semaphore_Simple.cpp +// $Id$ + +/* -*- C++ -*- */ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/SV_Semaphore_Simple.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_SV_Semaphore_Simple) + +void +ACE_SV_Semaphore_Simple::dump (void) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::dump"); +} + +int +ACE_SV_Semaphore_Simple::control (int cmd, + int value, + int semnum) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::control"); + if (this->internal_id_ == -1) + return -1; + else + { + semun semctl_arg; + + semctl_arg.val = value; + return ACE_OS::semctl (this->internal_id_, semnum, + cmd, semctl_arg); + } +} + +int +ACE_SV_Semaphore_Simple::init (key_t k, int i) +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::init"); + this->key_ = k; + this->internal_id_ = i; + return 0; +} + +// General ACE_SV_Semaphore operation. Increment or decrement by a +// specific amount (positive or negative; amount can`t be zero). + +int +ACE_SV_Semaphore_Simple::op (int val, int n, int flags) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::op"); + sembuf op_op; + + op_op.sem_num = n; + op_op.sem_flg = flags; + + if (this->internal_id_ == -1) + return -1; + else if ((op_op.sem_op = val) == 0) + return -1; + else + return ACE_OS::semop (this->internal_id_, &op_op, 1); +} + +// Open or create one or more SV_Semaphores. We return 0 if all is +// OK, else -1. + +int +ACE_SV_Semaphore_Simple::open (key_t k, + int flags, + int initial_value, + int n, + int perms) +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::open"); + union semun ivalue; + + if (k == IPC_PRIVATE || k == ACE_INVALID_SEM_KEY) + return -1; + + ivalue.val = initial_value; + this->key_ = k; + this->sem_number_ = n; + + this->internal_id_ = ACE_OS::semget (this->key_, n, perms | flags); + + if (this->internal_id_ == -1) + return -1; + + if (flags == IPC_CREAT) + { + for (int i = 0; i < n; i++) + if (ACE_OS::semctl (this->internal_id_, i, SETVAL, ivalue) == -1) + return -1; + } + + return 0; +} + +ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple (key_t k, + int flags, + int initial_value, + int n, + int perms) + : key_ (k) +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple"); + if (this->open (k, flags, initial_value, n, perms) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_SV_Semaphore::ACE_SV_Semaphore")); +} + +// Convert name to key. This function is used internally to create keys +// for the semaphores. A valid name contains letters and digits +// only and MUST start with a letter. +// +// The method for generating names is not very sophisticated, so +// caller should not pass strings which match each other for the first +// LUSED characters when he wants to get a different key. + +key_t +ACE_SV_Semaphore_Simple::name_2_key (const char *name) +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::name_2_key"); + + if (name == 0 || !isalpha (*name)) + { + errno = EINVAL; + return ACE_INVALID_SEM_KEY; + } + + // The key is the character value of the first LUSED chars from name + // placed in proto. + + u_long proto = 0; + + for (int i = 0; i < LUSED; ++i) + { + if (*name == '\0') + break; + proto <<= 8; + proto |= *name++ & 0xff; + } + + return (key_t) proto; +} + +// Open or create a ACE_SV_Semaphore. We return 1 if all is OK, else +// 0. + +int +ACE_SV_Semaphore_Simple::open (const char *name, + int flags, + int initial_value, + int n, + int perms) +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::open"); + return this->open (this->name_2_key (name), + flags, initial_value, n, perms); +} + +ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple (const char *name, + int flags, + int initial_value, + int n, + int perms) +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple"); + if (this->open (name, flags, initial_value, n, perms) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", + "ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple")); +} + +ACE_SV_Semaphore_Simple::~ACE_SV_Semaphore_Simple (void) +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::~ACE_SV_Semaphore_Simple"); + this->close (); +} + diff --git a/ace/SV_Semaphore_Simple.h b/ace/SV_Semaphore_Simple.h new file mode 100644 index 00000000000..660c69faf5d --- /dev/null +++ b/ace/SV_Semaphore_Simple.h @@ -0,0 +1,138 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// SV_Semaphore_Simple.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SV_SEMAPHORE_SIMPLE_H) +#define ACE_SV_SEMAPHORE_SIMPLE_H + +#include "ace/ACE.h" + +class ACE_Export ACE_SV_Semaphore_Simple + // = TITLE + // This is a simple semaphore package that assumes there are + // no race conditions for initialization (i.e., the order of + // process startup must be well defined). +{ +public: + enum + { + ACE_CREATE = IPC_CREAT, + ACE_OPEN = 0 + }; + + // = Initialization and termination methods. + ACE_SV_Semaphore_Simple (void); + ACE_SV_Semaphore_Simple (key_t key, + int flags = ACE_SV_Semaphore_Simple::ACE_CREATE, + int initial_value = 1, + int nsems = 1, + int perms = ACE_DEFAULT_PERMS); + ACE_SV_Semaphore_Simple (const char *name, + int flags = ACE_SV_Semaphore_Simple::ACE_CREATE, + int initial_value = 1, + int nsems = 1, + int perms = ACE_DEFAULT_PERMS); + ~ACE_SV_Semaphore_Simple (void); + + int open (const char *name, + int flags = ACE_SV_Semaphore_Simple::ACE_CREATE, + int initial_value = 1, + int nsems = 1, + int perms = ACE_DEFAULT_PERMS); + + int open (key_t key, + int flags = ACE_SV_Semaphore_Simple::ACE_CREATE, + int initial_value = 1, + int nsems = 1, + int perms = ACE_DEFAULT_PERMS); + // Open or create one or more SV_Semaphores. We return 0 if all is + // OK, else -1. + + int close (void); + // Close a ACE_SV_Semaphore, marking it as invalid for subsequent + // operations... + + int remove (void) const; + // Remove all SV_Semaphores associated with a particular key. This + // call is intended to be called from a server, for example, when it + // is being shut down, as we do an IPC_RMID on the ACE_SV_Semaphore, + // regardless of whether other processes may be using it or not. + // Most other processes should use close() below. + + // = Semaphore acquire and release methods. + int acquire (int n = 0, int flags = 0) const; + // Wait until a ACE_SV_Semaphore's value is greater than 0, the + // decrement it by 1 and return. Dijkstra's P operation, Tannenbaums + // DOWN operation. + + int acquire_read (int n = 0, int flags = 0) const; + // Acquire a semaphore for reading. + + int acquire_write (int n = 0, int flags = 0) const; + // Acquire a semaphore for writing + + int tryacquire (int n = 0, int flags = 0) const; + // Non-blocking version of . + + int tryacquire_read (int n = 0, int flags = 0) const; + // Try to acquire the semaphore for reading. + + int tryacquire_write (int n = 0, int flags = 0) const; + // Try to acquire the semaphore for writing. + + int release (int n = 0, int flags = 0) const; + // Increment ACE_SV_Semaphore by one. Dijkstra's V operation, + // Tannenbaums UP operation. + + // = Semaphore operation methods. + int op (int val, int semnum = 0, int flags = 0) const; + // General ACE_SV_Semaphore operation. Increment or decrement by a + // specific amount (positive or negative; amount can`t be zero). + + int op (sembuf op_vec[], int nsems) const; + // General ACE_SV_Semaphore operation on an array of SV_Semaphores. + + // = Semaphore control methods. + int control (int cmd, semun arg, int semnum = 0) const; + int control (int cmd, int value = 0, int semnum = 0) const; + + int get_id (void) const; + // Get underlying internal id. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + key_t key_; + int internal_id_; + int sem_number_; + + int init (key_t k = ACE_INVALID_SEM_KEY, int i = -1); + key_t name_2_key (const char *name); + // Convert name to key This function is used internally to create + // keys for the semaphores. A valid name contains letters and + // digits only and MUST start with a letter. + // + // The method for generating names is not very sophisticated, so + // caller should not pass strings which match each other for the first + // LUSED characters when he wants to get a different key. +}; + +#include "ace/SV_Semaphore_Simple.i" +#endif /* _SV_SEMAPHORE_SIMPLE_H */ diff --git a/ace/SV_Semaphore_Simple.i b/ace/SV_Semaphore_Simple.i new file mode 100644 index 00000000000..1679dd724c6 --- /dev/null +++ b/ace/SV_Semaphore_Simple.i @@ -0,0 +1,132 @@ +/* -*- C++ -*- */ +// $Id$ + +// SV_Semaphore_Simple.i + +#include "ace/SV_Semaphore_Simple.h" +#include "ace/Trace.h" + +#undef LUSED +#define LUSED 4 // # of chars used from name + +inline int +ACE_SV_Semaphore_Simple::control (int cmd, + semun arg, + int semnum) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::control"); + return this->internal_id_ == -1 ? + -1 : ACE_OS::semctl (this->internal_id_, semnum, cmd, arg); +} + +// Remove all SV_Semaphores associated with a particular key. This +// call is intended to be called from a server, for example, when it +// is being shut down, as we do an IPC_RMID on the ACE_SV_Semaphore, +// regardless of whether other processes may be using it or not. Most +// other processes should use close() below. + +inline int +ACE_SV_Semaphore_Simple::remove (void) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::remove"); + int result = this->control (IPC_RMID); + ((ACE_SV_Semaphore_Simple *) this)->init (); + return result; +} + +// Close a ACE_SV_Semaphore, marking it as invalid for subsequent +// operations... + +inline int +ACE_SV_Semaphore_Simple::close (void) +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::close"); + return this->init (); +} + +// General ACE_SV_Semaphore operation on an array of SV_Semaphores. + +inline int +ACE_SV_Semaphore_Simple::op (sembuf op_vec[], int n) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::op"); + return this->internal_id_ == -1 + ? -1 : ACE_OS::semop (this->internal_id_, op_vec, n); +} + +inline +ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple (void) +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple"); + this->init (); +} + +// Wait until a ACE_SV_Semaphore's value is greater than 0, the +// decrement it by 1 and return. Dijkstra's P operation, Tannenbaums +// DOWN operation. + +inline int +ACE_SV_Semaphore_Simple::acquire (int n, int flags) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::acquire"); + return this->op (-1, n, flags); +} + +inline int +ACE_SV_Semaphore_Simple::acquire_read (int n, int flags) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::acquire_read"); + return this->acquire (n, flags); +} + +inline int +ACE_SV_Semaphore_Simple::acquire_write (int n, int flags) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::acquire_write"); + return this->acquire (n, flags); +} + +// Non-blocking version of acquire(). + +inline int +ACE_SV_Semaphore_Simple::tryacquire (int n, int flags) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::tryacquire"); + return this->op (-1, n, flags | IPC_NOWAIT); +} + +// Non-blocking version of acquire(). + +inline int +ACE_SV_Semaphore_Simple::tryacquire_read (int n, int flags) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::tryacquire_read"); + return this->tryacquire (n, flags); +} + +// Non-blocking version of acquire(). + +inline int +ACE_SV_Semaphore_Simple::tryacquire_write (int n, int flags) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::tryacquire_write"); + return this->tryacquire (n, flags); +} + +// Increment ACE_SV_Semaphore by one. Dijkstra's V operation, +// Tannenbaums UP operation. + +inline int +ACE_SV_Semaphore_Simple::release (int n, int flags) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::release"); + return this->op (1, n, flags); +} + +inline int +ACE_SV_Semaphore_Simple::get_id (void) const +{ + ACE_TRACE ("ACE_SV_Semaphore_Simple::get_id"); + return this->internal_id_; +} + diff --git a/ace/SV_Shared_Memory.cpp b/ace/SV_Shared_Memory.cpp new file mode 100644 index 00000000000..8cfc1adc2c8 --- /dev/null +++ b/ace/SV_Shared_Memory.cpp @@ -0,0 +1,82 @@ +// SV_Shared_Memory.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/SV_Shared_Memory.h" +#include "ace/Log_Msg.h" + +#if !defined (__ACE_INLINE__) +#include "ace/SV_Shared_Memory.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_SV_Shared_Memory) + +void +ACE_SV_Shared_Memory::dump (void) const +{ + ACE_TRACE ("ACE_SV_Shared_Memory::dump"); +} + +// Creates a shared memory segment of SIZE bytes and *does* attach to +// this segment. + +int +ACE_SV_Shared_Memory::open_and_attach (key_t external_id, + size_t sz, + int create, + int perms, + void *virtual_addr, + int flags) +{ + ACE_TRACE ("ACE_SV_Shared_Memory::open_and_attach"); + if (this->open (external_id, sz, create, perms) == -1) + return -1; + else if (this->attach (virtual_addr, flags) == -1) + return -1; + else + return 0; +} + +// Constructor interface to this->open_and_attach () member function. + +ACE_SV_Shared_Memory::ACE_SV_Shared_Memory (key_t external_id, + size_t sz, + int create, + int perms, + void *virtual_addr, + int flags) +{ + ACE_TRACE ("ACE_SV_Shared_Memory::ACE_SV_Shared_Memory"); + if (this->open_and_attach (external_id, sz, create, + perms, virtual_addr, flags) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", + "ACE_SV_Shared_Memory::ACE_SV_Shared_Memory")); +} + +// The "do nothing" constructor. + +ACE_SV_Shared_Memory::ACE_SV_Shared_Memory (void) + : segment_ptr_ (0), + internal_id_ (0), + size_ (0) +{ + ACE_TRACE ("ACE_SV_Shared_Memory::ACE_SV_Shared_Memory"); +} + +// Added this constructor to accept an internal id, the one generated +// when a server constructs with the key IPC_PRIVATE. The client can +// be passed ACE_SV_Shared_Memory::internal_id via a socket and call +// this construtor to attach the existing segment. This prevents +// having to hard-code a key in advance. Courtesy of Marvin Wolfthal +// (maw@fsg.com). + +ACE_SV_Shared_Memory::ACE_SV_Shared_Memory (ACE_HANDLE int_id, + int flags) + : internal_id_ (int_id), + size_ (0) +{ + ACE_TRACE ("ACE_SV_Shared_Memory::ACE_SV_Shared_Memory"); + if (this->attach (0, flags) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", + "ACE_SV_Shared_Memory::ACE_SV_Shared_Memory")); +} diff --git a/ace/SV_Shared_Memory.h b/ace/SV_Shared_Memory.h new file mode 100644 index 00000000000..b7de7c8febb --- /dev/null +++ b/ace/SV_Shared_Memory.h @@ -0,0 +1,107 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// SV_Shared_Memory.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SV_SHARED_MEMORY_H) +#define ACE_SV_SHARED_MEMORY_H + +#include "ace/ACE.h" + +class ACE_Export ACE_SV_Shared_Memory + // = TITLE + // This is a wrapper for System V shared memory. +{ +public: + enum + { + ACE_CREATE = IPC_CREAT, + ACE_OPEN = 0 + }; + + // = Initialization and termination methods. + ACE_SV_Shared_Memory (void); + ACE_SV_Shared_Memory (key_t external_id, + size_t size, + int create, + int perms = ACE_DEFAULT_PERMS, + void *virtual_addr = 0, + int flags = 0); + + ACE_SV_Shared_Memory (ACE_HANDLE internal_id, + int flags = 0); + + int open (key_t external_id, + size_t size, + int create = ACE_SV_Shared_Memory::ACE_OPEN, + int perms = ACE_DEFAULT_PERMS); + + int open_and_attach (key_t external_id, + size_t size, + int create = ACE_SV_Shared_Memory::ACE_OPEN, + int perms = ACE_DEFAULT_PERMS, + void *virtual_addr = 0, + int flags = 0); + + int attach (void *virtual_addr = 0, + int flags =0); + // Attach this shared memory segment. + + int detach (void); + // Detach this shared memory segment. + + int remove (void); + // Remove this shared memory segment. + + int control (int cmd, void *buf); + // Forward to underlying System V . + + // = Segment-related info. + void *get_segment_ptr (void) const; + int get_segment_size (void) const; + + ACE_HANDLE get_id (void) const; + // Return the ID of the shared memory segment (i.e., an ACE_HANDLE). + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + enum + { + ALIGN_WORDB = 8 // Most restrictive alignment. + }; + + ACE_HANDLE internal_id_; + // Internal identifier. + + int size_; + // Size of the mapped segment. + + void *segment_ptr_; + // Pointer to the beginning of the segment. + + int round_up (size_t len); + // Round up to an appropriate page size. +}; + +#if defined (__ACE_INLINE__) +#include "ace/SV_Shared_Memory.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_SV_SHARED_MEMORY_H */ diff --git a/ace/SV_Shared_Memory.i b/ace/SV_Shared_Memory.i new file mode 100644 index 00000000000..5ac4df7c133 --- /dev/null +++ b/ace/SV_Shared_Memory.i @@ -0,0 +1,105 @@ +/* -*- C++ -*- */ +// $Id$ + +// SV_Shared_Memory.i + +#include "ace/SV_Shared_Memory.h" + +ACE_INLINE int +ACE_SV_Shared_Memory::round_up (size_t len) +{ + ACE_TRACE ("ACE_SV_Shared_Memory::round_up"); + return (len + ACE_SV_Shared_Memory::ALIGN_WORDB - 1) & ~(ACE_SV_Shared_Memory::ALIGN_WORDB - 1); +} + +// Creates a shared memory segment of SIZE bytes. Does *not* attach +// this memory segment... + +ACE_INLINE int +ACE_SV_Shared_Memory::open (key_t external_id, size_t sz, int create, int perms) +{ + ACE_TRACE ("ACE_SV_Shared_Memory::open"); +#if defined (ACE_WIN32) + ACE_NOTSUP_RETURN (-1); +#else + this->segment_ptr_ = 0; + this->size_ = sz; + + this->internal_id_ = ACE_OS::shmget (external_id, sz, create | perms); + + return this->internal_id_ == -1 ? -1 : 0; +#endif /* ACE_WIN32 */ +} + +// Attachs to the shared memory segment. + +ACE_INLINE int +ACE_SV_Shared_Memory::attach (void *virtual_addr, int flags) +{ + ACE_TRACE ("ACE_SV_Shared_Memory::attach"); +#if defined (ACE_WIN32) + ACE_NOTSUP_RETURN (-1); +#else + this->segment_ptr_ = ACE_OS::shmat (this->internal_id_, virtual_addr, flags); + return this->segment_ptr_ == (void *) -1 ? -1 : 0; +#endif /* ACE_WIN32 */ +} + +// Interface to the underlying shared memory control function. + +ACE_INLINE int +ACE_SV_Shared_Memory::control (int cmd, void *buf) +{ + ACE_TRACE ("ACE_SV_Shared_Memory::control"); +#if defined (ACE_WIN32) + ACE_NOTSUP_RETURN (-1); +#else + return ACE_OS::shmctl (this->internal_id_, cmd, (struct shmid_ds *) buf); +#endif /* ACE_WIN32 */ +} + +// The overall size of the segment. + +ACE_INLINE int +ACE_SV_Shared_Memory::get_segment_size (void) const +{ + ACE_TRACE ("ACE_SV_Shared_Memory::get_segment_size"); + return this->size_; +} + +// Removes the shared memory segment. + +ACE_INLINE int +ACE_SV_Shared_Memory::remove (void) +{ + ACE_TRACE ("ACE_SV_Shared_Memory::remove"); +#if defined (ACE_WIN32) + ACE_NOTSUP_RETURN (-1); +#else + return ACE_OS::shmctl (this->internal_id_, IPC_RMID, 0); +#endif /* ACE_WIN32 */ +} + +// Detach the current binding between this->segment_ptr and the shared +// memory segment. + +ACE_INLINE int +ACE_SV_Shared_Memory::detach (void) +{ + ACE_TRACE ("ACE_SV_Shared_Memory::detach"); + return ACE_OS::shmdt (this->segment_ptr_); +} + +ACE_INLINE void * +ACE_SV_Shared_Memory::get_segment_ptr (void) const +{ + ACE_TRACE ("ACE_SV_Shared_Memory::get_segment_ptr"); + return this->segment_ptr_; +} + +ACE_INLINE ACE_HANDLE +ACE_SV_Shared_Memory::get_id (void) const +{ + ACE_TRACE ("ACE_SV_Shared_Memory::get_id"); + return this->internal_id_; +} diff --git a/ace/Service_Config.cpp b/ace/Service_Config.cpp new file mode 100644 index 00000000000..991ea1f9d76 --- /dev/null +++ b/ace/Service_Config.cpp @@ -0,0 +1,928 @@ +// Service_Config.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Svc_Conf.h" +#include "ace/Get_Opt.h" +#include "ace/ARGV.h" +#include "ace/Malloc.h" +#include "ace/Service_Manager.h" +#include "ace/Service_Repository.h" +#include "ace/Service_Record.h" +#include "ace/Set.h" +#include "ace/Auto_Ptr.h" +#include "ace/Service_Config.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Service_Config.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Service_Config) + +void +ACE_Service_Config::dump (void) const +{ + ACE_TRACE ("ACE_Service_Config::dump"); +} + +// All the factory functions that allocate default statically linked +// services should be placed below. + +// Allocate a Service Manager. + +ACE_SVC_FACTORY_DEFINE (ACE_Service_Manager) + +// ---------------------------------------- +// Process-wide Service Repository. +/* static */ +ACE_Service_Repository *ACE_Service_Config::svc_rep_ = 0; + +// Controls whether the Service_Repository is deleted when we shut +// down (we can only delete it safely if we created it!) +/* static */ +int ACE_Service_Config::delete_svc_rep_ = 0; + +// Process-wide Thread Manager. +/* static */ +ACE_Thread_Manager *ACE_Service_Config::thr_mgr_ = 0; + +// Controls whether the Thread_Manager is deleted when we shut down +// (we can only delete it safely if we created it!) +/* static */ +int ACE_Service_Config::delete_thr_mgr_ = 0; + +// Process-wide ACE_Allocator. +/* static */ +ACE_Allocator *ACE_Service_Config::allocator_ = 0; + +// Controls whether the Allocator is deleted when we shut down (we can +// only delete it safely if we created it!) +/* static */ +int ACE_Service_Config::delete_allocator_ = 0; + +// Process-wide ACE_Proactor. +/* static */ +ACE_Proactor *ACE_Service_Config::proactor_ = 0; + +// Controls whether the Proactor is deleted when we shut down (we can +// only delete it safely if we created it!) +/* static */ +int ACE_Service_Config::delete_proactor_ = 0; + +// Process-wide ACE_Reactor. +/* static */ +ACE_Reactor *ACE_Service_Config::reactor_ = 0; + +// Controls whether the Reactor is deleted when we shut down (we can +// only delete it safely if we created it!) +/* static */ +int ACE_Service_Config::delete_reactor_ = 0; + +// Process-wide ACE_ReactorEx. +/* static */ +ACE_ReactorEx *ACE_Service_Config::reactorEx_ = 0; + +// Controls whether the ReactorEx is deleted when we shut down (we can +// only delete it safely if we created it!) +/* static */ +int ACE_Service_Config::delete_reactorEx_ = 0; + +// Make this the default. +typedef ACE_Malloc + ACE_DEFAULT_MALLOC; + +// Terminate the eventloop. +/* static */ +sig_atomic_t ACE_Service_Config::end_reactor_event_loop_ = 0; +sig_atomic_t ACE_Service_Config::end_proactor_event_loop_ = 0; +sig_atomic_t ACE_Service_Config::end_reactorEx_event_loop_ = 0; + +// Trigger a reconfiguration. +/* static */ +sig_atomic_t ACE_Service_Config::reconfig_occurred_ = 0; + + // = Set by command-line options. +/* static */ +char ACE_Service_Config::debug_ = 0; +char ACE_Service_Config::be_a_daemon_ = 0; +char ACE_Service_Config::no_defaults_ = 0; + +// Number of the signal used to trigger reconfiguration. +/* static */ +int ACE_Service_Config::signum_ = SIGHUP; + +// Name of the service configuration file. +const char *ACE_Service_Config::service_config_file_ = ACE_DEFAULT_SVC_CONF; + +// Name of file used to store messages. +const char *ACE_Service_Config::logger_key_ = "/tmp/server_daemon"; + +// Define the object that describes the service statically. +ACE_STATIC_SVC_DEFINE (ACE_Service_Manager, + "ACE_Service_Manager", ACE_SVC_OBJ_T, &ACE_SVC_NAME (ACE_Service_Manager), + ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ, 0) + +ACE_STATIC_SVC_REQUIRE (ACE_Service_Manager) + +// List of statically configured services. + +ACE_STATIC_SVCS * +ACE_Service_Config::static_svcs (void) +{ + static ACE_STATIC_SVCS *instance_ = 0; + + // Add other default services here if you'd like. + + if (instance_ == 0) + ACE_NEW_RETURN (instance_, ACE_STATIC_SVCS, 0); + + return instance_; +} + +ACE_Allocator * +ACE_Service_Config::allocator (void) +{ + ACE_TRACE ("ACE_Service_Config::allocator"); + if (ACE_Service_Config::allocator_ == 0) + { + ACE_NEW_RETURN (ACE_Service_Config::allocator_, + ACE_Allocator_Adapter , + 0); + ACE_Service_Config::delete_allocator_ = 1; + } + return ACE_Service_Config::allocator_; +} + +ACE_Allocator * +ACE_Service_Config::allocator (ACE_Allocator *r) +{ + ACE_TRACE ("ACE_Service_Config::allocator"); + + ACE_Allocator *t = ACE_Service_Config::allocator_; + + // We can't safely delete it since we don't know who created it! + ACE_Service_Config::delete_allocator_ = 0; + + ACE_Service_Config::allocator_ = r; + return t; +} + +ACE_Reactor * +ACE_Service_Config::reactor (void) +{ + ACE_TRACE ("ACE_Service_Config::reactor"); + if (ACE_Service_Config::reactor_ == 0) + { + ACE_NEW_RETURN (ACE_Service_Config::reactor_, ACE_Reactor, 0); + ACE_Service_Config::delete_reactor_ = 1; + } + return ACE_Service_Config::reactor_; +} + +ACE_Reactor * +ACE_Service_Config::reactor (ACE_Reactor *r) +{ + ACE_TRACE ("ACE_Service_Config::reactor"); + + ACE_Reactor *t = ACE_Service_Config::reactor_; + // We can't safely delete it since we don't know who created it! + ACE_Service_Config::delete_reactor_ = 0; + + ACE_Service_Config::reactor_ = r; + return t; +} + +ACE_Proactor * +ACE_Service_Config::proactor (size_t threads) +{ + ACE_TRACE ("ACE_Service_Config::proactor"); + if (ACE_Service_Config::proactor_ == 0) + { + ACE_NEW_RETURN (ACE_Service_Config::proactor_, ACE_Proactor (threads), 0); + ACE_Service_Config::delete_proactor_ = 1; + } + return ACE_Service_Config::proactor_; +} + +ACE_Proactor * +ACE_Service_Config::proactor (ACE_Proactor *r) +{ + ACE_TRACE ("ACE_Service_Config::proactor"); + + ACE_Proactor *t = ACE_Service_Config::proactor_; + // We can't safely delete it since we don't know who created it! + ACE_Service_Config::delete_proactor_ = 0; + + ACE_Service_Config::proactor_ = r; + return t; +} + +ACE_ReactorEx * +ACE_Service_Config::reactorEx (void) +{ + ACE_TRACE ("ACE_Service_Config::reactorEx"); + if (ACE_Service_Config::reactorEx_ == 0) + { + ACE_NEW_RETURN (ACE_Service_Config::reactorEx_, ACE_ReactorEx, 0); + ACE_Service_Config::delete_reactorEx_ = 1; + } + + return ACE_Service_Config::reactorEx_; +} + +ACE_ReactorEx * +ACE_Service_Config::reactorEx (ACE_ReactorEx *r) +{ + ACE_TRACE ("ACE_Service_Config::reactorEx"); + + ACE_ReactorEx *t = ACE_Service_Config::reactorEx_; + // We can't safely delete it since we don't know who created it! + ACE_Service_Config::delete_reactorEx_ = 0; + + ACE_Service_Config::reactorEx_ = r; + return t; +} + +ACE_Service_Repository * +ACE_Service_Config::svc_rep (void) +{ + ACE_TRACE ("ACE_Service_Config::svc_rep"); + + if (ACE_Service_Config::svc_rep_ == 0) + { + ACE_NEW_RETURN (ACE_Service_Config::svc_rep_, ACE_Service_Repository, 0); + ACE_Service_Config::delete_svc_rep_ = 1; + } + + return ACE_Service_Config::svc_rep_; +} + +ACE_Service_Repository * +ACE_Service_Config::svc_rep (ACE_Service_Repository *s) +{ + ACE_TRACE ("ACE_Service_Config::svc_rep"); + + ACE_Service_Repository *t = ACE_Service_Config::svc_rep_; + // We can't safely delete it since we don't know who created it! + ACE_Service_Config::delete_svc_rep_ = 0; + + ACE_Service_Config::svc_rep_ = s; + return t; +} + +ACE_Thread_Manager * +ACE_Service_Config::thr_mgr (void) +{ + ACE_TRACE ("ACE_Service_Config::thr_mgr"); + + if (ACE_Service_Config::thr_mgr_ == 0) + { + ACE_NEW_RETURN (ACE_Service_Config::thr_mgr_, ACE_Thread_Manager, 0); + ACE_Service_Config::delete_thr_mgr_ = 1; + } + + return ACE_Service_Config::thr_mgr_; +} + +ACE_Thread_Manager * +ACE_Service_Config::thr_mgr (ACE_Thread_Manager *tm) +{ + ACE_TRACE ("ACE_Service_Config::thr_mgr"); + + ACE_Thread_Manager *t = ACE_Service_Config::thr_mgr_; + // We can't safely delete it since we don't know who created it! + ACE_Service_Config::delete_thr_mgr_ = 0; + + ACE_Service_Config::thr_mgr_ = tm; + return t; +} + +// Totally remove from the daemon by removing it from the +// ACE_Reactor, and unlinking it if necessary. + +int +ACE_Service_Config::remove (const char svc_name[]) +{ + ACE_TRACE ("ACE_Service_Config::remove"); + return ACE_Service_Config::svc_rep ()->remove (svc_name); +} + +// Suspend SVC_NAME. Note that this will not unlink the service from +// the daemon if it was dynamically linked, it will mark it as being +// suspended in the Service Repository and call the suspend() member +// function on the appropriate ACE_Service_Object. A service can be +// resumed later on by calling the RESUME() member function... + +int +ACE_Service_Config::suspend (const char svc_name[]) +{ + ACE_TRACE ("ACE_Service_Config::suspend"); + return ACE_Service_Config::svc_rep ()->suspend (svc_name); +} + +// Resume a SVC_NAME that was previously suspended or has not yet +// been resumed (e.g., a static service). + +int +ACE_Service_Config::resume (const char svc_name[]) +{ + ACE_TRACE ("ACE_Service_Config::resume"); + return ACE_Service_Config::svc_rep ()->resume (svc_name); +} + +// Initialize the Service Repository. Note that this *must* +// be performed in the constructor (rather than open()) since +// otherwise the repository will not be properly initialized +// to allow static configuration of services... + +ACE_Service_Config::ACE_Service_Config (int ignore_defaults, + size_t size, + int signum) +{ + ACE_TRACE ("ACE_Service_Config::ACE_Service_Config"); + ACE_Service_Config::no_defaults_ = ignore_defaults; + ACE_Service_Config::signum_ = signum; + + // Initialize the Service Repository. + + if (ACE_Service_Config::svc_rep_ == 0) + { + ACE_NEW (ACE_Service_Config::svc_rep_, + ACE_Service_Repository (size)); + + // We created it, so we own it! + ACE_Service_Config::delete_svc_rep_ = 1; + } + + // Initialize the ACE_Reactor (the ACE_Reactor should be the same + // size as the ACE_Service_Repository). + + if (ACE_Service_Config::reactor_ == 0) + { + ACE_NEW (ACE_Service_Config::reactor_, + ACE_Reactor (size)); + + // We created it, so we own it! + ACE_Service_Config::delete_reactor_ = 1; + } + +// There's no point in dealing with this on NT since it doesn't really +// support signals very well... +#if !defined (ACE_WIN32) + // This really ought to be a Singleton I suspect... + + if (ACE_Service_Config::reactor_->register_handler + (ACE_Service_Config::signum_, this) == -1) + ACE_ERROR ((LM_ERROR, "can't register signal handler\n")); +#endif /* !ACE_WIN32 */ +} + +// Handle the command-line options intended for the +// ACE_Service_Config. + +void +ACE_Service_Config::parse_args (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_Service_Config::parse_args"); + ACE_Get_Opt getopt (argc, argv, "bdf:ns:", 1); // Start at argv[1] + + for (int c; (c = getopt ()) != -1; ) + switch (c) + { + case 'b': + ACE_Service_Config::be_a_daemon_ = 1; + break; + case 'd': + ACE_Service_Config::debug_ = 1; + break; + case 'f': + ACE_Service_Config::service_config_file_ = getopt.optarg; + break; + case 'n': + ACE_Service_Config::no_defaults_ = 1; + break; + case 's': + { +// There's no point in dealing with this on NT since it doesn't really +// support signals very well... +#if !defined (ACE_WIN32) + ACE_Event_Handler *eh = 0; + + if (ACE_Service_Config::reactor ()->handler + (ACE_Service_Config::signum_, &eh) == -1) + ACE_ERROR ((LM_ERROR, "cannot obtain signal handler\n")); + + ACE_Service_Config::signum_ = ACE_OS::atoi (getopt.optarg); + + if (ACE_Service_Config::reactor ()->register_handler + (ACE_Service_Config::signum_, eh) == -1) + ACE_ERROR ((LM_ERROR, "cannot obtain signal handler\n")); +#endif /* !ACE_WIN32 */ + break; + } + default: + ACE_ERROR ((LM_ERROR, "%c is not a ACE_Service_Config option\n", c)); + break; + } +} + +// Initialize and activate a statically linked service. + +int +ACE_Service_Config::initialize (const char svc_name[], + char *parameters) +{ + ACE_TRACE ("ACE_Service_Config::initialize"); + ACE_ARGV args (parameters); + ACE_Service_Record *srp = 0; + + ACE_DEBUG ((LM_DEBUG, "opening static service %s\n", svc_name)); + + if (ACE_Service_Config::svc_rep ()->find + (svc_name, (const ACE_Service_Record **) &srp) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%s not found\n", svc_name), -1); + + else if (srp->type ()->init (args.argc (), args.argv ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "static initialization failed, %p\n", + svc_name), -1); + else + { + srp->active (1); + return 0; + } +} + +// Dynamically link the shared object file and retrieve a pointer to +// the designated shared object in this file. + +int +ACE_Service_Config::initialize (const ACE_Service_Record *sr, + char parameters[]) +{ + ACE_TRACE ("ACE_Service_Config::initialize"); + ACE_ARGV args (parameters); + + ACE_DEBUG ((LM_DEBUG, "opening dynamic service %s\n", sr->name ())); + + if (ACE_Service_Config::svc_rep ()->insert (sr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "insertion failed, %p\n", sr->name ()), -1); + + else if (sr->type ()->init (args.argc (), args.argv ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "dynamic initialization failed for %s\n", + sr->name ()), -1); + else + return 0; +} + +// Process service configuration requests as indicated in the +// . + +int +ACE_Service_Config::process_directives (void) +{ + ACE_TRACE ("ACE_Service_Config::process_directives"); + + FILE *fp = ACE_OS::fopen (ACE_Service_Config::service_config_file_, "r"); + + if (fp == 0) + { + errno = ENOENT; + return -1; // No service configuration file + } + else + { + ace_yyrestart (fp); + + ace_yyerrno = 0; + ace_yylineno = 1; + + // Use an auto_ptr to make sure that we release this memory + // regardless of how we exit... + ACE_NEW_RETURN (ace_obstack, ACE_Obstack, -1); + + auto_ptr holder (ace_obstack); + + ace_yyparse (); + + if (ace_yyerrno > 0) + errno = EINVAL; // This is a hack, better errors should be provided... + + return ace_yyerrno; + } +} + +// Add the default statically-linked services to the Service +// Repository. + +int +ACE_Service_Config::load_defaults (void) +{ + ACE_TRACE ("ACE_Service_Config::load_defaults"); + + ACE_Static_Svc_Descriptor **ssdp = 0; + ACE_STATIC_SVCS &svcs = *ACE_Service_Config::static_svcs (); + + for (ACE_STATIC_SVCS_ITERATOR iter (svcs); + iter.next (ssdp) != 0; + iter.advance ()) + { + ACE_Static_Svc_Descriptor *ssd = *ssdp; + + ACE_Service_Type *stp = + ace_create_service_type (ssd->name_, + ssd->type_, + (const void *) (*ssd->alloc_)(), + ssd->flags_); + if (stp == 0) + continue; + + const ACE_Service_Record *sr; + + ACE_NEW_RETURN (sr, ACE_Service_Record (ssd->name_, stp, + 0, ssd->active_), -1); + + if (ACE_Service_Config::svc_rep ()->insert (sr) == -1) + return -1; + } + return 0; +} + +// Performs an open without parsing command-line arguments. + +int +ACE_Service_Config::open (const char program_name[]) +{ + ACE_TRACE ("ACE_Service_Config::open"); + + // Only use STDERR if the users hasn't yet set the flags. + if (ACE_LOG_MSG->open (program_name, + ACE_LOG_MSG->flags() ? ACE_LOG_MSG->flags() : ACE_Log_Msg::STDERR, + ACE_Service_Config::logger_key_) == -1) + return -1; + ACE_DEBUG ((LM_STARTUP, "starting up daemon %n\n")); + + // Initialize the Service Repository (this will still work if user + // forgets to define an object of type ACE_Service_Config). + + if (ACE_Service_Config::svc_rep_ == 0) + { + ACE_NEW_RETURN (ACE_Service_Config::svc_rep_, + ACE_Service_Repository (ACE_Service_Config::MAX_SERVICES), -1); + + // We created it, so we own it! + ACE_Service_Config::delete_svc_rep_ = 1; + } + + // Initialize the ACE_Reactor (the ACE_Reactor should be the same + // size as the ACE_Service_Repository). + + if (ACE_Service_Config::reactor_ == 0) + { + ACE_NEW_RETURN (ACE_Service_Config::reactor_, + ACE_Reactor (ACE_Service_Config::MAX_SERVICES), -1); + // We created it, so we own it! + ACE_Service_Config::delete_reactor_ = 1; + } + + if (ACE_Service_Config::be_a_daemon_) + ACE_Service_Config::start_daemon (); + + // Register ourselves to receive reconfiguration requests via + // signals! + + if (ACE_Service_Config::no_defaults_ == 0 + && ACE_Service_Config::load_defaults () == -1) + return -1; + else + return ACE_Service_Config::process_directives (); +} + +ACE_Service_Config::ACE_Service_Config (const char program_name[]) +{ + ACE_TRACE ("ACE_Service_Config::ACE_Service_Config"); + + if (this->open (program_name) == -1 + && errno != ENOENT) + // Only print out an error if it wasn't the svc.conf file that was + // missing. + ACE_ERROR ((LM_ERROR, "%p\n", program_name)); +} + +// Signal handling API to trigger dynamic reconfiguration. + +int +ACE_Service_Config::handle_signal (int sig, siginfo_t *, ucontext_t *) +{ + ACE_TRACE ("ACE_Service_Config::handle_signal"); + + if (ACE_Service_Config::signum_ != sig) + ACE_ERROR ((LM_ERROR, + "error, signal %S does match %S\n", + sig, ACE_Service_Config::signum_)); + + if (ACE_Service_Config::debug_) + ACE_DEBUG ((LM_DEBUG, "signal %S occurred\n", sig)); + + ACE_Service_Config::reconfig_occurred_ = 1; + return 0; +} + +// Trigger the reconfiguration process. + +void +ACE_Service_Config::reconfigure (void) +{ + ACE_TRACE ("ACE_Service_Config::reconfigure"); + + ACE_Service_Config::reconfig_occurred_ = 0; + + if (ACE_Service_Config::debug_) + { + time_t t = ACE_OS::time (0); + ACE_DEBUG ((LM_DEBUG, "beginning reconfiguration at %s", ACE_OS::ctime (&t))); + } + + if (ACE_Service_Config::process_directives () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "process_directives")); +} + +// Run the event loop until the +// method returns -1 or the method +// is invoked. + +int +ACE_Service_Config::run_reactor_event_loop (void) +{ + ACE_TRACE ("ACE_Service_Config::run_reactor_event_loop"); + + while (ACE_Service_Config::end_reactor_event_loop_ == 0) + { + int result = ACE_Service_Config::reactor ()->handle_events (); + + if (ACE_Service_Config::reconfig_occurred_) + ACE_Service_Config::reconfigure (); + + else if (result == -1) + return -1; + } + /* NOTREACHED */ + return 0; +} + +// Run the event loop until the +// method returns -1, the method +// is invoked, or the expires. + +int +ACE_Service_Config::run_reactor_event_loop (ACE_Time_Value &tv) +{ + ACE_TRACE ("ACE_Service_Config::run_reactor_event_loop"); + + while (ACE_Service_Config::end_reactor_event_loop_ == 0) + { + int result = ACE_Service_Config::reactor ()->handle_events (tv); + if (ACE_Service_Config::reconfig_occurred_) + ACE_Service_Config::reconfigure (); + else if (result == -1) + return -1; + } + + /* NOTREACHED */ + return 0; +} + +// Tidy up and perform last rites on a terminating ACE_Service_Config. +int +ACE_Service_Config::close (void) +{ + ACE_TRACE ("ACE_Service_Config::close"); + + if (ACE_Service_Config::svc_rep_ != 0) + { + ACE_DEBUG ((LM_SHUTDOWN, "shutting down daemon %n\n")); + + // ACE_Service_Config must be deleted first so that an object's + // fini() method may reference a valid ACE_Reactor. + ACE_Service_Config::close_svcs (); + ACE_Service_Config::close_singletons (); + } + return 0; +} + +int +ACE_Service_Config::close_svcs (void) +{ + ACE_TRACE ("ACE_Service_Config::close_svcs"); + + if (ACE_Service_Config::delete_svc_rep_) + { + delete ACE_Service_Config::svc_rep_; + ACE_Service_Config::svc_rep_ = 0; + } + + return 0; +} + +int +ACE_Service_Config::close_singletons (void) +{ + ACE_TRACE ("ACE_Service_Config::close_singletons"); + + if (ACE_Service_Config::delete_reactor_) + { + delete ACE_Service_Config::reactor_; + ACE_Service_Config::reactor_ = 0; + } + + if (ACE_Service_Config::delete_proactor_) + { + delete ACE_Service_Config::proactor_; + ACE_Service_Config::proactor_ = 0; + } + + if (ACE_Service_Config::delete_reactorEx_) + { + delete ACE_Service_Config::reactorEx_; + ACE_Service_Config::reactorEx_ = 0; + } + + if (ACE_Service_Config::delete_thr_mgr_) + { + delete ACE_Service_Config::thr_mgr_; + ACE_Service_Config::thr_mgr_ = 0; + } + + if (ACE_Service_Config::delete_allocator_) + { + delete ACE_Service_Config::allocator_; + ACE_Service_Config::allocator_ = 0; + } + return 0; +} + +// Perform user-specified close activities and remove dynamic memory. + + +ACE_Service_Config::~ACE_Service_Config (void) +{ + ACE_TRACE ("ACE_Service_Config::~ACE_Service_Config"); + ACE_Service_Config::close (); +} + +/* static */ +int +ACE_Service_Config::end_reactor_event_loop (void) +{ + ACE_TRACE ("ACE_Service_Config::end_reactor_event_loop"); + ACE_Service_Config::end_reactor_event_loop_ = 1; + + return ACE_Service_Config::reactor ()->notify (); +} + +/* static */ +sig_atomic_t +ACE_Service_Config::reactor_event_loop_done (void) +{ + ACE_TRACE ("ACE_Service_Config::end_proactor_event_loop"); + return ACE_Service_Config::end_reactor_event_loop_; +} + +int +ACE_Service_Config::run_proactor_event_loop (void) +{ + ACE_TRACE ("ACE_Service_Config::run_proactor_event_loop"); + + while (ACE_Service_Config::end_proactor_event_loop_ == 0) + { + int result = ACE_Service_Config::proactor ()->handle_events (); + + if (ACE_Service_Config::reconfig_occurred_) + ACE_Service_Config::reconfigure (); + + else if (result == -1) + return -1; + } + /* NOTREACHED */ + return 0; +} + +int +ACE_Service_Config::run_proactor_event_loop (ACE_Time_Value &tv) +{ + ACE_TRACE ("ACE_Service_Config::run_proactor_event_loop"); + + while (ACE_Service_Config::end_proactor_event_loop_ == 0) + { + int result = ACE_Service_Config::proactor ()->handle_events (tv); + if (ACE_Service_Config::reconfig_occurred_) + ACE_Service_Config::reconfigure (); + else if (result == -1) + return -1; + } + + /* NOTREACHED */ + return 0; +} + +int +ACE_Service_Config::end_proactor_event_loop (void) +{ + ACE_TRACE ("ACE_Service_Config::end_proactor_event_loop"); + ACE_Service_Config::end_proactor_event_loop_ = 1; + // ACE_Service_Config::proactor ()->notify (); + return 0; +} + +/* static */ +sig_atomic_t +ACE_Service_Config::proactor_event_loop_done (void) +{ + ACE_TRACE ("ACE_Service_Config::end_proactor_event_loop"); + return ACE_Service_Config::end_proactor_event_loop_; +} + +// ************************************************************ + +int +ACE_Service_Config::run_reactorEx_event_loop (void) +{ + ACE_TRACE ("ACE_Service_Config::run_reactorEx_event_loop"); + + while (ACE_Service_Config::end_reactorEx_event_loop_ == 0) + { + int result = ACE_Service_Config::reactorEx ()->handle_events (); + + if (ACE_Service_Config::reconfig_occurred_) + ACE_Service_Config::reconfigure (); + + else if (result == -1) + return -1; + } + /* NOTREACHED */ + return 0; +} + +int +ACE_Service_Config::run_reactorEx_event_loop (ACE_Time_Value &tv) +{ + ACE_TRACE ("ACE_Service_Config::run_reactorEx_event_loop"); + + while (ACE_Service_Config::end_reactorEx_event_loop_ == 0) + { + int result = ACE_Service_Config::reactorEx ()->handle_events (tv); + if (ACE_Service_Config::reconfig_occurred_) + ACE_Service_Config::reconfigure (); + else if (result == -1) + return -1; + } + + /* NOTREACHED */ + return 0; +} + +int +ACE_Service_Config::end_reactorEx_event_loop (void) +{ + ACE_TRACE ("ACE_Service_Config::end_reactorEx_event_loop"); + ACE_Service_Config::end_reactorEx_event_loop_ = 1; + return ACE_Service_Config::reactorEx ()->notify (); +} + +/* static */ +sig_atomic_t +ACE_Service_Config::reactorEx_event_loop_done (void) +{ + ACE_TRACE ("ACE_Service_Config::end_reactorEx_event_loop"); + return ACE_Service_Config::end_reactorEx_event_loop_; +} + +// ************************************************************ + +/* static */ +sig_atomic_t +ACE_Service_Config::reconfig_occurred (void) +{ + ACE_TRACE ("ACE_Service_Config::reconfig_occurred"); + return ACE_Service_Config::reconfig_occurred_; +} + +void +ACE_Service_Config::reconfig_occurred (sig_atomic_t config_occurred) +{ + ACE_TRACE ("ACE_Service_Config::reconfig_occurred"); + ACE_Service_Config::reconfig_occurred_ = config_occurred; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Set_Node; +template class ACE_Unbounded_Set; +template class ACE_Unbounded_Set_Iterator; +template class ACE_Malloc; +template class ACE_Allocator_Adapter >; +template class auto_ptr; +#if !defined (ACE_HAS_THREADS) +template class ACE_Guard; +template class ACE_Read_Guard; +template class ACE_Write_Guard; +#endif /* ACE_HAS_THREADS */ +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/ace/Service_Config.h b/ace/Service_Config.h new file mode 100644 index 00000000000..52fbdb86090 --- /dev/null +++ b/ace/Service_Config.h @@ -0,0 +1,353 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Service_Config.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SERVICE_CONFIG_H) +#define ACE_SERVICE_CONFIG_H + +#include "ace/Service_Object.h" +#include "ace/Thread_Manager.h" +#include "ace/Set.h" +#include "ace/Proactor.h" +#include "ace/ReactorEx.h" + +// Forward decl. +class ACE_Service_Repository; +class ACE_Service_Record; +class ACE_Allocator; +class ACE_Reactor; +//class ACE_Proactor; + +struct ACE_Static_Svc_Descriptor +{ + char *name_; + // Name of the service. + + int type_; + // Type of service. + + ACE_Service_Object *(*alloc_)(void); + // Factory function that allocates the service. + + u_int flags_; + // Bitmask flags indicating how the framework should delete memory. + + int active_; + // Flag indicating whether the service starts out active. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +public: + int operator== (ACE_Static_Svc_Descriptor &) const; + // Compare two service descriptors for equality. +}; + +// = Maintain a set of the statically linked service descriptor. + +typedef ACE_Unbounded_Set ACE_STATIC_SVCS; +typedef ACE_Unbounded_Set_Iterator ACE_STATIC_SVCS_ITERATOR; + +class ACE_Export ACE_Service_Config : public ACE_Event_Handler + // = TITLE + // Provide the base class that supplies common server daemon + // operations. + // + // = DESCRIPTION + // This class inherits from so that it can + // be used as a signal handler. +{ +public: + enum {MAX_SERVICES = ACE_DEFAULT_REACTOR_SIZE}; + + // = Initialization and termination methods. + + ACE_Service_Config (int ignore_defaults = 0, + size_t size = ACE_Service_Config::MAX_SERVICES, + int signum = SIGHUP); + // Initialize the Service Repository. + + ACE_Service_Config (const char program_name[]); + // Performs an open without parsing command-line arguments. + + static int open (const char program_name[]); + // Performs an open without parsing command-line arguments. + + static int open (int argc, char *argv[]); + // This is the primary entry point into the ACE_Service_Config (the + // constructor just handles simple initializations). It parses + // arguments passed in from the command-line. + + virtual ~ACE_Service_Config (void); + // Perform user-specified close activities and remove dynamic + // memory. + + static int close (void); + // Tidy up and perform last rites when ACE_Service_Config is shut + // down. This method calls and . + + static int close_svcs (void); + // Perform user-specified close hooks on all of the configured + // services in the , then delete the + // itself. + + static int close_singletons (void); + // Delete the dynamically allocated Singletons (i.e., the , + // , , , and ). + + // = Reactor event loop management methods. + static int run_reactor_event_loop (void); + // Run the event loop until the method + // returns -1 or the method is invoked. + + static int run_reactor_event_loop (ACE_Time_Value &tv); + // Run the event loop until the method + // returns -1, the method is invoked, or the + // expires. + + static int end_reactor_event_loop (void); + // Instruct the to terminate its event loop and + // notifies the so that it can wake up + // and close down gracefully. + + static sig_atomic_t reactor_event_loop_done (void); + // Report if the Reactor's event loop is finished. + + // = Proactor event loop management methods. + static int run_proactor_event_loop (void); + // Run the event loop until the + // method returns -1 or the method + // is invoked. + + static int run_proactor_event_loop (ACE_Time_Value &tv); + // Run the event loop until the + // method returns -1, the method + // is invoked, or the expires. + + static int end_proactor_event_loop (void); + // Instruct the to terminate its event loop. + + static sig_atomic_t proactor_event_loop_done (void); + // Report if the proactor event loop is finished. + + // = ReactorEx event loop management methods. + static int run_reactorEx_event_loop (void); + // Run the event loop until the + // method returns -1 or the method + // is invoked. + + static int run_reactorEx_event_loop (ACE_Time_Value &tv); + // Run the event loop until the + // method returns -1, the method + // is invoked, or the expires. + + static int end_reactorEx_event_loop (void); + // Instruct the to terminate its event loop. + + static sig_atomic_t reactorEx_event_loop_done (void); + // Report if the ReactorEx event loop is finished. + + static sig_atomic_t reconfig_occurred (void); + // True if reconfiguration occurred. + + static void reconfig_occurred (sig_atomic_t); + // Indicate that reconfiguration occurred. + + // = The following methods are static in order to enforce Singleton + // semantics for the Reactor, Service_Repository, Thread_Manager, + // Acceptor/Connector Strategy factory, Proactor, and ReactorEx. + // Other portions of the system may need to access them at some + // point or another... + + // = Accessors and mutators for process-wide Singletons. + + static ACE_STATIC_SVCS *static_svcs (void); + // Returns a pointer to the list of statically linked services. + + static ACE_Reactor *reactor (void); + // Get pointer to a process-wide . + + static ACE_Reactor *reactor (ACE_Reactor *); + // Set pointer to a process-wide and return existing + // pointer. + + static ACE_Proactor *proactor (size_t threads = 0); + // Get pointer to a process-wide . should + // be part of another method. It's only here because I'm just a + // grad student and not in charge. No, I'm not bitter about this. + + static ACE_Proactor *proactor (ACE_Proactor *); + // Set pointer to a process-wide and return existing + // pointer. + + static ACE_ReactorEx *reactorEx (void); + // Get pointer to a process-wide . + + static ACE_ReactorEx *reactorEx (ACE_ReactorEx *); + // Set pointer to a process-wide and return existing + // pointer. + + static ACE_Service_Repository *svc_rep (void); + // Get pointer to a process-wide . + + static ACE_Service_Repository *svc_rep (ACE_Service_Repository *); + // Set pointer to a process-wide and return + // existing pointer. + + static ACE_Thread_Manager *thr_mgr (void); + // Get pointer to a process-wide . + + static ACE_Thread_Manager *thr_mgr (ACE_Thread_Manager *); + // Set pointer to a process-wide and return + // existing pointer. + + static ACE_Allocator *allocator (void); + // Get pointer to a default . + + static ACE_Allocator *allocator (ACE_Allocator *); + // Set pointer to a process-wide and return existing + // pointer. + + // = Member functions used by various other parts + // of the Service Configurator class category. + static int initialize (const ACE_Service_Record *, char parameters[]); + // Dynamically link the shared object file and retrieve + // a pointer to the designated shared object in this file. + + static int initialize (const char svc_name[], char parameters[]); + // Initialize and activate a statically service. + + static int resume (const char svc_name[]); + // Resume a that was previously suspended or has not yet + // been resumed (e.g., a static service). + + static int suspend (const char svc_name[]); + // Suspend . Note that this will not unlink the service + // from the daemon if it was dynamically linked, it will mark it + // as being suspended in the Service Repository and call the + // suspend() member function on the appropriate ACE_Service_Object. + // A service can be resumed later on by calling the RESUME() + // member function... + + static int remove (const char svc_name[]); + // Totally remove from the daemon by removing it + // from the ACE_Reactor, and unlinking it if necessary. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + static int process_directives (void); + // Process service configuration requests as indicated + // in the . + + static void parse_args (int, char *[]); + // Handle the command-line options intended for the . + + static void reconfigure (void); + // Perform the reconfiguration process. + + static int start_daemon (void); + // Become a daemon. + + static int load_defaults (void); + // Add the default statically-linked services to the . + + virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); + // Signal handling API to trigger dynamic reconfiguration. + +private: + + static ACE_Service_Repository *svc_rep_; + // Pointer to a process-wide . + + static int delete_svc_rep_; + // Must delete the if non-0. + + static ACE_Thread_Manager *thr_mgr_; + // Pointer to a process-wide . + + static int delete_thr_mgr_; + // Must delete the if non-0. + + static ACE_Allocator *allocator_; + // Pointer to a process-wide instance. + + static int delete_allocator_; + // Must delete the if non-0. + + static ACE_Proactor *proactor_; + // Pointer to a process-wide . + + static int delete_proactor_; + // Must delete the if non-0. + + static ACE_ReactorEx *reactorEx_; + // Pointer to a process-wide . + + static int delete_reactorEx_; + // Must delete the if non-0. + + static ACE_Reactor *reactor_; + // Pointer to a process-wide . + + static int delete_reactor_; + // Must delete the if non-0. + + static const char *service_config_file_; + // Name of service configuration file. + + static const char *logger_key_; + // Where to write the logging output. + + //static ACE_Static_Svc_Descriptor service_list_[]; + // List of statically linked services. + + static sig_atomic_t end_reactor_event_loop_; + // Terminate the event loop. + + static sig_atomic_t end_proactor_event_loop_; + // Terminate the proactor event loop. + + static sig_atomic_t end_reactorEx_event_loop_; + // Terminate the proactor event loop. + + static sig_atomic_t reconfig_occurred_; + // True if reconfiguration occurred. + + // = Set by command-line options. + static char debug_; + static char be_a_daemon_; + static char no_defaults_; + + static int signum_; + // Number of the signal used to trigger reconfiguration. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Service_Config.i" +#endif /* __ACE_INLINE__ */ + +// These must go here to avoid circular includes... +#include "ace/Reactor.h" +#include "ace/Svc_Conf_Tokens.h" +#endif /* ACE_SERVICE_CONFIG_H */ diff --git a/ace/Service_Config.i b/ace/Service_Config.i new file mode 100644 index 00000000000..2940c580a4c --- /dev/null +++ b/ace/Service_Config.i @@ -0,0 +1,32 @@ +/* -*- C++ -*- */ +// $Id$ + +// Service_Config.i + +// Become a daemon (i.e., run as a "background" process). + +ACE_INLINE int +ACE_Service_Config::start_daemon (void) +{ + ACE_TRACE ("ACE_Service_Config::start_daemon"); + return ACE::daemonize (); +} + +// This is the primary entry point into the ACE_Service_Config (the +// constructor just handles simple initializations). + +ACE_INLINE int +ACE_Service_Config::open (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_Service_Config::open"); + ACE_Service_Config::parse_args (argc, argv); + return ACE_Service_Config::open (argv[0]); +} + +// Compare two service descriptors for equality. + +ACE_INLINE int +ACE_Static_Svc_Descriptor::operator== (struct ACE_Static_Svc_Descriptor &d) const +{ + return ACE_OS::strcmp (name_, d.name_) == 0; +} diff --git a/ace/Service_Main.cpp b/ace/Service_Main.cpp new file mode 100644 index 00000000000..cf20fe799e8 --- /dev/null +++ b/ace/Service_Main.cpp @@ -0,0 +1,37 @@ +// Service_Main.cpp +// $Id$ + +/* This is an example of a canonical Service Configurator daemon's + main() function. Note how this driver file is completely generic + and may be used to configure almost any type of network daemon. */ + +#define ACE_BUILD_DLL +#include "ace/Service_Config.h" + +sig_atomic_t finished = 0; + +static void +handler (int) +{ + ACE_TRACE ("handler"); + finished = 1; +} + +int +sc_main (int argc, char *argv[]) +{ + ACE_TRACE ("sc_main"); + ACE_Service_Config daemon; + + ACE_OS::signal (SIGINT, ACE_SignalHandler (handler)); + + if (daemon.open (argc, argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "open", 1)); + + /* Run forever, performing the configured services. */ + + while (!finished) + daemon.run_reactor_event_loop (); + + return 0; +} diff --git a/ace/Service_Manager.cpp b/ace/Service_Manager.cpp new file mode 100644 index 00000000000..2658895e4c6 --- /dev/null +++ b/ace/Service_Manager.cpp @@ -0,0 +1,267 @@ +// Service_Manager.cpp +// $Id$ + + +#define ACE_BUILD_DLL +#include "ace/Get_Opt.h" +#include "ace/Service_Repository.h" +#include "ace/Service_Config.h" +#include "ace/Service_Manager.h" +#include "ace/Reactor.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Service_Manager.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Service_Manager) + +void +ACE_Service_Manager::dump (void) const +{ + ACE_TRACE ("ACE_Service_Manager::dump"); +} + +/* Static variables. */ + +u_short ACE_Service_Manager::DEFAULT_PORT_ = 10000; + +ACE_Service_Manager::ACE_Service_Manager (void) + : debug_ (0), + signum_ (SIGHUP) +{ + ACE_TRACE ("ACE_Service_Manager::ACE_Service_Manager"); +} + +int +ACE_Service_Manager::suspend (void) +{ + ACE_TRACE ("ACE_Service_Manager::suspend"); + return ACE_Service_Config::reactor ()->suspend_handler (this); +} + +int +ACE_Service_Manager::resume (void) +{ + ACE_TRACE ("ACE_Service_Manager::resume"); + return ACE_Service_Config::reactor ()->resume_handler (this); +} + +int +ACE_Service_Manager::open (const ACE_INET_Addr &sia) +{ + ACE_TRACE ("ACE_Service_Manager::open"); + // Reuse the listening address, even if it's already in use! + if (this->acceptor_.open (sia, 1) == -1) + return -1; + return 0; +} + +int +ACE_Service_Manager::info (char **strp, size_t length) const +{ + ACE_TRACE ("ACE_Service_Manager::info"); + ACE_INET_Addr sa; + char buf[BUFSIZ]; + + if (this->acceptor_.get_local_addr (sa) == -1) + return -1; + + ACE_OS::sprintf (buf, "%d/%s %s", sa.get_port_number (), "tcp", + "# lists all services in the daemon\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +int +ACE_Service_Manager::init (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_Service_Manager::init"); + ACE_INET_Addr local_addr (ACE_Service_Manager::DEFAULT_PORT_); + ACE_Get_Opt getopt (argc, argv, "dp:s:", 0); // Start at argv[0] + + for (int c; (c = getopt ()) != -1; ) + switch (c) + { + case 'd': + this->debug_ = 1; + break; + case 'p': + local_addr.set (ACE_OS::atoi (getopt.optarg)); + break; + case 's': + this->signum_ = ACE_OS::atoi (getopt.optarg); + break; + default: + break; + } + + if (this->open (local_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + else if (ACE_Service_Config::reactor ()->register_handler + (this, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "registering service with ACE_Reactor\n"), -1); + return 0; +} + +int +ACE_Service_Manager::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + ACE_TRACE ("ACE_Service_Manager::handle_close"); + return this->acceptor_.close (); +} + +int +ACE_Service_Manager::fini (void) +{ + ACE_TRACE ("ACE_Service_Manager::fini"); + return ACE_Service_Config::reactor ()->remove_handler + (this, ACE_Event_Handler::READ_MASK); +} + +ACE_HANDLE +ACE_Service_Manager::get_handle (void) const +{ + ACE_TRACE ("ACE_Service_Manager::get_handle"); + return this->acceptor_.get_handle (); +} + +int +ACE_Service_Manager::handle_signal (int sig, siginfo_t *, ucontext_t *) +{ + ACE_TRACE ("ACE_Service_Manager::handle_signal"); + if (this->debug_) + ACE_DEBUG ((LM_DEBUG, "got %S\n", sig)); + return 0; +} + +// Determine all the services offered by this daemon and return the +// information back to the client. + +int +ACE_Service_Manager::list_services (void) +{ + ACE_TRACE ("ACE_Service_Manager::list_services"); + ACE_Service_Repository_Iterator sri (*ACE_Service_Config::svc_rep ()); + + for (const ACE_Service_Record *sr; + sri.next (sr) != 0; + sri.advance ()) + { + int len = ACE_OS::strlen (sr->name ()) + 1; + char buf[BUFSIZ], *p = buf + len; + + ACE_OS::strcpy (buf, sr->name ()); + p[-1] = ' '; + p[0] = '\0'; + + len += sr->type ()->info (&p, sizeof buf - len); + + if (this->debug_) + ACE_DEBUG ((LM_DEBUG, "len = %d, info = %s%s", + len, buf, buf[len - 1] == '\n' ? "" : "\n")); + + if (len > 0) + { + ssize_t n = this->client_stream_.send_n (buf, len); + + if (n != len || (n == -1 && errno != EPIPE)) + ACE_ERROR ((LM_ERROR, "%p\n", "send_n")); + } + } + + return 0; +} + +// Trigger a remote reconfiguration of the Service Configurator. + +int +ACE_Service_Manager::reconfigure_services (void) +{ + ACE_TRACE ("ACE_Service_Manager::reconfigure_services"); + +#if 0 +// Send ourselves a signal! ACE_OS::kill (ACE_OS::getpid (), +// this->signum_); +#endif /* 0 */ + + // Flag the main event loop that a reconfiguration should occur. + // The next trip through the ACE_Service_Config::run_reactor_event_loop() + // should pick this up and cause a reconfiguration! + ACE_Service_Config::reconfig_occurred ((sig_atomic_t) 1); + return this->client_stream_.send_n ("done\n", sizeof ("done\n")); +} + +// Accept new connection from client and carry out the service they +// request. + +int +ACE_Service_Manager::handle_input (ACE_HANDLE) +{ + ACE_TRACE ("ACE_Service_Manager::handle_input"); + + if (this->acceptor_.accept (this->client_stream_) == -1) + return -1; + + if (this->debug_) + { + ACE_DEBUG ((LM_DEBUG, "client_stream fd = %d\n", + this->client_stream_.get_handle ())); + ACE_INET_Addr sa; + if (this->client_stream_.get_remote_addr (sa) == -1) + return -1; + + ACE_DEBUG ((LM_DEBUG, "accepted from host %s at port %d\n", + sa.get_host_name (), sa.get_port_number ())); + } + + char request[BUFSIZ]; + + // Read service request from client. + + switch (client_stream_.recv (request, sizeof request)) + { + case -1: + if (this->debug_) + ACE_DEBUG ((LM_ERROR, "%p\n", "recv")); + break; + case 0: + return 0; + /* NOTREACHED */ + default: + { + char *p; + + // Kill trailing newlines. + + for (p = request; + (*p != '\0') && (*p != '\r') && (*p != '\n'); + p++) + continue; + + *p = '\0'; + + ACE_Event_Handler *old_signal_handler = 0; + ACE_Service_Config::reactor ()->register_handler (SIGPIPE, this, 0, + &old_signal_handler); + + if (ACE_OS::strcmp (request, "help") == 0) + this->list_services (); + else if (ACE_OS::strcmp (request, "reconfigure") == 0) + this->reconfigure_services (); + + // Additional management services may be handled here... + + // Restore existing SIGPIPE handler + ACE_Service_Config::reactor ()->register_handler + (SIGPIPE, old_signal_handler); + } + } + if (this->client_stream_.close () == -1 && this->debug_) + ACE_DEBUG ((LM_ERROR, "%p\n", "close")); + + return 0; +} diff --git a/ace/Service_Manager.h b/ace/Service_Manager.h new file mode 100644 index 00000000000..c35b207e759 --- /dev/null +++ b/ace/Service_Manager.h @@ -0,0 +1,74 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Service_Manager.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SERVICE_MANAGER_H) +#define ACE_SERVICE_MANAGER_H + +#include "ace/SOCK_Stream.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/INET_Addr.h" +#include "ace/Service_Object.h" + +class ACE_Export ACE_Service_Manager : public ACE_Service_Object + // = TITLE + // Provide a standard service that returns a list of all services in the + // Service Repository. + // + // = DESCRIPTION + // +{ +public: + ACE_Service_Manager (void); + virtual int list_services (void); + virtual int reconfigure_services (void); + + // = Dynamic linking hooks. + virtual int init (int argc, char *argv[]); + virtual int info (char **info_string, size_t length) const; + virtual int fini (void); + + // = Scheduling hooks. + virtual int suspend (void); + virtual int resume (void); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + int open (const ACE_INET_Addr &sia); + + // = Demultiplexing hooks. + virtual ACE_HANDLE get_handle (void) const; + virtual int handle_input (ACE_HANDLE fd); + virtual int handle_close (ACE_HANDLE fd, ACE_Reactor_Mask); + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + + ACE_SOCK_Stream client_stream_; + ACE_SOCK_Acceptor acceptor_; + int debug_; + int signum_; + static u_short DEFAULT_PORT_; +}; + +#if defined (__ACE_INLINE__) +#include "ace/Service_Manager.i" +#endif /* __ACE_INLINE__ */ + +#endif /* _SERVICE_MANAGER_H */ diff --git a/ace/Service_Manager.i b/ace/Service_Manager.i new file mode 100644 index 00000000000..e4bcf581ee0 --- /dev/null +++ b/ace/Service_Manager.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// $Id$ + +// Service_Manager.i diff --git a/ace/Service_Object.cpp b/ace/Service_Object.cpp new file mode 100644 index 00000000000..e0defc425a7 --- /dev/null +++ b/ace/Service_Object.cpp @@ -0,0 +1,71 @@ +// Service_Object.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Service_Object.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Service_Object.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Service_Object) + +/* Provide the abstract base class common to all services */ + +ACE_Service_Object::ACE_Service_Object (void) +{ + ACE_TRACE ("ACE_Service_Object::ACE_Service_Object"); +} + +ACE_Service_Object::~ACE_Service_Object (void) +{ + ACE_TRACE ("ACE_Service_Object::~ACE_Service_Object"); +} + +int +ACE_Service_Object::suspend (void) +{ + ACE_TRACE ("ACE_Service_Object::suspend"); + return 0; +} + +int +ACE_Service_Object::resume (void) +{ + ACE_TRACE ("ACE_Service_Object::resume"); + return 0; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Service_Type) + +void +ACE_Service_Type::dump (void) const +{ + ACE_TRACE ("ACE_Service_Type::dump"); +} + +ACE_Service_Type::ACE_Service_Type (const void *so, + const char *s_name, + unsigned int f) + : obj_ (so), + flags_ (f) +{ + ACE_TRACE ("ACE_Service_Type::ACE_Service_Type"); + this->name (ACE_OS::strcpy (new char[::strlen (s_name) + 1], s_name)); +} + +int +ACE_Service_Type::fini (void) const +{ + ACE_TRACE ("ACE_Service_Type::fini"); + ACE_DEBUG ((LM_DEBUG, "destroying %s, flags = %d\n", + this->name_, this->flags_)); + + delete [] (char *) this->name_; + if (ACE_BIT_ENABLED (this->flags_, ACE_Service_Type::DELETE_OBJ)) + delete (void *) this->object (); + if (ACE_BIT_ENABLED (this->flags_, ACE_Service_Type::DELETE_THIS)) + delete (void *) this; // Prevent object's destructor from being called... + return 0; +} + diff --git a/ace/Service_Object.h b/ace/Service_Object.h new file mode 100644 index 00000000000..32624e21a4e --- /dev/null +++ b/ace/Service_Object.h @@ -0,0 +1,94 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Service_Object.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SERVICE_OBJECT_H) +#define ACE_SERVICE_OBJECT_H + +#include "ace/Shared_Object.h" +#include "ace/Event_Handler.h" +#include "ace/Log_Msg.h" + +class ACE_Export ACE_Service_Object : public ACE_Event_Handler, public ACE_Shared_Object + // = TITLE + // Provide the abstract base class common to all services +{ +public: + // = Initialization and termination methods. + ACE_Service_Object (void); + virtual ~ACE_Service_Object (void); + + virtual int suspend (void); + // Temporarily disable a service without removing it completely + virtual int resume (void); + // Re-enable a previously suspended service +}; + +class ACE_Export ACE_Service_Type + // = TITLE + // Provide the class hierarchy that defines the contents of + // the Service Repository search structure. +{ +public: + enum + { + DELETE_OBJ = 1, // Delete the payload object. + DELETE_THIS = 2 // Delete the enclosing object. + }; + + // = Initialization method. + ACE_Service_Type (const void *object, + const char *s_name, + u_int flags = 0); + + // = Pure virtual interface (must be defined by the subclass). + virtual int suspend (void) const = 0; + virtual int resume (void) const = 0; + virtual int init (int argc, char *argv[]) const = 0; + virtual int fini (void) const; + virtual int info (char **str, size_t len) const = 0; + + const void *object (void) const; + // The pointer to the service. + + const char *name (void) const; + // Get the name of the service. + + void name (const char *); + // Set the name of the service. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + const char *name_; + // Name of the service. + + const void *obj_; + // Pointer to object that implements the service. + + u_int flags_; + // Flags that control serivce behavior (particularly deletion). +}; + +#if defined (__ACE_INLINE__) +#include "ace/Service_Object.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_SERVICE_OBJECT_H */ diff --git a/ace/Service_Object.i b/ace/Service_Object.i new file mode 100644 index 00000000000..530757b6363 --- /dev/null +++ b/ace/Service_Object.i @@ -0,0 +1,26 @@ +/* -*- C++ -*- */ +// $Id$ + +// Service_Object.i + +ACE_INLINE const void * +ACE_Service_Type::object (void) const +{ + ACE_TRACE ("ACE_Service_Type::object"); + return this->obj_; +} + +ACE_INLINE const char * +ACE_Service_Type::name (void) const +{ + ACE_TRACE ("ACE_Service_Type::name"); + return this->name_; +} + +ACE_INLINE void +ACE_Service_Type::name (const char *n) +{ + ACE_TRACE ("ACE_Service_Type::name"); + this->name_ = n; +} + diff --git a/ace/Service_Record.cpp b/ace/Service_Record.cpp new file mode 100644 index 00000000000..b4b8dccbf65 --- /dev/null +++ b/ace/Service_Record.cpp @@ -0,0 +1,340 @@ +// Service_Record.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Service_Record.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Service_Record.i" +#endif /* __ACE_INLINE__ */ + +ACE_Service_Object_Type::ACE_Service_Object_Type (ACE_Service_Object *so, + const char *s_name, + unsigned int f) + : ACE_Service_Type ((const void *) so, s_name, f) +{ + ACE_TRACE ("ACE_Service_Object_Type::ACE_Service_Object_Type"); +} + +int +ACE_Service_Object_Type::init (int argc, char *argv[]) const +{ + ACE_TRACE ("ACE_Service_Object_Type::init"); + const void *obj = this->object (); + ACE_Service_Object *so = (ACE_Service_Object *) obj; + + if (so == 0) + return -1; + else + return so->init (argc, argv); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Module_Type) + +void +ACE_Module_Type::dump (void) const +{ + ACE_TRACE ("ACE_Module_Type::dump"); +} + +ACE_Module_Type::ACE_Module_Type (MT_Module *m, + const char *m_name, + u_int f) + : ACE_Service_Type ((const void *) m, m_name, f) +{ + ACE_TRACE ("ACE_Module_Type::ACE_Module_Type"); +} + +int +ACE_Module_Type::init (int argc, char *argv[]) const +{ + ACE_TRACE ("ACE_Module_Type::init"); + const void *obj = this->object (); + MT_Module *mod = (MT_Module *) obj; + MT_Task *reader = mod->reader (); + MT_Task *writer = mod->writer (); + + if (reader->init (argc, argv) == -1 + || writer->init (argc, argv) == -1) + return -1; + else + return 0; +} + +int +ACE_Module_Type::suspend (void) const +{ + ACE_TRACE ("ACE_Module_Type::suspend"); + const void *obj = this->object (); + MT_Module *mod = (MT_Module *) obj; + MT_Task *reader = mod->reader (); + MT_Task *writer = mod->writer (); + + if (reader->suspend () == -1 + || writer->suspend () == -1) + return -1; + else + return 0; +} + +int +ACE_Module_Type::resume (void) const +{ + ACE_TRACE ("ACE_Module_Type::resume"); + const void *obj = this->object (); + MT_Module *mod = (MT_Module *) obj; + MT_Task *reader = mod->reader (); + MT_Task *writer = mod->writer (); + + if (reader->resume () == -1 + || writer->resume () == -1) + return -1; + else + return 0; +} + +// Note, these operations are somewhat too familiar with the +// implementation of ACE_Module and ACE_Module::close... + +int +ACE_Module_Type::fini (void) const +{ + ACE_TRACE ("ACE_Module_Type::fini"); + const void *obj = this->object (); + MT_Module *mod = (MT_Module *) obj; + MT_Task *reader = mod->reader (); + MT_Task *writer = mod->writer (); + + reader->fini (); + writer->fini (); + delete reader; + delete writer; + return ACE_Service_Type::fini (); +} + +int +ACE_Module_Type::info (char **str, size_t len) const +{ + ACE_TRACE ("ACE_Module_Type::info"); + char buf[BUFSIZ]; + + ACE_OS::sprintf (buf, "%s\t %s", this->name (), "# ACE_Module\n"); + + if (*str == 0 && (*str = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*str, buf, len); + return ACE_OS::strlen (buf); +} + +void +ACE_Module_Type::link (ACE_Module_Type *n) +{ + ACE_TRACE ("ACE_Module_Type::link"); + this->next_ = n; +} + +ACE_Module_Type * +ACE_Module_Type::link (void) const +{ + ACE_TRACE ("ACE_Module_Type::link"); + return this->next_; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Stream_Type) + +void +ACE_Stream_Type::dump (void) const +{ + ACE_TRACE ("ACE_Stream_Type::dump"); +} + +int +ACE_Stream_Type::init (int, char *[]) const +{ + ACE_TRACE ("ACE_Stream_Type::init"); + return 0; +} + +int +ACE_Stream_Type::suspend (void) const +{ + ACE_TRACE ("ACE_Stream_Type::suspend"); + for (ACE_Module_Type *m = this->head_; m != 0; m = m->link ()) + m->suspend (); + + return 0; +} + +int +ACE_Stream_Type::resume (void) const +{ + ACE_TRACE ("ACE_Stream_Type::resume"); + for (ACE_Module_Type *m = this->head_; m != 0; m = m->link ()) + m->resume (); + + return 0; +} + +ACE_Stream_Type::ACE_Stream_Type (MT_Stream *s, + const char *s_name, + unsigned int f) + : ACE_Service_Type ((const void *) s, s_name, f), + head_ (0) +{ + ACE_TRACE ("ACE_Stream_Type::ACE_Stream_Type"); +} + +int +ACE_Stream_Type::info (char **str, size_t len) const +{ + ACE_TRACE ("ACE_Stream_Type::info"); + char buf[BUFSIZ]; + + ACE_OS::sprintf (buf, "%s\t %s", this->name (), "# STREAM\n"); + + if (*str == 0 && (*str = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*str, buf, len); + return ACE_OS::strlen (buf); +} + +int +ACE_Stream_Type::fini (void) const +{ + ACE_TRACE ("ACE_Stream_Type::fini"); + const void *obj = this->object (); + MT_Stream *str = (MT_Stream *) obj; + + for (ACE_Module_Type *m = this->head_; m != 0; ) + { + ACE_Module_Type *t = m->link (); + + // Final 0 arg disables ACE_Module::DELETE_THIS + str->remove (m->name (), 0); + m->fini (); + m = t; + } + + str->close (); + return ACE_Service_Type::fini (); +} + +// Locate and remove MOD_NAME from the ACE_Stream. + +int +ACE_Stream_Type::remove (ACE_Module_Type *mod) +{ + ACE_TRACE ("ACE_Stream_Type::remove"); + ACE_Module_Type *prev = 0; + const void *obj = this->object (); + MT_Stream *str = (MT_Stream *) obj; + int result = 0; + + ACE_Module_Type *m = this->head_; + + while (m != 0) + { + ACE_Module_Type *next = m->link (); + // We need to do this first so we don't bomb out if we delete m! + + if (m == mod) + { + if (prev == 0) + this->head_ = next; + else + prev->link (next); + + // Final 0 arg disables ACE_Module::DELETE_THIS + if (str->remove (m->name (), 0) == -1) + result = -1; + m->fini (); // This call may end up deleteing m! + } + else + prev = m; + + m = next; + } + + return result; +} + +int +ACE_Stream_Type::push (ACE_Module_Type *new_module) +{ + ACE_TRACE ("ACE_Stream_Type::push"); + const void *obj = this->object (); + MT_Stream *str = (MT_Stream *) obj; + + new_module->link (this->head_); + this->head_ = new_module; + obj = new_module->object (); + return str->push ((MT_Module *) obj); +} + +ACE_Module_Type * +ACE_Stream_Type::find (const char *mod_name) const +{ + ACE_TRACE ("ACE_Stream_Type::find"); + for (ACE_Module_Type *m = this->head_; m != 0; m = m->link ()) + if (ACE_OS::strcmp (m->name (), mod_name) == 0) + return m; + + return 0; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Service_Record) + +void +ACE_Service_Record::dump (void) const +{ + ACE_TRACE ("ACE_Service_Record::dump"); +} + +ACE_Service_Record::ACE_Service_Record (const char *n, + ACE_Service_Type *t, + const void *h, + int active) + : type_ (t), handle_ (h), active_ (active) +{ + ACE_TRACE ("ACE_Service_Record::ACE_Service_Record"); + this->name (n); +} + +ACE_Service_Record::~ACE_Service_Record (void) +{ + ACE_TRACE ("ACE_Service_Record::~ACE_Service_Record"); + this->type_->fini (); + if (this->handle_ != 0) + ACE_OS::dlclose ((void *) this->handle_); + delete [] (char *) this->name_; +} + +void +ACE_Service_Record::suspend (void) const +{ + ACE_TRACE ("ACE_Service_Record::suspend"); + ((ACE_Service_Record *) this)->active_ = 0; + this->type_->suspend (); +} + +void +ACE_Service_Record::resume (void) const +{ + ACE_TRACE ("ACE_Service_Record::resume"); + ((ACE_Service_Record *) this)->active_ = 1; + this->type_->resume (); +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Module; +template class ACE_Stream; +template class ACE_Task; +template class ACE_Message_Queue; +template class ACE_Task_Exit; +template class ACE_TSS >; +template class ACE_Thru_Task; +template class ACE_Stream_Head; +template class ACE_Stream_Tail; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/ace/Service_Record.h b/ace/Service_Record.h new file mode 100644 index 00000000000..427969d2b04 --- /dev/null +++ b/ace/Service_Record.h @@ -0,0 +1,153 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Service_Record.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SERVICE_RECORD_H) +#define ACE_SERVICE_RECORD_H + +#include "ace/Service_Object.h" +#include "ace/Synch.h" +#include "ace/Stream.h" + +typedef ACE_Stream MT_Stream; +typedef ACE_Module MT_Module; +typedef ACE_Task MT_Task; + +class ACE_Export ACE_Service_Object_Type : public ACE_Service_Type + // = TITLE + // Define the methods for handling . +{ +public: + ACE_Service_Object_Type (ACE_Service_Object *so, + const char *name, + u_int flags = 0); + virtual int suspend (void) const; + virtual int resume (void) const; + virtual int init (int argc, char *argv[]) const; + virtual int fini (void) const; + virtual int info (char **str, size_t len) const; +}; + +class ACE_Export ACE_Module_Type : public ACE_Service_Type + // = TITLE + // Define the methods for handling . +{ +public: + ACE_Module_Type (MT_Module *m, + const char *identifier, + u_int flags = 0); + + virtual int suspend (void) const; + virtual int resume (void) const; + virtual int init (int argc, char *argv[]) const; + virtual int fini (void) const; + virtual int info (char **str, size_t len) const; + + ACE_Module_Type *link (void) const; + void link (ACE_Module_Type *); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Module_Type *next_; +}; + +class ACE_Export ACE_Stream_Type : public ACE_Service_Type + // = TITLE + // Define the methods for handling . +{ +public: + ACE_Stream_Type (MT_Stream *s, + const char *identifier, + u_int flags = 0); + + virtual int suspend (void) const; + virtual int resume (void) const; + virtual int init (int argc, char *argv[]) const; + virtual int fini (void) const; + virtual int info (char **str, size_t len) const; + + int push (ACE_Module_Type *new_module); + int remove (ACE_Module_Type *module); + ACE_Module_Type *find (const char *mod_name) const; + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Module_Type *head_; +}; + +class ACE_Export ACE_Service_Record + // = TITLE + // Packaging interface for the various types of + // . +{ +public: + // = Initialization and termination methods. + ACE_Service_Record (const char *n, + ACE_Service_Type *o, + const void *handle, + int active); + ~ACE_Service_Record (void); + + const char *name (void) const; + void name (const char *); + + const ACE_Service_Type *type (void) const; + void type (const ACE_Service_Type *, + int active = 1); + + const void *handle (void) const; + void handle (const void *); + + void suspend (void) const; + void resume (void) const; + int active (void) const; + void active (int); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + const char *name_; + // Humanly readible name of svc. + + const ACE_Service_Type *type_; + // Pointer to C++ object that implements the svc. + + const void *handle_; + // Handle to shared object file (non-zero if dynamically linked). + + int active_; + // 1 if svc is currently active, otherwise 0. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Service_Record.i" +#endif /* __ACE_INLINE__ */ + +#endif /* _SERVICE_RECORD_H */ diff --git a/ace/Service_Record.i b/ace/Service_Record.i new file mode 100644 index 00000000000..bd6d667a593 --- /dev/null +++ b/ace/Service_Record.i @@ -0,0 +1,91 @@ +/* -*- C++ -*- */ +// $Id$ + +// Service_Record.i + +ACE_INLINE int +ACE_Service_Object_Type::suspend (void) const +{ + ACE_TRACE ("ACE_Service_Object_Type::suspend"); + return ((ACE_Service_Object *) this->object ())->suspend (); +} + +ACE_INLINE int +ACE_Service_Object_Type::resume (void) const +{ + ACE_TRACE ("ACE_Service_Object_Type::resume"); + return ((ACE_Service_Object *) this->object ())->resume (); +} + +ACE_INLINE int +ACE_Service_Object_Type::fini (void) const +{ + ACE_TRACE ("ACE_Service_Object_Type::fini"); + ACE_Service_Object *so = (ACE_Service_Object *) this->object (); + so->fini (); + return ACE_Service_Type::fini (); +} + +ACE_INLINE int +ACE_Service_Object_Type::info (char **str, size_t len) const +{ + ACE_TRACE ("ACE_Service_Object_Type::info"); + return ((ACE_Service_Object *) this->object ())->info (str, len); +} + +ACE_INLINE const char * +ACE_Service_Record::name (void) const +{ + ACE_TRACE ("ACE_Service_Record::name"); + return this->name_; +} + +ACE_INLINE const ACE_Service_Type * +ACE_Service_Record::type (void) const +{ + ACE_TRACE ("ACE_Service_Record::type"); + return this->type_; +} + +ACE_INLINE const void * +ACE_Service_Record::handle (void) const +{ + ACE_TRACE ("ACE_Service_Record::handle"); + return this->handle_; +} + +ACE_INLINE void +ACE_Service_Record::name (const char *n) +{ + ACE_TRACE ("ACE_Service_Record::name"); + this->name_ = ACE_OS::strcpy (new char [::strlen (n) + 1], n); +} + +ACE_INLINE void +ACE_Service_Record::type (const ACE_Service_Type *o, int enabled) +{ + ACE_TRACE ("ACE_Service_Record::type"); + this->type_ = o; + ((ACE_Service_Record *) this)->active_ = enabled; +} + +ACE_INLINE void +ACE_Service_Record::handle (const void *h) +{ + ACE_TRACE ("ACE_Service_Record::handle"); + this->handle_ = h; +} + +ACE_INLINE int +ACE_Service_Record::active (void) const +{ + ACE_TRACE ("ACE_Service_Record::active"); + return this->active_ != 0; +} + +ACE_INLINE void +ACE_Service_Record::active (int turnon) +{ + ACE_TRACE ("ACE_Service_Record::active"); + this->active_ = turnon; +} diff --git a/ace/Service_Repository.cpp b/ace/Service_Repository.cpp new file mode 100644 index 00000000000..24af60fd277 --- /dev/null +++ b/ace/Service_Repository.cpp @@ -0,0 +1,281 @@ +// Service_Repository.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Service_Repository.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Service_Repository.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Service_Repository) + +void +ACE_Service_Repository::dump (void) const +{ + ACE_TRACE ("ACE_Service_Repository::dump"); +} + +ACE_Service_Repository::ACE_Service_Repository (void) + : current_size_ (0), + total_size_ (0), + service_vector_ (0) +{ + ACE_TRACE ("ACE_Service_Repository::ACE_Service_Repository"); +} + +// Initialize the Repository to a clean slate. + +int +ACE_Service_Repository::open (int size) +{ + ACE_TRACE ("ACE_Service_Repository::open"); + + this->total_size_ = size; + this->service_vector_ = + (const ACE_Service_Record **) new ACE_Service_Record *[size]; + if (this->service_vector_ == 0) + { + errno = ENOMEM; + return -1; + } + + return 0; +} + +ACE_Service_Repository::ACE_Service_Repository (int size) + : current_size_ (0) +{ + ACE_TRACE ("ACE_Service_Repository::ACE_Service_Repository"); + + if (this->open (size) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Service_Repository")); +} + +/* Close down all the services */ + +int +ACE_Service_Repository::close (void) +{ + ACE_TRACE ("ACE_Service_Repository::close"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + if (this->service_vector_ != 0) + { + for (int i = 0; i < this->current_size_; i++) + { + ACE_DEBUG ((LM_DEBUG, "shutting down %s\n", + this->service_vector_[i]->name ())); + delete (ACE_Service_Record *) this->service_vector_[i]; + } + + delete [] this->service_vector_; + this->service_vector_ = 0; + this->current_size_ = 0; + } + return 0; +} + +ACE_Service_Repository::~ACE_Service_Repository (void) +{ + ACE_TRACE ("ACE_Service_Repository::~ACE_Service_Repository"); + this->close (); +} + +// Locate an entry with NAME in the table. If IGNORE_SUSPENDED is set +// then only consider services marked as resumed. If the caller wants +// the located entry, pass back a pointer to the located entry via +// SRP. If NAME is not found -1 is returned. If NAME is found, but +// it is suspended and the caller wants to ignore suspended services a +// -2 is returned. Must be called with locks held. + +int +ACE_Service_Repository::find_i (const char name[], + const ACE_Service_Record **srp, + int ignore_suspended) +{ + ACE_TRACE ("ACE_Service_Repository::find_i"); + int i; + + for (i = 0; i < this->current_size_; i++) + if (ACE_OS::strcmp (name, this->service_vector_[i]->name ()) == 0) + break; + + if (i < this->current_size_) + { + if (srp != 0) + *srp = this->service_vector_[i]; + if (ignore_suspended && this->service_vector_[i]->active () == 0) + return -2; + return i; + } + else + return -1; +} + +int +ACE_Service_Repository::find (const char name[], + const ACE_Service_Record **srp, + int ignore_suspended) +{ + ACE_TRACE ("ACE_Service_Repository::find"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + return this->find_i (name, srp, ignore_suspended); +} + + +// Insert the ACE_Service_Record SR into the repository. Note that +// services may be inserted either resumed or suspended. + +int +ACE_Service_Repository::insert (const ACE_Service_Record *sr) +{ + ACE_TRACE ("ACE_Service_Repository::insert"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + int i; + + for (i = 0; i < this->current_size_; i++) + if (ACE_OS::strcmp (sr->name (), + this->service_vector_[i]->name ()) == 0) + break; + + if (i < this->current_size_) // Replacing an existing entry + { + // Check for self-assignment... + if (sr == this->service_vector_[i]) + return 0; + delete (ACE_Service_Record *) this->service_vector_[i]; + this->service_vector_[i] = sr; + return 0; + } + else if (i < this->total_size_) // Adding a new entry. + { + this->service_vector_[i] = sr; + this->current_size_++; + return 0; + } + else + return -1; +} + +// Re-resume a service that was previously suspended. + +int +ACE_Service_Repository::resume (const char name[], + const ACE_Service_Record **srp) +{ + ACE_TRACE ("ACE_Service_Repository::resume"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + + int i = this->find_i (name, srp, 0); + + if (i == -1) + return -1; + + this->service_vector_[i]->resume (); + return 0; +} + +// Suspend a service so that it will not be considered active under +// most circumstances by other portions of the ACE_Service_Repository. + +int +ACE_Service_Repository::suspend (const char name[], + const ACE_Service_Record **srp) +{ + ACE_TRACE ("ACE_Service_Repository::suspend"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + int i = this->find_i (name, srp, 0); + + if (i == -1) + return -1; + + this->service_vector_[i]->suspend (); + return 0; +} + +// Completely remove a entry from the Repository and +// dynamically unlink it if it was originally dynamically linked. +// Since the order of services in the Respository does not matter, we +// simply overwrite the entry being deleted with the final entry in +// the array and decrement the by 1. + +int +ACE_Service_Repository::remove (const char name[]) +{ + ACE_TRACE ("ACE_Service_Repository::remove"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + int i = this->find_i (name, 0, 0); + + if (i == -1) + return -1; + else + { + const void *handle = this->service_vector_[i]->handle (); + delete (ACE_Service_Record *) this->service_vector_[i]; + + if (handle != 0) + ACE_OS::dlclose ((void *) handle); + + if (--this->current_size_ > 1) + this->service_vector_[i] + = this->service_vector_[this->current_size_]; + return 0; + } +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Service_Repository_Iterator) + +void +ACE_Service_Repository_Iterator::dump (void) const +{ + ACE_TRACE ("ACE_Service_Repository_Iterator::dump"); +} + +// Initializes the iterator and skips over any suspended entries at +// the beginning of the table, if necessary. Note, you must not +// perform destructive operations on elements during this iteration... + +ACE_Service_Repository_Iterator::ACE_Service_Repository_Iterator + (ACE_Service_Repository &sr, int ignr_suspended) + : svc_rep_ (sr), + next_ (-1), + ignore_suspended_ (ignr_suspended) +{ + this->advance (); +} + +// Obtains a pointer to the next valid service in the table. If there +// are no more entries, returns 0, else 1. + +int +ACE_Service_Repository_Iterator::next (const ACE_Service_Record *&sr) +{ + ACE_TRACE ("ACE_Service_Repository_Iterator::next"); + if (this->next_ < this->svc_rep_.current_size_) + { + sr = this->svc_rep_.service_vector_[this->next_]; + return 1; + } + else + return 0; +} + +// Advance the iterator by the proper amount. If we are ignoring +// suspended entries and the current entry is suspended, then we must +// skip over this entry. Otherwise, we must advance the NEXT index to +// reference the next valid service entry. + +int +ACE_Service_Repository_Iterator::advance (void) +{ + ACE_TRACE ("ACE_Service_Repository_Iterator::advance"); + for (++this->next_; + this->next_ < this->svc_rep_.current_size_ + && this->ignore_suspended_ + && this->svc_rep_.service_vector_[this->next_]->active () == 0; + this->next_++) + continue; + return this->next_; +} diff --git a/ace/Service_Repository.h b/ace/Service_Repository.h new file mode 100644 index 00000000000..2d758e1ffe3 --- /dev/null +++ b/ace/Service_Repository.h @@ -0,0 +1,130 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Service_Repository.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SERVICE_REPOSITORY_H) +#define ACE_SERVICE_REPOSITORY_H + +#include "ace/Service_Record.h" + +class ACE_Export ACE_Service_Repository + // = TITLE + // Provide the abstract base class that supplies common server + // repository operations. +{ +public: + enum {DEFAULT_SIZE = 50}; + // = Initialization and termination methods. + ACE_Service_Repository (void); + // Initialize the repository. + + ACE_Service_Repository (int size); + // Initialize the repository. + + int open (int size = DEFAULT_SIZE); + // Initialize the repository. + + ~ACE_Service_Repository (void); + // Terminate the repository. + + int close (void); + // Terminate the repository. + + // = Search structure operations (all acquire locks as necessary). + + int insert (const ACE_Service_Record *); + // Insert a new service record. + + int find (const char[], + const ACE_Service_Record ** = 0, + int ignore_suspended = 1); + // Locate an existing service record. + + int remove (const char[]); + // Remove an existing service record. + + // = Liveness control + int resume (const char[], const ACE_Service_Record ** = 0); + // Resume a service record. + + int suspend (const char[], const ACE_Service_Record ** = 0); + // Suspend a service record. + + int current_size (void); + // Return the current size of the repository. + + int total_size (void); + // Return the total size of the repository. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + int find_i (const char service_name[], + const ACE_Service_Record ** = 0, + int ignore_suspended = 1); + // Locates . Must be called without locks being + // held... + + const ACE_Service_Record **service_vector_; + // Contains all the configured services. + + int current_size_; + // Current number of services. + + int total_size_; + // Maximum number of service. + +#if defined (ACE_MT_SAFE) + ACE_Thread_Mutex lock_; + // Synchronization variable for the MT_SAFE Repository +#endif /* ACE_MT_SAFE */ + + friend class ACE_Service_Repository_Iterator; +}; + +class ACE_Export ACE_Service_Repository_Iterator + // = TITLE + // + // = DESCRIPTION + // +{ +public: + ACE_Service_Repository_Iterator (ACE_Service_Repository &sr, + int ignored_suspended = 1); + int next (const ACE_Service_Record *&so); + int advance (void); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Service_Repository &svc_rep_; + int next_; + int ignore_suspended_; +}; + +#if defined (__ACE_INLINE__) +#include "ace/Service_Repository.i" +#endif /* __ACE_INLINE__ */ + +#endif /* _SERVICE_REPOSITORY_H */ diff --git a/ace/Service_Repository.i b/ace/Service_Repository.i new file mode 100644 index 00000000000..d5b70714154 --- /dev/null +++ b/ace/Service_Repository.i @@ -0,0 +1,27 @@ +/* -*- C++ -*- */ +// $Id$ + +// Service_Repository.i + +// Returns a count of the number of currently valid entries (counting +// both resumed and suspended entries). + +ACE_INLINE int +ACE_Service_Repository::current_size (void) +{ + ACE_TRACE ("ACE_Service_Repository::current_size"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + return this->current_size_; +} + +// Returns a count of the total number of possible entries in the +// table. + +ACE_INLINE int +ACE_Service_Repository::total_size (void) +{ + ACE_TRACE ("ACE_Service_Repository::total_size"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + return this->total_size_; +} + diff --git a/ace/Set.cpp b/ace/Set.cpp new file mode 100644 index 00000000000..85d5568149d --- /dev/null +++ b/ace/Set.cpp @@ -0,0 +1,502 @@ +// Set.cpp +// $Id$ + +#if !defined (ACE_SET_C) +#define ACE_SET_C + +#define ACE_BUILD_DLL +#include "ace/Set.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Set.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Fixed_Set) + +template void +ACE_Fixed_Set::dump (void) const +{ + ACE_TRACE ("ACE_Fixed_Set::dump"); +} + +template +ACE_Fixed_Set::~ACE_Fixed_Set (void) +{ + ACE_TRACE ("ACE_Fixed_Set::~ACE_Fixed_Set"); + this->cur_size_ = 0; +} + +template +ACE_Fixed_Set::ACE_Fixed_Set (void) + : cur_size_ (0), + max_size_ (SIZE) +{ + ACE_TRACE ("ACE_Fixed_Set::ACE_Fixed_Set"); + for (size_t i = 0; i < this->max_size_; i++) + this->search_structure_[i].is_free_ = 1; +} + +template int +ACE_Fixed_Set::find (const T &item) const +{ + ACE_TRACE ("ACE_Fixed_Set::find"); + for (size_t i = 0; i < this->cur_size_; i++) + { + if (this->search_structure_[i].item_ == item + && this->search_structure_[i].is_free_ == 0) + return 1; + } + + return 0; +} + +template int +ACE_Fixed_Set::insert (const T &item) + +{ + ACE_TRACE ("ACE_Fixed_Set::insert"); + int first_free = -1; // Keep track of first free slot. + size_t i; + + for (i = 0; i < this->cur_size_; i++) + { + // First, make sure we don't allow duplicates. + + if (this->search_structure_[i].item_ == item + && this->search_structure_[i].is_free_ == 0) + return 1; + else if (this->search_structure_[i].is_free_ + && first_free == -1) + first_free = i; + } + + // If we found a free spot let's reuse it. + if (first_free > -1) + { + this->search_structure_[first_free].item_ = item; + this->search_structure_[first_free].is_free_ = 0; + return 0; + } + // Insert at the end of the active portion. + else if (i < this->max_size_) + { + this->search_structure_[i].item_ = item; + this->search_structure_[i].is_free_ = 0; + this->cur_size_++; + return 0; + } + else /* No more room! */ + { + errno = ENOMEM; + return -1; + } +} + +template int +ACE_Fixed_Set::remove (const T &item) +{ + ACE_TRACE ("ACE_Fixed_Set::remove"); + for (size_t i = 0; i < this->cur_size_; i++) + { + if (this->search_structure_[i].item_ == item) + { + size_t index = i; + + // Mark this entry as being free. + this->search_structure_[i].is_free_ = 1; + + // If we just unbound the highest entry, then we need to + // figure out where the next highest active entry is. + if (i + 1 == this->cur_size_) + { + while (i > 0 + && this->search_structure_[--i].is_free_) + continue; + + if (i == 0 + && this->search_structure_[i].is_free_) + this->cur_size_ = 0; + else + this->cur_size_ = i + 1; + } + return 1; + } + } + return 0; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Fixed_Set_Iterator) + +template void +ACE_Fixed_Set_Iterator::dump (void) const +{ + ACE_TRACE ("ACE_Fixed_Set_Iterator::dump"); +} + +template +ACE_Fixed_Set_Iterator::ACE_Fixed_Set_Iterator (ACE_Fixed_Set &s) + : s_ (s), + next_ (-1) +{ + ACE_TRACE ("ACE_Fixed_Set_Iterator::ACE_Fixed_Set_Iterator"); + this->advance (); +} + +template int +ACE_Fixed_Set_Iterator::advance (void) +{ + ACE_TRACE ("ACE_Fixed_Set_Iterator::advance"); + for (++this->next_; + size_t (this->next_) < this->s_.cur_size_ + && this->s_.search_structure_[this->next_].is_free_; + ++this->next_) + continue; + + return this->next_; +} + +template int +ACE_Fixed_Set_Iterator::next (T *&item) +{ + ACE_TRACE ("ACE_Fixed_Set_Iterator::next"); + if (size_t (this->next_) < this->s_.cur_size_) + { + item = &this->s_.search_structure_[this->next_].item_; + return 1; + } + else + return 0; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Bounded_Set) + +template void +ACE_Bounded_Set::dump (void) const +{ + ACE_TRACE ("ACE_Bounded_Set::dump"); +} + +template +ACE_Bounded_Set::~ACE_Bounded_Set (void) +{ + ACE_TRACE ("ACE_Bounded_Set::~ACE_Bounded_Set"); + delete [] this->search_structure_; +} + +template +ACE_Bounded_Set::ACE_Bounded_Set (void) + : cur_size_ (0), + max_size_ (size_t (ACE_Bounded_Set::DEFAULT_SIZE)) +{ + ACE_TRACE ("ACE_Bounded_Set::ACE_Bounded_Set"); + + ACE_NEW (this->search_structure_, ACE_Bounded_Set::Search_Structure[this->max_size_]); + + for (size_t i = 0; i < this->max_size_; i++) + this->search_structure_[i].is_free_ = 1; +} + +template +ACE_Bounded_Set::ACE_Bounded_Set (size_t size) + : cur_size_ (0), + max_size_ (size) +{ + ACE_TRACE ("ACE_Bounded_Set::ACE_Bounded_Set"); + ACE_NEW (this->search_structure_, ACE_Bounded_Set::Search_Structure[size]); + + for (size_t i = 0; i < this->max_size_; i++) + this->search_structure_[i].is_free_ = 1; +} + +template int +ACE_Bounded_Set::find (const T &item) const +{ + ACE_TRACE ("ACE_Bounded_Set::find"); + for (size_t i = 0; i < this->cur_size_; i++) + { + if (this->search_structure_[i].item_ == item + && this->search_structure_[i].is_free_ == 0) + return 1; + } + + return 0; +} + +template int +ACE_Bounded_Set::insert (const T &item) +{ + ACE_TRACE ("ACE_Bounded_Set::insert"); + int first_free = -1; // Keep track of first free slot. + size_t i; + + for (i = 0; i < this->cur_size_; i++) + { + // First, make sure we don't allow duplicates. + + if (this->search_structure_[i].item_ == item + && this->search_structure_[i].is_free_ == 0) + return 1; + else if (this->search_structure_[i].is_free_ && first_free == -1) + first_free = i; + } + + if (first_free > -1) // If we found a free spot let's reuse it. + { + this->search_structure_[first_free].item_ = item; + this->search_structure_[first_free].is_free_ = 0; + return 0; + } + else if (i < this->max_size_) // Insert at the end of the active portion. + { + this->search_structure_[i].item_ = item; + this->search_structure_[i].is_free_ = 0; + this->cur_size_++; + return 0; + } + else /* No more room! */ + { + errno = ENOMEM; + return -1; + } +} + +template int +ACE_Bounded_Set::remove (const T &item) +{ + ACE_TRACE ("ACE_Bounded_Set::remove"); + for (size_t i = 0; i < this->cur_size_; i++) + { + if (this->search_structure_[i].item_ == item) + { + size_t index = i; + + // Mark this entry as being free. + this->search_structure_[i].is_free_ = 1; + + // If we just unbound the highest entry, then we need to + // figure out where the next highest active entry is. + if (i + 1 == this->cur_size_) + { + while (i > 0 && this->search_structure_[--i].is_free_) + continue; + + if (i == 0 && this->search_structure_[i].is_free_) + this->cur_size_ = 0; + else + this->cur_size_ = i + 1; + } + return 1; + } + } + return 0; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Bounded_Set_Iterator) + +template void +ACE_Bounded_Set_Iterator::dump (void) const +{ + ACE_TRACE ("ACE_Bounded_Set_Iterator::dump"); +} + +template +ACE_Bounded_Set_Iterator::ACE_Bounded_Set_Iterator (ACE_Bounded_Set &s) + : s_ (s), + next_ (-1) +{ + ACE_TRACE ("ACE_Bounded_Set_Iterator::ACE_Bounded_Set_Iterator"); + this->advance (); +} + +template int +ACE_Bounded_Set_Iterator::advance (void) +{ + ACE_TRACE ("ACE_Bounded_Set_Iterator::advance"); + for (++this->next_; + size_t (this->next_) < this->s_.cur_size_ + && this->s_.search_structure_[this->next_].is_free_; + ++this->next_) + continue; + + return this->next_; +} + +template int +ACE_Bounded_Set_Iterator::next (T *&item) +{ + ACE_TRACE ("ACE_Bounded_Set_Iterator::next"); + if (size_t (this->next_) < this->s_.cur_size_) + { + item = &this->s_.search_structure_[this->next_].item_; + return 1; + } + else + return 0; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Set_Node) + +template +class ACE_Set_Node +{ +friend class ACE_Unbounded_Set; +friend class ACE_Unbounded_Set_Iterator; +public: + // = Initialization methods + ACE_Set_Node (const T &i, ACE_Set_Node *n); + ACE_Set_Node (ACE_Set_Node *n = 0); + ACE_Set_Node (const ACE_Set_Node &n); + +private: + ACE_Set_Node *next_; + // Pointer to next element in the list of ACE_Set_Nodes. + + T item_; + // Current value of the item in this node. +}; + +template +ACE_Set_Node::ACE_Set_Node (const T &i, ACE_Set_Node *n) + : next_ (n), + item_ (i) +{ +// ACE_TRACE ("ACE_Set_Node::ACE_Set_Node"); +} + +template +ACE_Set_Node::ACE_Set_Node (ACE_Set_Node *n) + : next_ (n) +{ +// ACE_TRACE ("ACE_Set_Node::ACE_Set_Node"); +} + +template +ACE_Set_Node::ACE_Set_Node (const ACE_Set_Node &s) + : next_ (s.next_), + item_ (s.item_) +{ +// ACE_TRACE ("ACE_Set_Node::ACE_Set_Node"); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Unbounded_Set) + +template void +ACE_Unbounded_Set::dump (void) const +{ +// ACE_TRACE ("ACE_Unbounded_Set::dump"); +} + +template +ACE_Unbounded_Set::~ACE_Unbounded_Set (void) +{ +// ACE_TRACE ("ACE_Unbounded_Set::~ACE_Unbounded_Set"); + while (this->head_ != 0) + { + ACE_Set_Node *temp = this->head_; + this->head_ = this->head_->next_; + this->cur_size_--; + delete temp; + } +} + +template int +ACE_Unbounded_Set::find (const T &item) const +{ +// ACE_TRACE ("ACE_Unbounded_Set::find"); + for (ACE_Set_Node *temp = this->head_; + temp != 0; + temp = temp->next_) + if (temp->item_ == item) + return 1; + + return 0; +} + +template +ACE_Unbounded_Set::ACE_Unbounded_Set (void) + : head_ (0), + cur_size_ (0) +{ +// ACE_TRACE ("ACE_Unbounded_Set::ACE_Unbounded_Set"); +} + +template int +ACE_Unbounded_Set::insert (const T &item) +{ +// ACE_TRACE ("ACE_Unbounded_Set::insert"); + if (this->find (item) == 0) + { + ACE_NEW_RETURN (this->head_, ACE_Set_Node (item, this->head_), -1); + this->cur_size_++; + return 0; + } + else + return 1; +} + +template int +ACE_Unbounded_Set::remove (const T &item) +{ +// ACE_TRACE ("ACE_Unbounded_Set::remove"); + ACE_Set_Node *prev = 0; + ACE_Set_Node *temp; + + for (temp = this->head_; + temp != 0; + temp = temp->next_) + { + if (temp->item_ == item) + break; + prev = temp; + } + + if (temp == 0) + return 0; + else if (prev == 0) // Deleting the front of the list. + this->head_ = this->head_->next_; + else + prev->next_ = temp->next_; + + this->cur_size_--; + + delete temp; + return 1; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Unbounded_Set_Iterator) + +template void +ACE_Unbounded_Set_Iterator::dump (void) const +{ +// ACE_TRACE ("ACE_Unbounded_Set_Iterator::dump"); +} + +template +ACE_Unbounded_Set_Iterator::ACE_Unbounded_Set_Iterator (ACE_Unbounded_Set &s) + : current_ (s.head_) +{ +// ACE_TRACE ("ACE_Unbounded_Set_Iterator::ACE_Unbounded_Set_Iterator"); +} + +template int +ACE_Unbounded_Set_Iterator::advance (void) +{ +// ACE_TRACE ("ACE_Unbounded_Set_Iterator::advance"); + this->current_ = this->current_->next_; + return 1; +} + +template int +ACE_Unbounded_Set_Iterator::next (T *&item) +{ +// ACE_TRACE ("ACE_Unbounded_Set_Iterator::next"); + if (this->current_ == 0) + return 0; + else + { + item = &this->current_->item_; + return 1; + } +} + +#endif /* ACE_SET_C */ diff --git a/ace/Set.h b/ace/Set.h new file mode 100644 index 00000000000..be0c3246e56 --- /dev/null +++ b/ace/Set.h @@ -0,0 +1,321 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Set.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SET) +#define ACE_SET + +#include "ace/ACE.h" + +// Forward declarations. +template class ACE_Unbounded_Set; + +// "Cheshire cat" +template class ACE_Set_Node; + +template +class ACE_Unbounded_Set_Iterator + // = TITLE + // Implement an iterator over an unbounded set. +{ +public: + // = Initialization method. + ACE_Unbounded_Set_Iterator (ACE_Unbounded_Set &s); + + // = Iteration methods. + + int next (T *&next_item); + // Pass back the that hasn't been seen in the Set. + // Returns 0 when all items have been seen, else 1. + + int advance (void); + // Move forward by one element in the set. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Set_Node *current_; +}; + +// Forward declaration (use the "Cheshire Cat" approach to information +// hiding). +template +class ACE_Set_Node; + +template +class ACE_Unbounded_Set + // = TITLE + // Implement a simple unordered set of of unbounded size. + // + // = DESCRIPTION + // This implementation of an unordered set uses a linked list. + // This implementation does not allow duplicates... +{ +friend class ACE_Unbounded_Set_Iterator; +public: + // = Initialization and termination methods. + ACE_Unbounded_Set (void); + ~ACE_Unbounded_Set (void); + + // = Classic unordered set operations. + int insert (const T &new_item); + // Insert into the set (doesn't allow duplicates). + // Returns -1 if failures occur, 1 if item is already present, else + // 0. + + int remove (const T &item); + // Remove first occurrence of from the set. Returns 1 if + // it removes the item, 0 if it can't find the item, and -1 if a + // failure occurs. + + int find (const T &item) const; + // Return first occurrence of from the set. + // Returns 0 if can't find, else 1. + + size_t size (void) const; + // Size of the set. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Set_Node *head_; + // Head of the linked list of Nodes. + + size_t cur_size_; + // Current size of the set. +}; + +// Forward declaration. +template +class ACE_Fixed_Set; + +template +class ACE_Fixed_Set_Iterator + // = TITLE + // Interates through an unordered set. + // + // = DESCRIPTION + // This implementation of an unordered set uses a fixed array. + // Allows deletions while iteration is occurring. +{ +public: + // = Initialization method. + ACE_Fixed_Set_Iterator (ACE_Fixed_Set &s); + + // = Iteration methods. + + int next (T *&next_item); + // Pass back the that hasn't been seen in the Set. + // Returns 0 when all items have been seen, else 1. + + int advance (void); + // Move forward by one element in the set. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Fixed_Set &s_; + // Set we are iterating over. + + ssize_t next_; + // How far we've advanced over the set. +}; + +template +class ACE_Fixed_Set + // = TITLE + // Implement a simple unordered set of with maximum . + // + // = DESCRIPTION + // This implementation of an unordered set uses a fixed array. + // This implementation does not allow duplicates... +{ +friend class ACE_Fixed_Set_Iterator; +public: + // = Initialization and termination methods. + ACE_Fixed_Set (void); + ~ACE_Fixed_Set (void); + + // = Classic unordered set operations. + int insert (const T &new_item); + // Insert into the set (doesn't allow duplicates). + // Returns -1 if failures occur, 1 if item is already present, else + // 0. + + int remove (const T &item); + // Remove first occurrence of from the set. Returns 1 if + // it removes the item, 0 if it can't find the item, and -1 if a + // failure occurs. + + int find (const T &item) const; + // Return first occurrence of from the set. + // Returns 0 if can't find, else 1. + + size_t size (void) const; + // Size of the set. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + struct + { + T item_; + // Item in the set. + int is_free_; + // Keeps track of whether this item is in use or not. + } search_structure_[SIZE]; + // Holds the contents of the set. + + size_t cur_size_; + // Current size of the set. + + size_t max_size_; + // Maximum size of the set. +}; + +// Forward declaration. +template +class ACE_Bounded_Set; + +template +class ACE_Bounded_Set_Iterator + // = TITLE + // Interates through an unordered set. + // + // = DESCRIPTION + // This implementation of an unordered set uses a Bounded array. + // Allows deletions while iteration is occurring. +{ +public: + // = Initialization method. + ACE_Bounded_Set_Iterator (ACE_Bounded_Set &s); + + // = Iteration methods. + + int next (T *&next_item); + // Pass back the that hasn't been seen in the Set. + // Returns 0 when all items have been seen, else 1. + + int advance (void); + // Move forward by one element in the set. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Bounded_Set &s_; + // Set we are iterating over. + + ssize_t next_; + // How far we've advanced over the set. +}; + +template +class ACE_Bounded_Set + // = TITLE + // Implement a simple unordered set of with maximum + // set at creation time. + // + // = DESCRIPTION + // This implementation of an unordered set uses a Bounded array. + // This implementation does not allow duplicates... +{ +friend class ACE_Bounded_Set_Iterator; +public: + enum + { + DEFAULT_SIZE = 10 + }; + + // = Initialization and termination methods. + ACE_Bounded_Set (void); + ACE_Bounded_Set (size_t size); + ~ACE_Bounded_Set (void); + + // = Classic unordered set operations. + int insert (const T &new_item); + // Insert into the set (doesn't allow duplicates). + // Returns -1 if failures occur, 1 if item is already present, else + // 0. + + int remove (const T &item); + // Remove first occurrence of from the set. Returns 1 if it + // removes the item, 0 if it can't find the item, and -1 if a + // failure occurs. + + int find (const T &item) const; + // Return first occurrence of from the set. + // Returns 0 if can't find, else 1. + + size_t size (void) const; + // Size of the set. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + struct Search_Structure + { + T item_; + // Item in the set. + int is_free_; + // Keeps track of whether this item is in use or not. + }; + + Search_Structure *search_structure_; + // Holds the contents of the set. + + size_t cur_size_; + // Current size of the set. + + size_t max_size_; + // Maximum size of the set. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Set.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Set.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Set.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_SET */ diff --git a/ace/Set.i b/ace/Set.i new file mode 100644 index 00000000000..baec2deb9f2 --- /dev/null +++ b/ace/Set.i @@ -0,0 +1,24 @@ +/* -*- C++ -*- */ +// $Id$ + +// Set.i + +template ACE_INLINE size_t +ACE_Fixed_Set::size (void) const +{ + return this->cur_size_; +} + +template ACE_INLINE size_t +ACE_Bounded_Set::size (void) const +{ + ACE_TRACE ("ACE_Bounded_Set::size"); + return this->cur_size_; +} + +template ACE_INLINE size_t +ACE_Unbounded_Set::size (void) const +{ +// ACE_TRACE ("ACE_Unbounded_Set::size"); + return this->cur_size_; +} diff --git a/ace/Shared_Memory.h b/ace/Shared_Memory.h new file mode 100644 index 00000000000..b175cbde497 --- /dev/null +++ b/ace/Shared_Memory.h @@ -0,0 +1,43 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Shared_Memory.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SHARED_MEMORY_H) +#define ACE_SHARED_MEMORY_H + +#include "ace/ACE.h" + +class ACE_Export ACE_Shared_Memory + // = TITLE + // This base class adapts both System V shared memory and "BSD" + // mmap to a common API. + // + // = DESCRIPTION + // This is a very simple-minded wrapper, i.e., it really is only + // useful for allocating large contiguous chunks of shared + // memory. For a much more sophisticated version, please check + // out the class. +{ +public: + // = Note that all methods are pure virtual. + virtual int close (void) = 0; + virtual int remove (void) = 0; + virtual void *malloc (size_t = 0) = 0; + virtual int free (void *p) = 0; + virtual int get_segment_size (void) const = 0; + virtual ACE_HANDLE get_id (void) const = 0; +}; +#endif /* ACE_SHARED_MEMORY_H */ diff --git a/ace/Shared_Memory_MM.cpp b/ace/Shared_Memory_MM.cpp new file mode 100644 index 00000000000..cc5f93846c4 --- /dev/null +++ b/ace/Shared_Memory_MM.cpp @@ -0,0 +1,52 @@ +// Shared_Memory_MM.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Shared_Memory_MM.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Shared_Memory_MM.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Shared_Memory_MM) + +void +ACE_Shared_Memory_MM::dump (void) const +{ + ACE_TRACE ("ACE_Shared_Memory_MM::dump"); +} + +// Creates a shared memory segment of SIZE bytes. + +ACE_Shared_Memory_MM::ACE_Shared_Memory_MM (ACE_HANDLE handle, + int length, + int prot, + int share, + char *addr, + off_t pos) + : shared_memory_ (handle, length, prot, share, addr, pos) +{ + ACE_TRACE ("ACE_Shared_Memory_MM::ACE_Shared_Memory_MM"); +} + +ACE_Shared_Memory_MM::ACE_Shared_Memory_MM (char file_name[], + int len, + int flags, + int mode, + int prot, + int share, + char *addr, + off_t pos) + : shared_memory_ (file_name, len, flags, mode, + prot, share, addr, pos) +{ + ACE_TRACE ("ACE_Shared_Memory_MM::ACE_Shared_Memory_MM"); +} + +// The "do-nothing" constructor. + +ACE_Shared_Memory_MM::ACE_Shared_Memory_MM (void) +{ + ACE_TRACE ("ACE_Shared_Memory_MM::ACE_Shared_Memory_MM"); +} + diff --git a/ace/Shared_Memory_MM.h b/ace/Shared_Memory_MM.h new file mode 100644 index 00000000000..9567e0e33df --- /dev/null +++ b/ace/Shared_Memory_MM.h @@ -0,0 +1,95 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Shared_Memory_MM.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SHARED_MALLOC_MM_H) +#define ACE_SHARED_MALLOC_MM_H + +#include "ace/Shared_Memory.h" +#include "ace/Mem_Map.h" + +class ACE_Export ACE_Shared_Memory_MM : public ACE_Shared_Memory + // = TITLE + // Shared memory wrapper based on MMAP. +{ +public: + // = Initialization and termination methods. + ACE_Shared_Memory_MM (void); + ACE_Shared_Memory_MM (ACE_HANDLE handle, + int length = -1, + int prot = PROT_RDWR, + int share = MAP_PRIVATE, + char *addr = 0, + off_t pos = 0); + ACE_Shared_Memory_MM (char file_name[], + int len = -1, + int flags = O_RDWR | O_CREAT, + int mode = ACE_DEFAULT_PERMS, + int prot = PROT_RDWR, + int share = MAP_SHARED, + char *addr = 0, off_t pos = 0); + + int open (ACE_HANDLE handle, + int length = -1, + int prot = PROT_RDWR, + int share = MAP_PRIVATE, + char *addr = 0, + off_t pos = 0); + + int open (char file_name[], + int len = -1, + int flags = O_RDWR | O_CREAT, + int mode = ACE_DEFAULT_PERMS, + int prot = PROT_RDWR, + int share = MAP_SHARED, + char *addr = 0, + off_t pos = 0); + + virtual int close (void); + // Close down the shared memory segment. + + virtual int remove (void); + // Remove the shared memory segment and the underlying file. + + // = Allocation and deallocation methods. + virtual void *malloc (size_t size = 0); + // Create a new chuck of memory containing bytes. + + virtual int free (void *p); + // Free a chuck of memory allocated by . + + virtual int get_segment_size (void) const; + // Return the size of the shared memory segment. + + virtual ACE_HANDLE get_id (void) const; + // Return the ID of the shared memory segment (i.e., an ACE_HANDLE). + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Mem_Map shared_memory_; + // This version is implemented with memory-mapped files. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Shared_Memory_MM.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_SHARED_MALLOC_MM_H */ diff --git a/ace/Shared_Memory_MM.i b/ace/Shared_Memory_MM.i new file mode 100644 index 00000000000..4f49965c3f3 --- /dev/null +++ b/ace/Shared_Memory_MM.i @@ -0,0 +1,81 @@ +/* -*- C++ -*- */ +// $Id$ + +// Shared_Memory_MM.i + +ACE_INLINE int +ACE_Shared_Memory_MM::open (ACE_HANDLE handle, + int length, + int prot, + int share, + char *addr, + off_t pos) +{ + ACE_TRACE ("ACE_Shared_Memory_MM::open"); + return shared_memory_.map (handle, length, prot, share, addr, pos); +} + +ACE_INLINE int +ACE_Shared_Memory_MM::open (char file_name[], + int len, + int flags, + int mode, + int prot, + int share, + char *addr, + off_t pos) +{ + ACE_TRACE ("ACE_Shared_Memory_MM::open"); + return shared_memory_.map (file_name, len, flags, mode, + prot, share, addr, pos); +} + +// The overall size of the segment. + +ACE_INLINE int +ACE_Shared_Memory_MM::get_segment_size (void) const +{ + ACE_TRACE ("ACE_Shared_Memory_MM::get_segment_size"); + return this->shared_memory_.size (); +} + +// Unmaps the shared memory segment. + +ACE_INLINE int +ACE_Shared_Memory_MM::remove (void) +{ + ACE_TRACE ("ACE_Shared_Memory_MM::remove"); + return shared_memory_.unmap (); +} + +// Closes (unmaps) the shared memory segment. + +ACE_INLINE int +ACE_Shared_Memory_MM::close (void) +{ + ACE_TRACE ("ACE_Shared_Memory_MM::close"); + return shared_memory_.unmap (); +} + +ACE_INLINE void * +ACE_Shared_Memory_MM::malloc (size_t) +{ + ACE_TRACE ("ACE_Shared_Memory_MM::malloc"); + void *addr; + + return this->shared_memory_ (addr) == -1 ? 0 : addr; +} + +ACE_INLINE ACE_HANDLE +ACE_Shared_Memory_MM::get_id (void) const +{ + ACE_TRACE ("ACE_Shared_Memory_MM::get_id"); + return this->shared_memory_.handle (); +} + +ACE_INLINE int +ACE_Shared_Memory_MM::free (void *p) +{ + ACE_TRACE ("ACE_Shared_Memory_MM::free"); + return p != 0; +} diff --git a/ace/Shared_Memory_SV.cpp b/ace/Shared_Memory_SV.cpp new file mode 100644 index 00000000000..eec600c2ea1 --- /dev/null +++ b/ace/Shared_Memory_SV.cpp @@ -0,0 +1,29 @@ +// Shared_Memory_SV.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Shared_Memory_SV.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Shared_Memory_SV.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Shared_Memory_SV) + +void +ACE_Shared_Memory_SV::dump (void) const +{ + ACE_TRACE ("ACE_Shared_Memory_SV::dump"); +} + +ACE_Shared_Memory_SV::ACE_Shared_Memory_SV (key_t id, + int length, + int create, + int perms, + void *addr, + int flags) + : shared_memory_ (id, length, create, perms, addr, flags) +{ + ACE_TRACE ("ACE_Shared_Memory_SV::ACE_Shared_Memory_SV"); +} + diff --git a/ace/Shared_Memory_SV.h b/ace/Shared_Memory_SV.h new file mode 100644 index 00000000000..56ee316cd38 --- /dev/null +++ b/ace/Shared_Memory_SV.h @@ -0,0 +1,87 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Shared_Memory_SV.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SHARED_MALLOC_SV_H) +#define ACE_SHARED_MALLOC_SV_H + +#include "ace/Shared_Memory.h" +#include "ace/SV_Shared_Memory.h" + +class ACE_Export ACE_Shared_Memory_SV : public ACE_Shared_Memory + // = TITLE + // Shared memory wrapper based on System V shared memory. +{ +public: + enum + { + ACE_CREATE = IPC_CREAT, + ACE_OPEN = 0 + }; + + // = Initialization and termination methods. + ACE_Shared_Memory_SV (void); + ACE_Shared_Memory_SV (key_t id, + int length, + int create = ACE_Shared_Memory_SV::ACE_OPEN, + int perms = ACE_DEFAULT_PERMS, + void *addr = 0, + int flags = 0); + + int open (key_t id, + int length, + int create = ACE_Shared_Memory_SV::ACE_OPEN, + int perms = ACE_DEFAULT_PERMS, + void *addr = 0, + int flags = 0); + + virtual int close (void); + // Close down the shared memory segment. + + virtual int remove (void); + // Remove the shared memory segment and the underlying file. + + // = Allocation and deallocation methods. + virtual void *malloc (size_t = 0); + // Create a new chuck of memory containing bytes. + + virtual int free (void *p); + // Free a chuck of memory allocated by . + + virtual int get_segment_size (void) const; + // Return the size of the shared memory segment. + + virtual ACE_HANDLE get_id (void) const; + // Return the ID of the shared memory segment (i.e., a System V + // shared memory internal id). + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_SV_Shared_Memory shared_memory_; + // This version is implemented with System V shared memory + // segments. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Shared_Memory_SV.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_SHARED_MALLOC_SV_H */ diff --git a/ace/Shared_Memory_SV.i b/ace/Shared_Memory_SV.i new file mode 100644 index 00000000000..400d9e63201 --- /dev/null +++ b/ace/Shared_Memory_SV.i @@ -0,0 +1,73 @@ +/* -*- C++ -*- */ +// $Id$ + +// Shared_Memory_SV.i + +ACE_INLINE int +ACE_Shared_Memory_SV::open (key_t id, + int length, + int create, + int perms, + void *addr, + int flags) +{ + ACE_TRACE ("ACE_Shared_Memory_SV::open"); + return shared_memory_.open_and_attach (id, length, create, + perms, addr, flags); +} + +// The overall size of the segment. + +ACE_INLINE int +ACE_Shared_Memory_SV::get_segment_size (void) const +{ + ACE_TRACE ("ACE_Shared_Memory_SV::get_segment_size"); + return this->shared_memory_.get_segment_size (); +} + +// Removes the shared memory segment. + +ACE_INLINE int +ACE_Shared_Memory_SV::remove (void) +{ + ACE_TRACE ("ACE_Shared_Memory_SV::remove"); + return shared_memory_.remove (); +} + +// Closes (detaches) the shared memory segment. + +ACE_INLINE int +ACE_Shared_Memory_SV::close (void) +{ + ACE_TRACE ("ACE_Shared_Memory_SV::close"); + return shared_memory_.detach (); +} + +ACE_INLINE void * +ACE_Shared_Memory_SV::malloc (size_t) +{ + ACE_TRACE ("ACE_Shared_Memory_SV::malloc"); + return this->shared_memory_.get_segment_ptr (); +} + +ACE_INLINE ACE_HANDLE +ACE_Shared_Memory_SV::get_id (void) const +{ + ACE_TRACE ("ACE_Shared_Memory_SV::get_id"); + return this->shared_memory_.get_id (); +} + +// The "do-nothing" constructor. + +ACE_INLINE +ACE_Shared_Memory_SV::ACE_Shared_Memory_SV (void) +{ + ACE_TRACE ("ACE_Shared_Memory_SV::ACE_Shared_Memory_SV"); +} + +ACE_INLINE int +ACE_Shared_Memory_SV::free (void *p) +{ + ACE_TRACE ("ACE_Shared_Memory_SV::free"); + return p != 0; +} diff --git a/ace/Shared_Object.cpp b/ace/Shared_Object.cpp new file mode 100644 index 00000000000..a18c728959e --- /dev/null +++ b/ace/Shared_Object.cpp @@ -0,0 +1,46 @@ +// Shared_Object.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Shared_Object.h" +/* Provide the abstract base class used to access dynamic linking + facilities */ + + +#if !defined (__ACE_INLINE__) +#include "ace/Shared_Object.i" +#endif /* __ACE_INLINE__ */ + +// Initializes object when dynamic linking occurs. + +int +ACE_Shared_Object::init (int, char *[]) +{ + ACE_TRACE ("ACE_Shared_Object::init"); + return -1; +} + +// Terminates object when dynamic unlinking occurs. + +int +ACE_Shared_Object::fini (void) +{ + ACE_TRACE ("ACE_Shared_Object::fini"); + return -1; +} + +// Returns information on active object. + +int +ACE_Shared_Object::info (char **, size_t) const +{ + ACE_TRACE ("ACE_Shared_Object::info"); + return -1; +} + +// Need to give a default implementation. + +ACE_Shared_Object::~ACE_Shared_Object (void) +{ + ACE_TRACE ("ACE_Shared_Object::~ACE_Shared_Object"); +} diff --git a/ace/Shared_Object.h b/ace/Shared_Object.h new file mode 100644 index 00000000000..7298a53b9a6 --- /dev/null +++ b/ace/Shared_Object.h @@ -0,0 +1,45 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Shared_Object.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SHARED_OBJECT_H) +#define ACE_SHARED_OBJECT_H + +#include "ace/ACE.h" + +class ACE_Export ACE_Shared_Object + // = TITLE + // Provide the abstract base class used to access dynamic linking + // facilities +{ +public: + virtual int init (int argc, char *argv[]); + // Initializes object when dynamic linking occurs. + + virtual int fini (void); + // Terminates object when dynamic unlinking occurs. + + virtual int info (char **info_string, size_t length = 0) const; + // Returns information on active object. + + virtual ~ACE_Shared_Object (void); +}; + +#if defined (__ACE_INLINE__) +#include "ace/Shared_Object.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_SHARED_OBJECT_H */ diff --git a/ace/Shared_Object.i b/ace/Shared_Object.i new file mode 100644 index 00000000000..c6840a221cc --- /dev/null +++ b/ace/Shared_Object.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// $Id$ + +// Shared_Object.i diff --git a/ace/Signal.cpp b/ace/Signal.cpp new file mode 100644 index 00000000000..5acd5195d66 --- /dev/null +++ b/ace/Signal.cpp @@ -0,0 +1,632 @@ +// Signal.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Signal.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Signal.i" +#endif /* __ACE_INLINE__ */ + +// Static definitions. + +#if defined (ACE_MT_SAFE) +ACE_Recursive_Thread_Mutex ACE_Sig_Handler::ace_sig_handler_lock_; +#endif /* ACE_MT_SAFE */ + +// Array of Event_Handlers that will handle the signals. +ACE_Event_Handler *ACE_Sig_Handler::signal_handlers_[NSIG]; + +// Remembers if a signal has occurred. +sig_atomic_t ACE_Sig_Handler::sig_pending_ = 0; + +ACE_ALLOC_HOOK_DEFINE(ACE_Sig_Action) + +void +ACE_Sig_Action::dump (void) const +{ + ACE_TRACE ("ACE_Sig_Action::dump"); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Sig_Set) + +void +ACE_Sig_Set::dump (void) const +{ + ACE_TRACE ("ACE_Sig_Set::dump"); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Sig_Guard) + +void +ACE_Sig_Guard::dump (void) const +{ + ACE_TRACE ("ACE_Sig_Guard::dump"); +} + +ACE_Sig_Action::ACE_Sig_Action (void) +{ + ACE_TRACE ("ACE_Sig_Action::ACE_Sig_Action"); + this->sa_.sa_flags = 0; + ACE_OS::sigemptyset (&this->sa_.sa_mask); + this->sa_.sa_handler = 0; +} + +ACE_Sig_Action::ACE_Sig_Action (ACE_SignalHandler sig_handler, + sigset_t *sig_mask, + int sig_flags) +{ + ACE_TRACE ("ACE_Sig_Action::ACE_Sig_Action"); + this->sa_.sa_flags = sig_flags; + + if (sig_mask == 0) + ACE_OS::sigemptyset (&this->sa_.sa_mask); + else + this->sa_.sa_mask = *sig_mask; // Structure assignment... + + this->sa_.sa_handler = ACE_SignalHandlerV (sig_handler); +} + +ACE_Sig_Action::ACE_Sig_Action (ACE_SignalHandler sig_handler, + int signum, + sigset_t *sig_mask, + int sig_flags) +{ + ACE_TRACE ("ACE_Sig_Action::ACE_Sig_Action"); + this->sa_.sa_flags = sig_flags; + + if (sig_mask == 0) + ACE_OS::sigemptyset (&this->sa_.sa_mask); + else + this->sa_.sa_mask = *sig_mask; // Structure assignment... + + this->sa_.sa_handler = ACE_SignalHandlerV (sig_handler); + ACE_OS::sigaction (signum, &this->sa_, 0); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Sig_Handler) + +void +ACE_Sig_Handler::dump (void) const +{ + ACE_TRACE ("ACE_Sig_Handler::dump"); +} + +sig_atomic_t +ACE_Sig_Handler::sig_pending (void) +{ + ACE_TRACE ("ACE_Sig_Handler::sig_pending"); + ACE_MT (ACE_TSS_Guard m (ACE_Sig_Handler::ace_sig_handler_lock_)); + return ACE_Sig_Handler::sig_pending_; +} + +void +ACE_Sig_Handler::sig_pending (sig_atomic_t pending) +{ + ACE_TRACE ("ACE_Sig_Handler::sig_pending"); + ACE_MT (ACE_TSS_Guard m (ACE_Sig_Handler::ace_sig_handler_lock_)); + ACE_Sig_Handler::sig_pending_ = pending; +} + +ACE_Event_Handler * +ACE_Sig_Handler::handler (int signum) +{ + ACE_TRACE ("ACE_Sig_Handler::handler"); + ACE_MT (ACE_TSS_Guard m (ACE_Sig_Handler::ace_sig_handler_lock_)); + + if (ACE_Sig_Handler::in_range (signum)) + return ACE_Sig_Handler::signal_handlers_[signum]; + else + return 0; +} + +ACE_Event_Handler * +ACE_Sig_Handler::handler (int signum, ACE_Event_Handler *new_sh) +{ + ACE_TRACE ("ACE_Sig_Handler::handler"); + ACE_MT (ACE_TSS_Guard m (ACE_Sig_Handler::ace_sig_handler_lock_)); + + if (ACE_Sig_Handler::in_range (signum)) + { + ACE_Event_Handler *sh = ACE_Sig_Handler::signal_handlers_[signum]; + + ACE_Sig_Handler::signal_handlers_[signum] = new_sh; + return sh; + } + else + return 0; +} + +// Register an ACE_Event_Handler along with the corresponding SIGNUM. + +int +ACE_Sig_Handler::register_handler (int signum, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp, + ACE_Event_Handler **old_sh, + ACE_Sig_Action *old_disp) +{ + ACE_TRACE ("ACE_Sig_Handler::register_handler"); + ACE_MT (ACE_TSS_Guard m (ACE_Sig_Handler::ace_sig_handler_lock_)); + + if (ACE_Sig_Handler::in_range (signum)) + { + ACE_Sig_Action sa; // Define a "null" action. + ACE_Event_Handler *sh = this->handler (signum, new_sh); + + // Stack the old ACE_Sig_Handler if the user gives us a pointer + // to a object. + if (old_sh != 0) + *old_sh = sh; + + // Make sure that new_disp points to a valid location if the + // user doesn't care... + if (new_disp == 0) + new_disp = &sa; + + new_disp->handler (ACE_SignalHandler (ACE_Sig_Handler::dispatch)); + new_disp->flags (new_disp->flags () | SA_SIGINFO); + return new_disp->register_action (signum, old_disp); + } + else + return -1; +} + +// Remove an ACE_Event_Handler. + +int +ACE_Sig_Handler::remove_handler (int signum, + ACE_Sig_Action *new_disp, + ACE_Sig_Action *old_disp, + int sigkey) +{ + ACE_TRACE ("ACE_Sig_Handler::remove_handler"); + ACE_MT (ACE_TSS_Guard m (ACE_Sig_Handler::ace_sig_handler_lock_)); + + if (ACE_Sig_Handler::in_range (signum)) + { + ACE_Sig_Action sa (SIG_DFL); // Define the default disposition. + + if (new_disp == 0) + new_disp = &sa; + + ACE_Sig_Handler::signal_handlers_[signum] = 0; + + // Register either the new disposition or restore the default. + return new_disp->register_action (signum, old_disp); + } + else + return -1; +} + +// Master dispatcher function that gets called by a signal handler and +// dispatches one handler... + +void +ACE_Sig_Handler::dispatch (int signum, + siginfo_t *siginfo, + ucontext_t *ucontext) +{ + ACE_TRACE ("ACE_Sig_Handler::dispatch"); + ACE_MT (ACE_TSS_Guard m (ACE_Sig_Handler::ace_sig_handler_lock_)); + + // Preserve errno across callbacks! + int old_errno = errno; + + ACE_Sig_Handler::sig_pending (1); + + // Darn well better be in range since the OS dispatched this... + ACE_ASSERT (ACE_Sig_Handler::in_range (signum)); + + ACE_Event_Handler *eh = ACE_Sig_Handler::signal_handlers_[signum]; + + if (eh != 0 && eh->handle_signal (signum, siginfo, ucontext) == -1) + { + // Define the default disposition. + ACE_Sig_Action sa (SIG_DFL); + + ACE_Sig_Handler::signal_handlers_[signum] = 0; + + // Remove the current disposition by registering the default + // disposition. + sa.register_action (signum); + } + + // Restore error when callback completes. + errno = old_errno; +} + +ACE_Sig_Adapter::ACE_Sig_Adapter (ACE_Sig_Action &sa, int sigkey) + : sa_ (sa), + type_ (SIG_ACTION), + sigkey_ (sigkey) +{ + ACE_TRACE ("ACE_Sig_Adapter::ACE_Sig_Adapter"); +} + +ACE_Sig_Adapter::ACE_Sig_Adapter (ACE_Event_Handler *eh, + int sigkey) + : eh_ (eh), + type_ (ACE_HANDLER), + sigkey_ (sigkey) +{ + ACE_TRACE ("ACE_Sig_Adapter::ACE_Sig_Adapter"); +} + +ACE_Sig_Adapter::ACE_Sig_Adapter (ACE_Sig_Handler_Ex sig_func, + int sigkey) + : sig_func_ (sig_func), + type_ (C_FUNCTION), + sigkey_ (sigkey) +{ + ACE_TRACE ("ACE_Sig_Adapter::ACE_Sig_Adapter"); +} + +int +ACE_Sig_Adapter::sigkey (void) +{ + ACE_TRACE ("ACE_Sig_Adapter::sigkey"); + return this->sigkey_; +} + +int +ACE_Sig_Adapter::handle_signal (int signum, + siginfo_t *siginfo, + ucontext_t *ucontext) +{ + ACE_TRACE ("ACE_Sig_Adapter::handle_signal"); + + switch (this->type_) + { + case SIG_ACTION: + { + // We have to dispatch a handler that was registered by a + // third-party library. + + ACE_Sig_Action old_disp; + + // Make sure this handler executes in the context it was + // expecting... + this->sa_.register_action (signum, &old_disp); + + ACE_Sig_Handler_Ex sig_func = ACE_Sig_Handler_Ex (this->sa_.handler ()); + + (*sig_func) (signum, siginfo, ucontext); + // Restore the original disposition. + old_disp.register_action (signum); + break; + } + case ACE_HANDLER: + this->eh_->handle_signal (signum, siginfo, ucontext); + break; + case C_FUNCTION: + (*this->sig_func_) (signum, siginfo, ucontext); + break; + } + return 0; +} + +// ---------------------------------------- +// The following classes are local to this file. + +// HPUX sucks big time! +#if !defined (HPUX) +// This needs to be fixed... +#define ACE_MAX_SIGNAL_HANDLERS size_t (20) + +// Keeps track of the id that uniquely identifies each registered +// signal handler. This id can be used to cancel a timer via the +// method. +int ACE_Sig_Handlers::sigkey_ = 0; + +// If this is > 0 then a 3rd party library has registered a +// handler... +int ACE_Sig_Handlers::third_party_sig_handler_ = 0; + +// Make life easier by defining typedefs... +typedef ACE_Fixed_Set + ACE_SIG_HANDLERS_SET; +typedef ACE_Fixed_Set_Iterator + ACE_SIG_HANDLERS_ITERATOR; + +class ACE_Sig_Handlers_Set +{ +public: + static ACE_SIG_HANDLERS_SET *instance (int signum); + +private: + static ACE_SIG_HANDLERS_SET *sig_handlers_[NSIG]; +}; + +/* static */ +ACE_SIG_HANDLERS_SET *ACE_Sig_Handlers_Set::sig_handlers_[NSIG]; + +/* static */ +ACE_SIG_HANDLERS_SET * +ACE_Sig_Handlers_Set::instance (int signum) +{ + if (signum <= 0 || signum >= NSIG) + return 0; // This will cause problems... + else if (ACE_Sig_Handlers_Set::sig_handlers_[signum] == 0) + ACE_NEW_RETURN (ACE_Sig_Handlers_Set::sig_handlers_[signum], ACE_SIG_HANDLERS_SET, 0); + + return ACE_Sig_Handlers_Set::sig_handlers_[signum]; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Sig_Handlers) + +void +ACE_Sig_Handlers::dump (void) const +{ + ACE_TRACE ("ACE_Sig_Handlers::dump"); +} + +// This is the method that does all the dirty work... The basic +// structure of this method was devised by Detlef Becker +// (beckerd@erlh.siemens.de). + +int +ACE_Sig_Handlers::register_handler (int signum, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp, + ACE_Event_Handler **old_sh, + ACE_Sig_Action *old_disp) +{ + ACE_TRACE ("ACE_Sig_Handlers::register_handler"); + ACE_MT (ACE_TSS_Guard m (ACE_Sig_Handler::ace_sig_handler_lock_)); + + if (ACE_Sig_Handler::in_range (signum)) + { + ACE_Sig_Adapter *ace_sig_adapter = 0; // Our signal handler. + ACE_Sig_Adapter *extern_sh = 0; // An external signal handler. + ACE_Sig_Action sa; + + // Get current signal disposition. + sa.retrieve_action (signum); + + // Check whether we are already in control of the signal + // handling disposition... + + if (!(sa.handler () == ACE_SignalHandler (ACE_Sig_Handlers::dispatch) + || sa.handler () == ACE_SignalHandler (SIG_IGN) + || sa.handler () == ACE_SignalHandler (SIG_DFL))) + { + // Drat, a 3rd party library has already installed a signal ;-( + + // Upto here we never disabled RESTART_MODE. Thus, + // RESTART_MODE can only be changed by 3rd party libraries. + + if (ACE_BIT_DISABLED (sa.flags (), SA_RESTART) + && ACE_Sig_Handlers::third_party_sig_handler_) + // Toggling is disallowed since we might break 3rd party + // code. + return -1; + + // Note that we've seen a 3rd party handler... + ACE_Sig_Handlers::third_party_sig_handler_ = 1; + + // Create a new 3rd party disposition, remembering its + // preferred signal blocking etc...; + ACE_NEW_RETURN (extern_sh, ACE_Sig_Adapter (sa, ++ACE_Sig_Handlers::sigkey_), -1); + + // Add the external signal handler to the set of handlers + // for this signal. + if (ACE_Sig_Handlers_Set::instance (signum)->insert (extern_sh) == -1) + { + delete extern_sh; + return -1; + } + } + // Add our new handler at this point. + ACE_NEW_RETURN (ace_sig_adapter, ACE_Sig_Adapter (new_sh, ++ACE_Sig_Handlers::sigkey_), -1); + + // Add the ACE signal handler to the set of handlers for this + // signal (make sure it goes before the external one if there is + // one of these). + if (ACE_Sig_Handlers_Set::instance (signum)->insert (ace_sig_adapter) == -1) + { + // We couldn't reinstall our handler, so let's pretend like + // none of this happened... + if (extern_sh) + { + ACE_Sig_Handlers_Set::instance (signum)->remove (extern_sh); + delete extern_sh; + } + delete ace_sig_adapter; + return -1; + } + // If ACE_Sig_Handler::dispatch() was set we're done. + else if (sa.handler () == ACE_SignalHandler (ACE_Sig_Handlers::dispatch)) + return ace_sig_adapter->sigkey (); + + // Otherwise, we need to register our handler function so that + // all signals will be dispatched through ACE. + else + { + // Make sure that new_disp points to a valid location if the + // user doesn't care... + if (new_disp == 0) + new_disp = &sa; + + new_disp->handler (ACE_SignalHandler (ACE_Sig_Handlers::dispatch)); + + // Default is to restart signal handlers. + new_disp->flags (new_disp->flags () | SA_RESTART); + new_disp->flags (new_disp->flags () | SA_SIGINFO); + + // Finally install (possibly reinstall) the ACE signal + // handler disposition with the SA_RESTART mode enabled. + if (new_disp->register_action (signum, old_disp) == -1) + { + // Yikes, lots of roll back at this point... + ACE_Sig_Handlers_Set::instance (signum)->remove (ace_sig_adapter); + delete ace_sig_adapter; + + if (extern_sh) + { + ACE_Sig_Handlers_Set::instance (signum)->remove (extern_sh); + delete extern_sh; + } + return -1; + } + else // Return the signal key so that programs can cancel this + // handler if they want! + return ace_sig_adapter->sigkey (); + } + } + else + return -1; +} + +// Remove the ACE_Event_Handler currently associated with . +// Install the new disposition (if given) and return the previous +// disposition (if desired by the caller). Returns 0 on success and +// -1 if is invalid. + +int +ACE_Sig_Handlers::remove_handler (int signum, + ACE_Sig_Action *new_disp, + ACE_Sig_Action *old_disp, + int sigkey) +{ + ACE_TRACE ("ACE_Sig_Handlers::remove_handler"); + ACE_MT (ACE_TSS_Guard m (ACE_Sig_Handler::ace_sig_handler_lock_)); + + if (ACE_Sig_Handler::in_range (signum)) + { + ACE_SIG_HANDLERS_SET *handler_set = + ACE_Sig_Handlers_Set::instance (signum); + + ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set); + + // Iterate through the set of handlers for this signal. + + for (ACE_Event_Handler **eh; + handler_iterator.next (eh) != 0; + handler_iterator.advance ()) + { + // Type-safe downcast would be nice here... + ACE_Sig_Adapter *sh = (ACE_Sig_Adapter *) *eh; + + // Remove the handler if (1) it's key matches the key we've + // been told to remove or (2) if we've been told to remove + // *all* handlers (i.e., == -1). + + if (sh->sigkey () == sigkey || sigkey == -1) + { + handler_set->remove (*eh); + delete *eh; + } + } + + if (handler_set->size () == 0) + { + // If there are no more handlers left for a signal then + // register the new disposition or restore the default + // disposition. + + ACE_Sig_Action sa (SIG_DFL); + + if (new_disp == 0) + new_disp = &sa; + + return new_disp->register_action (signum, old_disp); + } + return 0; + } + else + return -1; +} + +// Master dispatcher function that gets called by a signal handler and +// dispatches *all* the handlers... + +void +ACE_Sig_Handlers::dispatch (int signum, + siginfo_t *siginfo, + ucontext_t *ucontext) +{ + ACE_TRACE ("ACE_Sig_Handlers::dispatch"); + ACE_MT (ACE_TSS_Guard m (ACE_Sig_Handler::ace_sig_handler_lock_)); + + // Preserve errno across callbacks! + int old_errno = errno; + + ACE_Sig_Handler::sig_pending (1); + + // Darn well better be in range since the OS dispatched this... + ACE_ASSERT (ACE_Sig_Handler::in_range (signum)); + + ACE_SIG_HANDLERS_SET *handler_set = + ACE_Sig_Handlers_Set::instance (signum); + + ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set); + + for (ACE_Event_Handler **eh = 0; + handler_iterator.next (eh) != 0; + handler_iterator.advance ()) + { + if ((*eh)->handle_signal (signum, siginfo, ucontext) == -1) + { + handler_set->remove (*eh); + delete *eh; + } + } + + // Restore error when callback completes. + errno = old_errno; +} + +// Return the first item in the list of handlers. Note that this will +// trivially provide the same behavior as the ACE_Sig_Handler +// version if there is only 1 handler registered! + +ACE_Event_Handler * +ACE_Sig_Handlers::handler (int signum) +{ + ACE_TRACE ("ACE_Sig_Handlers::handler"); + ACE_SIG_HANDLERS_SET *handler_set = + ACE_Sig_Handlers_Set::instance (signum); + ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set); + ACE_Event_Handler **eh = 0; + handler_iterator.next (eh); + return *eh; +} + +// The following is a strange bit of logic that tries to give the same +// semantics as what happens in ACE_Sig_Handler when we replace the +// current signal handler with a new one. Note that if there is only +// one signal handler the behavior will be identical. If there is +// more than one handler then things get weird... + +ACE_Event_Handler * +ACE_Sig_Handlers::handler (int signum, ACE_Event_Handler *new_sh) +{ + ACE_TRACE ("ACE_Sig_Handlers::handler"); + ACE_SIG_HANDLERS_SET *handler_set = + ACE_Sig_Handlers_Set::instance (signum); + ACE_SIG_HANDLERS_ITERATOR handler_iterator (*handler_set); + ACE_Event_Handler **eh = 0; + + // Find the first handler... + handler_iterator.next (eh); + + // ... then remove it from the set ... + handler_set->remove (*eh); + + // ... and then insert the new signal handler into the beginning of + // the set (note, this is a bit too tied up in the implementation of + // ACE_Unbounded_Set...). + ACE_Sig_Adapter *temp; + + ACE_NEW_RETURN (temp, ACE_Sig_Adapter (new_sh, ++ACE_Sig_Handlers::sigkey_), 0); + handler_set->insert (temp); + return *eh; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Fixed_Set; +template class ACE_Fixed_Set_Iterator; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ +#endif /* HPUX */ diff --git a/ace/Signal.h b/ace/Signal.h new file mode 100644 index 00000000000..9396ac8c807 --- /dev/null +++ b/ace/Signal.h @@ -0,0 +1,350 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Signal.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SIGNAL_HANDLER_H) +#define ACE_SIGNAL_HANDLER_H + +#include "ace/Synch.h" +#include "ace/Event_Handler.h" +#include "ace/Set.h" + +// This worksaround a horrible bug with HP/UX C++... +typedef struct sigaction ACE_SIGACTION; + +class ACE_Export ACE_Sig_Set + // = TITLE + // Provide a C++ wrapper for the C sigset_t interface. + // + // = DESCRIPTION + // Handle signals via a more elegant C++ interface (e.g., + // doesn't require the use of global variables or global + // functions in an application). +{ +public: + // = Initialization and termination methods. + ACE_Sig_Set (sigset_t *); + ACE_Sig_Set (int fill = 0); + ~ACE_Sig_Set (void); + + int empty_set (void); + // Create a set that excludes all signals defined by the system. + + int fill_set (void); + // Create a set that includes all signals defined by the system. + + int sig_add (int signo); + // Adds the individual signal specified by to the set. + + int sig_del (int signo); + // Deletes the individual signal specified by from the set. + + int is_member (int signo) const; + // Checks whether the signal specified by is in the set. + + operator sigset_t *(); + // Returns a pointer to the underlying sigset_t. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + sigset_t sigset_; + // Set of signals. +}; + +class ACE_Export ACE_Sig_Action + // = TITLE + // C++ wrapper around struct sigaction. +{ +public: + // = Initialization methods. + ACE_Sig_Action (void); + ACE_Sig_Action (ACE_SignalHandler handler, + sigset_t *sigmask = 0, + int flags = 0); + ACE_Sig_Action (ACE_SignalHandler handler, + int signum, + sigset_t *sigmask = 0, + int flags = 0); + ACE_Sig_Action (const ACE_Sig_Action &s); + ACE_Sig_Action (struct sigaction *); + + // = Signal action management. + int register_action (int signum, ACE_Sig_Action *oaction = 0); + // Register as the current disposition and store old + // disposition into if it is non-NULL. + + int restore_action (int signum, ACE_Sig_Action &oaction); + // Assign the value of to and make it become the + // new signal disposition. + + int retrieve_action (int signum); + // Retrieve the current disposition into . + + // = Set/get current signal action. + void set (struct sigaction *); + struct sigaction *get (void); + operator ACE_SIGACTION *(); + + // = Set/get current signal flags. + void flags (int); + int flags (void); + + // = Set/get current signal mask. + void mask (sigset_t *); + sigset_t *mask (void); + + // = Set/get current signal handler (pointer to function). + void handler (ACE_SignalHandler); + ACE_SignalHandler handler (void); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + struct sigaction sa_; + // Controls signal behavior. +}; + +class ACE_Export ACE_Sig_Guard + // = TITLE + // Hold signals in MASK for duration of a C++ statement block. + // Note that a "0" for mask causes all signals to be held. +{ +public: + // = Set/remove mask. + ACE_Sig_Guard (ACE_Sig_Set *mask = 0); + ~ACE_Sig_Guard (void); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Sig_Set omask_; + // Original signal mask. +}; + +class ACE_Export ACE_Sig_Handler + // = TITLE + // This is the main dispatcher of signals for ACE. It improves + // the existing UNIX signal handling mechanism by allowing C++ + // objects to handle signals in a way that avoids the use of + // global/static variables and functions. + // + // = DESCRIPTION + // Using this class a program can register an + // with the in order to handle a designated + // . When a signal occurs that corresponds to this + // , the method of the registered + // is invoked automatically. +{ +public: + // = Registration and removal methods. + virtual int register_handler (int signum, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp = 0, + ACE_Event_Handler **old_sh = 0, + ACE_Sig_Action *old_disp = 0); + // Add a new and a new sigaction associated with + // . Passes back the existing ACE_Event_Handler and its + // sigaction if pointers are non-zero. Returns -1 on failure and >= + // 0 on success. + + virtual int remove_handler (int signum, + ACE_Sig_Action *new_disp = 0, + ACE_Sig_Action *old_disp = 0, + int sigkey = -1); + // Remove the currently associated with + // . is ignored in this implementation since there + // is only one instance of a signal handler. Install the new + // disposition (if given) and return the previous disposition (if + // desired by the caller). Returns 0 on success and -1 if + // is invalid. + + // Set/get signal status. + static sig_atomic_t sig_pending (void); + // True if there is a pending signal. + + static void sig_pending (sig_atomic_t); + // Reset the value of so that no signal is pending. + + // = Set/get the handler associated with a particular signal. + + virtual ACE_Event_Handler *handler (int signum); + // Return the list of associated with . + + virtual ACE_Event_Handler *handler (int signum, ACE_Event_Handler *); + // Set a new that is associated with . + // Return the existing handler. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + // = These methods and data members are shared by derived classes. + + static int in_range (int signum); + // Check whether the SIGNUM is within the legal range of signals. + + static sig_atomic_t sig_pending_; + // Keeps track of whether a signal is pending. + +#if defined (ACE_MT_SAFE) + static ACE_Recursive_Thread_Mutex ace_sig_handler_lock_; +#endif /* ACE_MT_SAFE */ + +private: + static void dispatch (int, siginfo_t *, ucontext_t *); + // Callback routine registered with sigaction(2) that dispatches the + // handle_signal() method of the appropriate pre-registered + // ACE_Event_Handler. + + static ACE_Event_Handler *signal_handlers_[NSIG]; + // Array used to store one user-defined Event_Handler for every + // signal. +}; + +class ACE_Export ACE_Sig_Adapter : public ACE_Event_Handler + // = TITLE + // Provide an adapter that transforms various types of signal + // handlers into the scheme used by the . + +{ +public: + ACE_Sig_Adapter (ACE_Sig_Action &, int sigkey); + ACE_Sig_Adapter (ACE_Event_Handler *, int sigkey); + ACE_Sig_Adapter (ACE_Sig_Handler_Ex, int sigkey = 0); + + int sigkey (void); + // Returns this signal key that's used to remove this from the + // 's internal table. + + virtual int handle_signal (int, siginfo_t *, ucontext_t *); + // Called by the to dispatch the signal handler. + +private: + int sigkey_; + // Key for this signal handler (used to remove it). + + enum + { + ACE_HANDLER, // We're just wrapping an ACE_Event_Handler. + SIG_ACTION, // An ACE_Sig_Action. + C_FUNCTION // A normal C function. + } type_; + // Is this an external handler or an ACE handler? + + // = This should be a union, but C++ won't allow that because the + // has a constructor. + ACE_Sig_Action sa_; + // This is an external handler (ugh). + + ACE_Event_Handler *eh_; + // This is an ACE hander. + + ACE_Sig_Handler_Ex sig_func_; + // This is a normal C function. +}; + +// HPUX sucks big time! +#if !defined (HPUX) +class ACE_Export ACE_Sig_Handlers : public ACE_Sig_Handler + // = TITLE + // This is an alternative signal handling dispatcher for ACE. It + // allows a list of signal handlers to be registered for each + // signal. It also makes SA_RESTART the default mode. + // + // = DESCRIPTION + // Using this class a program can register one or more + // ACE_Event_Handler with the ACE_Sig_Handler in order to + // handle a designated . When a signal occurs that + // corresponds to this , the methods of + // all the registered ACE_Event_Handlers are invoked + // automatically. +{ +public: + // = Registration and removal methods. + virtual int register_handler (int signum, + ACE_Event_Handler *new_sh, + ACE_Sig_Action *new_disp = 0, + ACE_Event_Handler **old_sh = 0, + ACE_Sig_Action *old_disp = 0); + // Add a new ACE_Event_Handler and a new sigaction associated with + // . Passes back the existing ACE_Event_Handler and its + // sigaction if pointers are non-zero. Returns -1 on failure and + // a that is >= 0 on success. + + virtual int remove_handler (int signum, + ACE_Sig_Action *new_disp = 0, + ACE_Sig_Action *old_disp = 0, + int sigkey = -1); + // Remove the ACE_Event_Handler currently associated with . + // Install the new disposition (if given) and return the previous + // disposition (if desired by the caller). Returns 0 on success and + // -1 if is invalid. + + // = Set/get the handler associated with a particular signal. + + virtual ACE_Event_Handler *handler (int signum); + // Return the head of the list of ACE_Sig_Handlers associated + // with SIGNUM. + + virtual ACE_Event_Handler *handler (int signum, ACE_Event_Handler *); + // Set a new ACE_Event_Handler that is associated with SIGNUM at the + // head of the list of signals. Return the existing handler that + // was at the head. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + static void dispatch (int signum, siginfo_t *, ucontext_t *); + // Callback routine registered with sigaction(2) that dispatches the + // handle_signal() method of all the pre-registered + // ACE_Event_Handlers for + + static int sigkey_; + // Keeps track of the id that uniquely identifies each registered + // signal handler. This id can be used to cancel a timer via the + // method. + + static int third_party_sig_handler_; + // If this is > 0 then a 3rd party library has registered a + // handler... +}; +#endif /* HPUX */ + +#if defined (__ACE_INLINE__) +#include "ace/Signal.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_SIGNAL_HANDLER_H */ diff --git a/ace/Signal.i b/ace/Signal.i new file mode 100644 index 00000000000..e90f1431b38 --- /dev/null +++ b/ace/Signal.i @@ -0,0 +1,213 @@ +/* -*- C++ -*- */ +// $Id$ + +// Signal.i + +ACE_INLINE +ACE_Sig_Set::ACE_Sig_Set (sigset_t *ss) + : sigset_ (*ss) // Structure assignment +{ + ACE_TRACE ("ACE_Sig_Set::ACE_Sig_Set"); +} + +ACE_INLINE +ACE_Sig_Set::ACE_Sig_Set (int fill) +{ + ACE_TRACE ("ACE_Sig_Set::ACE_Sig_Set"); + if (fill) + ACE_OS::sigfillset (&this->sigset_); + else + ACE_OS::sigemptyset (&this->sigset_); +} + +ACE_INLINE +ACE_Sig_Set::~ACE_Sig_Set (void) +{ + ACE_TRACE ("ACE_Sig_Set::~ACE_Sig_Set"); + ACE_OS::sigemptyset (&this->sigset_); +} + +ACE_INLINE int +ACE_Sig_Set::empty_set (void) +{ + ACE_TRACE ("ACE_Sig_Set::empty_set"); + return ACE_OS::sigemptyset (&this->sigset_); +} + +ACE_INLINE int +ACE_Sig_Set::fill_set (void) +{ + ACE_TRACE ("ACE_Sig_Set::fill_set"); + return ACE_OS::sigfillset (&this->sigset_); +} + +ACE_INLINE int +ACE_Sig_Set::sig_add (int signo) +{ + ACE_TRACE ("ACE_Sig_Set::sig_add"); + return ACE_OS::sigaddset (&this->sigset_, signo); +} + +ACE_INLINE int +ACE_Sig_Set::sig_del (int signo) +{ + ACE_TRACE ("ACE_Sig_Set::sig_del"); + return ACE_OS::sigdelset (&this->sigset_, signo); +} + +ACE_INLINE int +ACE_Sig_Set::is_member (int signo) const +{ + ACE_TRACE ("ACE_Sig_Set::is_member"); + return ACE_OS::sigismember ((sigset_t *) &this->sigset_, signo); +} + +ACE_INLINE +ACE_Sig_Set::operator sigset_t *(void) +{ + ACE_TRACE ("ACE_Sig_Set::operator sigset_t *"); + return &this->sigset_; +} + +ACE_INLINE int +ACE_Sig_Action::flags (void) +{ + ACE_TRACE ("ACE_Sig_Action::flags"); + return this->sa_.sa_flags; +} + +ACE_INLINE void +ACE_Sig_Action::flags (int flags) +{ + ACE_TRACE ("ACE_Sig_Action::flags"); + this->sa_.sa_flags = flags; +} + +ACE_INLINE sigset_t * +ACE_Sig_Action::mask (void) +{ + ACE_TRACE ("ACE_Sig_Action::mask"); + return &this->sa_.sa_mask; +} + +ACE_INLINE void +ACE_Sig_Action::mask (sigset_t *ss) +{ + ACE_TRACE ("ACE_Sig_Action::mask"); + this->sa_.sa_mask = *ss; // Structure assignment +} + +ACE_INLINE ACE_SignalHandler +ACE_Sig_Action::handler (void) +{ + ACE_TRACE ("ACE_Sig_Action::handler"); + return ACE_SignalHandler (this->sa_.sa_handler); +} + +ACE_INLINE void +ACE_Sig_Action::handler (ACE_SignalHandler handler) +{ + ACE_TRACE ("ACE_Sig_Action::handler"); + this->sa_.sa_handler = ACE_SignalHandlerV (handler); +} + +ACE_INLINE void +ACE_Sig_Action::set (struct sigaction *sa) +{ + ACE_TRACE ("ACE_Sig_Action::set"); + this->sa_ = *sa; // Structure assignment. +} + +ACE_INLINE struct sigaction * +ACE_Sig_Action::get (void) +{ + ACE_TRACE ("ACE_Sig_Action::get"); + return &this->sa_; +} + +ACE_INLINE +ACE_Sig_Action::operator ACE_SIGACTION * () +{ + ACE_TRACE ("ACE_Sig_Action::operator ACE_SIGACTION *"); + return &this->sa_; +} + +ACE_INLINE +ACE_Sig_Action::ACE_Sig_Action (const ACE_Sig_Action &s) +{ + ACE_TRACE ("ACE_Sig_Action::ACE_Sig_Action"); + *this = s; // structure copy. +} + +ACE_INLINE int +ACE_Sig_Action::register_action (int signum, ACE_Sig_Action *oaction) +{ + ACE_TRACE ("ACE_Sig_Action::register_action"); + struct sigaction *sa = oaction == 0 ? 0 : oaction->get (); + + return ACE_OS::sigaction (signum, &this->sa_, sa); +} + +ACE_INLINE int +ACE_Sig_Action::retrieve_action (int signum) +{ + ACE_TRACE ("ACE_Sig_Action::retrieve_action"); + return ACE_OS::sigaction (signum, 0, &this->sa_); +} + +ACE_INLINE int +ACE_Sig_Action::restore_action (int signum, ACE_Sig_Action &oaction) +{ + ACE_TRACE ("ACE_Sig_Action::restore_action"); + this->sa_ = *oaction.get (); // Structure assignment + return ACE_OS::sigaction (signum, &this->sa_, 0); +} + +// Block out the signal MASK until the destructor is called. + +ACE_INLINE +ACE_Sig_Guard::ACE_Sig_Guard (ACE_Sig_Set *mask) +{ + ACE_TRACE ("ACE_Sig_Guard::ACE_Sig_Guard"); + // If MASK is 0 then block all signals! + if (mask == 0) + { + ACE_Sig_Set smask (1); + +#if 0 // defined (ACE_MT_SAFE) + ACE_OS::thr_sigsetmask (SIG_BLOCK, (sigset_t *) smask, (sigset_t *) + this->omask_); +#else + ACE_OS::sigprocmask (SIG_BLOCK, (sigset_t *) smask, (sigset_t *) + this->omask_); +#endif /* ACE_MT_SAFE */ + } + else +#if 0 // defined (ACE_MT_SAFE) + ACE_OS::thr_sigsetmask (SIG_BLOCK, (sigset_t *) *mask, (sigset_t *) + this->omask_); +#else + ACE_OS::sigprocmask (SIG_BLOCK, (sigset_t *) *mask, (sigset_t *) + this->omask_); +#endif /* ACE_MT_SAFE */ +} + +// Restore the signal mask. + +ACE_INLINE +ACE_Sig_Guard::~ACE_Sig_Guard (void) +{ + ACE_TRACE ("ACE_Sig_Guard::~ACE_Sig_Guard"); +#if 0 // defined (ACE_MT_SAFE) + ACE_OS::thr_sigsetmask (SIG_SETMASK, (sigset_t *) this->omask_, 0); +#else + ACE_OS::sigprocmask (SIG_SETMASK, (sigset_t *) this->omask_, 0); +#endif /* ACE_MT_SAFE */ +} + +ACE_INLINE int +ACE_Sig_Handler::in_range (int signum) +{ + ACE_TRACE ("ACE_Sig_Handler::in_range"); + return signum > 0 && signum < NSIG; +} diff --git a/ace/Singleton.cpp b/ace/Singleton.cpp new file mode 100644 index 00000000000..5d6a6e8ea31 --- /dev/null +++ b/ace/Singleton.cpp @@ -0,0 +1,78 @@ +// Singleton.cpp +// $Id$ + +#if !defined (ACE_SINGLETON_C) +#define ACE_SINGLETON_C + +#define ACE_BUILD_DLL +#include "ace/Singleton.h" +#include "ace/Synch_T.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Singleton.i" +#endif /* __ACE_INLINE__ */ + +template void +ACE_Singleton::dump (void) const +{ + ACE_TRACE ("ACE_Singleton::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + ACE_DEBUG ((LM_DEBUG, "instance_ = %x", this->instance_)); + ace_singleton_lock_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ +} + +template TYPE * +ACE_Singleton::instance (void) +{ + ACE_TRACE ("ACE_Singleton::instance"); + +#if defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + // Pointer to the Singleton instance. This works around a bug with + // G++... + static TYPE *instance_ = 0; + + // Lock the creation of the singleton. This works around a + // "feature" of G++... ;-) + static LOCK ace_singleton_lock_; + // Perform the Double-Check pattern... + if (instance_ == 0) + { + ACE_GUARD_RETURN (LOCK, ace_mon, ace_singleton_lock_, 0); + + if (instance_ == 0) + ACE_NEW_RETURN (instance_, TYPE, 0); + } + + return instance_; +#else + + // Perform the Double-Check pattern... + if (ACE_Singleton::instance_ == 0) + { + ACE_GUARD_RETURN (LOCK, ace_mon, (ACE_Singleton::ace_singleton_lock_), 0); + + if (ACE_Singleton::instance_ == 0) + ACE_NEW_RETURN ((ACE_Singleton::instance_), TYPE, 0); + } + + return ACE_Singleton::instance_; + +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ + +} + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) +// Pointer to the Singleton instance. +template TYPE * +ACE_Singleton::instance_ = 0; + +// Lock the creation of the singleton. +template LOCK +ACE_Singleton::ace_singleton_lock_; +#endif /* !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */ + +#endif /* ACE_SINGLETON_C */ diff --git a/ace/Singleton.h b/ace/Singleton.h new file mode 100644 index 00000000000..7761acf53c4 --- /dev/null +++ b/ace/Singleton.h @@ -0,0 +1,65 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Singleton.h +// +// = DESCRIPTION +// +// = AUTHOR +// Tim Harrison (harrison@cs.wustl.edu) and Douglas C. Schmidt +// +// ============================================================================ + +#if !defined (ACE_SINGLETON_H) +#define ACE_SINGLETON_H + +#include "ace/ACE.h" + +template +class ACE_Singleton + // = TITLE + // A Singleton Adapter. + // + // = DESCRIPTION + // Uses the Adapter pattern to turn ordinary classes into + // Singletons optimized with the Double-Check pattern. +{ +public: + static TYPE *instance (void); + // Global access point to the Singleton. + + void dump (void) const; + // Dump the state of the object. + +protected: +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + static TYPE *instance_; + // Pointer to the Singleton instance. + + static LOCK ace_singleton_lock_; + // Lock the creation of the singleton. +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ +}; + +#if defined (__ACE_INLINE__) +#include "ace/Singleton.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Singleton.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Singleton.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_SINGLETON_H */ + + diff --git a/ace/Singleton.i b/ace/Singleton.i new file mode 100644 index 00000000000..0cdd5148964 --- /dev/null +++ b/ace/Singleton.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// $Id$ + +// Singleton.i diff --git a/ace/Stack.cpp b/ace/Stack.cpp new file mode 100644 index 00000000000..4f2a642244e --- /dev/null +++ b/ace/Stack.cpp @@ -0,0 +1,428 @@ +// Stack.cpp +// $Id$ + +#if !defined (ACE_STACK_C) +#define ACE_STACK_C + +#define ACE_BUILD_DLL +#include "ace/Stack.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Stack.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Bounded_Stack) + +template void +ACE_Bounded_Stack::dump (void) const +{ + ACE_TRACE ("ACE_Bounded_Stack::dump"); +} + +template +ACE_Bounded_Stack::ACE_Bounded_Stack (size_t size) + : top_ (0), + size_ (size) +{ + ACE_NEW (this->stack_, T[size]); + + ACE_TRACE ("ACE_Bounded_Stack::ACE_Bounded_Stack"); +} + +template +ACE_Bounded_Stack::ACE_Bounded_Stack (const ACE_Bounded_Stack &s) + : top_ (s.top_), + size_ (s.size_) +{ + ACE_NEW (this->stack_, T[s.size_]); + + ACE_TRACE ("ACE_Bounded_Stack::ACE_Bounded_Stack"); + + for (size_t i = 0; i < this->top_; i++) + this->stack_[i] = s.stack_[i]; +} + +template void +ACE_Bounded_Stack::operator= (const ACE_Bounded_Stack &s) +{ + ACE_TRACE ("ACE_Bounded_Stack::operator="); + if (&s == this) + return; + else if (this->size_ < s.size_) + { + delete [] this->stack_; + ACE_NEW (this->stack_, T[s.size_]); + } + this->top_ = s.top_; + + for (size_t i = 0; i < this->top_; i++) + this->stack_[i] = s.stack_[i]; +} + +template +ACE_Bounded_Stack::~ACE_Bounded_Stack (void) +{ + ACE_TRACE ("ACE_Bounded_Stack::~ACE_Bounded_Stack"); + delete [] this->stack_; +} + +// ---------------------------------------- + +ACE_ALLOC_HOOK_DEFINE(ACE_Fixed_Stack) + +template void +ACE_Fixed_Stack::dump (void) const +{ + ACE_TRACE ("ACE_Fixed_Stack::dump"); +} + +template +ACE_Fixed_Stack::ACE_Fixed_Stack (void) + : top_ (0), + size_ (SIZE) +{ + ACE_TRACE ("ACE_Fixed_Stack::ACE_Fixed_Stack"); +} + +template +ACE_Fixed_Stack::ACE_Fixed_Stack (const ACE_Fixed_Stack &s) + : top_ (s.top_), + size_ (s.size_) +{ + ACE_TRACE ("ACE_Fixed_Stack::ACE_Fixed_Stack"); + for (size_t i = 0; i < this->top_; i++) + this->stack_[i] = s.stack_[i]; +} + +template void +ACE_Fixed_Stack::operator= (const ACE_Fixed_Stack &s) +{ + ACE_TRACE ("ACE_Fixed_Stack::operator="); + if (&s == this) + return; + this->top_ = s.top_; + + for (size_t i = 0; i < this->top_; i++) + this->stack_[i] = s.stack_[i]; +} + +template +ACE_Fixed_Stack::~ACE_Fixed_Stack (void) +{ + ACE_TRACE ("ACE_Fixed_Stack::~ACE_Fixed_Stack"); + delete [] this->stack_; +} + +//---------------------------------------- + +template +class ACE_Stack_Node +{ +friend class ACE_Unbounded_Stack; +private: +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + // = Only use a free list if the compiler supports static data + // members... + + void *operator new (size_t bytes); + void operator delete (void *ptr); + + // Returns all dynamic memory on the free list to the free store. + static void free_all_nodes (void); + + static ACE_Stack_Node *free_list_; + // Head of the free list of Nodes used to speed up allocation. +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ + + ACE_Stack_Node (T i, ACE_Stack_Node *n); + ACE_Stack_Node (void); + + ACE_Stack_Node *next_; + T item_; +}; + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) +/* static */ +template ACE_Stack_Node * +ACE_Stack_Node::free_list_ = 0; + +template void * +ACE_Stack_Node::operator new (size_t bytes) +{ + ACE_TRACE ("ACE_Stack_Node::operator new"); + ACE_Stack_Node *temp = ACE_Stack_Node::free_list_; + + if (temp) + ACE_Stack_Node::free_list_ = ACE_Stack_Node::free_list_->next_; + else + temp = (ACE_Stack_Node *) new char[bytes]; + + return temp; +} + +template void +ACE_Stack_Node::operator delete (void *ptr) +{ + ACE_TRACE ("ACE_Stack_Node::operator delete"); + ((ACE_Stack_Node *) ptr)->next_ = ACE_Stack_Node::free_list_; + ACE_Stack_Node::free_list_ = (ACE_Stack_Node *) ptr; +} + +template void +ACE_Stack_Node::free_all_nodes (void) +{ + ACE_TRACE ("ACE_Stack_Node::free_all_nodes"); + + while (ACE_Stack_Node::free_list_) + { + ACE_Stack_Node *temp = ACE_Stack_Node::free_list_; + ACE_Stack_Node::free_list_ = ACE_Stack_Node::free_list_->next_; + ::delete temp; + } +} + +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ + +template +ACE_Stack_Node::ACE_Stack_Node (T i, ACE_Stack_Node *n) + : next_ (n), + item_ (i) +{ + ACE_TRACE ("ACE_Stack_Node::ACE_Stack_Node"); +} + +template +ACE_Stack_Node::ACE_Stack_Node (void) + : next_ (0) +{ + ACE_TRACE ("ACE_Stack_Node::ACE_Stack_Node"); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Unbounded_Stack) + +template void +ACE_Unbounded_Stack::dump (void) const +{ + ACE_TRACE ("ACE_Unbounded_Stack::dump"); +} + +template +ACE_Unbounded_Stack::ACE_Unbounded_Stack (void) + : head_ (0) +{ + ACE_NEW (this->last_resort_, ACE_Stack_Node); + ACE_TRACE ("ACE_Unbounded_Stack::ACE_Unbounded_Stack"); +} + +template void +ACE_Unbounded_Stack::delete_all_nodes (void) +{ + ACE_TRACE ("ACE_Unbounded_Stack::delete_all_nodes"); + while (this->head_ != 0) + { + ACE_Stack_Node *temp = this->head_; + this->head_ = this->head_->next_; + delete temp; + } + + delete this->last_resort_; + this->last_resort_ = 0; +} + +template void +ACE_Unbounded_Stack::copy_all_nodes (const ACE_Unbounded_Stack &s) +{ + ACE_TRACE ("ACE_Unbounded_Stack::copy_all_nodes"); + // Push all of 's nodes onto our stack (this puts them in the + // reverse order). + ACE_Stack_Node *temp; + + for (temp = s.head_; + temp != 0; + temp = temp->next_) + { + if (!this->is_full ()) + this->push (temp->item_); + else + break; + } + + // Reverse the order of our stack. + + ACE_Stack_Node *prev = 0; + + for (temp = this->head_; temp != 0; ) + { + ACE_Stack_Node *next = temp->next_; + + temp->next_ = prev; + prev = temp; + temp = next; + } + + this->head_ = prev; +} + +template +ACE_Unbounded_Stack::ACE_Unbounded_Stack (const ACE_Unbounded_Stack &s) + : head_ (0) +{ + ACE_NEW (this->last_resort_, ACE_Stack_Node); + + ACE_TRACE ("ACE_Unbounded_Stack::ACE_Unbounded_Stack"); + this->copy_all_nodes (s); +} + +template void +ACE_Unbounded_Stack::operator= (const ACE_Unbounded_Stack &s) +{ + ACE_TRACE ("ACE_Unbounded_Stack::operator="); + if (this == &s) + return; + + this->delete_all_nodes (); + this->copy_all_nodes (s); +} + +template +ACE_Unbounded_Stack::~ACE_Unbounded_Stack (void) +{ + ACE_TRACE ("ACE_Unbounded_Stack::~ACE_Unbounded_Stack"); + this->delete_all_nodes (); +} + +template void +ACE_Unbounded_Stack::push (const T &new_item) +{ + ACE_TRACE ("ACE_Unbounded_Stack::push"); + + ACE_Stack_Node *temp = new ACE_Stack_Node (new_item, this->head_); + + if (temp == 0) + { + temp = this->last_resort_; + this->last_resort_ = 0; + } + + this->head_ = temp; +} + +template void +ACE_Unbounded_Stack::pop (T &item) +{ + ACE_TRACE ("ACE_Unbounded_Stack::pop"); + item = this->head_->item_; + ACE_Stack_Node *temp = this->head_; + this->head_ = this->head_->next_; + + // Restore the node of last resort if necessary. + if (this->last_resort_ == 0) + this->last_resort_ = temp; + else + delete temp; +} + +template void +ACE_Unbounded_Stack::delete_free_list (void) +{ + ACE_TRACE ("ACE_Unbounded_Stack::delete_free_list"); +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + ACE_Stack_Node::free_all_nodes (); +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ +} + +template +class ACE_Queue_Node +{ +friend class ACE_Unbounded_Queue; + ACE_Queue_Node (T i, ACE_Queue_Node *n); + + ACE_Queue_Node *next_; + T item_; +}; + +template +ACE_Queue_Node::ACE_Queue_Node (T i, ACE_Queue_Node *n) + : next_ (n), + item_ (i) +{ + ACE_TRACE ("ACE_Queue_Node::ACE_Queue_Node"); +} + +template +ACE_Unbounded_Queue::ACE_Unbounded_Queue (void) + : head_ (0), + tail_ (0), + cur_size_ (0) +{ + ACE_TRACE ("ACE_Unbounded_Queue::ACE_Unbounded_Queue (void)"); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Unbounded_Queue) + +template void +ACE_Unbounded_Queue::dump (void) const +{ + ACE_TRACE ("ACE_Unbounded_Queue::dump"); +} + +template +ACE_Unbounded_Queue::~ACE_Unbounded_Queue (void) +{ + ACE_TRACE ("ACE_Unbounded_Queue::~ACE_Unbounded_Queue (void)"); + ACE_Queue_Node *temp = head_; + while (temp != 0) + { + head_ = head_->next_; + delete temp; + temp = head_; + this->cur_size_--; + } +} + +template int +ACE_Unbounded_Queue::enqueue (const TYPE &new_item) +{ + ACE_TRACE ("ACE_Unbounded_Queue::enqueue (const TYPE& new_item)"); + + ACE_Queue_Node *temp = new ACE_Queue_Node (new_item, 0); + + if (temp == 0) + return -1; + + if (head_ == 0) + head_ = tail_ = temp; + else + { + tail_->next_ = temp; + tail_ = temp; + } + + ++this->cur_size_; + + return 0; +} + +template int +ACE_Unbounded_Queue::dequeue (TYPE &item) +{ + ACE_TRACE ("ACE_Unbounded_Queue::dequeue (TYPE *&item)"); + + if (head_ == 0) + return -1; + + item = head_->item_; + ACE_Queue_Node *temp = head_; + head_ = head_->next_; + delete temp; + --this->cur_size_; + return 0; +} + +template int +ACE_Unbounded_Queue::size (void) const +{ + return this->cur_size_; +} + +#endif /* ACE_STACK_C */ diff --git a/ace/Stack.h b/ace/Stack.h new file mode 100644 index 00000000000..6b7e9ad7ed8 --- /dev/null +++ b/ace/Stack.h @@ -0,0 +1,280 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Stack.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_STACK_H) +#define ACE_STACK_H + +#include "ace/ACE.h" + +template +class ACE_Bounded_Stack + // = TITLE + // Implement a generic LIFO abstract data type. + // + // = DESCRIPTION + // This implementation of a Stack uses a bounded array + // that is allocated dynamically. +{ +public: + // = Initialization, assignemnt, and termination methods. + ACE_Bounded_Stack (size_t size); + // Initialize a new stack so that it is empty. + + ACE_Bounded_Stack (const ACE_Bounded_Stack &s); + // The copy constructor (performs initialization). + + void operator= (const ACE_Bounded_Stack &s); + // Assignment operator (performs assignment). + + ~ACE_Bounded_Stack (void); + // Perform actions needed when stack goes out of scope. + + // = Classic Stack operations. + + void push (const T &new_item); + // Place a new item on top of the stack. Does not check if the + // stack is full. + + void pop (T &item); + // Remove and return the top stack item. Does not check if stack + // is full. + + void top (T &item) const; + // Return top stack item without removing it. Does not check if + // stack is empty. + + // = Check boundary conditions for Stack operations. + + int is_empty (void) const; + // Returns 1 if the stack is empty, otherwise returns 0. + + int is_full (void) const; + // Returns 1 if the stack is full, otherwise returns 0. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + size_t size_; + // Size of the dynamically allocated data. + + size_t top_; + // Keeps track of the current top of stack. + + T *stack_; + // Holds the stack's contents. +}; + +//---------------------------------------- + +template +class ACE_Fixed_Stack + // = TITLE + // Implement a generic LIFO abstract data type. + // + // = DESCRIPTION + // This implementation of a Stack uses a fixed array + // with the size fixed at instantiation time. +{ +public: + // = Initialization, assignemnt, and termination methods. + ACE_Fixed_Stack (void); + // Initialize a new stack so that it is empty. + + ACE_Fixed_Stack (const ACE_Fixed_Stack &s); + // The copy constructor (performs initialization). + + void operator= (const ACE_Fixed_Stack &s); + // Assignment operator (performs assignment). + + ~ACE_Fixed_Stack (void); + // Perform actions needed when stack goes out of scope. + + // = Classic Stack operations. + + void push (const T &new_item); + // Place a new item on top of the stack. Does not check if the + // stack is full. + + void pop (T &item); + // Remove and return the top stack item. Does not check if stack + // is full. + + void top (T &item) const; + // Return top stack item without removing it. Does not check if + // stack is empty. + + // = Check boundary conditions for Stack operations. + + int is_empty (void) const; + // Returns 1 if the stack is empty, otherwise returns 0. + + int is_full (void) const; + // Returns 1 if the stack is full, otherwise returns 0. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + size_t size_; + // Size of the dynamically allocated data. + + size_t top_; + // Keeps track of the current top of stack. + + T stack_[SIZE]; + // Holds the stack's contents. +}; + +//---------------------------------------- + +// Forward declaration (use the "Cheshire Cat" approach to information +// hiding). +template +class ACE_Stack_Node; + +template +class ACE_Unbounded_Stack + // = TITLE + // Implement a generic LIFO abstract data type. + // + // = DESCRIPTION + // This implementation of an unbounded Stack uses a linked list. +{ +public: + // = Initialization, assignemnt, and termination methods. + ACE_Unbounded_Stack (void); + // Initialize a new stack so that it is empty. + + ACE_Unbounded_Stack (const ACE_Unbounded_Stack &s); + // The copy constructor (performs initialization). + + void operator= (const ACE_Unbounded_Stack &s); + // Assignment operator (performs assignment). + + ~ACE_Unbounded_Stack (void); + // Perform actions needed when stack goes out of scope. + + // = Classic Stack operations. + + void push (const T &new_item); + // Place a new item on top of the stack. Does not check if the + // stack is full. + + void pop (T &item); + // Remove and return the top stack item. Does not check if stack + // is full. + + void top (T &item) const; + // Return top stack item without removing it. Does not check if + // stack is empty. + + // = Check boundary conditions for Stack operations. + + int is_empty (void) const; + // Returns 1 if the stack is empty, otherwise returns 0. + + int is_full (void) const; + // Returns 1 if the stack is full, otherwise returns 0. + + static void delete_free_list (void); + // Returns all dynamic memory on the free list to the free store. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + void delete_all_nodes (void); + // Delete all the nodes in the stack. + + void copy_all_nodes (const ACE_Unbounded_Stack &s); + // Copy all nodes from to . + + ACE_Stack_Node *head_; + // Head of the linked list of Nodes. + + ACE_Stack_Node *last_resort_; + // Use this node when all memory is exhausted... +}; + +// Forward declaration (use the "Cheshire Cat" approach to information +// hiding). +template +class ACE_Queue_Node; + +template +class ACE_Unbounded_Queue + // = TITLE + // A Queue of "infinite" length. + + // = DESCRIPTION + // Implemented using dynamic memory... +{ +public: + ACE_Unbounded_Queue (void); + // construction. + + ~ACE_Unbounded_Queue (void); + // construction. + + int enqueue (const TYPE &new_item); + // Returns 0 on success -1 on failure. + + int dequeue (TYPE &item); + // Returns 0 on success -1 if nothing was found. + + int size (void) const; + // The size of the queue + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + ACE_Queue_Node *head_; + // Head of the Queue. + + ACE_Queue_Node *tail_; + // Tail of the Queue. + + size_t cur_size_; + // Current size of the queue. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Stack.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Stack.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Stack.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_STACK_H */ diff --git a/ace/Stack.i b/ace/Stack.i new file mode 100644 index 00000000000..7c34c0efa22 --- /dev/null +++ b/ace/Stack.i @@ -0,0 +1,100 @@ +/* -*- C++ -*- */ +// $Id$ + +// Stack.i + +template ACE_INLINE void +ACE_Bounded_Stack::push (const T &new_item) +{ + ACE_TRACE ("ACE_Bounded_Stack::push"); + this->stack_[this->top_++] = new_item; +} + +template ACE_INLINE void +ACE_Bounded_Stack::pop (T &item) +{ + ACE_TRACE ("ACE_Bounded_Stack::pop"); + item = this->stack_[--this->top_]; +} + +template ACE_INLINE void +ACE_Bounded_Stack::top (T &item) const +{ + ACE_TRACE ("ACE_Bounded_Stack::top"); + item = this->stack_[this->top_ - 1]; +} + +template ACE_INLINE int +ACE_Bounded_Stack::is_empty (void) const +{ + ACE_TRACE ("ACE_Bounded_Stack::is_empty"); + return this->top_ == 0; +} + +template ACE_INLINE int +ACE_Bounded_Stack::is_full (void) const +{ + ACE_TRACE ("ACE_Bounded_Stack::is_full"); + return this->top_ >= this->size_; +} + +//---------------------------------------- + +template ACE_INLINE void +ACE_Fixed_Stack::push (const T &new_item) +{ + ACE_TRACE ("ACE_Fixed_Stack::push"); + this->stack_[this->top_++] = new_item; +} + +template ACE_INLINE void +ACE_Fixed_Stack::pop (T &item) +{ + ACE_TRACE ("ACE_Fixed_Stack::pop"); + item = this->stack_[--this->top_]; +} + +template ACE_INLINE void +ACE_Fixed_Stack::top (T &item) const +{ + ACE_TRACE ("ACE_Fixed_Stack::top"); + item = this->stack_[this->top_ - 1]; +} + +template ACE_INLINE int +ACE_Fixed_Stack::is_empty (void) const +{ + ACE_TRACE ("ACE_Fixed_Stack::is_empty"); + return this->top_ == 0; +} + +template ACE_INLINE int +ACE_Fixed_Stack::is_full (void) const +{ + ACE_TRACE ("ACE_Fixed_Stack::is_full"); + return this->top_ >= this->size_; +} + +//---------------------------------------- + +template ACE_INLINE void +ACE_Unbounded_Stack::top (T &item) const +{ + ACE_TRACE ("ACE_Unbounded_Stack::top"); + item = this->head_->item_; +} + +template ACE_INLINE int +ACE_Unbounded_Stack::is_empty (void) const +{ + ACE_TRACE ("ACE_Unbounded_Stack::is_empty"); + return this->head_ == 0; +} + +template ACE_INLINE int +ACE_Unbounded_Stack::is_full (void) const +{ + ACE_TRACE ("ACE_Unbounded_Stack::is_full"); + return this->last_resort_ == 0; +} + diff --git a/ace/Strategies.cpp b/ace/Strategies.cpp new file mode 100644 index 00000000000..fc85d67e150 --- /dev/null +++ b/ace/Strategies.cpp @@ -0,0 +1,504 @@ +// Strategies.cpp +// $Id$ + +#if !defined (ACE_STRATEGIES_C) +#define ACE_STRATEGIES_C + +#define ACE_BUILD_DLL +#include "ace/Strategies.h" + +#define SH SVC_HANDLER +#define PR_AC_1 ACE_PEER_ACCEPTOR_1 +#define PR_AC_2 ACE_PEER_ACCEPTOR_2 +#define PR_AD ACE_PEER_ACCEPTOR_ADDR + +ACE_ALLOC_HOOK_DEFINE(ACE_Singleton_Strategy) + +template void +ACE_Singleton_Strategy::dump (void) const +{ + ACE_TRACE ("ACE_Singleton_Strategy::dump"); +} + +template int +ACE_Singleton_Strategy::open (SVC_HANDLER *sh, + ACE_Thread_Manager *) +{ + ACE_TRACE ("ACE_Singleton_Strategy::open"); + if (this->svc_handler_ != 0) + delete this->svc_handler_; + + this->svc_handler_ = sh; + return 0; +} + +template +ACE_Singleton_Strategy::ACE_Singleton_Strategy (SVC_HANDLER *sh, + ACE_Thread_Manager *tm) + : svc_handler_ (0) +{ + ACE_TRACE ("ACE_Singleton_Strategy::ACE_Singleton_Strategy"); + this->open (sh, tm); +} + +template +ACE_Singleton_Strategy::~ACE_Singleton_Strategy (void) +{ + ACE_TRACE ("ACE_Singleton_Strategy::~ACE_Singleton_Strategy"); + delete this->svc_handler_; +} + +// Create a Singleton SVC_HANDLER by always returning the same +// SVC_HANDLER. + +template SVC_HANDLER * +ACE_Singleton_Strategy::make_svc_handler (void) +{ + ACE_TRACE ("ACE_Singleton_Strategy::make_svc_handler"); + return this->svc_handler_; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Creation_Strategy) + +template void +ACE_Creation_Strategy::dump (void) const +{ + ACE_TRACE ("ACE_Creation_Strategy::dump"); +} + +template int +ACE_Creation_Strategy::open (ACE_Thread_Manager *thr_mgr) +{ + ACE_TRACE ("ACE_Creation_Strategy::open"); + this->thr_mgr_ = thr_mgr; + return 0; +} + + +template +ACE_Creation_Strategy::ACE_Creation_Strategy (ACE_Thread_Manager *thr_mgr) +{ + ACE_TRACE ("ACE_Creation_Strategy::ACE_Creation_Strategy"); + this->open (thr_mgr); +} + +// Default behavior is to make a new SVC_HANDLER, passing in the +// Thread_Manager (if any). + +template SH * +ACE_Creation_Strategy::make_svc_handler (void) +{ + ACE_TRACE ("ACE_Creation_Strategy::make_svc_handler"); + return new SH (this->thr_mgr_); +} + +template +ACE_Creation_Strategy::~ACE_Creation_Strategy (void) +{ + ACE_TRACE ("ACE_Creation_Strategy::~ACE_Creation_Strategy"); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_DLL_Strategy) + +template void +ACE_DLL_Strategy::dump (void) const +{ + ACE_TRACE ("ACE_DLL_Strategy::dump"); +} + +template int +ACE_DLL_Strategy::open (const char svc_dll_info[], + ACE_Service_Config *svc_config, + ACE_Thread_Manager *thr_mgr) +{ + ACE_TRACE ("ACE_DLL_Strategy::open"); + this->inherited::open (thr_mgr); + this->svc_config_ = svc_config; + return 0; +} + +template +ACE_DLL_Strategy::ACE_DLL_Strategy (const char svc_dll_info[], + ACE_Service_Config *sc, + ACE_Thread_Manager *thr_mgr) +{ + ACE_TRACE ("ACE_DLL_Strategy::ACE_DLL_Strategy"); + if (this->open (svc_dll_info, sc, thr_mgr) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "open")); +} + +template +ACE_DLL_Strategy::ACE_DLL_Strategy (void) +{ + ACE_TRACE ("ACE_DLL_Strategy::ACE_DLL_Strategy"); +} + +// Create a SVC_HANDLER by dynamically linking it from a DLL. + +template SH * +ACE_DLL_Strategy::make_svc_handler (void) +{ + ACE_TRACE ("ACE_DLL_Strategy::make_svc_handler"); + // Open the shared library. + void *handle = (void *) ACE_OS::dlopen (this->shared_library_); + + // Extract the factory function. + SH *(*factory)(void) = (SH *(*)(void)) ACE_OS::dlsym (handle, + this->factory_function_); + + // Call the factory function to obtain the new SVC_Handler (should + // use RTTI here when it becomes available...) + SH *svc_handler = (*factory)(); + + if (svc_handler != 0) + { + // Create an ACE_Service_Record containing the SVC_Handler and + // insert into this->svc_config_->svc_rep; + + // @@ This remains to be implemented... + // @@ Somehow, we need to deal with this->thr_mgr_... + } + + return svc_handler; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Concurrency_Strategy) + +template void +ACE_Concurrency_Strategy::dump (void) const +{ + ACE_TRACE ("ACE_Concurrency_Strategy::dump"); +} + +// Default behavior is to activate the SVC_HANDLER by calling it's +// open() method, which allows the SVC_HANDLER to determine its own +// concurrency strategy. + +template int +ACE_Concurrency_Strategy::activate_svc_handler (SH *svc_handler, + void *arg) +{ + ACE_TRACE ("ACE_Concurrency_Strategy::activate_svc_handler"); + // Delegate control to the application-specific service + // handler. + + if (svc_handler->open (arg) == -1) + { + // Close down handler to avoid resource leaks. + svc_handler->close (0); + return -1; + } + else + return 0; +} + +template +ACE_Concurrency_Strategy::~ACE_Concurrency_Strategy (void) +{ + ACE_TRACE ("ACE_Concurrency_Strategy::~ACE_Concurrency_Strategy"); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Strategy) + +template void +ACE_Thread_Strategy::dump (void) const +{ + ACE_TRACE ("ACE_Thread_Strategy::dump"); +} + +template int +ACE_Thread_Strategy::open (ACE_Thread_Manager *thr_mgr, + long thr_flags, + int n_threads) +{ + ACE_TRACE ("ACE_Thread_Strategy::open"); + this->thr_mgr_ = thr_mgr; + this->n_threads_ = n_threads; + this->thr_flags_ = thr_flags; + + // Must have a thread manager! + if (this->thr_mgr_ == 0) + ACE_ERROR_RETURN ((LM_ERROR, + "error: must have a non-NULL thread manager\n"), -1); + else + return 0; +} + +template +ACE_Thread_Strategy::ACE_Thread_Strategy (ACE_Thread_Manager *thr_mgr, + long thr_flags, + int n_threads) +{ + ACE_TRACE ("ACE_Thread_Strategy::ACE_Thread_Strategy"); + this->open (thr_mgr, thr_flags, n_threads); +} + +template +ACE_Thread_Strategy::ACE_Thread_Strategy (void) +{ + ACE_TRACE ("ACE_Thread_Strategy::ACE_Thread_Strategy"); +} + +template +ACE_Thread_Strategy::~ACE_Thread_Strategy (void) +{ + ACE_TRACE ("ACE_Thread_Strategy::~ACE_Thread_Strategy"); +} + +template int +ACE_Thread_Strategy::activate_svc_handler (SH *svc_handler, + void *arg) +{ + ACE_TRACE ("ACE_Thread_Strategy::activate_svc_handler"); + // Call up to our parent to do the SVC_HANDLER initialization. + if (this->inherited::activate_svc_handler (svc_handler, arg) == -1) + return -1; + else + // Turn the into an active object (if it isn't + // already one as a result of the first activation...) + return svc_handler->activate (this->thr_flags_, this->n_threads_); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Accept_Strategy) + +template void +ACE_Accept_Strategy::dump (void) const +{ + ACE_TRACE ("ACE_Accept_Strategy::dump"); +} + +template int +ACE_Accept_Strategy::open (const PR_AD &local_addr, + int restart) +{ + ACE_TRACE ("ACE_Accept_Strategy::open"); + return this->peer_acceptor_.open (local_addr, restart); +} + +template +ACE_Accept_Strategy::ACE_Accept_Strategy (const PR_AD &local_addr, + int restart) +{ + ACE_TRACE ("ACE_Accept_Strategy::ACE_Accept_Strategy"); + if (this->open (local_addr, restart) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "open")); +} + +template +ACE_Accept_Strategy::ACE_Accept_Strategy (void) +{ + ACE_TRACE ("ACE_Accept_Strategy::ACE_Accept_Strategy"); +} + +template int +ACE_Accept_Strategy::accept_svc_handler (SH *svc_handler) +{ + ACE_TRACE ("ACE_Accept_Strategy::accept_svc_handler"); + if (this->peer_acceptor_.accept (*svc_handler) == -1) + { + svc_handler->close (0); + return -1; + } + else + return 0; +} + +template ACE_HANDLE +ACE_Accept_Strategy::get_handle (void) const +{ + ACE_TRACE ("ACE_Accept_Strategy::get_handle"); + return this->peer_acceptor_.get_handle (); +} + +template ACE_PEER_ACCEPTOR & +ACE_Accept_Strategy::acceptor (void) const +{ + ACE_TRACE ("ACE_Accept_Strategy::acceptor"); + return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_; +} + +template +ACE_Accept_Strategy::~ACE_Accept_Strategy (void) +{ + ACE_TRACE ("ACE_Accept_Strategy::~ACE_Accept_Strategy"); + if (this->peer_acceptor_.close () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "close")); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Process_Strategy) + +template void +ACE_Process_Strategy::dump (void) const +{ + ACE_TRACE ("ACE_Process_Strategy::dump"); +} + +template int +ACE_Process_Strategy::open (int n_processes) +{ + ACE_TRACE ("ACE_Process_Strategy::open"); + this->n_processes_ = n_processes; + + return 0; +} + +template +ACE_Process_Strategy::ACE_Process_Strategy (int n_processes) +{ + ACE_TRACE ("ACE_Process_Strategy::ACE_Process_Strategy"); + this->open (thr_mgr, thr_flags, n_threads); +} + +template +ACE_Process_Strategy::ACE_Process_Strategy (void) +{ + ACE_TRACE ("ACE_Process_Strategy::ACE_Process_Strategy"); +} + +template +ACE_Process_Strategy::~ACE_Process_Strategy (void) +{ + ACE_TRACE ("ACE_Process_Strategy::~ACE_Process_Strategy"); +} + +template int +ACE_Process_Strategy::activate_svc_handler (SH *svc_handler, + void *arg) +{ + ACE_TRACE ("ACE_Process_Strategy::activate_svc_handler"); + switch (ACE_OS::fork ()) + { + case -1: + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "fork"), -1); + /* NOTREACHED */ + case 0: // In child process. + // Call up to our ancestor in the inheritance to do the + // SVC_HANDLER initialization. + return this->inherited::activate_svc_handler (svc_handler, arg); + /* NOTREACHED */ + default: // In parent process. + return 0; + } +} + +template +ACE_Scheduling_Strategy::ACE_Scheduling_Strategy (SH *scheduler) + : scheduler_ (scheduler), + delete_scheduler_ (0) +{ + ACE_TRACE ("ACE_Scheduling_Strategy::ACE_Scheduling_Strategy"); + + if (this->scheduler_ == 0) + { + // Create a new SVC_HANDLER and assign the global Thread_Manager + // and Reactor to it... + ACE_NEW (this->scheduler_, SH); + + if (this->scheduler_->thr_mgr () == 0) + this->scheduler_->thr_mgr (ACE_Service_Config::thr_mgr ()); + + if (this->scheduler_->reactor () == 0) + this->scheduler_->reactor (ACE_Service_Config::reactor ()); + + this->delete_scheduler_ = 1; + } +} + +template +ACE_Scheduling_Strategy::~ACE_Scheduling_Strategy (void) +{ + ACE_TRACE ("ACE_Scheduling_Strategy::~ACE_Scheduling_Strategy"); + + if (this->delete_scheduler_) + this->scheduler_->destroy (); +} + +template void +ACE_Scheduling_Strategy::dump (void) const +{ + ACE_TRACE ("ACE_Scheduling_Strategy::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "scheduler_ = %x", this->scheduler_)); + ACE_DEBUG ((LM_DEBUG, "\ndelete_scheduler_ = %d", this->delete_scheduler_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +template int +ACE_Scheduling_Strategy::suspend (void) +{ + ACE_TRACE ("ACE_Scheduling_Strategy::suspend"); + return -1; +} + +template int +ACE_Scheduling_Strategy::resume (void) +{ + ACE_TRACE ("ACE_Scheduling_Strategy::resume"); + return -1; +} + +template +ACE_Schedule_All_Reactive_Strategy::ACE_Schedule_All_Reactive_Strategy (SH *scheduler) + : ACE_Scheduling_Strategy (scheduler) +{ + ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy::ACE_Schedule_All_Reactive_Strategy"); +} + +template int +ACE_Schedule_All_Reactive_Strategy::suspend (void) +{ + ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy::suspend"); + return this->scheduler_->reactor ()->suspend_handlers (); +} + +template void +ACE_Schedule_All_Reactive_Strategy::dump (void) const +{ + ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy::dump"); + + ACE_Scheduling_Strategy::dump (); +} + +template int +ACE_Schedule_All_Reactive_Strategy::resume (void) +{ + ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy::resume"); + return this->scheduler_->reactor ()->resume_handlers (); +} + +template +ACE_Schedule_All_Threaded_Strategy::ACE_Schedule_All_Threaded_Strategy (SH *scheduler) + : ACE_Scheduling_Strategy (scheduler) +{ + ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy::ACE_Schedule_All_Threaded_Strategy"); +} + +template int +ACE_Schedule_All_Threaded_Strategy::suspend (void) +{ + ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy::suspend"); + return this->scheduler_->thr_mgr ()->suspend_all (); +} + +template int +ACE_Schedule_All_Threaded_Strategy::resume (void) +{ + ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy::resume"); + return this->scheduler_->thr_mgr ()->resume_all (); +} + +template void +ACE_Schedule_All_Threaded_Strategy::dump (void) const +{ + ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy::dump"); + + ACE_Scheduling_Strategy::dump (); +} + +#undef SH +#undef PR_AC_1 +#undef PR_AC_2 +#undef PR_AD + +#endif /* ACE_STRATEGIES_C */ diff --git a/ace/Strategies.h b/ace/Strategies.h new file mode 100644 index 00000000000..f8677201f5f --- /dev/null +++ b/ace/Strategies.h @@ -0,0 +1,445 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// ACE_Strategies.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_STRATEGIES_H) +#define ACE_STRATEGIES_H + +#include "ace/Service_Config.h" + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) +#define ACE_PEER_ACCEPTOR_1 class PEER_ACCEPTOR +#define ACE_PEER_ACCEPTOR_2 PEER_ACCEPTOR +#define ACE_PEER_ACCEPTOR PEER_ACCEPTOR +#define ACE_PEER_ACCEPTOR_ADDR PEER_ACCEPTOR::PEER_ADDR +#else +#define ACE_PEER_ACCEPTOR_1 class PEER_ACCEPTOR, class PEER_ADDR +#define ACE_PEER_ACCEPTOR_2 PEER_ACCEPTOR, PEER_ADDR +#define ACE_PEER_ACCEPTOR PEER_ACCEPTOR +#define ACE_PEER_ACCEPTOR_ADDR PEER_ADDR +#endif /* ACE_TEMPLATE_TYPEDEFS */ + +template +class ACE_Creation_Strategy + // = TITLE + // Defines the interface for specifying a creation strategy for + // a SVC_HANDLER. + // + // = DESCRIPTION + // The default behavior is to make a new SVC_HANDLER. However, + // subclasses can override this strategy to perform SVC_HANDLER + // creation in any way that they like (such as creating subclass + // instances of SVC_HANDLER, using a singleton, dynamically + // linking the handler, etc.). +{ +public: + // = Initialization and termination methods. + + ACE_Creation_Strategy (ACE_Thread_Manager * = 0); + // Default constructor. + + int open (ACE_Thread_Manager * = 0); + // A is useful when creating active objects. + + virtual ~ACE_Creation_Strategy (void); + + // = Factory method. + virtual SVC_HANDLER *make_svc_handler (void); + // Create a SVC_HANDLER with the appropriate creation strategy. The + // default behavior of this method is to make a new SVC_HANDLER, + // passing in the Thread_Manager (if any). + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + ACE_Thread_Manager *thr_mgr_; +}; + +template +class ACE_Singleton_Strategy : public ACE_Creation_Strategy + // = TITLE + // Defines the interface for specifying a creation strategy for + // a that always returns the same (i.e., + // it's a Singleton). + // + // = DESCRIPTION + // Note that this class takes over the ownership of the + // SVC_HANDLER passed into it as a parameter and it becomes + // responsible for deleting this object. +{ +public: + // = Initialization and termination methods. + ACE_Singleton_Strategy (SVC_HANDLER * = 0, + ACE_Thread_Manager * = 0); + int open (SVC_HANDLER *, + ACE_Thread_Manager * = 0); + ~ACE_Singleton_Strategy (void); + + // = Factory method. + virtual SVC_HANDLER *make_svc_handler (void); + // Create a Singleton SVC_HANDLER by always returning the same + // SVC_HANDLER. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + SVC_HANDLER *svc_handler_; + // Pointer to the Singleton svc_handler. +}; + +template +class ACE_DLL_Strategy : public ACE_Creation_Strategy + // = TITLE + // Defines the interface for specifying a creation strategy for + // a SVC_HANDLER based on dynamic linking of the SVC_HANDLER. +{ +public: + // = Intialization and termination methods. + + ACE_DLL_Strategy (void); + // "Do-nothing" constructor. + + ACE_DLL_Strategy (const char svc_dll_info[], + ACE_Service_Config *, + ACE_Thread_Manager * = 0); + // Initialize the DLL strategy based upon the service's DLL + // information contained in the string. + + int open (const char svc_dll_info[], + ACE_Service_Config *, + ACE_Thread_Manager * = 0); + // Initialize the DLL strategy based upon the service's DLL + // information contained in the string. + + // = Factory method. + virtual SVC_HANDLER *make_svc_handler (void); + // Create a SVC_HANDLER by dynamically linking it from a DLL. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + typedef ACE_Creation_Strategy inherited; + + char shared_library_[MAXPATHLEN]; + // Name of the shared library to dynamically link. + + char factory_function_[MAXPATHLEN]; + // Name of the factory function in the shared library to use to + // obtain a pointer to the new SVC_HANDLER. + + char svc_name[MAXNAMELEN]; + // Name of the service. + + ACE_Service_Config *svc_config_; + // Pointer to the Service_Configurator. +}; + +template +class ACE_Concurrency_Strategy + // = TITLE + // Defines the interface for specifying a concurrency strategy + // for a SVC_HANDLER. + // + // = DESCRIPTION + // Default behavior is to activate the SVC_HANDLER by calling + // its open() method (which allows the SVC_HANDLER to define its + // own concurrency strategy). However, subclasses can override + // this default strategy to do more sophisticated concurrency + // activations (such as creating the SVC_HANDLER as an active + // object via multi-threading or multi-processing). +{ +public: + // = Factory method. + virtual int activate_svc_handler (SVC_HANDLER *svc_handler, + void *arg = 0); + // Activate the with an appropriate concurrency + // strategy. The default behavior of this method is to activate the + // SVC_HANDLER by calling its open() method (which allows the + // SVC_HANDLER to define its own concurrency strategy). + + virtual ~ACE_Concurrency_Strategy (void); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +template +class ACE_Thread_Strategy : public ACE_Concurrency_Strategy + // = TITLE + // Defines the interface for specifying a concurrency strategy + // for a based on multithreading. + // + // = DESCRIPTION + // This class provides a strategy that manages the creation of + // threads to handle requests from clients concurrently. It + // behaves as a "thread factory", spawning threads "on-demand" + // to run the service specified by a user-supplied + // . +{ +public: + // = Intialization and termination methods. + ACE_Thread_Strategy (void); + // "Do-nothing constructor" + + ACE_Thread_Strategy (ACE_Thread_Manager *tm, + long thr_flags, + int n_threads = 1); + // Initialize the strategy. + + virtual int open (ACE_Thread_Manager *tm, + long thr_flags, + int n_threads = 1); + // Initialize the strategy. + + ~ACE_Thread_Strategy (void); + + // = Factory method. + virtual int activate_svc_handler (SVC_HANDLER *svc_handler, + void *arg = 0); + // Activate the with an appropriate concurrency + // strategy. This method activates the SVC_HANDLER by first calling + // its open() method and then calling its activate() method to turn + // it into an active object. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + typedef ACE_Concurrency_Strategy inherited; + + ACE_Thread_Manager *thr_mgr_; + // Thread manager for this class (must be provided). + + long thr_flags_; + // Flags to pass into the SVC_HANDLER::activate() method. + + int n_threads_; + // Number of threads to spawn. +}; + +template +class ACE_Process_Strategy : public ACE_Concurrency_Strategy + // = TITLE + // Defines the interface for specifying a concurrency strategy + // for a based on multiprocessing. + // + // = DESCRIPTION + // This class provides a strategy that manages the creation of + // processes to handle requests from clients concurrently. It + // behaves as a "process factory", forking threads "on-demand" + // to run the service specified by a user-supplied + // . +{ +public: + // = Intialization and termination methods. + ACE_Process_Strategy (void); + // "Do-nothing constructor" + + ACE_Process_Strategy (int n_processes = 1); + // Initialize the strategy. + + virtual int open (int n_processes = 1); + // Initialize the strategy. + + ~ACE_Process_Strategy (void); + + // = Factory method. + virtual int activate_svc_handler (SVC_HANDLER *svc_handler, + void *arg = 0); + // Activate the with an appropriate concurrency + // strategy. This method activates the SVC_HANDLER by first forking + // and then calling the open() method of the SVC_HANDLER in the + // child. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + typedef ACE_Concurrency_Strategy inherited; + + int n_processes_; + // Number of processes to spawn. +}; + +template +class ACE_Accept_Strategy + // = TITLE + // Defines the interface for specifying a passive connection + // acceptance strategy for a SVC_HANDLER. + // + // = DESCRIPTION + // This class provides a strategy that manages passive + // connection acceptance of a client. +{ +public: + // = Initialization and termination methods. + ACE_Accept_Strategy (void); + // Default constructor. + + ACE_Accept_Strategy (const ACE_PEER_ACCEPTOR_ADDR &local_addr, + int restart = 0); + // Initialize the with . + + virtual int open (const ACE_PEER_ACCEPTOR_ADDR &local_addr, + int restart = 0); + // Initialize the with . + + virtual ACE_HANDLE get_handle (void) const; + // Return the underlying ACE_HANDLE of the . + + virtual ACE_PEER_ACCEPTOR &acceptor (void) const; + // Return a reference to the . + + ~ACE_Accept_Strategy (void); + + // = Factory method. + virtual int accept_svc_handler (SVC_HANDLER *); + // The default behavior delegates to the method of the + // PEER_ACCEPTOR. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + ACE_PEER_ACCEPTOR peer_acceptor_; + // Factory that establishes connections passively. +}; + +template +class ACE_Scheduling_Strategy + // = TITLE + // Defines the interface for specifying how to suspend and + // resume a service . + // + // = DESCRIPTION + // This class provides a strategy that allows arbitrarily + // sophisticated service suspension and resumption. The default + // behavior is to do nothing... +{ +public: + // = Initialization and termination methods. + + ACE_Scheduling_Strategy (SVC_HANDLER * = 0); + // Constructor + + ~ACE_Scheduling_Strategy (void); + // Destructor + + // = Scheduling methods + + virtual int suspend (void); + // Suspend hook. + + virtual int resume (void); + // Resume hook. + + virtual void dump (void) const; + // Dump the state of the object. + +protected: + SVC_HANDLER *scheduler_; + // Points to the scheduler strategy object... + + int delete_scheduler_; + // Keeps track of whether we need to delete this or not... +}; + +template +class ACE_Schedule_All_Reactive_Strategy : public ACE_Scheduling_Strategy + // = TITLE + // Defines the interface for specifying how to suspend and + // resume a single-threaded reactive service . + // + // = DESCRIPTION + // This class provides a strategy that suspends and resumes all + // the Event_Handlers in a Reactor in one fell swoop. +{ +public: + // = Initialization and termination methods. + ACE_Schedule_All_Reactive_Strategy (SVC_HANDLER * = 0); + // Constructor + + // = Scheduling methods + + virtual int suspend (void); + // Suspend hook. + + virtual int resume (void); + // Resume hook. + + virtual void dump (void) const; + // Dump the state of the object. +}; + +template +class ACE_Schedule_All_Threaded_Strategy : public ACE_Scheduling_Strategy + // = TITLE + // Defines the interface for specifying how to suspend and + // resume a multithreaded service . + // + // = DESCRIPTION + // This class provides a strategy that suspends and resumes all + // the Event_Handlers controlled by a Thread_Manager in one fell swoop. +{ +public: + // = Initialization and termination methods. + ACE_Schedule_All_Threaded_Strategy (SVC_HANDLER * = 0); + // Constructor + + // = Scheduling methods + + virtual int suspend (void); + // Suspend hook. + + virtual int resume (void); + // Resume hook. + + virtual void dump (void) const; + // Dump the state of the object. +}; + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Strategies.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Strategies.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_STRATEGIES_H */ diff --git a/ace/Strategies.i b/ace/Strategies.i new file mode 100644 index 00000000000..a8f84ba003e --- /dev/null +++ b/ace/Strategies.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// $Id$ + +// Strategies.i diff --git a/ace/Stream.cpp b/ace/Stream.cpp new file mode 100644 index 00000000000..7b17d555b80 --- /dev/null +++ b/ace/Stream.cpp @@ -0,0 +1,512 @@ +// Stream.cpp +// $Id$ + +#if !defined (ACE_STREAM_C) +#define ACE_STREAM_C + +#define ACE_BUILD_DLL +//#include "ace/Module.h" +#include "ace/Stream.h" +#include "ace/Stream_Modules.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Stream.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Stream) + +// Give some idea of what the heck is going on in a stream! + +template void +ACE_Stream::dump (void) const +{ + ACE_TRACE ("ACE_Stream::dump"); + ACE_DEBUG ((LM_DEBUG, "-------- module links --------\n")); + + for (ACE_Module *mp = this->stream_head_; ; mp = mp->next ()) + { + ACE_DEBUG ((LM_DEBUG, "module name = %s\n", mp->name ())); + if (mp == this->stream_tail_) + break; + } + + ACE_DEBUG ((LM_DEBUG, "-------- writer links --------\n")); + + ACE_Task *qp; + + for (qp = this->stream_head_->writer (); ; qp = qp->next ()) + { + ACE_DEBUG ((LM_DEBUG, "writer queue name = %s\n", qp->name ())); + qp->dump (); + ACE_DEBUG ((LM_DEBUG, "-------\n")); + if (qp == this->stream_tail_->writer () + || (this->linked_us_ && qp == this->linked_us_->stream_head_->reader ())) + break; + } + + ACE_DEBUG ((LM_DEBUG, "-------- reader links --------\n")); + for (qp = this->stream_tail_->reader (); ; qp = qp->next ()) + { + ACE_DEBUG ((LM_DEBUG, "reader queue name = %s\n", qp->name ())); + qp->dump (); + ACE_DEBUG ((LM_DEBUG, "-------\n")); + if (qp == this->stream_head_->reader () + || (this->linked_us_ && qp == this->linked_us_->stream_head_->writer ())) + break; + } +} + +template int +ACE_Stream::push (ACE_Module *new_top) +{ + ACE_TRACE ("ACE_Stream::push"); + if (this->push_module (new_top, + this->stream_head_->next (), + this->stream_head_) == -1) + return -1; + else + return 0; +} + +template int +ACE_Stream_Iterator::advance (void) +{ + ACE_TRACE ("ACE_Stream_Iterator::advance"); + this->next_ = this->next_->next (); + return 0; +} + +template int +ACE_Stream::put (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Stream::put"); + return this->stream_head_->writer ()->put (mb, tv); +} + +template int +ACE_Stream::get (ACE_Message_Block *&mb, ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Stream::get"); + return this->stream_head_->reader ()->getq (mb, tv); +} + +// Return the "top" ACE_Module in a ACE_Stream, skipping over the +// stream_head. + +template int +ACE_Stream::top (ACE_Module *&m) +{ + ACE_TRACE ("ACE_Stream::top"); + if (this->stream_head_->next () == this->stream_tail_) + return -1; + else + { + m = this->stream_head_->next (); + return 0; + } +} + +// Remove the "top" ACE_Module in a ACE_Stream, skipping over the +// stream_head. + +template int +ACE_Stream::pop (u_long flags) +{ + ACE_TRACE ("ACE_Stream::pop"); + if (this->stream_head_->next () == this->stream_tail_) + return -1; + else + { + // Skip over the ACE_Stream head. + ACE_Module *top = this->stream_head_->next (); + ACE_Module *new_top = top->next (); + + this->stream_head_->next (new_top); + + // Close the top ACE_Module. + + top->close (flags); + + this->stream_head_->writer ()->next (new_top->writer ()); + new_top->reader ()->next (this->stream_head_->reader ()); + + return 0; + } +} + +// Remove a named ACE_Module from an arbitrary place in the +// ACE_Stream. + +template int +ACE_Stream::remove (const char *name, u_long flags) +{ + ACE_TRACE ("ACE_Stream::remove"); + ACE_Module *prev = 0; + + for (ACE_Module *mod = this->stream_head_; mod != 0; mod = mod->next ()) + if (ACE_OS::strcmp (mod->name (), name) == 0) + { + if (prev == 0) // Deleting ACE_Stream Head + this->stream_head_->link (mod->next ()); + else + prev->link (mod->next ()); + + mod->close (flags); + return 0; + } + else + prev = mod; + + return -1; +} + +template ACE_Module * +ACE_Stream::find (const char *name) +{ + ACE_TRACE ("ACE_Stream::find"); + for (ACE_Module *mod = this->stream_head_; + mod != 0; + mod = mod->next ()) + if (ACE_OS::strcmp (mod->name (), name) == 0) + return mod; + + return 0; +} + +// Actually push a module onto the stack... + +template int +ACE_Stream::push_module (ACE_Module *new_top, + ACE_Module *current_top, + ACE_Module *head) +{ + ACE_TRACE ("ACE_Stream::push_module"); + ACE_Task *nt_reader = new_top->reader (); + ACE_Task *nt_writer = new_top->writer (); + ACE_Task *ct_reader = 0; + ACE_Task *ct_writer = 0; + + if (current_top) + { + ct_reader = current_top->reader (); + ct_writer = current_top->writer (); + ct_reader->next (nt_reader); + } + + nt_writer->next (ct_writer); + + if (head) + { + if (head != new_top) + head->link (new_top); + } + else + nt_reader->next (0); + + new_top->next (current_top); + + if (nt_reader->open (new_top->arg ()) == -1) + return -1; + + if (nt_writer->open (new_top->arg ()) == -1) + return -1; + return 0; +} + +#if 0 +int +ACE_Stream::open (void *a, + ACE_Multiplexor &muxer, + ACE_Module *head) +{ + ACE_TRACE ("ACE_Stream::open"); + this->stream_head_ = head == 0 + ? new ACE_Module ("ACE_Stream_Head", + new ACE_Stream_Head, + new ACE_Stream_Head, a) : head; + this->stream_tail_ = 0; + return muxer.link_from_below (this->stream_head_); +} +#endif + +template int +ACE_Stream::open (void *a, + ACE_Module *head, + ACE_Module *tail) +{ + ACE_TRACE ("ACE_Stream::open"); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); + ACE_Task *h1, *h2; + ACE_Task *t1, *t2; + + if (head == 0) + { + h1 = new ACE_Stream_Head; + h2 = new ACE_Stream_Head; + head = new ACE_Module ("ACE_Stream_Head", h1, h2, a); + } + + if (tail == 0) + { + t1 = new ACE_Stream_Tail; + t2 = new ACE_Stream_Tail; + tail = new ACE_Module ("ACE_Stream_Tail", + t1, t2, a); + } + + // Make sure *all* the allocation succeeded! + if (h1 == 0 || h2 == 0 || head == 0 + || t1 == 0 || t2 == 0 || tail == 0) + { + delete h1; + delete h2; + delete t1; + delete t2; + // Note that we can't call delete on these, we must call close! + head->close (); + tail->close (); + errno = ENOMEM; + return -1; + } + + this->stream_head_ = head; + this->stream_tail_ = tail; + + if (this->push_module (this->stream_tail_) == -1) + return -1; + else if (this->push_module (this->stream_head_, + this->stream_tail_, + this->stream_head_) == -1) + return -1; + else + return 0; +} + +template int +ACE_Stream::close (u_long flags) +{ + ACE_TRACE ("ACE_Stream::close"); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); + + if (this->stream_head_ != 0 + && this->stream_tail_ != 0) + { + // Don't bother checking return value here. + this->unlink_i (); + + int result = 0; + + // Remove and cleanup all the intermediate modules. + + while (this->stream_head_->next () != this->stream_tail_) + { + if (this->pop (flags) == -1) + result = -1; + } + + // Clean up the head and tail of the stream. + if (this->stream_head_->close (flags) == -1) + result = -1; + if (this->stream_tail_->close (flags) == -1) + result = -1; + + this->stream_head_ = 0; + this->stream_tail_ = 0; + + // Tell all threads waiting on the close that we are done. + this->final_close_.broadcast (); + return result; + } + return 0; +} + +template int +ACE_Stream::control (ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds cmd, + void *a) +{ + ACE_TRACE ("ACE_Stream::control"); + ACE_IO_Cntl_Msg ioc (cmd); + + // Create a data block that contains the user-supplied data. + ACE_Message_Block *db = + new ACE_Message_Block (sizeof (int), + ACE_Message_Block::MB_IOCTL, + 0, + (char *) a); + + // Create a control block that contains the control field and a + // pointer to the data block. + ACE_Message_Block *cb = + new ACE_Message_Block (sizeof ioc, + ACE_Message_Block::MB_IOCTL, + db, + (char *) &ioc); + + // Make sure all of the allocation succeeded before continuing. + if (db == 0 || cb == 0) + { + delete cb; + delete db; + errno = ENOMEM; + return -1; + } + + int result = 0; + + if (this->stream_head_->writer ()->put (cb) == -1) + result = -1; + else if (this->stream_head_->reader ()->getq (cb) == -1) + result = -1; + else + result = ((ACE_IO_Cntl_Msg *) cb->rd_ptr ())->rval (); + + delete cb; // This also deletes db... + return result; +} + +// Link two streams together at their bottom-most Modules (i.e., the +// one just above the Stream tail). Note that all of this is premised +// on the fact that the Stream head and Stream tail are non-NULL... +// This must be called with locks held. + +template int +ACE_Stream::link_i (ACE_Stream &us) +{ + ACE_TRACE ("ACE_Stream::link_i"); + this->linked_us_ = &us; + // Make sure the other side is also linked to us! + us.linked_us_ = this; + + ACE_Module *my_tail = this->stream_head_; + + if (my_tail == 0) + return -1; + + // Locate the module just above our Stream tail. + while (my_tail->next () != this->stream_tail_) + my_tail = my_tail->next (); + + ACE_Module *other_tail = us.stream_head_; + + if (other_tail == 0) + return -1; + + // Locate the module just above the other Stream's tail. + while (other_tail->next () != us.stream_tail_) + other_tail = other_tail->next (); + + // Reattach the pointers so that the two streams are linked! + my_tail->writer ()->next (other_tail->reader ()); + other_tail->writer ()->next (my_tail->reader ()); + return 0; +} + +template int +ACE_Stream::link (ACE_Stream &us) +{ + ACE_TRACE ("ACE_Stream::link"); + + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); + + return this->link_i (us); +} + +// Must be called with locks held... + +template int +ACE_Stream::unlink_i (void) +{ + ACE_TRACE ("ACE_Stream::unlink_i"); + + // Only try to unlink if we are in fact still linked! + + if (this->linked_us_ != 0) + { + ACE_Module *my_tail = this->stream_head_; + + // Only relink if we still exist! + if (my_tail) + { + // Find the module that's just before our stream tail. + while (my_tail->next () != this->stream_tail_) + my_tail = my_tail->next (); + + // Restore the writer's next() link to our tail. + my_tail->writer ()->next (this->stream_tail_->writer ()); + } + + ACE_Module *other_tail = + this->linked_us_->stream_head_; + + // Only fiddle with the other side if it in fact still remains. + if (other_tail != 0) + { + while (other_tail->next () != this->linked_us_->stream_tail_) + other_tail = other_tail->next (); + + other_tail->writer ()->next (this->linked_us_->stream_tail_->writer ()); + + } + + // Make sure the other side is also aware that it's been unlinked! + this->linked_us_->linked_us_ = 0; + + this->linked_us_ = 0; + return 0; + } + else + return -1; +} + +template int +ACE_Stream::unlink (void) +{ + ACE_TRACE ("ACE_Stream::unlink"); + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); + return this->unlink_i (); +} + +template ACE_INLINE +ACE_Stream::ACE_Stream (void * a, + ACE_Module *head, + ACE_Module *tail) + : final_close_ (this->lock_), + linked_us_ (0) +{ + ACE_TRACE ("ACE_Stream::ACE_Stream"); + if (this->open (a, head, tail) == -1) + ACE_ERROR ((LM_ERROR, "ACE_Stream::open (%s, %s)\n", + head->name (), tail->name ())); +} + +#if 0 +ACE_INLINE +ACE_Stream::ACE_Stream (void *a, + ACE_Multiplexor &muxer, + ACE_Module *head) + : final_close_ (this->lock_), + linked_us_ (0) +{ + ACE_TRACE ("ACE_Stream::ACE_Stream"); + if (this->open (a, muxer, head) == -1) + ACE_ERROR ((LM_ERROR, "ACE_Stream::open (%s, %s)\n", + head->name ())); +} +#endif + +template ACE_INLINE +ACE_Stream::~ACE_Stream (void) +{ + ACE_TRACE ("ACE_Stream::~ACE_Stream"); + if (this->stream_head_ != 0) + this->close (); +} + +template ACE_INLINE +ACE_Stream_Iterator::ACE_Stream_Iterator (const ACE_Stream &sr) + : next_ (sr.stream_head_) +{ + ACE_TRACE ("ACE_Stream_Iterator::ACE_Stream_Iterator"); +} + +#endif /* ACE_STREAM_C */ diff --git a/ace/Stream.h b/ace/Stream.h new file mode 100644 index 00000000000..0eeac5fc837 --- /dev/null +++ b/ace/Stream.h @@ -0,0 +1,185 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Stream.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_STREAM_H) +#define ACE_STREAM_H + +//#include "ace/Multiplexor.h" + +#include "ace/ACE.h" +#include "ace/IO_Cntl_Msg.h" +#include "ace/Message_Block.h" +#include "ace/Time_Value.h" +#include "ace/Module.h" + +// Forward decls. +template class ACE_Stream_Iterator; +//template class ACE_Module; + +template +class ACE_Stream + // = TITLE + // This class is the primary abstraction for the ASX framework. + // It is moduled after System V Stream. + // + // = DESCRIPTION + // A Stream consists of a stack of , each of which + // contains two . +{ +friend class ACE_Stream_Iterator; +public: + enum + { + M_DELETE = 1 + // Indicates that close() deletes the Tasks. Don't change this + // value without updating the same enum in class ACE_Module... + }; + + // = Initializatation and termination methods. + ACE_Stream (void *arg = 0, + ACE_Module *head = 0, + ACE_Module *tail = 0); + // Create a Stream consisting of and as the Stream + // head and Stream tail, respectively. If these are 0 then the + // and are used, respectively. + // is the value past in to the open() methods of the tasks. + + int open (void *arg, + ACE_Module *head = 0, + ACE_Module *tail = 0); + // Create a Stream consisting of and as the Stream + // head and Stream tail, respectively. If these are 0 then the + // and are used, respectively. + // is the value past in to the open() methods of the tasks. + + int close (u_long flags = M_DELETE); + // Close down the stream and release all the resources. + + ~ACE_Stream (void); + // Close down the stream and release all the resources. + + // = ACE_Stream plumbing operations + + int push (ACE_Module *mod); + // Add a new module right below the Stream head. + + int pop (u_long flags = M_DELETE); + // Remove the right below the Stream head and close it down. + + int top (ACE_Module *&mod); + // Return the top module on the stream (right below the stream + // head). + + int remove (const char *mod, u_long flags = M_DELETE); + // Remove the named module from the stream. This bypasses the + // strict LIFO ordering of push() and pop(). + + ACE_Module *head (void); + // Return current stream head. + + ACE_Module *tail (void); + // Return current stream tail. + + ACE_Module *find (const char *mod); + // Find a particular ACE_Module. + + int link (ACE_Stream &); + // Create a pipe between two Streams. + + int unlink (void); + // Remove a pipe formed between two Streams. + + // = Blocking data transfer operations + int put (ACE_Message_Block *mb, ACE_Time_Value *timeout); + // Send the message down the stream, starting at the Module + // below the Stream head. Wait for upto amount of time + // for the operation to complete (or block forever if == + // 0). + + int get (ACE_Message_Block *&mb, ACE_Time_Value *timeout); + // Read the message that is stored in the the stream head. + // Wait for upto amount of time for the operation to + // complete (or block forever if == 0). + + int control (ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds cmd, void *args); + // Send control message down the stream. + + int wait (void); + // Synchronize with the final close of the stream. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + int unlink_i (void); + // Actually perform the unlinking of two Streams (must be called + // with locks held). + + int link_i (ACE_Stream &); + // Actually perform the linking of two Streams (must be called with + // locks held). + + int push_module (ACE_Module *, + ACE_Module * = 0, + ACE_Module * = 0); + // Must a new module onto the Stream. + + ACE_Module *stream_head_; + // Pointer to the head of the stream. + + ACE_Module *stream_tail_; + // Pointer to the tail of the stream. + + ACE_Stream *linked_us_; + // Pointer to an adjoining linked stream. + + // = Synchronization objects used for thread-safe streams. + ACE_SYNCH_MUTEX lock_; + // Protect the stream against race conditions. + + ACE_SYNCH_CONDITION final_close_; + // Use to tell all threads waiting on the close that we are done. +}; + +template +class ACE_Stream_Iterator +{ +public: + ACE_Stream_Iterator (const ACE_Stream &sr); + int next (const ACE_Module *&mo); + int advance (void); + +private: + ACE_Module *next_; +}; + +#if defined (__ACE_INLINE__) +#include "ace/Stream.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Stream.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Stream.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_STREAM_H */ diff --git a/ace/Stream.i b/ace/Stream.i new file mode 100644 index 00000000000..2a0fcc438a2 --- /dev/null +++ b/ace/Stream.i @@ -0,0 +1,35 @@ +/* -*- C++ -*- */ +// $Id$ + +// Stream.i + +#include "ace/Log_Msg.h" + +template ACE_INLINE ACE_Module * +ACE_Stream::head (void) +{ + ACE_TRACE ("ACE_Stream::head"); + return this->stream_head_; +} + +template ACE_INLINE ACE_Module * +ACE_Stream::tail (void) +{ + ACE_TRACE ("ACE_Stream::tail"); + return this->stream_tail_; +} + +template ACE_INLINE int +ACE_Stream::wait (void) +{ + ACE_TRACE ("ACE_Stream::wait"); + return this->final_close_.wait (); +} + +template ACE_INLINE int +ACE_Stream_Iterator::next (const ACE_Module *&mod) +{ + ACE_TRACE ("ACE_Stream_Iterator::next"); + mod = this->next_; + return this->next_ != 0; +} diff --git a/ace/Stream_Modules.cpp b/ace/Stream_Modules.cpp new file mode 100644 index 00000000000..53428b31305 --- /dev/null +++ b/ace/Stream_Modules.cpp @@ -0,0 +1,330 @@ +// Stream_Modules.cpp +// $Id$ + +#if !defined (ACE_STREAM_MODULES_C) +#define ACE_STREAM_MODULES_C + +#define ACE_BUILD_DLL +#include "ace/Stream_Modules.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Stream_Modules.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Stream_Head) + +template void +ACE_Stream_Head::dump (void) const +{ + ACE_TRACE ("ACE_Stream_Head::dump"); +} + +/* ACE_Module that act as the head and tail of a Stream. */ + +template int +ACE_Stream_Head::open (void *) +{ + ACE_TRACE ("ACE_Stream_Head::open"); + return 0; +} + +template int +ACE_Stream_Head::close (u_long) +{ + ACE_TRACE ("ACE_Stream_Head::close"); + return 0; +} + +template int +ACE_Stream_Head::svc (void) +{ + ACE_TRACE ("ACE_Stream_Head::svc"); + return -1; +} + +template int +ACE_Stream_Head::control (ACE_Message_Block *mb) +{ + ACE_TRACE ("ACE_Stream_Head::control"); + ACE_IO_Cntl_Msg *ioc = (ACE_IO_Cntl_Msg *) mb->rd_ptr (); + ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds cmd; + + switch (cmd = ioc->cmd ()) + { + case ACE_IO_Cntl_Msg::SET_LWM: + case ACE_IO_Cntl_Msg::SET_HWM: + this->water_marks (cmd, *(size_t *) mb->cont ()->rd_ptr ()); + ioc->rval (0); + break; + default: + return 0; + } + return ioc->rval (); +} + +/* Performs canonical flushing at the ACE_Stream Head */ + +template int +ACE_Stream_Head::canonical_flush (ACE_Message_Block *mb) +{ + ACE_TRACE ("ACE_Stream_Head::canonical_flush"); + char *cp = mb->rd_ptr (); + + if (*cp & ACE_Task_Flags::ACE_FLUSHR) + { + this->flush (ACE_Task_Flags::ACE_FLUSHALL); + *cp &= ~ACE_Task_Flags::ACE_FLUSHR; + } + if (*cp & ACE_Task_Flags::ACE_FLUSHW) + return this->reply (mb); + else + delete mb; + return 0; +} + +template int +ACE_Stream_Head::put (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Stream_Head::put"); + int res = 0; + + if (mb->msg_type () == ACE_Message_Block::MB_IOCTL + && (res = this->control (mb)) == -1) + return res; + + if (this->is_writer ()) + { + return this->put_next (mb, tv); + } + else /* this->is_reader () */ + { + switch (mb->msg_type ()) + { + case ACE_Message_Block::MB_FLUSH: + return this->canonical_flush (mb); + default: + break; + } + + return this->putq (mb, tv); + } +} + +template int +ACE_Stream_Head::init (int, char *[]) +{ + ACE_TRACE ("ACE_Stream_Head::init"); + return 0; +} + +template int +ACE_Stream_Head::info (char **strp, size_t length) const +{ + ACE_TRACE ("ACE_Stream_Head::info"); + const char *name = this->name (); + + if (*strp == 0 && (*strp = ACE_OS::strdup (name)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, name, length); + return ACE_OS::strlen (name); +} + +template int +ACE_Stream_Head::fini (void) +{ + ACE_TRACE ("ACE_Stream_Head::fini"); + return 0; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Stream_Tail) + +template void +ACE_Stream_Tail::dump (void) const +{ + ACE_TRACE ("ACE_Stream_Tail::dump"); +} + +template int +ACE_Stream_Tail::open (void *) +{ + ACE_TRACE ("ACE_Stream_Tail::open"); + return 0; +} + +template int +ACE_Stream_Tail::close (u_long) +{ + ACE_TRACE ("ACE_Stream_Tail::close"); + return 0; +} + +template int +ACE_Stream_Tail::svc (void) +{ + ACE_TRACE ("ACE_Stream_Tail::svc"); + return -1; +} + +template int +ACE_Stream_Tail::control (ACE_Message_Block *mb) +{ + ACE_TRACE ("ACE_Stream_Tail::control"); + ACE_IO_Cntl_Msg *ioc = (ACE_IO_Cntl_Msg *) mb->rd_ptr (); + ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds cmd; + + switch (cmd = ioc->cmd ()) + { + case ACE_IO_Cntl_Msg::SET_LWM: + case ACE_IO_Cntl_Msg::SET_HWM: + { + size_t size = *(size_t *) mb->cont ()->rd_ptr (); + + this->water_marks (cmd, size); + this->sibling ()->water_marks (cmd, size); + ioc->rval (0); + break; + } + default: + mb->msg_type (ACE_Message_Block::MB_IOCNAK); + } + return this->reply (mb); +} + +/* Perform flush algorithm as though we were the driver */ + +template int +ACE_Stream_Tail::canonical_flush (ACE_Message_Block *mb) +{ + ACE_TRACE ("ACE_Stream_Tail::canonical_flush"); + char *cp = mb->rd_ptr (); + + if (*cp & ACE_Task_Flags::ACE_FLUSHW) + { + this->flush (ACE_Task_Flags::ACE_FLUSHALL); + *cp &= ~ACE_Task_Flags::ACE_FLUSHW; + } + if (*cp & ACE_Task_Flags::ACE_FLUSHR) + { + this->sibling ()->flush (ACE_Task_Flags::ACE_FLUSHALL); + return this->reply (mb); + } + else + delete mb; + return 0; +} + +template int +ACE_Stream_Tail::put (ACE_Message_Block *mb, ACE_Time_Value * + +) +{ + ACE_TRACE ("ACE_Stream_Tail::put"); + if (this->is_writer ()) + { + switch (mb->msg_type ()) + { + case ACE_Message_Block::MB_IOCTL: + return this->control (mb); + /* NOTREACHED */ + default: + delete mb; + } + } + + return -1; +} + +template int +ACE_Stream_Tail::init (int, char *[]) +{ + ACE_TRACE ("ACE_Stream_Tail::init"); + return 0; +} + +template int +ACE_Stream_Tail::info (char **strp, size_t length) const +{ + ACE_TRACE ("ACE_Stream_Tail::info"); + const char *name = this->name (); + + if (*strp == 0 && (*strp = ACE_OS::strdup (name)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, name, length); + return ACE_OS::strlen (name); +} + +template int +ACE_Stream_Tail::fini (void) +{ + ACE_TRACE ("ACE_Stream_Tail::fini"); + return 0; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Thru_Task) + +template void +ACE_Thru_Task::dump (void) const +{ + ACE_TRACE ("ACE_Thru_Task::dump"); +} + +template int +ACE_Thru_Task::open (void *) +{ + ACE_TRACE ("ACE_Thru_Task::open"); + return 0; +} + +template int +ACE_Thru_Task::close (u_long) +{ + ACE_TRACE ("ACE_Thru_Task::close"); + return 0; +} + +template int +ACE_Thru_Task::svc (void) +{ + ACE_TRACE ("ACE_Thru_Task::svc"); + return -1; +} + +template int +ACE_Thru_Task::put (ACE_Message_Block *msg, + ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Thru_Task::put"); + return this->put_next (msg, tv); +} + +template int +ACE_Thru_Task::init (int, char *[]) +{ + ACE_TRACE ("ACE_Thru_Task::init"); + return 0; +} + +template int +ACE_Thru_Task::info (char **strp, + size_t length) const +{ + ACE_TRACE ("ACE_Thru_Task::info"); + const char *name = this->name (); + + if (*strp == 0 && (*strp = ACE_OS::strdup (name)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, name, length); + return ACE_OS::strlen (name); +} + +template int +ACE_Thru_Task::fini (void) +{ + ACE_TRACE ("ACE_Thru_Task::fini"); + return 0; +} + +#endif /* ACE_STREAM_MODULES_C */ diff --git a/ace/Stream_Modules.h b/ace/Stream_Modules.h new file mode 100644 index 00000000000..71db2247af5 --- /dev/null +++ b/ace/Stream_Modules.h @@ -0,0 +1,118 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Stream_Modules.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_STREAM_MODULES) +#define ACE_STREAM_MODULES + +#include "ace/Task.h" + +template +class ACE_Stream_Head : public ACE_Task + // = TITLE + // Standard module that acts as the head of a ustream. +{ +public: + // = ACE_Task hooks + virtual int open (void *a = 0); + virtual int close (u_long flags = 0); + virtual int put (ACE_Message_Block *msg, ACE_Time_Value * = 0); + virtual int svc (void); + + // = Dynamic linking hooks + virtual int init (int argc, char *argv[]); + virtual int info (char **info_string, size_t length) const; + virtual int fini (void); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + int control (ACE_Message_Block *); + int canonical_flush (ACE_Message_Block *); + // Performs canonical flushing at the ACE_Stream Head. +}; + +template +class ACE_Stream_Tail : public ACE_Task + // = TITLE + // Standard module that acts as the head of a ustream. +{ +public: + // = ACE_Task hooks + virtual int open (void *a = 0); + virtual int close (u_long flags = 0); + virtual int put (ACE_Message_Block *msg, ACE_Time_Value * = 0); + virtual int svc (void); + + // = Dynamic linking hooks + virtual int init (int argc, char *argv[]); + virtual int info (char **info_string, size_t length) const; + virtual int fini (void); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + int control (ACE_Message_Block *); + int canonical_flush (ACE_Message_Block *); + // Performs canonical flushing at the ACE_Stream tail. +}; + +template +class ACE_Thru_Task : public ACE_Task + // = TITLE + // Standard module that acts as a "no op", simply passing on all + // data to its adjacent neighbor. +{ +public: + // = ACE_Task hooks + virtual int open (void *a = 0); + virtual int close (u_long flags = 0); + virtual int put (ACE_Message_Block *msg, ACE_Time_Value * = 0); + virtual int svc (void); + + // = Dynamic linking hooks + virtual int init (int argc, char *argv[]); + virtual int info (char **info_string, size_t length) const; + virtual int fini (void); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Stream_Modules.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Stream_Modules.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Stream_Modules.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_STREAM_MODULES */ diff --git a/ace/Stream_Modules.i b/ace/Stream_Modules.i new file mode 100644 index 00000000000..da761143bd8 --- /dev/null +++ b/ace/Stream_Modules.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// $Id$ + +// Stream_Modules.i diff --git a/ace/Svc_Conf.h b/ace/Svc_Conf.h new file mode 100644 index 00000000000..a777b1ef880 --- /dev/null +++ b/ace/Svc_Conf.h @@ -0,0 +1,81 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Svc_Conf.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SVC_CONF_H) +#define ACE_SVC_CONF_H + +// Globally visible macros, type decls, and extern var decls for +// Service Configurator utility. + +#include "ace/Obstack.h" +#include "ace/Service_Config.h" +#include "ace/Parse_Node.h" + +#if defined (DEBUGGING) +#if defined (YY_DECL) +#undef YY_DECL +#endif +#define YY_DECL extern "C" char *ace_yylex (void) +#else +#define YY_DECL extern "C" int ace_yylex (void) +#endif /* DEBUGGING */ + +void ace_yyrestart (FILE *); +// Restart input file parsing + +int ace_yyparse (void); +// Performs the parsing + +YY_DECL; +// Performs the lexical analysis + +extern FILE *ace_yyin; +// Name of input stream + +void ace_yyerror (char *); +// Error handling routine required by YACC or BISON + +extern int ace_yylineno; +// Keeps track of the current line number for error-handling routine + +extern int ace_yyerrno; +// Keeps track of the number of errors encountered so far + +extern char *ace_yytext; +// Holds the lexeme for the current token + +extern int ace_yyleng; +// Holds the length of the lexeme for the current token + +extern ACE_Obstack *ace_obstack; +// Efficient memory allocation technique + +ACE_Service_Type *ace_create_service_type (const char *, int, const void *, unsigned int); +// Factory that creates a new ACE_Service_Type. + +typedef union +{ + int type_; + ACE_Location_Node *location_node_; + ACE_Parse_Node *parse_node_; + ACE_Static_Node *ACE_Static_Node_; + ACE_Service_Record *svc_record_; + char *ident_; +} YYSTYPE; +extern YYSTYPE ace_yylval; +#endif /* ACE_SVC_CONF_H */ + diff --git a/ace/Svc_Conf.l b/ace/Svc_Conf.l new file mode 100644 index 00000000000..029869e29c1 --- /dev/null +++ b/ace/Svc_Conf.l @@ -0,0 +1,77 @@ +%{ +// Sample lexical analysis for regular expression subset. Must be +// compiled with FLEX and an ANSI C++ compiler. + +// Lexical tokens values defined by YACC. +#include "ace/Svc_Conf.h" +#include "ace/Svc_Conf_Tokens.h" + +// Keeps track of the current line for debugging output. +int yylineno = 1; + +// Keeps track of the number of errors encountered so far. +int yyerrno = 0; + +#define token(x) x +%} + +%s PARAMETERS +%s NORMAL + +letter [a-zA-Z_] +letter_or_digit [a-zA-Z_0-9] +digit [0-9] +ident {letter}{letter_or_digit}* +pathname ([A-Za-z]:)?[a-zA-Z_0-9/\.\\-]+ +symbol [ -~] +string \"{symbol}+\" +white_space [ \t] +newline \n +other . + +%% + +^#{other}*$ ; /* EMPTY */ +dynamic { return token (ACE_DYNAMIC); } +static { return token (ACE_STATIC); } +suspend { return token (ACE_SUSPEND); } +resume { return token (ACE_RESUME); } +remove { return token (ACE_REMOVE); } +stream { return token (ACE_USTREAM); } +Module { return token (ACE_MODULE_T); } +Service_Object { return token (ACE_SVC_OBJ_T); } +STREAM { return token (ACE_STREAM_T); } +active { return token (ACE_ACTIVE); } +inactive { return token (ACE_INACTIVE); } +":" { return token (ACE_COLON); } +"*" { return token (ACE_STAR); } +"(" { return token (ACE_LPAREN); } +")" { return token (ACE_RPAREN); } +"{" { return token (ACE_LBRACE); } +"}" { return token (ACE_RBRACE); } +{string} { // Eliminate the opening and closing double quotes + *strrchr (yytext, '"') = '\0'; + yyleng -= 1; + yylval.ident_ = ace_obstack->copy (yytext + 1, yyleng); + return token (ACE_STRING); } +{ident} { + yylval.ident_ = ace_obstack->copy (yytext, yyleng); + return token (ACE_IDENT); + } +{pathname} { + yylval.ident_ = ace_obstack->copy (yytext, yyleng); + return token (ACE_PATHNAME); + } +{white_space}+ ; /* EMPTY */ +{newline} { yylineno++; } +{other} { ACE_ERROR ((LM_ERROR, "unknown char = %d\n", *yytext)); } +<> { YY_NEW_FILE; yyterminate(); } +%% +int +yywrap (void) +{ + ::fflush (yyin); + yytext[0] = '#'; + yyleng = 0; + return 1; +} diff --git a/ace/Svc_Conf.y b/ace/Svc_Conf.y new file mode 100644 index 00000000000..842fbf1ce7b --- /dev/null +++ b/ace/Svc_Conf.y @@ -0,0 +1,342 @@ +%{ +#define ACE_BUILD_DLL +#include "ace/ARGV.h" +#include "ace/Svc_Conf.h" +#include "ace/Module.h" +#include "ace/Stream.h" + +static ACE_Module_Type *get_module (ACE_Static_Node *str_rec, ACE_Static_Node *svc_type); +static ACE_Module_Type *get_module (ACE_Static_Node *str_rec, const char *svc_name); + +#define YYDEBUG_LEXER_TEXT (yytext[yyleng] = '\0', yytext) +// Force the pretty debugging code to compile. +#define YYDEBUG 1 + +// Efficient memory allocation technique. +ACE_Obstack *ace_obstack; + +%} +%token ACE_DYNAMIC ACE_STATIC ACE_SUSPEND ACE_RESUME ACE_REMOVE ACE_USTREAM +%token ACE_MODULE_T ACE_STREAM_T ACE_SVC_OBJ_T ACE_ACTIVE ACE_INACTIVE +%token ACE_PATHNAME ACE_IDENT ACE_STRING +%token ACE_LPAREN ACE_RPAREN ACE_LBRACE ACE_RBRACE ACE_STAR ACE_COLON + +%start svc_config_entries + +%type ACE_IDENT ACE_STRING ACE_PATHNAME parameters_opt +%type type status +%type dynamic static suspend resume remove module_list stream +%type stream_modules module svc_config_entry +%type stream_ops +%type svc_location +%type svc_initializer + +%% + +svc_config_entries + : svc_config_entries svc_config_entry + { + $2->apply (); delete $2; ace_obstack->release (); + } + | svc_config_entries error + { + ace_obstack->release (); + } + | /* EMPTY */ + ; + +svc_config_entry + : dynamic + | static + | suspend + | resume + | remove + | stream + ; + +dynamic + : ACE_DYNAMIC svc_location parameters_opt + { + $$ = new ACE_Dynamic_Node ($2, $3); + } + ; + +static + : ACE_STATIC ACE_IDENT parameters_opt + { + $$ = new ACE_Static_Node ($2, $3); + } + ; + +suspend + : ACE_SUSPEND ACE_IDENT + { + $$ = new ACE_Suspend_Node ($2); + } + ; + +resume + : ACE_RESUME ACE_IDENT + { + $$ = new ACE_Resume_Node ($2); + } + ; + +remove + : ACE_REMOVE ACE_IDENT + { + $$ = new ACE_Remove_Node ($2); + } + ; + +stream + : ACE_USTREAM stream_ops stream_modules + { + $$ = new ACE_Stream_Node ($2, $3); + } + | ACE_USTREAM ACE_IDENT { $$ = new ACE_Static_Node ($2); } stream_modules + { + $$ = new ACE_Dummy_Node ($3, $4); + } + ; + +stream_ops + : dynamic + { + } + | static + { + } + ; + +stream_modules + : ACE_LBRACE + { + // Initialize left context... + $$ = $0; + } + module_list ACE_RBRACE + { + $$ = $3; + } + | /* EMPTY */ { $$ = 0; } + ; + +module_list + : module_list module { $2->link ($1); $$ = $2; } + | /* EMPTY */ { $$ = 0; } + ; + +module + : dynamic + { + ACE_ARGV args ($1->parameters ()); + ACE_Module_Type *mt = get_module ($-1, $1); + + if (::strcmp ($1->name (), + ((MT_Module *) mt->object ())->name ()) != 0) + ACE_ERROR ((LM_ERROR, "warning, service name %s is different from Module name %s\n", + $1->name (), ((MT_Module *) mt->object ())->name ())); + + if (mt->init (args.argc (), args.argv ()) == -1 + || ((ACE_Stream_Type *) ($-1)->record ()->type ())->push (mt) == -1) + { + ACE_ERROR ((LM_ERROR, "dynamic initialization failed for Module %s\n", + $1->name ())); + yyerrno++; + } + } + | static + { + ACE_Module_Type *mt = get_module ($-1, $1->name ()); + if (::strcmp ($1->name (), + ((MT_Module *) mt->object ())->name ()) != 0) + ACE_ERROR ((LM_ERROR, "warning, service name %s is different from Module name %s\n", + $1->name (), ((MT_Module *) mt->object ())->name ())); + if (((ACE_Stream_Type *) ($-1)->record ()->type ())->push (mt) == -1) + yyerrno++; + } + | suspend + { + ACE_Module_Type *mt = get_module ($-1, $1->name ()); + if (mt != 0) + mt->suspend (); + } + | resume + { + ACE_Module_Type *mt = get_module ($-1, $1->name ()); + if (mt != 0) + mt->resume (); + } + | remove + { + ACE_Module_Type *mt = get_module ($-1, $1->name ()); + if (mt != 0 + && ((ACE_Stream_Type *) ($-1)->record ()->type ())->remove (mt) == -1) + { + ACE_ERROR ((LM_ERROR, "cannot remove Module_Type %s from STREAM_Type %s\n", + $1->name (), ($-1)->name ())); + yyerrno++; + } + } + ; + +svc_location + : ACE_IDENT type svc_initializer status + { + unsigned int flags + = ACE_Service_Type::DELETE_THIS | ($3->dispose () == 0 ? 0 : ACE_Service_Type::DELETE_OBJ); + ACE_Service_Type *stp = ace_create_service_type ($1, $2, $3->symbol (), flags); + $$ = new ACE_Service_Record ($1, stp, $3->handle (), $4); + } + ; + +status + : ACE_ACTIVE + { + $$ = 1; + } + | ACE_INACTIVE + { + $$ = 0; + } + | /* EMPTY */ + { + $$ = 1; + } + ; + +svc_initializer + : ACE_PATHNAME ACE_COLON ACE_IDENT + { + $$ = new ACE_Object_Node ($1, $3); + } + | ACE_PATHNAME ACE_COLON ACE_IDENT ACE_LPAREN ACE_RPAREN + { + $$ = new ACE_Function_Node ($1, $3); + } + ; + +type + : ACE_MODULE_T ACE_STAR + { + $$ = ACE_MODULE_T; + } + | ACE_SVC_OBJ_T ACE_STAR + { + $$ = ACE_SVC_OBJ_T; + } + | ACE_STREAM_T ACE_STAR + { + $$ = ACE_STREAM_T; + } + ; + +parameters_opt + : ACE_STRING + | /* EMPTY */ { $$ = 0; } + ; + +%% +// Prints the error string to standard output. Cleans up the error +// messages. + +void +yyerror (char *s) +{ + ACE_ERROR ((LM_ERROR, "[error %d] on line %d: %s\n", + ++yyerrno, yylineno, s)); +} + +// Note that SRC_REC represents left context, which is the STREAM * +// record. + +static ACE_Module_Type * +get_module (ACE_Static_Node *str_rec, const char *svc_name) +{ + const ACE_Service_Record *sr = str_rec->record (); + const ACE_Service_Type *type = sr->type (); + ACE_Stream_Type *st = sr == 0 ? 0 : (ACE_Stream_Type *) type; + ACE_Module_Type *mt = st == 0 ? 0 : st->find (svc_name); + + if (sr == 0 || st == 0 || mt == 0) + { + ACE_ERROR ((LM_ERROR, "cannot locate Module_Type %s in STREAM_Type %s\n", + svc_name, str_rec->name ())); + yyerrno++; + } + return mt; +} + +static ACE_Module_Type * +get_module (ACE_Static_Node *str_rec, ACE_Static_Node *svc_type) +{ + const ACE_Service_Record *sr = str_rec->record (); + const ACE_Service_Type *type = sr->type (); + ACE_Stream_Type *st = sr == 0 ? 0 : (ACE_Stream_Type *) type; + const ACE_Service_Record *sv = svc_type->record (); + type = sv->type (); + ACE_Module_Type *mt = (ACE_Module_Type *) type; + + if (sr == 0 || st == 0 || mt == 0) + { + ACE_ERROR ((LM_ERROR, "cannot locate Module_Type %s or STREAM_Type %s\n", + svc_type->name (), str_rec->name ())); + yyerrno++; + } + return mt; +} + +ACE_Service_Type * +ace_create_service_type (const char *name, + int type, + const void *symbol, + unsigned int flags) +{ + ACE_Service_Type *stp = 0; + + // Note, the only place we need to put a case statement. This is + // also the place where we'd put the RTTI tests, if the compiler + // actually supported them! + + switch (type) + { + case ACE_SVC_OBJ_T: + stp = new ACE_Service_Object_Type ((ACE_Service_Object *) symbol, name, flags); + break; + case ACE_MODULE_T: + stp = new ACE_Module_Type ((MT_Module *) symbol, name, flags); + break; + case ACE_STREAM_T: + stp = new ACE_Stream_Type ((MT_Stream *) symbol, name, flags); + break; + default: + ACE_ERROR ((LM_ERROR, "unknown case\n")); + yyerrno++; + break; + } + return stp; +} + +#if defined (DEBUGGING) +// Current line number. +int yylineno = 1; + +// Name given on the command-line to envoke the program. +char *program_name; + +// Main driver program. + +int +main (int argc, char *argv[]) +{ + yyin = stdin; + ace_obstack = new ACE_Obstack; + + // Try to reopen any filename argument to use YYIN. + if (argc > 1 && (yyin = freopen (argv[1], "r", stdin)) == 0) + (void) ::fprintf (stderr, "usage: %s [file]\n", argv[0]), exit (1); + + return yyparse (); +} +#endif /* DEBUGGING */ diff --git a/ace/Svc_Conf_Tokens.h b/ace/Svc_Conf_Tokens.h new file mode 100644 index 00000000000..39e0e0ac4f0 --- /dev/null +++ b/ace/Svc_Conf_Tokens.h @@ -0,0 +1,23 @@ +/* -*- C++ -*- */ +// $Id$ + +#define ACE_DYNAMIC 257 +#define ACE_STATIC 258 +#define ACE_SUSPEND 259 +#define ACE_RESUME 260 +#define ACE_REMOVE 261 +#define ACE_USTREAM 262 +#define ACE_MODULE_T 263 +#define ACE_STREAM_T 264 +#define ACE_SVC_OBJ_T 265 +#define ACE_ACTIVE 266 +#define ACE_INACTIVE 267 +#define ACE_PATHNAME 268 +#define ACE_IDENT 269 +#define ACE_STRING 270 +#define ACE_LPAREN 271 +#define ACE_RPAREN 272 +#define ACE_LBRACE 273 +#define ACE_RBRACE 274 +#define ACE_STAR 275 +#define ACE_COLON 276 diff --git a/ace/Svc_Conf_l.cpp b/ace/Svc_Conf_l.cpp new file mode 100644 index 00000000000..9e7cd5ad934 --- /dev/null +++ b/ace/Svc_Conf_l.cpp @@ -0,0 +1,1504 @@ +/* A lexical scanner generated by flex */ +// $Id$ + + +/* Scanner skeleton version: + * $Header$ + */ + +#define FLEX_SCANNER + +#include + + +/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ +#ifdef c_plusplus +#ifndef __cplusplus +#define __cplusplus +#endif +#endif + + +#ifdef __cplusplus + +#include +#include + +/* Use prototypes in function declarations. */ +#define YY_USE_PROTOS + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#ifdef __STDC__ + +#define YY_USE_PROTOS +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + + +#ifdef __TURBOC__ +#define YY_USE_CONST +#endif + + +#ifndef YY_USE_CONST +#ifndef const +#define const +#endif +#endif + + +#ifdef YY_USE_PROTOS +#define YY_PROTO(proto) proto +#else +#define YY_PROTO(proto) () +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN ace_yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. + */ +#define YY_START ((ace_yy_start - 1) / 2) + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". Now included + * only for backward compatibility with previous versions of flex. + */ +#define YY_NEW_FILE ace_yyrestart( ace_yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#define YY_BUF_SIZE 16384 + +typedef struct ace_yy_buffer_state *YY_BUFFER_STATE; + +extern int ace_yyleng; +extern FILE *ace_yyin, *ace_yyout; + +#ifdef __cplusplus +extern "C" { +#endif + extern int ace_yywrap YY_PROTO(( void )); +#ifdef __cplusplus + } +#endif + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +/* The funky do-while in the following #define is used to turn the definition + * int a single C statement (which needs a semi-colon terminator). This + * avoids problems with code like: + * + * if ( condition_holds ) + * ace_yyless( 5 ); + * else + * do_something_else(); + * + * Prior to using the do-while the compiler would get upset at the + * "else" because it interpreted the "if" statement as being all + * done when it reached the ';' after the ace_yyless() call. + */ + +/* Return all but the first 'n' matched characters back to the input stream. */ + +#define ace_yyless(n) \ + do \ + { \ + /* Undo effects of setting up ace_yytext. */ \ + *ace_yy_cp = ace_yy_hold_char; \ + ace_yy_c_buf_p = ace_yy_cp = ace_yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up ace_yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) ace_yyunput( c, ace_yytext_ptr ) + + +struct ace_yy_buffer_state + { + FILE *ace_yy_input_file; + + char *ace_yy_ch_buf; /* input buffer */ + char *ace_yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int ace_yy_buf_size; + + /* Number of characters read into ace_yy_ch_buf, not including EOB + * characters. + */ + int ace_yy_n_chars; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int ace_yy_is_interactive; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int ace_yy_fill_buffer; + + int ace_yy_buffer_status; +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via ace_yyrestart()), so that the user can continue scanning by + * just pointing ace_yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + }; + +static YY_BUFFER_STATE ace_yy_current_buffer = 0; + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + */ +#define YY_CURRENT_BUFFER ace_yy_current_buffer + + +/* ace_yy_hold_char holds the character lost when ace_yytext is formed. */ +static char ace_yy_hold_char; + +static int ace_yy_n_chars; /* number of characters read into ace_yy_ch_buf */ + + +int ace_yyleng; + +/* Points to current character in buffer. */ +static char *ace_yy_c_buf_p = (char *) 0; +static int ace_yy_init = 1; /* whether we need to initialize */ +static int ace_yy_start = 0; /* start state number */ + +/* Flag which is used to allow ace_yywrap()'s to do buffer switches + * instead of setting up a fresh ace_yyin. A bit of a hack ... + */ +static int ace_yy_did_buffer_switch_on_eof; + +static void ace_yyunput YY_PROTO(( int c, char *buf_ptr )); +void ace_yyrestart YY_PROTO(( FILE *input_file )); +void ace_yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); +void ace_yy_load_buffer_state YY_PROTO(( void )); +YY_BUFFER_STATE ace_yy_create_buffer YY_PROTO(( FILE *file, int size )); +void ace_yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); +void ace_yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); + +static int ace_yy_start_stack_ptr = 0; +static int ace_yy_start_stack_depth = 0; +static int *ace_yy_start_stack = 0; +static void ace_yy_push_state YY_PROTO(( int new_state )); +static void ace_yy_pop_state YY_PROTO(( void )); +static int ace_yy_top_state YY_PROTO(( void )); + +static void *ace_yy_flex_alloc YY_PROTO(( unsigned int )); +static void *ace_yy_flex_realloc YY_PROTO(( void *, unsigned int )); +static void ace_yy_flex_free YY_PROTO(( void * )); + +#define ace_yy_new_buffer ace_yy_create_buffer + +#define INITIAL 0 +#define PARAMETERS 1 +#define NORMAL 2 +typedef unsigned char YY_CHAR; +typedef int ace_yy_state_type; +FILE *ace_yyin = (FILE *) 0, *ace_yyout = (FILE *) 0; +extern char *ace_yytext; +#define ace_yytext_ptr ace_yytext + +#ifndef ace_yytext_ptr +static void ace_yy_flex_strncpy YY_PROTO(( char *, const char *, int )); +#endif + +#ifdef __cplusplus +static int ace_yyinput YY_PROTO(( void )); +#else +static int input YY_PROTO(( void )); +#endif + +static ace_yy_state_type ace_yy_get_previous_state YY_PROTO(( void )); +static ace_yy_state_type ace_yy_try_NUL_trans YY_PROTO(( ace_yy_state_type current_state )); +static int ace_yy_get_next_buffer YY_PROTO(( void )); +static void ace_yy_fatal_error YY_PROTO(( const char msg[] )); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up ace_yytext. + */ +#define YY_DO_BEFORE_ACTION \ + ace_yytext_ptr = ace_yy_bp; \ + ace_yyleng = ace_yy_cp - ace_yy_bp; \ + ace_yy_hold_char = *ace_yy_cp; \ + *ace_yy_cp = '\0'; \ + ace_yy_c_buf_p = ace_yy_cp; + +#define YY_END_OF_BUFFER 26 +static const short int ace_yy_accept[103] = + { 0, + 0, 0, 0, 0, 0, 0, 26, 24, 22, 23, + 24, 15, 16, 14, 21, 13, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 17, 18, 24, 22, 0, + 21, 20, 0, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 0, 1, 19, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 8, 10, + 20, 11, 20, 20, 6, 5, 3, 7, 20, 20, + 2, 20, 4, 20, 12, 20, 20, 20, 20, 20, + + 9, 0 + } ; + +static const int ace_yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 4, 5, 6, 7, 5, 5, 5, 5, 8, + 9, 10, 5, 5, 11, 11, 11, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 13, 5, 5, + 5, 5, 5, 5, 14, 15, 15, 15, 16, 15, + 15, 15, 15, 15, 15, 15, 17, 15, 18, 15, + 15, 19, 20, 21, 15, 15, 15, 15, 15, 15, + 5, 11, 5, 5, 22, 5, 23, 24, 25, 26, + + 27, 15, 15, 15, 28, 29, 15, 30, 31, 32, + 33, 34, 15, 35, 36, 37, 38, 39, 15, 15, + 40, 15, 41, 5, 42, 5, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static const int ace_yy_meta[43] = + { 0, + 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2 + } ; + +static const short int ace_yy_base[107] = + { 0, + 0, 111, 0, 107, 0, 90, 91, 313, 41, 313, + 0, 313, 313, 313, 0, 313, 33, 36, 37, 40, + 41, 44, 48, 49, 52, 313, 313, 82, 66, 76, + 0, 60, 0, 61, 64, 68, 75, 81, 82, 85, + 88, 89, 75, 313, 61, 93, 104, 96, 111, 115, + 116, 97, 121, 129, 133, 134, 137, 138, 142, 143, + 150, 151, 158, 161, 162, 166, 167, 172, 185, 180, + 173, 190, 193, 196, 197, 200, 201, 204, 209, 215, + 216, 220, 224, 227, 228, 231, 234, 235, 239, 240, + 243, 244, 247, 250, 256, 259, 262, 263, 267, 266, + + 271, 313, 302, 53, 304, 308 + } ; + +static const short int ace_yy_def[107] = + { 0, + 102, 1, 1, 1, 1, 1, 102, 102, 102, 102, + 103, 102, 102, 102, 104, 102, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 102, 102, 106, 102, 103, + 104, 105, 104, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 106, 102, 103, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + + 105, 0, 102, 102, 102, 102 + } ; + +static const short int ace_yy_nxt[356] = + { 0, + 8, 9, 10, 9, 8, 11, 8, 12, 13, 14, + 15, 15, 16, 17, 17, 17, 18, 17, 17, 19, + 17, 20, 21, 17, 17, 22, 17, 23, 17, 17, + 17, 17, 17, 17, 24, 25, 17, 17, 17, 17, + 26, 27, 29, 31, 29, 33, 31, 31, 33, 33, + 31, 31, 102, 33, 31, 31, 33, 35, 31, 31, + 33, 33, 31, 36, 33, 37, 45, 29, 34, 29, + 31, 31, 102, 102, 31, 40, 102, 44, 31, 39, + 102, 45, 47, 38, 44, 31, 46, 102, 41, 42, + 102, 31, 31, 102, 102, 31, 28, 102, 31, 31, + + 102, 102, 48, 31, 51, 102, 31, 31, 102, 102, + 54, 49, 50, 28, 31, 52, 102, 28, 102, 58, + 53, 31, 55, 102, 56, 31, 31, 102, 102, 63, + 57, 31, 102, 102, 59, 102, 102, 61, 60, 31, + 62, 102, 102, 31, 31, 102, 102, 31, 31, 102, + 102, 69, 31, 31, 102, 102, 102, 102, 64, 66, + 31, 31, 102, 102, 102, 65, 68, 67, 31, 70, + 102, 31, 31, 102, 102, 102, 31, 31, 102, 102, + 72, 71, 31, 31, 102, 102, 102, 73, 77, 76, + 31, 75, 102, 78, 102, 31, 74, 102, 79, 82, + + 31, 80, 102, 31, 81, 102, 31, 31, 102, 102, + 31, 31, 102, 102, 31, 102, 102, 83, 102, 31, + 84, 102, 85, 86, 87, 31, 31, 102, 102, 102, + 31, 88, 102, 102, 31, 89, 102, 31, 31, 102, + 102, 31, 90, 102, 31, 31, 102, 102, 91, 31, + 31, 102, 102, 31, 31, 102, 102, 31, 102, 102, + 31, 94, 102, 102, 93, 92, 31, 96, 102, 31, + 95, 102, 31, 31, 102, 102, 31, 31, 102, 102, + 102, 31, 97, 102, 102, 102, 102, 102, 102, 99, + 98, 100, 102, 102, 102, 102, 102, 102, 102, 102, + + 102, 102, 101, 30, 30, 30, 32, 32, 43, 43, + 43, 43, 7, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102 + } ; + +static const short int ace_yy_chk[356] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 9, 17, 9, 17, 18, 19, 18, 19, + 20, 21, 20, 21, 22, 104, 22, 19, 23, 24, + 23, 24, 25, 19, 25, 21, 45, 29, 18, 29, + 32, 34, 32, 34, 35, 24, 35, 43, 36, 23, + 36, 30, 35, 22, 28, 37, 34, 37, 25, 25, + 7, 38, 39, 38, 39, 40, 6, 40, 41, 42, + + 41, 42, 36, 46, 39, 46, 48, 52, 48, 52, + 41, 37, 38, 4, 47, 40, 47, 2, 0, 47, + 40, 49, 41, 49, 42, 50, 51, 50, 51, 52, + 46, 53, 0, 53, 48, 0, 0, 50, 49, 54, + 51, 54, 0, 55, 56, 55, 56, 57, 58, 57, + 58, 58, 59, 60, 59, 60, 0, 0, 53, 55, + 61, 62, 61, 62, 0, 54, 57, 56, 63, 59, + 63, 64, 65, 64, 65, 0, 66, 67, 66, 67, + 61, 60, 68, 71, 68, 71, 0, 62, 66, 65, + 70, 64, 70, 67, 0, 69, 63, 69, 68, 71, + + 72, 69, 72, 73, 70, 73, 74, 75, 74, 75, + 76, 77, 76, 77, 78, 0, 78, 72, 0, 79, + 73, 79, 74, 75, 76, 80, 81, 80, 81, 0, + 82, 77, 82, 0, 83, 78, 83, 84, 85, 84, + 85, 86, 81, 86, 87, 88, 87, 88, 83, 89, + 90, 89, 90, 91, 92, 91, 92, 93, 0, 93, + 94, 90, 94, 0, 89, 84, 95, 94, 95, 96, + 92, 96, 97, 98, 97, 98, 100, 99, 100, 99, + 0, 101, 96, 101, 0, 0, 0, 0, 0, 98, + 97, 99, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 100, 103, 103, 103, 105, 105, 106, 106, + 106, 106, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102 + } ; + +static ace_yy_state_type ace_yy_last_accepting_state; +static char *ace_yy_last_accepting_cpos; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define ace_yymore() ace_yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +char *ace_yytext; +# line 1 "Svc_Conf.l" +# line 2 "Svc_Conf.l" +// Sample lexical analysis for regular expression subset. Must be +// compiled with FLEX and an ANSI C++ compiler. + +// Lexical tokens values defined by YACC. +#include "ace/Svc_Conf.h" +#include "ace/Svc_Conf_Tokens.h" + +// Keeps track of the current line for debugging output. +int ace_yylineno = 1; + +// Keeps track of the number of errors encountered so far. +int ace_yyerrno = 0; + +#define token(x) x + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifdef YY_MALLOC_DECL +YY_MALLOC_DECL +#else +#if __STDC__ +#ifndef __cplusplus +#include +#endif +#else +/* Just try to get by without declaring the routines. This will fail + * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) + * or sizeof(void*) != sizeof(int). + */ +#endif +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ + +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( ace_yytext, ace_yyleng, 1, ace_yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( ace_yy_current_buffer->ace_yy_is_interactive ) \ + { \ + int c = getc( ace_yyin ); \ + result = c == EOF ? 0 : 1; \ + buf[0] = (char) c; \ + } \ + else if ( ((result = fread( buf, 1, max_size, ace_yyin )) == 0) \ + && ferror( ace_yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); +#endif + +/* No semi-colon after return; correct usage is to write "ace_yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef ace_yyterminate +#define ace_yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) ace_yy_fatal_error( msg ) +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL int ace_yylex YY_PROTO(( void )) +#endif + +/* Code executed at the beginning of each rule, after ace_yytext and ace_yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +YY_DECL + { + register ace_yy_state_type ace_yy_current_state; + register char *ace_yy_cp, *ace_yy_bp; + register int ace_yy_act; + +# line 32 "Svc_Conf.l" + + + + if ( ace_yy_init ) + { +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! ace_yy_start ) + ace_yy_start = 1; /* first start state */ + + if ( ! ace_yyin ) + ace_yyin = stdin; + + if ( ! ace_yyout ) + ace_yyout = stdout; + + if ( ace_yy_current_buffer ) + ace_yy_init_buffer( ace_yy_current_buffer, ace_yyin ); + else + ace_yy_current_buffer = + ace_yy_create_buffer( ace_yyin, YY_BUF_SIZE ); + + ace_yy_load_buffer_state(); + + ace_yy_init = 0; + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + ace_yy_cp = ace_yy_c_buf_p; + + /* Support of ace_yytext. */ + *ace_yy_cp = ace_yy_hold_char; + + /* ace_yy_bp points to the position in ace_yy_ch_buf of the start of + * the current run. + */ + ace_yy_bp = ace_yy_cp; + + ace_yy_current_state = ace_yy_start; + if ( ace_yy_bp[-1] == '\n' ) + ++ace_yy_current_state; +ace_yy_match: + do + { + register YY_CHAR ace_yy_c = ace_yy_ec[YY_SC_TO_UI(*ace_yy_cp)]; + if ( ace_yy_accept[ace_yy_current_state] ) + { + ace_yy_last_accepting_state = ace_yy_current_state; + ace_yy_last_accepting_cpos = ace_yy_cp; + } + while ( ace_yy_chk[ace_yy_base[ace_yy_current_state] + ace_yy_c] != ace_yy_current_state ) + { + ace_yy_current_state = (int) ace_yy_def[ace_yy_current_state]; + if ( ace_yy_current_state >= 103 ) + ace_yy_c = ace_yy_meta[(unsigned int) ace_yy_c]; + } + ace_yy_current_state = ace_yy_nxt[ace_yy_base[ace_yy_current_state] + (unsigned int) ace_yy_c]; + ++ace_yy_cp; + } + while ( ace_yy_base[ace_yy_current_state] != 313 ); + +ace_yy_find_action: + ace_yy_act = ace_yy_accept[ace_yy_current_state]; + + YY_DO_BEFORE_ACTION; + + +do_action: /* This label is used only to access EOF actions. */ + + + switch ( ace_yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *ace_yy_cp = ace_yy_hold_char; + ace_yy_cp = ace_yy_last_accepting_cpos; + ace_yy_current_state = ace_yy_last_accepting_state; + goto ace_yy_find_action; + +case 1: +*ace_yy_cp = ace_yy_hold_char; /* undo effects of setting up ace_yytext */ +ace_yy_c_buf_p = ace_yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up ace_yytext again */ +YY_USER_ACTION +# line 34 "Svc_Conf.l" +; /* EMPTY */ + YY_BREAK +case 2: +YY_USER_ACTION +# line 35 "Svc_Conf.l" +{ return token (ACE_DYNAMIC); } + YY_BREAK +case 3: +YY_USER_ACTION +# line 36 "Svc_Conf.l" +{ return token (ACE_STATIC); } + YY_BREAK +case 4: +YY_USER_ACTION +# line 37 "Svc_Conf.l" +{ return token (ACE_SUSPEND); } + YY_BREAK +case 5: +YY_USER_ACTION +# line 38 "Svc_Conf.l" +{ return token (ACE_RESUME); } + YY_BREAK +case 6: +YY_USER_ACTION +# line 39 "Svc_Conf.l" +{ return token (ACE_REMOVE); } + YY_BREAK +case 7: +YY_USER_ACTION +# line 40 "Svc_Conf.l" +{ return token (ACE_USTREAM); } + YY_BREAK +case 8: +YY_USER_ACTION +# line 41 "Svc_Conf.l" +{ return token (ACE_MODULE_T); } + YY_BREAK +case 9: +YY_USER_ACTION +# line 42 "Svc_Conf.l" +{ return token (ACE_SVC_OBJ_T); } + YY_BREAK +case 10: +YY_USER_ACTION +# line 43 "Svc_Conf.l" +{ return token (ACE_STREAM_T); } + YY_BREAK +case 11: +YY_USER_ACTION +# line 44 "Svc_Conf.l" +{ return token (ACE_ACTIVE); } + YY_BREAK +case 12: +YY_USER_ACTION +# line 45 "Svc_Conf.l" +{ return token (ACE_INACTIVE); } + YY_BREAK +case 13: +YY_USER_ACTION +# line 46 "Svc_Conf.l" +{ return token (ACE_COLON); } + YY_BREAK +case 14: +YY_USER_ACTION +# line 47 "Svc_Conf.l" +{ return token (ACE_STAR); } + YY_BREAK +case 15: +YY_USER_ACTION +# line 48 "Svc_Conf.l" +{ return token (ACE_LPAREN); } + YY_BREAK +case 16: +YY_USER_ACTION +# line 49 "Svc_Conf.l" +{ return token (ACE_RPAREN); } + YY_BREAK +case 17: +YY_USER_ACTION +# line 50 "Svc_Conf.l" +{ return token (ACE_LBRACE); } + YY_BREAK +case 18: +YY_USER_ACTION +# line 51 "Svc_Conf.l" +{ return token (ACE_RBRACE); } + YY_BREAK +case 19: +YY_USER_ACTION +# line 52 "Svc_Conf.l" +{ // Eliminate the opening and closing double quotes + *strrchr (ace_yytext, '"') = '\0'; + ace_yyleng -= 1; + ace_yylval.ident_ = ace_obstack->copy (ace_yytext + 1, ace_yyleng); + return token (ACE_STRING); } + YY_BREAK +case 20: +YY_USER_ACTION +# line 57 "Svc_Conf.l" +{ + ace_yylval.ident_ = ace_obstack->copy (ace_yytext, ace_yyleng); + return token (ACE_IDENT); + } + YY_BREAK +case 21: +YY_USER_ACTION +# line 61 "Svc_Conf.l" +{ + ace_yylval.ident_ = ace_obstack->copy (ace_yytext, ace_yyleng); + return token (ACE_PATHNAME); + } + YY_BREAK +case 22: +YY_USER_ACTION +# line 65 "Svc_Conf.l" +; /* EMPTY */ + YY_BREAK +case 23: +YY_USER_ACTION +# line 66 "Svc_Conf.l" +{ ace_yylineno++; } + YY_BREAK +case 24: +YY_USER_ACTION +# line 67 "Svc_Conf.l" +{ ACE_ERROR ((LM_ERROR, "unknown char = %d\n", *ace_yytext)); } + YY_BREAK +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(PARAMETERS): +case YY_STATE_EOF(NORMAL): +# line 68 "Svc_Conf.l" +{ YY_NEW_FILE; ace_yyterminate(); } + YY_BREAK +case 25: +YY_USER_ACTION +# line 69 "Svc_Conf.l" +ECHO; + YY_BREAK + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int ace_yy_amount_of_matched_text = ace_yy_cp - ace_yytext_ptr - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *ace_yy_cp = ace_yy_hold_char; + + if ( ace_yy_current_buffer->ace_yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed ace_yyin at a new source and called + * ace_yylex(). If so, then we have to assure + * consistency between ace_yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + ace_yy_n_chars = ace_yy_current_buffer->ace_yy_n_chars; + ace_yy_current_buffer->ace_yy_input_file = ace_yyin; + ace_yy_current_buffer->ace_yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for ace_yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since ace_yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( ace_yy_c_buf_p <= &ace_yy_current_buffer->ace_yy_ch_buf[ace_yy_n_chars] ) + { /* This was really a NUL. */ + ace_yy_state_type ace_yy_next_state; + + ace_yy_c_buf_p = ace_yytext_ptr + ace_yy_amount_of_matched_text; + + ace_yy_current_state = ace_yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * ace_yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + ace_yy_next_state = ace_yy_try_NUL_trans( ace_yy_current_state ); + + ace_yy_bp = ace_yytext_ptr + YY_MORE_ADJ; + + if ( ace_yy_next_state ) + { + /* Consume the NUL. */ + ace_yy_cp = ++ace_yy_c_buf_p; + ace_yy_current_state = ace_yy_next_state; + goto ace_yy_match; + } + + else + { + ace_yy_cp = ace_yy_c_buf_p; + goto ace_yy_find_action; + } + } + + else switch ( ace_yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + ace_yy_did_buffer_switch_on_eof = 0; + + if ( ace_yywrap() ) + { + /* Note: because we've taken care in + * ace_yy_get_next_buffer() to have set up + * ace_yytext, we can now set up + * ace_yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + ace_yy_c_buf_p = ace_yytext_ptr + YY_MORE_ADJ; + + ace_yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! ace_yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + ace_yy_c_buf_p = + ace_yytext_ptr + ace_yy_amount_of_matched_text; + + ace_yy_current_state = ace_yy_get_previous_state(); + + ace_yy_cp = ace_yy_c_buf_p; + ace_yy_bp = ace_yytext_ptr + YY_MORE_ADJ; + goto ace_yy_match; + + case EOB_ACT_LAST_MATCH: + ace_yy_c_buf_p = + &ace_yy_current_buffer->ace_yy_ch_buf[ace_yy_n_chars]; + + ace_yy_current_state = ace_yy_get_previous_state(); + + ace_yy_cp = ace_yy_c_buf_p; + ace_yy_bp = ace_yytext_ptr + YY_MORE_ADJ; + goto ace_yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of ace_yylex */ + + +/* ace_yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ + +static int ace_yy_get_next_buffer() + { + register char *dest = ace_yy_current_buffer->ace_yy_ch_buf; + register char *source = ace_yytext_ptr - 1; /* copy prev. char, too */ + register int number_to_move, i; + int ret_val; + + if ( ace_yy_c_buf_p > &ace_yy_current_buffer->ace_yy_ch_buf[ace_yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( ace_yy_current_buffer->ace_yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( ace_yy_c_buf_p - ace_yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a singled characater, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = ace_yy_c_buf_p - ace_yytext_ptr; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( ace_yy_current_buffer->ace_yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + ace_yy_n_chars = 0; + + else + { + int num_to_read = + ace_yy_current_buffer->ace_yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ +#ifdef YY_USES_REJECT + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); +#else + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = ace_yy_current_buffer; + + int ace_yy_c_buf_p_offset = ace_yy_c_buf_p - b->ace_yy_ch_buf; + + b->ace_yy_buf_size *= 2; + b->ace_yy_ch_buf = (char *) + ace_yy_flex_realloc( (void *) b->ace_yy_ch_buf, + b->ace_yy_buf_size ); + + if ( ! b->ace_yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + ace_yy_c_buf_p = &b->ace_yy_ch_buf[ace_yy_c_buf_p_offset]; + + num_to_read = ace_yy_current_buffer->ace_yy_buf_size - + number_to_move - 1; +#endif + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&ace_yy_current_buffer->ace_yy_ch_buf[number_to_move]), + ace_yy_n_chars, num_to_read ); + } + + if ( ace_yy_n_chars == 0 ) + { + if ( number_to_move - YY_MORE_ADJ == 1 ) + { + ret_val = EOB_ACT_END_OF_FILE; + ace_yyrestart( ace_yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + ace_yy_current_buffer->ace_yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + ace_yy_n_chars += number_to_move; + ace_yy_current_buffer->ace_yy_ch_buf[ace_yy_n_chars] = YY_END_OF_BUFFER_CHAR; + ace_yy_current_buffer->ace_yy_ch_buf[ace_yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + /* ace_yytext begins at the second character in ace_yy_ch_buf; the first + * character is the one which preceded it before reading in the latest + * buffer; it needs to be kept around in case it's a newline, so + * ace_yy_get_previous_state() will have with '^' rules active. + */ + + ace_yytext_ptr = &ace_yy_current_buffer->ace_yy_ch_buf[1]; + + return ret_val; + } + + +/* ace_yy_get_previous_state - get the state just before the EOB char was reached */ + +static ace_yy_state_type ace_yy_get_previous_state() + { + register ace_yy_state_type ace_yy_current_state; + register char *ace_yy_cp; + + register char *ace_yy_bp = ace_yytext_ptr; + + ace_yy_current_state = ace_yy_start; + if ( ace_yy_bp[-1] == '\n' ) + ++ace_yy_current_state; + + for ( ace_yy_cp = ace_yytext_ptr + YY_MORE_ADJ; ace_yy_cp < ace_yy_c_buf_p; ++ace_yy_cp ) + { + register YY_CHAR ace_yy_c = (*ace_yy_cp ? ace_yy_ec[YY_SC_TO_UI(*ace_yy_cp)] : 1); + if ( ace_yy_accept[ace_yy_current_state] ) + { + ace_yy_last_accepting_state = ace_yy_current_state; + ace_yy_last_accepting_cpos = ace_yy_cp; + } + while ( ace_yy_chk[ace_yy_base[ace_yy_current_state] + ace_yy_c] != ace_yy_current_state ) + { + ace_yy_current_state = (int) ace_yy_def[ace_yy_current_state]; + if ( ace_yy_current_state >= 103 ) + ace_yy_c = ace_yy_meta[(unsigned int) ace_yy_c]; + } + ace_yy_current_state = ace_yy_nxt[ace_yy_base[ace_yy_current_state] + (unsigned int) ace_yy_c]; + } + + return ace_yy_current_state; + } + + +/* ace_yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = ace_yy_try_NUL_trans( current_state ); + */ + +#ifdef YY_USE_PROTOS +static ace_yy_state_type ace_yy_try_NUL_trans( ace_yy_state_type ace_yy_current_state ) +#else +static ace_yy_state_type ace_yy_try_NUL_trans( ace_yy_current_state ) +ace_yy_state_type ace_yy_current_state; +#endif + { + register int ace_yy_is_jam; + register char *ace_yy_cp = ace_yy_c_buf_p; + + register YY_CHAR ace_yy_c = 1; + if ( ace_yy_accept[ace_yy_current_state] ) + { + ace_yy_last_accepting_state = ace_yy_current_state; + ace_yy_last_accepting_cpos = ace_yy_cp; + } + while ( ace_yy_chk[ace_yy_base[ace_yy_current_state] + ace_yy_c] != ace_yy_current_state ) + { + ace_yy_current_state = (int) ace_yy_def[ace_yy_current_state]; + if ( ace_yy_current_state >= 103 ) + ace_yy_c = ace_yy_meta[(unsigned int) ace_yy_c]; + } + ace_yy_current_state = ace_yy_nxt[ace_yy_base[ace_yy_current_state] + (unsigned int) ace_yy_c]; + ace_yy_is_jam = (ace_yy_current_state == 102); + + return ace_yy_is_jam ? 0 : ace_yy_current_state; + } + + +#ifdef YY_USE_PROTOS +static void ace_yyunput( int c, register char *ace_yy_bp ) +#else +static void ace_yyunput( c, ace_yy_bp ) +int c; +register char *ace_yy_bp; +#endif + { + register char *ace_yy_cp = ace_yy_c_buf_p; + + /* undo effects of setting up ace_yytext */ + *ace_yy_cp = ace_yy_hold_char; + + if ( ace_yy_cp < ace_yy_current_buffer->ace_yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = ace_yy_n_chars + 2; + register char *dest = &ace_yy_current_buffer->ace_yy_ch_buf[ + ace_yy_current_buffer->ace_yy_buf_size + 2]; + register char *source = + &ace_yy_current_buffer->ace_yy_ch_buf[number_to_move]; + + while ( source > ace_yy_current_buffer->ace_yy_ch_buf ) + *--dest = *--source; + + ace_yy_cp += dest - source; + ace_yy_bp += dest - source; + ace_yy_n_chars = ace_yy_current_buffer->ace_yy_buf_size; + + if ( ace_yy_cp < ace_yy_current_buffer->ace_yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + if ( ace_yy_cp > ace_yy_bp && ace_yy_cp[-1] == '\n' ) + ace_yy_cp[-2] = '\n'; + + *--ace_yy_cp = (char) c; + + + /* Note: the formal parameter *must* be called "ace_yy_bp" for this + * macro to now work correctly. + */ + YY_DO_BEFORE_ACTION; /* set up ace_yytext again */ + } + + +#ifdef __cplusplus +static int ace_yyinput() +#else +static int input() +#endif + { + int c; + + *ace_yy_c_buf_p = ace_yy_hold_char; + + if ( *ace_yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* ace_yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( ace_yy_c_buf_p < &ace_yy_current_buffer->ace_yy_ch_buf[ace_yy_n_chars] ) + /* This was really a NUL. */ + *ace_yy_c_buf_p = '\0'; + + else + { /* need more input */ + ace_yytext_ptr = ace_yy_c_buf_p; + ++ace_yy_c_buf_p; + + switch ( ace_yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + if ( ace_yywrap() ) + { + ace_yy_c_buf_p = + ace_yytext_ptr + YY_MORE_ADJ; + return EOF; + } + + YY_NEW_FILE; +#ifdef __cplusplus + return ace_yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + ace_yy_c_buf_p = ace_yytext_ptr + YY_MORE_ADJ; + break; + + case EOB_ACT_LAST_MATCH: +#ifdef __cplusplus + YY_FATAL_ERROR( + "unexpected last match in ace_yyinput()" ); +#else + YY_FATAL_ERROR( + "unexpected last match in input()" ); +#endif + } + } + } + + c = *(unsigned char *) ace_yy_c_buf_p; /* cast for 8-bit char's */ + *ace_yy_c_buf_p = '\0'; /* preserve ace_yytext */ + ace_yy_hold_char = *++ace_yy_c_buf_p; + + return c; + } + + +#ifdef YY_USE_PROTOS +void ace_yyrestart( FILE *input_file ) +#else +void ace_yyrestart( input_file ) +FILE *input_file; +#endif + { + if ( ! ace_yy_current_buffer ) + ace_yy_current_buffer = ace_yy_create_buffer( ace_yyin, YY_BUF_SIZE ); + + ace_yy_init_buffer( ace_yy_current_buffer, input_file ); + ace_yy_load_buffer_state(); + } + + +#ifdef YY_USE_PROTOS +void ace_yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +#else +void ace_yy_switch_to_buffer( new_buffer ) +YY_BUFFER_STATE new_buffer; +#endif + { + if ( ace_yy_current_buffer == new_buffer ) + return; + + if ( ace_yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *ace_yy_c_buf_p = ace_yy_hold_char; + ace_yy_current_buffer->ace_yy_buf_pos = ace_yy_c_buf_p; + ace_yy_current_buffer->ace_yy_n_chars = ace_yy_n_chars; + } + + ace_yy_current_buffer = new_buffer; + ace_yy_load_buffer_state(); + + /* We don't actually know whether we did this switch during + * EOF (ace_yywrap()) processing, but the only time this flag + * is looked at is after ace_yywrap() is called, so it's safe + * to go ahead and always set it. + */ + ace_yy_did_buffer_switch_on_eof = 1; + } + + +#ifdef YY_USE_PROTOS +void ace_yy_load_buffer_state( void ) +#else +void ace_yy_load_buffer_state() +#endif + { + ace_yy_n_chars = ace_yy_current_buffer->ace_yy_n_chars; + ace_yytext_ptr = ace_yy_c_buf_p = ace_yy_current_buffer->ace_yy_buf_pos; + ace_yyin = ace_yy_current_buffer->ace_yy_input_file; + ace_yy_hold_char = *ace_yy_c_buf_p; + } + + +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE ace_yy_create_buffer( FILE *file, int size ) +#else +YY_BUFFER_STATE ace_yy_create_buffer( file, size ) +FILE *file; +int size; +#endif + { + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) ace_yy_flex_alloc( sizeof( struct ace_yy_buffer_state ) ); + + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in ace_yy_create_buffer()" ); + + b->ace_yy_buf_size = size; + + /* ace_yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->ace_yy_ch_buf = (char *) ace_yy_flex_alloc( b->ace_yy_buf_size + 2 ); + + if ( ! b->ace_yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in ace_yy_create_buffer()" ); + + ace_yy_init_buffer( b, file ); + + return b; + } + + +#ifdef YY_USE_PROTOS +void ace_yy_delete_buffer( YY_BUFFER_STATE b ) +#else +void ace_yy_delete_buffer( b ) +YY_BUFFER_STATE b; +#endif + { + if ( b == ace_yy_current_buffer ) + ace_yy_current_buffer = (YY_BUFFER_STATE) 0; + + ace_yy_flex_free( (void *) b->ace_yy_ch_buf ); + ace_yy_flex_free( (void *) b ); + } + + +#ifdef YY_USE_PROTOS +void ace_yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) +#else +void ace_yy_init_buffer( b, file ) +YY_BUFFER_STATE b; +FILE *file; +#endif + { + b->ace_yy_input_file = file; + + /* We put in the '\n' and start reading from [1] so that an + * initial match-at-newline will be true. + */ + + b->ace_yy_ch_buf[0] = '\n'; + b->ace_yy_n_chars = 1; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->ace_yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + b->ace_yy_ch_buf[2] = YY_END_OF_BUFFER_CHAR; + + b->ace_yy_buf_pos = &b->ace_yy_ch_buf[1]; + + b->ace_yy_is_interactive = file ? isatty( fileno(file) ) : 0; + + b->ace_yy_fill_buffer = 1; + + b->ace_yy_buffer_status = YY_BUFFER_NEW; + } + + +#ifdef YY_USE_PROTOS +static void ace_yy_push_state( int new_state ) +#else +static void ace_yy_push_state( new_state ) +int new_state; +#endif + { + if ( ace_yy_start_stack_ptr >= ace_yy_start_stack_depth ) + { + int new_size; + + ace_yy_start_stack_depth += YY_START_STACK_INCR; + new_size = ace_yy_start_stack_depth * sizeof( int ); + + if ( ! ace_yy_start_stack ) + ace_yy_start_stack = (int *) ace_yy_flex_alloc( new_size ); + + else + ace_yy_start_stack = (int *) ace_yy_flex_realloc( + (void *) ace_yy_start_stack, new_size ); + + if ( ! ace_yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + ace_yy_start_stack[ace_yy_start_stack_ptr++] = YY_START; + + BEGIN(new_state); + } + + +static void ace_yy_pop_state() + { + if ( --ace_yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN(ace_yy_start_stack[ace_yy_start_stack_ptr]); + } + + +static int ace_yy_top_state() + { + return ace_yy_start_stack[ace_yy_start_stack_ptr - 1]; + } + + +#ifdef YY_USE_PROTOS +static void ace_yy_fatal_error( const char msg[] ) +#else +static void ace_yy_fatal_error( msg ) +char msg[]; +#endif + { + (void) fprintf( stderr, "%s\n", msg ); + exit( 1 ); + } + + + +/* Redefine ace_yyless() so it works in section 3 code. */ + +#undef ace_yyless +#define ace_yyless(n) \ + do \ + { \ + /* Undo effects of setting up ace_yytext. */ \ + ace_yytext[ace_yyleng] = ace_yy_hold_char; \ + ace_yy_c_buf_p = ace_yytext + n - YY_MORE_ADJ; \ + ace_yy_hold_char = *ace_yy_c_buf_p; \ + *ace_yy_c_buf_p = '\0'; \ + ace_yyleng = n; \ + } \ + while ( 0 ) + + +/* Internal utility routines. */ + +#ifndef ace_yytext_ptr +#ifdef YY_USE_PROTOS +static void ace_yy_flex_strncpy( char *s1, const char *s2, int n ) +#else +static void ace_yy_flex_strncpy( s1, s2, n ) +char *s1; +const char *s2; +int n; +#endif + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } +#endif + + +#ifdef YY_USE_PROTOS +static void *ace_yy_flex_alloc( unsigned int size ) +#else +static void *ace_yy_flex_alloc( size ) +unsigned int size; +#endif + { + return (void *) malloc( size ); + } + +#ifdef YY_USE_PROTOS +static void *ace_yy_flex_realloc( void *ptr, unsigned int size ) +#else +static void *ace_yy_flex_realloc( ptr, size ) +void *ptr; +unsigned int size; +#endif + { + return (void *) realloc( ACE_MALLOC_T (ptr), size ); + } + +#ifdef YY_USE_PROTOS +static void ace_yy_flex_free( void *ptr ) +#else +static void ace_yy_flex_free( ptr ) +void *ptr; +#endif + { + free( ACE_MALLOC_T (ptr) ); + } +# line 69 "Svc_Conf.l" + +int +ace_yywrap (void) +{ + ::fflush (ace_yyin); + ace_yytext[0] = '#'; + ace_yyleng = 0; + return 1; +} diff --git a/ace/Svc_Conf_y.cpp b/ace/Svc_Conf_y.cpp new file mode 100644 index 00000000000..b094b72247d --- /dev/null +++ b/ace/Svc_Conf_y.cpp @@ -0,0 +1,923 @@ +#ifndef lint +// @(#)Svc_Conf_y.cpp 1.1 10/18/96 + +char ace_yysccsid[] = "@(#)yaccpar 1.4 (Berkeley) 02/25/90 \n\ + Modified 5/2/90 by J. Roskind to support graphic debugging modes"; +#endif +#line 2 "Svc_Conf.y" +#define ACE_BUILD_DLL +#include "ace/ARGV.h" +#include "ace/Svc_Conf.h" +#include "ace/Module.h" +#include "ace/Stream.h" + +static ACE_Module_Type *get_module (ACE_Static_Node *str_rec, ACE_Static_Node *svc_type); +static ACE_Module_Type *get_module (ACE_Static_Node *str_rec, const char *svc_name); + +#define YYDEBUG_LEXER_TEXT (ace_yytext[ace_yyleng] = '\0', ace_yytext) +/* Force the pretty debugging code to compile.*/ +#define YYDEBUG 1 + +/* Efficient memory allocation technique.*/ +ACE_Obstack *ace_obstack; + +#line 23 "y.tab.c" +#define ACE_DYNAMIC 257 +#define ACE_STATIC 258 +#define ACE_SUSPEND 259 +#define ACE_RESUME 260 +#define ACE_REMOVE 261 +#define ACE_USTREAM 262 +#define ACE_MODULE_T 263 +#define ACE_STREAM_T 264 +#define ACE_SVC_OBJ_T 265 +#define ACE_ACTIVE 266 +#define ACE_INACTIVE 267 +#define ACE_PATHNAME 268 +#define ACE_IDENT 269 +#define ACE_STRING 270 +#define ACE_LPAREN 271 +#define ACE_RPAREN 272 +#define ACE_LBRACE 273 +#define ACE_RBRACE 274 +#define ACE_STAR 275 +#define ACE_COLON 276 +#define YYERRCODE 256 +short ace_yylhs[] = { -1, + 0, 0, 0, 13, 13, 13, 13, 13, 13, 4, + 5, 6, 7, 8, 10, 17, 10, 14, 14, 18, + 11, 11, 9, 9, 12, 12, 12, 12, 12, 15, + 3, 3, 3, 16, 16, 2, 2, 2, 1, 1, +}; +short ace_yylen[] = { 2, + 2, 2, 0, 1, 1, 1, 1, 1, 1, 3, + 3, 2, 2, 2, 3, 0, 4, 1, 1, 0, + 4, 0, 2, 0, 1, 1, 1, 1, 1, 4, + 1, 1, 0, 3, 5, 2, 2, 2, 1, 0, +}; +short ace_yydefred[] = { 3, + 0, 2, 0, 0, 0, 0, 0, 0, 4, 5, + 6, 7, 8, 9, 1, 0, 0, 0, 12, 13, + 14, 16, 18, 19, 0, 0, 0, 0, 0, 39, + 10, 11, 0, 20, 15, 36, 38, 37, 0, 0, + 17, 24, 0, 31, 32, 30, 0, 0, 21, 25, + 26, 27, 28, 29, 23, 0, 35, +}; +short ace_yydgoto[] = { 1, + 31, 29, 46, 9, 10, 11, 12, 13, 47, 14, + 35, 55, 15, 25, 17, 40, 33, 42, +}; +short ace_yysindex[] = { 0, + -244, 0, -266, -260, -250, -243, -239, -247, 0, 0, + 0, 0, 0, 0, 0, -240, -237, -237, 0, 0, + 0, 0, 0, 0, -242, -241, -235, -233, -236, 0, + 0, 0, -242, 0, 0, 0, 0, 0, -232, -238, + 0, 0, -234, 0, 0, 0, -253, -228, 0, 0, + 0, 0, 0, 0, 0, -227, 0, +}; +short ace_yyrindex[] = { 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 27, 27, 0, 0, + 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, + 0, 0, 46, 0, 0, 0, 0, 0, 0, 20, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, +}; +short ace_yygindex[] = { 0, + 18, 0, 0, -8, -6, -10, -9, 2, 0, 0, + 14, 0, 0, 0, 0, 0, 0, 0, +}; +#define YYTABLESIZE 308 +short ace_yytable[] = { 23, + 34, 24, 16, 3, 4, 5, 6, 7, 18, 3, + 4, 2, 3, 4, 5, 6, 7, 8, 19, 33, + 49, 22, 26, 27, 28, 20, 40, 44, 45, 21, + 34, 39, 30, 36, 48, 32, 52, 53, 50, 37, + 51, 38, 56, 43, 57, 22, 41, 0, 54, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, + 34, 34, 34, 0, 0, 0, 34, 34, 0, 0, + 34, 0, 0, 34, 34, 33, 33, 33, 33, 33, + 33, 33, 40, 40, 40, 40, 40, 40, 40, 33, + 0, 0, 33, 33, 0, 0, 0, 0, 0, 40, + 40, 22, 22, 22, 22, 22, 22, 22, +}; +short ace_yycheck[] = { 8, + 0, 8, 269, 257, 258, 259, 260, 261, 269, 257, + 258, 256, 257, 258, 259, 260, 261, 262, 269, 0, + 274, 269, 263, 264, 265, 269, 0, 266, 267, 269, + 273, 268, 270, 275, 269, 18, 47, 47, 47, 275, + 47, 275, 271, 276, 272, 0, 33, -1, 47, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 256, 257, 258, 259, + 260, 261, 262, -1, -1, -1, 266, 267, -1, -1, + 270, -1, -1, 273, 274, 256, 257, 258, 259, 260, + 261, 262, 256, 257, 258, 259, 260, 261, 262, 270, + -1, -1, 273, 274, -1, -1, -1, -1, -1, 273, + 274, 256, 257, 258, 259, 260, 261, 262, +}; +#define YYFINAL 1 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 276 +#if YYDEBUG +char *ace_yyname[] = { +"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"ACE_DYNAMIC","ACE_STATIC", +"ACE_SUSPEND","ACE_RESUME","ACE_REMOVE","ACE_USTREAM","ACE_MODULE_T", +"ACE_STREAM_T","ACE_SVC_OBJ_T","ACE_ACTIVE","ACE_INACTIVE","ACE_PATHNAME", +"ACE_IDENT","ACE_STRING","ACE_LPAREN","ACE_RPAREN","ACE_LBRACE","ACE_RBRACE", +"ACE_STAR","ACE_COLON", +}; +char *ace_yyrule[] = { +"$accept : svc_config_entries", +"svc_config_entries : svc_config_entries svc_config_entry", +"svc_config_entries : svc_config_entries error", +"svc_config_entries :", +"svc_config_entry : dynamic", +"svc_config_entry : static", +"svc_config_entry : suspend", +"svc_config_entry : resume", +"svc_config_entry : remove", +"svc_config_entry : stream", +"dynamic : ACE_DYNAMIC svc_location parameters_opt", +"static : ACE_STATIC ACE_IDENT parameters_opt", +"suspend : ACE_SUSPEND ACE_IDENT", +"resume : ACE_RESUME ACE_IDENT", +"remove : ACE_REMOVE ACE_IDENT", +"stream : ACE_USTREAM stream_ops stream_modules", +"$$1 :", +"stream : ACE_USTREAM ACE_IDENT $$1 stream_modules", +"stream_ops : dynamic", +"stream_ops : static", +"$$2 :", +"stream_modules : ACE_LBRACE $$2 module_list ACE_RBRACE", +"stream_modules :", +"module_list : module_list module", +"module_list :", +"module : dynamic", +"module : static", +"module : suspend", +"module : resume", +"module : remove", +"svc_location : ACE_IDENT type svc_initializer status", +"status : ACE_ACTIVE", +"status : ACE_INACTIVE", +"status :", +"svc_initializer : ACE_PATHNAME ACE_COLON ACE_IDENT", +"svc_initializer : ACE_PATHNAME ACE_COLON ACE_IDENT ACE_LPAREN ACE_RPAREN", +"type : ACE_MODULE_T ACE_STAR", +"type : ACE_SVC_OBJ_T ACE_STAR", +"type : ACE_STREAM_T ACE_STAR", +"parameters_opt : ACE_STRING", +"parameters_opt :", +}; +#endif +#define ace_yyclearin (ace_yychar=(-1)) +#define ace_yyerrok (ace_yyerrflag=0) +#ifndef YYSTACKSIZE +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 300 +#endif +#endif +int ace_yydebug; +int ace_yynerrs; +int ace_yyerrflag; +int ace_yychar; +short *ace_yyssp; +YYSTYPE *ace_yyvsp; +YYSTYPE ace_yyval; +YYSTYPE ace_yylval; +#define ace_yystacksize YYSTACKSIZE +short ace_yyss[YYSTACKSIZE]; +YYSTYPE ace_yyvs[YYSTACKSIZE]; +#line 241 "Svc_Conf.y" +// Prints the error string to standard output. Cleans up the error +// messages. + +void +ace_yyerror (char *s) +{ + ACE_ERROR ((LM_ERROR, "[error %d] on line %d: %s\n", + ++ace_yyerrno, ace_yylineno, s)); +} + +// Note that SRC_REC represents left context, which is the STREAM * +// record. + +static ACE_Module_Type * +get_module (ACE_Static_Node *str_rec, const char *svc_name) +{ + const ACE_Service_Record *sr = str_rec->record (); + const ACE_Service_Type *type = sr->type (); + ACE_Stream_Type *st = sr == 0 ? 0 : (ACE_Stream_Type *) type; + ACE_Module_Type *mt = st == 0 ? 0 : st->find (svc_name); + + if (sr == 0 || st == 0 || mt == 0) + { + ACE_ERROR ((LM_ERROR, "cannot locate Module_Type %s in STREAM_Type %s\n", + svc_name, str_rec->name ())); + ace_yyerrno++; + } + return mt; +} + +static ACE_Module_Type * +get_module (ACE_Static_Node *str_rec, ACE_Static_Node *svc_type) +{ + const ACE_Service_Record *sr = str_rec->record (); + const ACE_Service_Type *type = sr->type (); + ACE_Stream_Type *st = sr == 0 ? 0 : (ACE_Stream_Type *) type; + const ACE_Service_Record *sv = svc_type->record (); + type = sv->type (); + ACE_Module_Type *mt = (ACE_Module_Type *) type; + + if (sr == 0 || st == 0 || mt == 0) + { + ACE_ERROR ((LM_ERROR, "cannot locate Module_Type %s or STREAM_Type %s\n", + svc_type->name (), str_rec->name ())); + ace_yyerrno++; + } + return mt; +} + +ACE_Service_Type * +ace_create_service_type (const char *name, + int type, + const void *symbol, + unsigned int flags) +{ + ACE_Service_Type *stp = 0; + + // Note, the only place we need to put a case statement. This is + // also the place where we'd put the RTTI tests, if the compiler + // actually supported them! + + switch (type) + { + case ACE_SVC_OBJ_T: + stp = new ACE_Service_Object_Type ((ACE_Service_Object *) symbol, name, flags); + break; + case ACE_MODULE_T: + stp = new ACE_Module_Type ((MT_Module *) symbol, name, flags); + break; + case ACE_STREAM_T: + stp = new ACE_Stream_Type ((MT_Stream *) symbol, name, flags); + break; + default: + ACE_ERROR ((LM_ERROR, "unknown case\n")); + ace_yyerrno++; + break; + } + return stp; +} + +#if defined (DEBUGGING) +// Current line number. +int ace_yylineno = 1; + +// Name given on the command-line to envoke the program. +char *program_name; + +// Main driver program. + +int +main (int argc, char *argv[]) +{ + ace_yyin = stdin; + ace_obstack = new ACE_Obstack; + + // Try to reopen any filename argument to use YYIN. + if (argc > 1 && (ace_yyin = freopen (argv[1], "r", stdin)) == 0) + (void) ::fprintf (stderr, "usage: %s [file]\n", argv[0]), exit (1); + + return ace_yyparse (); +} +#endif /* DEBUGGING */ +#line 342 "y.tab.c" +#define YYABORT goto ace_yyabort +#define YYACCEPT goto ace_yyaccept +#define YYERROR goto ace_yyerrlab +#ifdef YYDEBUG +#ifndef YYDEBUG_LEXER_TEXT /* pointer to the text isolated by the lexer*/ +#define YYDEBUG_LEXER_TEXT "YYDEBUG_LEXER_TEXT not defined" +#endif +#ifndef YYDEBUG_INDENT_STRING +#define YYDEBUG_INDENT_STRING "| " +#endif +#ifndef YYDEBUG_REDUCE_STRING +#define YYDEBUG_REDUCE_STRING "+-------" +#endif +#ifndef YYDEBUG_INDENT +#ifdef __cplusplus +void YYDEBUG_INDENT(int ace_yyindent) +#else +YYDEBUG_INDENT(ace_yyindent) +int ace_yyindent; +#endif +{ + while(ace_yyindent-- > 0) + printf("%s", YYDEBUG_INDENT_STRING); +} +#endif /* YYDEBUG_INDENT */ +#ifndef YYDEBUG_REDUCE +#ifdef __cplusplus +void YYDEBUG_REDUCE(int ace_yynew_state, int ace_yyrule_num, char *ace_yyrule_string, int ace_yynew_indent, int ace_yyrhs_count) +#else +YYDEBUG_REDUCE(ace_yynew_state, ace_yyrule_num, ace_yyrule_string, ace_yynew_indent, ace_yyrhs_count) +int ace_yynew_state; +int ace_yyrule_num; +char * ace_yyrule_string; +int ace_yynew_indent; +int ace_yyrhs_count; +#endif +{ + if (1 < ace_yyrhs_count) + { /* draw the graphics for the reduction */ + YYDEBUG_INDENT(ace_yynew_indent); + while(1 < ace_yyrhs_count--) + printf("%s", YYDEBUG_REDUCE_STRING); + putchar('+'); /* left rotated L would look nice */ + putchar('\n'); + YYDEBUG_INDENT(ace_yynew_indent); + putchar('|'); /* down arrow would look nice */ + putchar('\n'); + } + YYDEBUG_INDENT(ace_yynew_indent); + /* Only print the resulting token name */ + while (*ace_yyrule_string) + putchar(*ace_yyrule_string++); + putchar('\n'); +} +#endif /* YYDEBUG_REDUCE */ +#ifndef YYDEBUG_SHIFT_LEXEME +#ifdef __cplusplus +void YYDEBUG_SHIFT_LEXEME(int ace_yyold_state, int ace_yynew_state, char *ace_yytoken_string, int ace_yynew_indent) +#else +YYDEBUG_SHIFT_LEXEME(ace_yyold_state, ace_yynew_state, ace_yytoken_string, ace_yynew_indent) +int ace_yyold_state; +int ace_yynew_state; +char * ace_yytoken_string; +int ace_yynew_indent; +#endif +{ + YYDEBUG_INDENT(ace_yynew_indent); + printf("%s <-- `%s'\n", ace_yytoken_string, YYDEBUG_LEXER_TEXT); +} +#endif /* YYDEBUG_SHIFT_LEXEME */ +#ifndef YYDEBUG_LOOK_AHEAD +#ifdef __cplusplus +void YYDEBUG_LOOK_AHEAD(int ace_yynew_state, int ace_yytoken_num, char *ace_yytoken_string, int ace_yyindent) +#else +YYDEBUG_LOOK_AHEAD(ace_yynew_state, ace_yytoken_num, ace_yytoken_string, ace_yyindent) +int ace_yynew_state; +int ace_yytoken_num; +char * ace_yytoken_string; +int ace_yyindent; +#endif +{ + YYDEBUG_INDENT(ace_yyindent); + printf(" .... look ahead at %s `%s'\n", + ace_yytoken_string, + (0 == ace_yytoken_num)? "\0": YYDEBUG_LEXER_TEXT); +} +#endif /* YYDEBUG_LOOK_AHEAD */ +#ifndef YYDEBUG_DISCARD_STATE +#ifdef __cplusplus +void YYDEBUG_DISCARD_STATE(int ace_yynew_state, int ace_yyindent) +#else +YYDEBUG_DISCARD_STATE(ace_yynew_state, ace_yyindent) +int ace_yynew_state; +int ace_yyindent; +#endif +{ + if (0 < ace_yyindent) + { /* draw the graphics for the reduction */ + YYDEBUG_INDENT(ace_yyindent-1); + printf("%s", YYDEBUG_REDUCE_STRING); + putchar('+'); /* left rotated L would look nice */ + printf(" discarding state\n"); + YYDEBUG_INDENT(ace_yyindent-1); + putchar('|'); /* down arrow would look nice */ + putchar('\n'); + } + else + { + if (0 == ace_yyindent) + printf("discarding state\n"); + else + printf("no more states to discard: parser will abort\n"); + } +} +#endif /* YYDEBUG_DISCARD_STATE */ +#ifndef YYDEBUG_DISCARD_TOKEN +#ifdef __cplusplus +void YYDEBUG_DISCARD_TOKEN(int ace_yynew_state, int ace_yytoken_num, char *ace_yytoken_string, int ace_yyindent) +#else +YYDEBUG_DISCARD_TOKEN(ace_yynew_state, ace_yytoken_num, ace_yytoken_string, ace_yyindent) +int ace_yynew_state; +int ace_yytoken_num; +char * ace_yytoken_string; +int ace_yyindent; +#endif +{ + YYDEBUG_INDENT(ace_yyindent); + printf("discarding token %s\n", ace_yytoken_string); +} +#endif /* YYDEBUG_DISCARD_TOKEN */ +#ifndef YYDEBUG_SHIFT_ERROR_LEXEME +#ifdef __cplusplus +void YYDEBUG_SHIFT_ERROR_LEXEME(int ace_yyold_state, int ace_yynew_state, int ace_yyindent) +#else +YYDEBUG_SHIFT_ERROR_LEXEME(ace_yyold_state, ace_yynew_state, ace_yyindent) +int ace_yyold_state; +int ace_yynew_state; +int ace_yyindent; +#endif +{ + YYDEBUG_INDENT(ace_yyindent); + printf("error\n"); +} +#endif /* YYDEBUG_SHIFT_ERROR_LEXEME */ +#endif /* YYDEBUG */ +#ifdef __cplusplus +extern "C" { extern char *getenv(const char *); } +#endif +int +ace_yyparse() +{ + register int ace_yym, ace_yyn, ace_yystate; +#if YYDEBUG + register char *ace_yys; +#ifndef __cplusplus + extern char *getenv(); +#endif + + if (ace_yys = ACE_OS::getenv("YYDEBUG")) + { + ace_yyn = *ace_yys; + if (ace_yyn >= '0' && ace_yyn <= '9') + ace_yydebug = ace_yyn - '0'; + } +#endif + + ace_yynerrs = 0; + ace_yyerrflag = 0; + ace_yychar = (-1); + + ace_yyssp = ace_yyss; + ace_yyvsp = ace_yyvs; + *ace_yyssp = ace_yystate = 0; + +ace_yyloop: + if (ace_yyn = ace_yydefred[ace_yystate]) goto ace_yyreduce; + if (ace_yychar < 0) + { + if ((ace_yychar = ace_yylex()) < 0) ace_yychar = 0; +#if YYDEBUG + if (ace_yydebug) + { + ace_yys = 0; + if (ace_yychar <= YYMAXTOKEN) ace_yys = ace_yyname[ace_yychar]; + if (!ace_yys) ace_yys = "illegal-symbol"; + if (5 < ace_yydebug) + printf("ace_yydebug: state %d, reading %d (%s)\n", ace_yystate, + ace_yychar, ace_yys); + else + YYDEBUG_LOOK_AHEAD(ace_yystate, ace_yychar, ace_yys, ace_yyssp-ace_yyss); + } +#endif + } + if ((ace_yyn = ace_yysindex[ace_yystate]) && (ace_yyn += ace_yychar) >= 0 && + ace_yyn <= YYTABLESIZE && ace_yycheck[ace_yyn] == ace_yychar) + { +#if YYDEBUG + if (ace_yydebug) + if (5 < ace_yydebug) + printf("ace_yydebug: state %d, shifting to state %d\n", + ace_yystate, ace_yytable[ace_yyn]); + else + YYDEBUG_SHIFT_LEXEME(ace_yystate, ace_yytable[ace_yyn], ace_yys, ace_yyssp-ace_yyss); +#endif + if (ace_yyssp >= ace_yyss + ace_yystacksize - 1) + { + goto ace_yyoverflow; + } + *++ace_yyssp = ace_yystate = ace_yytable[ace_yyn]; + *++ace_yyvsp = ace_yylval; + ace_yychar = (-1); + if (ace_yyerrflag > 0) --ace_yyerrflag; + goto ace_yyloop; + } + if ((ace_yyn = ace_yyrindex[ace_yystate]) && (ace_yyn += ace_yychar) >= 0 && + ace_yyn <= YYTABLESIZE && ace_yycheck[ace_yyn] == ace_yychar) + { + ace_yyn = ace_yytable[ace_yyn]; + goto ace_yyreduce; + } + if (ace_yyerrflag) goto ace_yyinrecovery; +#ifdef lint + goto ace_yynewerror; +#endif + + ace_yyerror("syntax error"); +#ifdef lint + goto ace_yyerrlab; +#endif + + ++ace_yynerrs; +ace_yyinrecovery: + if (ace_yyerrflag < 3) + { + ace_yyerrflag = 3; + for (;;) + { + if ((ace_yyn = ace_yysindex[*ace_yyssp]) && (ace_yyn += YYERRCODE) >= 0 && + ace_yyn <= YYTABLESIZE && ace_yycheck[ace_yyn] == YYERRCODE) + { +#if YYDEBUG + if (ace_yydebug) + if (5 < ace_yydebug) + printf("ace_yydebug: state %d, error recovery shifting\ + to state %d\n", *ace_yyssp, ace_yytable[ace_yyn]); + else + YYDEBUG_SHIFT_ERROR_LEXEME(*ace_yyssp, ace_yytable[ace_yyn], ace_yyssp-ace_yyss); +#endif + if (ace_yyssp >= ace_yyss + ace_yystacksize - 1) + { + goto ace_yyoverflow; + } + *++ace_yyssp = ace_yystate = ace_yytable[ace_yyn]; + *++ace_yyvsp = ace_yylval; + goto ace_yyloop; + } + else + { +#if YYDEBUG + if (ace_yydebug) + if (5 < ace_yydebug) + printf("ace_yydebug: error recovery discarding state %d\ +", + *ace_yyssp); + else + YYDEBUG_DISCARD_STATE(*ace_yyssp, ace_yyssp-ace_yyss-1); +#endif + if (ace_yyssp <= ace_yyss) goto ace_yyabort; + --ace_yyssp; + --ace_yyvsp; + } + } + } + else + { + if (ace_yychar == 0) goto ace_yyabort; +#if YYDEBUG + if (ace_yydebug) + { + ace_yys = 0; + if (ace_yychar <= YYMAXTOKEN) ace_yys = ace_yyname[ace_yychar]; + if (!ace_yys) ace_yys = "illegal-symbol"; + if (5 < ace_yydebug) + printf("ace_yydebug: state %d, error recovery discards token %d (%s)\n", + ace_yystate, ace_yychar, ace_yys); + else + YYDEBUG_DISCARD_TOKEN(ace_yystate, ace_yychar, ace_yys, ace_yyssp-ace_yyss); + } +#endif + ace_yychar = (-1); + goto ace_yyloop; + } +ace_yyreduce: + ace_yym = ace_yylen[ace_yyn]; + ace_yyval = ace_yyvsp[1-ace_yym]; +#if YYDEBUG + if (ace_yydebug) + if (5 < ace_yydebug) + printf("ace_yydebug: state %d, reducing by rule %d (%s)\n", + ace_yystate, ace_yyn, ace_yyrule[ace_yyn]); + else + YYDEBUG_REDUCE(ace_yystate, ace_yyn, ace_yyrule[ace_yyn], ace_yyssp-ace_yyss-ace_yym, ace_yym); +#endif + switch (ace_yyn) + { +case 1: +#line 38 "Svc_Conf.y" +{ + ace_yyvsp[0].parse_node_->apply (); delete ace_yyvsp[0].parse_node_; ace_obstack->release (); + } +break; +case 2: +#line 42 "Svc_Conf.y" +{ + ace_obstack->release (); + } +break; +case 10: +#line 59 "Svc_Conf.y" +{ + ace_yyval.parse_node_ = new ACE_Dynamic_Node (ace_yyvsp[-1].svc_record_, ace_yyvsp[0].ident_); + } +break; +case 11: +#line 66 "Svc_Conf.y" +{ + ace_yyval.parse_node_ = new ACE_Static_Node (ace_yyvsp[-1].ident_, ace_yyvsp[0].ident_); + } +break; +case 12: +#line 73 "Svc_Conf.y" +{ + ace_yyval.parse_node_ = new ACE_Suspend_Node (ace_yyvsp[0].ident_); + } +break; +case 13: +#line 80 "Svc_Conf.y" +{ + ace_yyval.parse_node_ = new ACE_Resume_Node (ace_yyvsp[0].ident_); + } +break; +case 14: +#line 87 "Svc_Conf.y" +{ + ace_yyval.parse_node_ = new ACE_Remove_Node (ace_yyvsp[0].ident_); + } +break; +case 15: +#line 94 "Svc_Conf.y" +{ + ace_yyval.parse_node_ = new ACE_Stream_Node (ace_yyvsp[-1].ACE_Static_Node_, ace_yyvsp[0].parse_node_); + } +break; +case 16: +#line 97 "Svc_Conf.y" +{ ace_yyval.ACE_Static_Node_ = new ACE_Static_Node (ace_yyvsp[0].ident_); } +break; +case 17: +#line 98 "Svc_Conf.y" +{ + ace_yyval.parse_node_ = new ACE_Dummy_Node (ace_yyvsp[-1].ACE_Static_Node_, ace_yyvsp[0].parse_node_); + } +break; +case 18: +#line 105 "Svc_Conf.y" +{ + } +break; +case 19: +#line 108 "Svc_Conf.y" +{ + } +break; +case 20: +#line 114 "Svc_Conf.y" +{ + /* Initialize left context...*/ + ace_yyval.ACE_Static_Node_ = ace_yyvsp[-1].ACE_Static_Node_; + } +break; +case 21: +#line 119 "Svc_Conf.y" +{ + ace_yyval.parse_node_ = ace_yyvsp[-1].parse_node_; + } +break; +case 22: +#line 122 "Svc_Conf.y" +{ ace_yyval.parse_node_ = 0; } +break; +case 23: +#line 126 "Svc_Conf.y" +{ ace_yyvsp[0].parse_node_->link (ace_yyvsp[-1].parse_node_); ace_yyval.parse_node_ = ace_yyvsp[0].parse_node_; } +break; +case 24: +#line 127 "Svc_Conf.y" +{ ace_yyval.parse_node_ = 0; } +break; +case 25: +#line 132 "Svc_Conf.y" +{ + ACE_ARGV args (ace_yyvsp[0].ACE_Static_Node_->parameters ()); + ACE_Module_Type *mt = get_module (ace_yyvsp[-2].ACE_Static_Node_, ace_yyvsp[0].ACE_Static_Node_); + + if (::strcmp (ace_yyvsp[0].ACE_Static_Node_->name (), + ((MT_Module *) mt->object ())->name ()) != 0) + ACE_ERROR ((LM_ERROR, "warning, service name %s is different from Module name %s\n", + ace_yyvsp[0].ACE_Static_Node_->name (), ((MT_Module *) mt->object ())->name ())); + + if (mt->init (args.argc (), args.argv ()) == -1 + || ((ACE_Stream_Type *) (ace_yyvsp[-2].ACE_Static_Node_)->record ()->type ())->push (mt) == -1) + { + ACE_ERROR ((LM_ERROR, "dynamic initialization failed for Module %s\n", + ace_yyvsp[0].ACE_Static_Node_->name ())); + ace_yyerrno++; + } + } +break; +case 26: +#line 150 "Svc_Conf.y" +{ + ACE_Module_Type *mt = get_module (ace_yyvsp[-2].ACE_Static_Node_, ace_yyvsp[0].ACE_Static_Node_->name ()); + if (::strcmp (ace_yyvsp[0].ACE_Static_Node_->name (), + ((MT_Module *) mt->object ())->name ()) != 0) + ACE_ERROR ((LM_ERROR, "warning, service name %s is different from Module name %s\n", + ace_yyvsp[0].ACE_Static_Node_->name (), ((MT_Module *) mt->object ())->name ())); + if (((ACE_Stream_Type *) (ace_yyvsp[-2].ACE_Static_Node_)->record ()->type ())->push (mt) == -1) + ace_yyerrno++; + } +break; +case 27: +#line 160 "Svc_Conf.y" +{ + ACE_Module_Type *mt = get_module (ace_yyvsp[-2].ACE_Static_Node_, ace_yyvsp[0].ACE_Static_Node_->name ()); + if (mt != 0) + mt->suspend (); + } +break; +case 28: +#line 166 "Svc_Conf.y" +{ + ACE_Module_Type *mt = get_module (ace_yyvsp[-2].ACE_Static_Node_, ace_yyvsp[0].ACE_Static_Node_->name ()); + if (mt != 0) + mt->resume (); + } +break; +case 29: +#line 172 "Svc_Conf.y" +{ + ACE_Module_Type *mt = get_module (ace_yyvsp[-2].ACE_Static_Node_, ace_yyvsp[0].ACE_Static_Node_->name ()); + if (mt != 0 + && ((ACE_Stream_Type *) (ace_yyvsp[-2].ACE_Static_Node_)->record ()->type ())->remove (mt) == -1) + { + ACE_ERROR ((LM_ERROR, "cannot remove Module_Type %s from STREAM_Type %s\n", + ace_yyvsp[0].ACE_Static_Node_->name (), (ace_yyvsp[-2].ACE_Static_Node_)->name ())); + ace_yyerrno++; + } + } +break; +case 30: +#line 186 "Svc_Conf.y" +{ + unsigned int flags + = ACE_Service_Type::DELETE_THIS | (ace_yyvsp[-1].location_node_->dispose () == 0 ? 0 : ACE_Service_Type::DELETE_OBJ); + ACE_Service_Type *stp = ace_create_service_type (ace_yyvsp[-3].ident_, ace_yyvsp[-2].type_, ace_yyvsp[-1].location_node_->symbol (), flags); + ace_yyval.svc_record_ = new ACE_Service_Record (ace_yyvsp[-3].ident_, stp, ace_yyvsp[-1].location_node_->handle (), ace_yyvsp[0].type_); + } +break; +case 31: +#line 196 "Svc_Conf.y" +{ + ace_yyval.type_ = 1; + } +break; +case 32: +#line 200 "Svc_Conf.y" +{ + ace_yyval.type_ = 0; + } +break; +case 33: +#line 204 "Svc_Conf.y" +{ + ace_yyval.type_ = 1; + } +break; +case 34: +#line 211 "Svc_Conf.y" +{ + ace_yyval.location_node_ = new ACE_Object_Node (ace_yyvsp[-2].ident_, ace_yyvsp[0].ident_); + } +break; +case 35: +#line 215 "Svc_Conf.y" +{ + ace_yyval.location_node_ = new ACE_Function_Node (ace_yyvsp[-4].ident_, ace_yyvsp[-2].ident_); + } +break; +case 36: +#line 222 "Svc_Conf.y" +{ + ace_yyval.type_ = ACE_MODULE_T; + } +break; +case 37: +#line 226 "Svc_Conf.y" +{ + ace_yyval.type_ = ACE_SVC_OBJ_T; + } +break; +case 38: +#line 230 "Svc_Conf.y" +{ + ace_yyval.type_ = ACE_STREAM_T; + } +break; +case 40: +#line 237 "Svc_Conf.y" +{ ace_yyval.ident_ = 0; } +break; +#line 862 "y.tab.c" + } + ace_yyssp -= ace_yym; + ace_yystate = *ace_yyssp; + ace_yyvsp -= ace_yym; + ace_yym = ace_yylhs[ace_yyn]; + if (ace_yystate == 0 && ace_yym == 0) + { +#ifdef YYDEBUG + if (5 < ace_yydebug) + printf("ace_yydebug: after reduction, shifting from state 0 to\ + state %d\n", YYFINAL); +#endif + ace_yystate = YYFINAL; + *++ace_yyssp = YYFINAL; + *++ace_yyvsp = ace_yyval; + if (ace_yychar < 0) + { + if ((ace_yychar = ace_yylex()) < 0) ace_yychar = 0; +#if YYDEBUG + if (ace_yydebug) + { + ace_yys = 0; + if (ace_yychar <= YYMAXTOKEN) ace_yys = ace_yyname[ace_yychar]; + if (!ace_yys) ace_yys = "illegal-symbol"; + if (5 < ace_yydebug) + printf("ace_yydebug: state %d, reading %d (%s)\n", + YYFINAL, ace_yychar, ace_yys); + else + YYDEBUG_LOOK_AHEAD(YYFINAL, ace_yychar, ace_yys, ace_yyssp-ace_yyss); + } +#endif + } + if (ace_yychar == 0) goto ace_yyaccept; + goto ace_yyloop; + } + if ((ace_yyn = ace_yygindex[ace_yym]) && (ace_yyn += ace_yystate) >= 0 && + ace_yyn <= YYTABLESIZE && ace_yycheck[ace_yyn] == ace_yystate) + ace_yystate = ace_yytable[ace_yyn]; + else + ace_yystate = ace_yydgoto[ace_yym]; +#ifdef YYDEBUG + if (5 < ace_yydebug) + printf("ace_yydebug: after reduction, shifting from state %d \ +to state %d\n", *ace_yyssp, ace_yystate); +#endif + if (ace_yyssp >= ace_yyss + ace_yystacksize - 1) + { + goto ace_yyoverflow; + } + *++ace_yyssp = ace_yystate; + *++ace_yyvsp = ace_yyval; + goto ace_yyloop; +ace_yyoverflow: + ace_yyerror("yacc stack overflow"); +ace_yyabort: + return (1); +ace_yyaccept: + return (0); +} diff --git a/ace/Svc_Handler.cpp b/ace/Svc_Handler.cpp new file mode 100644 index 00000000000..499fb44ab56 --- /dev/null +++ b/ace/Svc_Handler.cpp @@ -0,0 +1,282 @@ +// Svc_Handler.cpp +// $Id$ + +#if !defined (ACE_SVC_HANDLER_C) +#define ACE_SVC_HANDLER_C + +#define ACE_BUILD_DLL +#include "ace/Svc_Handler.h" +#include "ace/Log_Msg.h" +#include "ace/Dynamic.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Svc_Handler.i" +#endif /* __ACE_INLINE__ */ + +#define PR_ST_1 ACE_PEER_STREAM_1 +#define PR_ST_2 ACE_PEER_STREAM_2 + +#if defined (ACE_MT_SAFE) && !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) +// Lock the creation of the Singleton. +template +ACE_Thread_Mutex ACE_Svc_Handler::ace_svc_handler_lock_; +#endif /* defined (ACE_MT_SAFE) && !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */ + +template ACE_Dynamic * +ACE_Svc_Handler::instance (void) +{ + ACE_TRACE ("ACE_Svc_Handler::allocated"); + +#if defined (ACE_MT_SAFE) && defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + // Lock the creation of the Singleton. This should be inside of + // ACE_Svc_Handler, but GNU G++ is too lame to handle this... + static ACE_Thread_Mutex ace_svc_handler_lock_; +#endif /* defined (ACE_MT_SAFE) && defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */ + + static ACE_TSS_TYPE (ACE_Dynamic) *instance_; + // Determines if we were dynamically allocated. Note that this + // should be inside of ACE_Svc_Handler, but G++ is too lame to + // support this... + + // Implement the Double Check pattern. + + if (instance_ == 0) + { + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, ace_svc_handler_lock_, 0)); + + if (instance_ == 0) + ACE_NEW_RETURN (instance_, ACE_TSS_TYPE (ACE_Dynamic), 0); + } + + return ACE_TSS_GET (instance_, ACE_Dynamic); +} + +template void * +ACE_Svc_Handler::operator new (size_t n) +{ + ACE_TRACE ("ACE_Svc_Handler::operator new"); + // Allocate the memory and store it (usually in thread-specific + // storage, depending on config flags). + return ACE_Svc_Handler::instance ()->set (::new char[n]); +} + +template void +ACE_Svc_Handler::destroy (void) +{ + ACE_TRACE ("ACE_Svc_Handler::destroy"); + + // Only delete ourselves if we've been allocated dynamically. + if (this->dynamic_) + // Will call the destructor, which automatically calls . + // Note that if we are *not* allocated dynamically then the + // destructor will call automatically when it gets run + // during cleanup. + delete this; +} + +template void +ACE_Svc_Handler::operator delete (void *obj) +{ + ACE_TRACE ("ACE_Svc_Handler::delete"); + ::delete obj; +} + +/* Default constructor */ + +template +ACE_Svc_Handler::ACE_Svc_Handler (ACE_Thread_Manager *tm, + ACE_Message_Queue *mq, + ACE_Reactor *reactor) + : ACE_Task (tm, mq), + reactor_ (reactor) +{ + ACE_TRACE ("ACE_Svc_Handler::ACE_Svc_Handler"); + + // This clever idiom transparently checks if we were allocated + // dynamically. This information is used by the method to + // decide if we need to delete ... The idiom is based on a + // paper by Michael van Rooyen (mrooyen@cellnet.co.uk) that appeared + // in the April '96 issue of the C++ Report. We've spruced it up to + // work correctly in multi-threaded programs by using our ACE_TSS + // class. + this->dynamic_ = ACE_Svc_Handler::instance()->is_dynamic (this); +} + +// Default behavior for a ACE_Svc_Handler object is to be registered with +// the ACE_Reactor (thereby ensuring single threading). + +template int +ACE_Svc_Handler::open (void *) +{ + ACE_TRACE ("ACE_Svc_Handler::open"); +#if defined (DEBUGGING) + char buf[BUFSIZ]; + ACE_PEER_STREAM_ADDR client_addr; + + if (this->peer_.get_remote_addr (client_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "get_remote_addr"), -1); + + if (client_addr.addr_to_string (buf, sizeof buf) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", + "can't obtain peer's address"), -1); + + ACE_DEBUG ((LM_DEBUG, "connected to %s on fd %d\n", + buf, this->peer_.get_handle ())); +#endif /* DEBUGGING */ + if (this->reactor_ + && this->reactor_->register_handler (this, + ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p", + "unable to register client handler"), -1); + return 0; +} + +// Perform termination activities. + +template void +ACE_Svc_Handler::shutdown (void) +{ + ACE_TRACE ("ACE_Svc_Handler::shutdown"); + // Deregister this handler with the ACE_Reactor. + if (this->reactor_) + { + ACE_Reactor_Mask mask = ACE_Event_Handler::WRITE_MASK | + ACE_Event_Handler::READ_MASK | + ACE_Event_Handler::DONT_CALL; + + // Remove self from reactor. + this->reactor_->remove_handler (this, mask); + + // Make sure there are no timers. + this->reactor_->cancel_timer( this ); + + // Note the fact that the Reactor has shut down. + this->reactor_ = 0; + } + + this->peer ().close (); +} + +template ACE_Reactor * +ACE_Svc_Handler::reactor (void) const +{ + ACE_TRACE ("ACE_Svc_Handler::reactor"); + return this->reactor_; +} + +template void +ACE_Svc_Handler::reactor (ACE_Reactor *r) +{ + ACE_TRACE ("ACE_Svc_Handler::reactor"); + this->reactor_ = r; +} + +template void +ACE_Svc_Handler::dump (void) const +{ + ACE_TRACE ("ACE_Svc_Handler::dump"); +} + +template ACE_INLINE ACE_PEER_STREAM & +ACE_Svc_Handler::peer (void) const +{ + ACE_TRACE ("ACE_Svc_Handler::peer"); + return (PEER_STREAM &) this->peer_; +} + +// Extract the underlying PEER_STREAM (e.g., used by ACE_Connector and +// ACE_Acceptor). + +template +ACE_Svc_Handler::operator ACE_PEER_STREAM &() +{ + return this->peer_; +} + +/* Extract the underlying I/O descriptor. */ + +template ACE_HANDLE +ACE_Svc_Handler::get_handle (void) const +{ + ACE_TRACE ("ACE_Svc_Handler::get_handle"); + return this->peer_.get_handle (); +} + +/* Set the underlying I/O descriptor. */ + +template void +ACE_Svc_Handler::set_handle (ACE_HANDLE h) +{ + ACE_TRACE ("ACE_Svc_Handler::set_handle"); + this->peer_.set_handle (h); +} + +template +ACE_Svc_Handler::~ACE_Svc_Handler (void) +{ + ACE_TRACE ("ACE_Svc_Handler::~ACE_Svc_Handler"); + this->shutdown (); +} + +template int +ACE_Svc_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + ACE_TRACE ("ACE_Svc_Handler::handle_close"); + + this->destroy (); + return 0; +} + +template int +ACE_Svc_Handler::handle_timeout (const ACE_Time_Value &, + const void *) +{ + ACE_TRACE ("ACE_Svc_Handler::handle_timeout"); + return this->handle_close (); +} + +template int +ACE_Svc_Handler::close (unsigned long) +{ + ACE_TRACE ("ACE_Svc_Handler::close"); + return this->handle_close (); +} + +template int +ACE_Svc_Handler::svc (void) +{ + ACE_TRACE ("ACE_Svc_Handler::svc"); + return -1; +} + +template int +ACE_Svc_Handler::put (ACE_Message_Block *, + ACE_Time_Value *) +{ + ACE_TRACE ("ACE_Svc_Handler::put"); + return -1; +} + +template int +ACE_Svc_Handler::init (int, char *[]) +{ + ACE_TRACE ("ACE_Svc_Handler::init"); + return -1; +} + +template int +ACE_Svc_Handler::fini (void) +{ + ACE_TRACE ("ACE_Svc_Handler::fini"); + return -1; +} + +template int +ACE_Svc_Handler::info (char **, size_t) const +{ + ACE_TRACE ("ACE_Svc_Handler::info"); + return -1; +} +#undef PR_ST_1 +#undef PR_ST_2 +#endif /* ACE_SVC_HANDLER_C */ diff --git a/ace/Svc_Handler.h b/ace/Svc_Handler.h new file mode 100644 index 00000000000..2862d1f2ad0 --- /dev/null +++ b/ace/Svc_Handler.h @@ -0,0 +1,178 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Svc_Handler.h +// +// = AUTHOR +// Doug Schmidt and Irfan Pyrarli. +// +// ============================================================================ + +#if !defined (ACE_SVC_HANDLER_H) +#define ACE_SVC_HANDLER_H + +#include "ace/Synch_Options.h" +#include "ace/Task.h" +#include "ace/Service_Config.h" +#include "ace/Synch_T.h" + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) +#define ACE_PEER_STREAM_1 class PEER_STREAM +#define ACE_PEER_STREAM_2 PEER_STREAM +#define ACE_PEER_STREAM PEER_STREAM +#define ACE_PEER_STREAM_ADDR PEER_STREAM::PEER_ADDR +#else +#define ACE_PEER_STREAM_1 class PEER_STREAM, class PEER_ADDR +#define ACE_PEER_STREAM_2 PEER_STREAM, PEER_ADDR +#define ACE_PEER_STREAM PEER_STREAM +#define ACE_PEER_STREAM_ADDR PEER_ADDR +#endif /* ACE_TEMPLATE_TYPEDEFS */ + +// Forward decls. +class ACE_Dynamic; + +template +class ACE_Svc_Handler : public ACE_Task + // = TITLE + // Defines the interface for a service that exchanges data with + // its connected peer. + // + // = DESCRIPTION + // This class provides a well-defined interface that the + // Acceptor and Connector pattern factories use as their target. + // Typically, client applications will subclass ACE_Svc_Handler + // and do all the interesting work in the subclass. One thing + // that the ACE_Svc_Handler does contain is a PEER_STREAM + // endpoint that is initialized by an ACE_Acceptor or + // ACE_Connector when a connection is established successfully. + // This endpoint is used to exchange data between a + // ACE_Svc_Handler and the peer it is connected with. +{ +public: + // = Initialization and termination methods. + ACE_Svc_Handler (ACE_Thread_Manager * = 0, + ACE_Message_Queue * = 0, + ACE_Reactor * = ACE_Service_Config::reactor ()); + + virtual ~ACE_Svc_Handler (void); + + virtual int open (void * = 0); + // Activate the client handler (called by the ACE_Acceptor or + // ACE_Connector). + + virtual int close (u_long flags = 0); + // Object termination hook. + + // = Dynamic linking hooks. + virtual int init (int argc, char *argv[]); + // Default version does no work and returns -1. Must be overloaded + // by application developer to do anything meaningful. + + virtual int fini (void); + // Default version does no work and returns -1. Must be overloaded + // by application developer to do anything meaningful. + + virtual int info (char **info_string, size_t length) const; + // Default version does no work and returns -1. Must be overloaded + // by application developer to do anything meaningful. + + // = Demultiplexing hooks. + + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::RWE_MASK); + // Perform termination activities on the SVC_HANDLER. The default + // behavior is to close down the (to avoid descriptor leaks) + // and to delete this (to avoid memory leaks)! If you don't want + // this behavior make sure you override this method... + + virtual int handle_timeout (const ACE_Time_Value &time, + const void *); + // Default behavior when timeouts occur is to close down the + // by calling . + + virtual ACE_HANDLE get_handle (void) const; + // Get the underlying handle associated with the . + + virtual void set_handle (ACE_HANDLE); + // Set the underlying handle associated with the . + + ACE_PEER_STREAM &peer (void) const; + // Returns the underlying PEER_STREAM + + operator ACE_PEER_STREAM &(); + // Returns the underlying PEER_STREAM (used by + // ACE_Acceptor::accept() and ACE_Connector::connect() factories). + + virtual int put (ACE_Message_Block *, ACE_Time_Value *tv = 0); + // Provide a default implementation to simplify ancestors... + + ACE_Reactor *reactor (void) const; + // Get the underlying Reactor *. + + void reactor (ACE_Reactor *); + // Set the underlying Reactor *. + + virtual void destroy (void); + // Call this instead of to free up dynamically allocated + // . This method knows whether or not the object was + // allocated dynamically, and can act accordingly (i.e., deleting it + // if it was allocated dynamically, otherwise ignoring it). + + void *operator new (size_t n); + // Overloaded new operator. This is used to unobtrusively detect + // when a Svc_Handler is allocated dynamically. + + void dump (void) const; + // Dump the state of an object. + +public: + + void operator delete (void *); + // This really should be private so that users are forced to call + // destroy(). + + virtual int svc (void); + // Provide a default implementation to simplify ancestors... + +private: + void shutdown (void); + // Close down the descriptor + + ACE_PEER_STREAM peer_; + // Maintain connection with client. + + ACE_Reactor *reactor_; + // Event demultiplex associated with this object. + + static ACE_Dynamic *instance (void); + // Point of access to the singleton. + + char dynamic_; + // Have we been dynamically created? + +#if defined (ACE_MT_SAFE) && !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + static ACE_Thread_Mutex ace_svc_handler_lock_; + // Lock the creation of the Singleton. +#endif /* defined (ACE_MT_SAFE) && !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */ +}; + +#if defined (__ACE_INLINE__) +#include "ace/Svc_Handler.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Svc_Handler.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Svc_Handler.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_SVC_HANDLER_H */ diff --git a/ace/Svc_Handler.i b/ace/Svc_Handler.i new file mode 100644 index 00000000000..f138a9fd2b7 --- /dev/null +++ b/ace/Svc_Handler.i @@ -0,0 +1,5 @@ +/* -*- C++ -*- */ +// $Id$ + +// Svc_Handler.i + diff --git a/ace/Synch.cpp b/ace/Synch.cpp new file mode 100644 index 00000000000..7201a4bb933 --- /dev/null +++ b/ace/Synch.cpp @@ -0,0 +1,839 @@ +// Synch.cpp +// $Id$ + +#if !defined (ACE_SYNCH_C) +#define ACE_SYNCH_C + +#define ACE_BUILD_DLL +#include "ace/Thread.h" +#include "ace/Synch.h" +#include "ace/Log_Msg.h" +#include "ace/Time_Value.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Synch.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Null_Mutex) +ACE_ALLOC_HOOK_DEFINE(ACE_File_Lock) +ACE_ALLOC_HOOK_DEFINE(ACE_RW_Process_Mutex) + +ACE_ALLOC_HOOK_DEFINE(ACE_Process_Mutex) + +void +ACE_Process_Mutex::dump (void) const +{ +// ACE_TRACE ("ACE_Process_Mutex::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->lock_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Process_Mutex::ACE_Process_Mutex (LPCTSTR name, void *arg) +#if defined (ACE_WIN32) || defined (ACE_HAS_POSIX_SEM) + : lock_ (USYNC_PROCESS, name, arg) +#else + : lock_ (name) +#endif /* ACE_WIN32 || ACE_HAS_POSIX_SEM */ +{ +// ACE_TRACE ("ACE_Process_Mutex::ACE_Process_Mutex"); +} + +ACE_Process_Mutex::~ACE_Process_Mutex (void) +{ +} + +// Explicitly destroy the mutex. +int +ACE_Process_Mutex::remove (void) +{ + return this->lock_.remove (); +} + +// Acquire lock ownership (wait on priority queue if necessary). +int +ACE_Process_Mutex::acquire (void) +{ + return this->lock_.acquire (); +} + +// Conditionally acquire lock (i.e., don't wait on queue). +int +ACE_Process_Mutex::tryacquire (void) +{ + return this->lock_.tryacquire (); +} + +// Release lock and unblock a thread at head of priority queue. +int +ACE_Process_Mutex::release (void) +{ + return this->lock_.release (); +} + +// Acquire lock ownership (wait on priority queue if necessary). +int +ACE_Process_Mutex::acquire_read (void) +{ + return this->lock_.acquire_read (); +} + +// Acquire lock ownership (wait on priority queue if necessary). +int ACE_Process_Mutex::acquire_write (void) +{ + return this->lock_.acquire_write (); +} + +// Conditionally acquire a lock (i.e., won't block). +int +ACE_Process_Mutex::tryacquire_read (void) +{ + return this->lock_.tryacquire_read (); +} + +// Conditionally acquire a lock (i.e., won't block). +int +ACE_Process_Mutex::tryacquire_write (void) +{ + return this->lock_.tryacquire_write (); +} + +ACE_RW_Process_Mutex::ACE_RW_Process_Mutex (LPCTSTR name, + void *arg) + : ACE_Process_Mutex (name, arg) +{ +// ACE_TRACE ("ACE_RW_Process_Mutex::ACE_RW_Process_Mutex"); +} + +void +ACE_RW_Process_Mutex::dump (void) const +{ +// ACE_TRACE ("ACE_RW_Process_Mutex::dump"); + ACE_Process_Mutex::dump (); +} + +void +ACE_File_Lock::dump (void) const +{ +// ACE_TRACE ("ACE_File_Lock::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->lock_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_File_Lock::ACE_File_Lock (ACE_HANDLE h) +{ +// ACE_TRACE ("ACE_File_Lock::ACE_File_Lock"); + if (ACE_OS::flock_init (&this->lock_) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_File_Lock::ACE_File_Lock")); + this->set_handle (h); +} + +ACE_File_Lock::ACE_File_Lock (const char *name, + int flags, + mode_t perms) +{ +// ACE_TRACE ("ACE_File_Lock::ACE_File_Lock"); + + if (ACE_OS::flock_init (&this->lock_, flags, name, perms) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_File_Lock::ACE_File_Lock")); +} + +ACE_File_Lock::~ACE_File_Lock (void) +{ +// ACE_TRACE ("ACE_File_Lock::~ACE_File_Lock"); + if (this->remove () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_File_Lock::~ACE_File_Lock")); +} + +#if defined (ACE_HAS_THREADS) + +ACE_Event::ACE_Event (int manual_reset, + int initial_state, + int type, + LPCTSTR name, + void *arg) +{ + if (ACE_OS::event_init (&this->handle_, + manual_reset, + initial_state, + type, + name, + arg) != 0) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Event::ACE_Event")); +} + +ACE_Event::~ACE_Event (void) +{ + if (this->remove () != 0) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Event::~ACE_Event")); +} + +int +ACE_Event::remove (void) +{ + return ACE_OS::event_destroy (&this->handle_); +} + +ACE_event_t +ACE_Event::handle (void) const +{ + return this->handle_; +} + +int +ACE_Event::wait (void) +{ + return ACE_OS::event_wait (&this->handle_); +} + +int +ACE_Event::wait (const ACE_Time_Value *abstime) +{ + return ACE_OS::event_timedwait (&this->handle_, + (ACE_Time_Value *) abstime); +} + +int +ACE_Event::signal (void) +{ + return ACE_OS::event_signal (&this->handle_); +} + +int +ACE_Event::pulse (void) +{ + return ACE_OS::event_pulse (&this->handle_); +} + +int +ACE_Event::reset (void) +{ + return ACE_OS::event_reset (&this->handle_); +} + +void +ACE_Event::dump (void) const +{ + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Manual_Event::ACE_Manual_Event (int initial_state, + int type, + LPCTSTR name, + void *arg) + : ACE_Event (1, + initial_state, + type, + name, + arg) +{ +} + +void +ACE_Manual_Event::dump (void) const +{ + ACE_Event::dump (); +} + +ACE_Auto_Event::ACE_Auto_Event (int initial_state, + int type, + LPCTSTR name, + void *arg) + : ACE_Event (0, + initial_state, + type, + name, + arg) +{ +} + +void +ACE_Auto_Event::dump (void) const +{ + ACE_Event::dump (); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Recursive_Thread_Mutex) +ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Mutex_Guard) +ACE_ALLOC_HOOK_DEFINE(ACE_Mutex) +ACE_ALLOC_HOOK_DEFINE(ACE_Semaphore) + +void +ACE_Semaphore::dump (void) const +{ +// ACE_TRACE ("ACE_Semaphore::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +void +ACE_Thread_Semaphore::dump (void) const +{ +// ACE_TRACE ("ACE_Thread_Semaphore::dump"); + + ACE_Semaphore::dump (); +} + +ACE_Semaphore::ACE_Semaphore (u_int count, + int type, + LPCTSTR name, + void *arg, + int max) +{ +// ACE_TRACE ("ACE_Semaphore::ACE_Semaphore"); + if (ACE_OS::sema_init (&this->semaphore_, count, type, + name, arg, max) != 0) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Semaphore::ACE_Semaphore")); +} + +ACE_Thread_Semaphore::ACE_Thread_Semaphore (u_int count, + LPCTSTR name, + void *arg, + int max) + : ACE_Semaphore (count, USYNC_THREAD, name, arg, max) +{ +// ACE_TRACE ("ACE_Thread_Semaphore::ACE_Thread_Semaphore"); +} + +void +ACE_Process_Semaphore::dump (void) const +{ +// ACE_TRACE ("ACE_Process_Semaphore::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->lock_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Process_Semaphore::ACE_Process_Semaphore (u_int count, + LPCTSTR name, + void *arg, + int max) +#if defined (ACE_WIN32) || defined (ACE_HAS_POSIX_SEM) + : lock_ (count, USYNC_PROCESS, name, arg, max) +#else + : lock_ (name, ACE_SV_Semaphore_Complex::ACE_CREATE, count) +#endif /* ACE_WIN32 || ACE_HAS_POSIX_SEM */ +{ +// ACE_TRACE ("ACE_Process_Semaphore::ACE_Process_Semaphore"); +} + +ACE_Process_Semaphore::~ACE_Process_Semaphore (void) +{ +// ACE_TRACE ("ACE_Process_Semaphore::~ACE_Process_Semaphore"); +} + +// Explicitly destroy the semaphore. + +int +ACE_Process_Semaphore::remove (void) +{ +// ACE_TRACE ("ACE_Process_Semaphore::remove"); + return this->lock_.remove (); +} + +// Block the thread until the semaphore count becomes +// greater than 0, then decrement it. + +int +ACE_Process_Semaphore::acquire (void) +{ +// ACE_TRACE ("ACE_Process_Semaphore::acquire"); + return this->lock_.acquire (); +} + +// Conditionally decrement the semaphore if count is greater +// than 0 (i.e., won't block). + +int +ACE_Process_Semaphore::tryacquire (void) +{ +// ACE_TRACE ("ACE_Process_Semaphore::tryacquire"); + return this->lock_.tryacquire (); +} + +// Increment the semaphore, potentially unblocking +// a waiting thread. + +int +ACE_Process_Semaphore::release (void) +{ +// ACE_TRACE ("ACE_Process_Semaphore::release"); + return this->lock_.release (); +} + +ACE_Semaphore::~ACE_Semaphore (void) +{ +// ACE_TRACE ("ACE_Semaphore::~ACE_Semaphore"); + this->remove (); +} + +void +ACE_Thread_Mutex_Guard::dump (void) const +{ +// ACE_TRACE ("ACE_Thread_Mutex_Guard::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +void +ACE_Mutex::dump (void) const +{ +// ACE_TRACE ("ACE_Mutex::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Mutex::ACE_Mutex (int type, LPCTSTR name, void *arg) +{ +// ACE_TRACE ("ACE_Mutex::ACE_Mutex"); + + if (ACE_OS::mutex_init (&this->lock_, type, name, arg) != 0) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Mutex::ACE_Mutex")); +} + +ACE_Mutex::~ACE_Mutex (void) +{ +// ACE_TRACE ("ACE_Mutex::~ACE_Mutex"); + if (this->remove () != 0) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Mutex::~ACE_Mutex")); +} + +ACE_thread_t +ACE_Recursive_Thread_Mutex::get_thread_id (void) +{ +// ACE_TRACE ("ACE_Recursive_Thread_Mutex::get_thread_id"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->nesting_mutex_, ACE_OS::NULL_thread); + return this->owner_id_; +} + +int +ACE_Recursive_Thread_Mutex::get_nesting_level (void) +{ +// ACE_TRACE ("ACE_Recursive_Thread_Mutex::get_nesting_level"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->nesting_mutex_, -1); + return this->nesting_level_; +} + +ACE_Recursive_Thread_Mutex::ACE_Recursive_Thread_Mutex (const ACE_Recursive_Thread_Mutex &rm) + : lock_available_ ((ACE_Thread_Mutex &) rm.nesting_mutex_) +{ +} + +ACE_Recursive_Thread_Mutex::ACE_Recursive_Thread_Mutex (LPCTSTR name, + void *arg) + : nesting_level_ (0), + owner_id_ (ACE_OS::NULL_thread), + nesting_mutex_ (name, arg), + lock_available_ (nesting_mutex_, name, arg) +{ +#if defined (ACE_HAS_FSU_PTHREADS) +// Initialize FSU pthreads package. +// If called more than once, pthread_init does nothing +// and so does no harm. + pthread_init (); +#endif // ACE_HAS_FSU_PTHREADS +// ACE_TRACE ("ACE_Recursive_Thread_Mutex::ACE_Recursive_Thread_Mutex"); +} + +ACE_Recursive_Thread_Mutex::~ACE_Recursive_Thread_Mutex (void) +{ +// ACE_TRACE ("ACE_Recursive_Thread_Mutex::~ACE_Recursive_Thread_Mutex"); +} + +int +ACE_Recursive_Thread_Mutex::acquire (void) +{ +// ACE_TRACE ("ACE_Recursive_Thread_Mutex::acquire"); + ACE_thread_t t_id = ACE_Thread::self (); + + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->nesting_mutex_, -1); + + // If there's no contention, just grab the lock immediately. + if (this->nesting_level_ == 0) + { + this->set_thread_id (t_id); + this->nesting_level_ = 1; + } + // If we already own the lock, then increment the nesting level and + // proceed. + else if (ACE_OS::thr_equal (t_id, this->owner_id_)) + this->nesting_level_++; + else + { + // Wait until the nesting level has dropped to zero, + // at which point we can acquire the lock. + while (this->nesting_level_ > 0) + this->lock_available_.wait (); + + // Note that at this point the nesting_mutex_ is held... + + this->set_thread_id (t_id); + this->nesting_level_ = 1; + } + + return 0; +} + +int +ACE_Recursive_Thread_Mutex::release (void) +{ +// ACE_TRACE ("ACE_Recursive_Thread_Mutex::release"); + ACE_thread_t t_id = ACE_Thread::self (); + + // Automatically acquire mutex. + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->nesting_mutex_, -1); + +#if !defined (ACE_NDEBUG) + if (this->nesting_level_ == 0 + || ACE_OS::thr_equal (t_id, this->owner_id_) == 0) + { + errno = EINVAL; + ACE_RETURN (-1); + } +#endif /* ACE_NDEBUG */ + + this->nesting_level_--; + if (this->nesting_level_ == 0) + { + // This may not be strictly necessary, but it does put the mutex + // into a known state... + this->set_thread_id (ACE_OS::NULL_thread); + + // Inform waiters that the lock is free. + this->lock_available_.signal (); + } + return 0; +} + +int +ACE_Recursive_Thread_Mutex::tryacquire (void) +{ +// ACE_TRACE ("ACE_Recursive_Thread_Mutex::tryacquire"); + ACE_thread_t t_id = ACE_Thread::self (); + + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->nesting_mutex_, -1); + + // If there's no contention, just grab the lock immediately. + if (this->nesting_level_ == 0) + { + this->set_thread_id (t_id); + this->nesting_level_ = 1; + } + // If we already own the lock, then increment the nesting level and + // proceed. + else if (ACE_OS::thr_equal (t_id, this->owner_id_)) + this->nesting_level_++; + else + { + errno = EBUSY; + ACE_RETURN (-1); + } + return 0; +} + +void +ACE_Recursive_Thread_Mutex::dump (void) const +{ +// ACE_TRACE ("ACE_Recursive_Thread_Mutex::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->lock_available_.dump (); + this->nesting_mutex_.dump (); + ACE_DEBUG ((LM_DEBUG, "nesting_level_ = %d", this->nesting_level_)); +#if !defined (ACE_HAS_DCETHREADS) && !defined (ACE_HAS_PTHREADS) + ACE_DEBUG ((LM_DEBUG, "\nowner_id_ = %u", this->owner_id_)); +#else + ACE_DEBUG ((LM_DEBUG, "\n")); +#endif /* !ACE_HAS_DCETHREADS */ + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Condition_Thread_Mutex) + +void +ACE_Condition_Thread_Mutex::dump (void) const +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\n")); +#if defined (ACE_WIN32) + ACE_DEBUG ((LM_DEBUG, + "waiters = %d\n", + this->cond_.waiters_)); +#endif /* ACE_WIN32 */ + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex (const ACE_Thread_Mutex &m, + LPCTSTR name, + void *arg) + : mutex_ ((ACE_Thread_Mutex &) m) +{ +#if defined (ACE_HAS_FSU_PTHREADS) +// Initialize FSU pthreads package. +// If called more than once, pthread_init does nothing +// and so does no harm. + pthread_init (); +#endif // ACE_HAS_FSU_PTHREADS + +// ACE_TRACE ("ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex"); + if (ACE_OS::cond_init (&this->cond_, USYNC_THREAD, name, arg) != 0) + ACE_ERROR ((LM_ERROR, "%p\n", + "ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex")); +} + +ACE_Condition_Thread_Mutex::~ACE_Condition_Thread_Mutex (void) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::~ACE_Condition_Thread_Mutex"); + if (this->remove () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Condition_Thread_Mutex::~ACE_Condition_Thread_Mutex")); +} + +// Peform an "alertable" timed wait. If the argument == 0 +// then we do a regular , else we do a timed wait for up to +// using the function. + +int +ACE_Condition_Thread_Mutex::wait (void) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::wait"); + ACE_thread_mutex_t &mutex = (ACE_thread_mutex_t &) this->mutex_.lock (); + + return ACE_OS::cond_wait (&this->cond_, &mutex); +} + +int +ACE_Condition_Thread_Mutex::wait (ACE_Thread_Mutex &mutex, + const ACE_Time_Value *abstime) +{ +// ACE_TRACE ("ACE_Condition::wait"); + if (abstime == 0) + return this->wait (); + else + return ACE_OS::cond_timedwait (&this->cond_, + &mutex.lock_, + (ACE_Time_Value *) abstime); +} + +int +ACE_Condition_Thread_Mutex::wait (const ACE_Time_Value *abstime) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::wait"); + if (abstime == 0) + return this->wait (); + else + return this->wait (this->mutex_, abstime); +} + +int +ACE_Condition_Thread_Mutex::signal (void) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::signal"); + return ACE_OS::cond_signal (&this->cond_); +} + +int +ACE_Condition_Thread_Mutex::broadcast (void) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::broadcast"); + return ACE_OS::cond_broadcast (&this->cond_); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Sub_Barrier) + +void +ACE_Sub_Barrier::dump (void) const +{ +// ACE_TRACE ("ACE_Sub_Barrier::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->barrier_finished_.dump (); + ACE_DEBUG ((LM_DEBUG, "running_threads_ = %d", this->running_threads_)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Sub_Barrier::ACE_Sub_Barrier (u_int count, + ACE_Thread_Mutex &lock, + LPCTSTR name, + void *arg) + : barrier_finished_ (lock, name, arg), + running_threads_ (count) +{ +// ACE_TRACE ("ACE_Sub_Barrier::ACE_Sub_Barrier"); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Barrier) +ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Barrier) +ACE_ALLOC_HOOK_DEFINE(ACE_Process_Barrier) + +void +ACE_Barrier::dump (void) const +{ +// ACE_TRACE ("ACE_Barrier::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->lock_.dump (); + ACE_DEBUG ((LM_DEBUG, "current_generation_ = %d", this->current_generation_)); + ACE_DEBUG ((LM_DEBUG, "\ncount_ = %d", this->count_)); + this->sub_barrier_1_.dump (); + this->sub_barrier_2_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Barrier::ACE_Barrier (u_int count, + LPCTSTR name, + void *arg) + : lock_ (name, arg), + current_generation_ (0), + count_ (count), + sub_barrier_1_ (count, lock_, name, arg), + sub_barrier_2_ (count, lock_, name, arg) +{ +// ACE_TRACE ("ACE_Barrier::ACE_Barrier"); + this->sub_barrier_[0] = &this->sub_barrier_1_; + this->sub_barrier_[1] = &this->sub_barrier_2_; +} + +int +ACE_Barrier::wait (void) +{ +// ACE_TRACE ("ACE_Barrier::wait"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + ACE_Sub_Barrier *sbp = + this->sub_barrier_[this->current_generation_]; + + // Check for shutdown... + if (sbp == 0) + return -1; + + if (sbp->running_threads_ == 1) + { + // We're the last running thread, so swap generations and tell + // all the threads waiting on the barrier to continue on their + // way. + + sbp->running_threads_ = this->count_; + // Swap generations. + this->current_generation_ = 1 - this->current_generation_; + sbp->barrier_finished_.broadcast (); + } + else + { + --sbp->running_threads_; + + // Block until all the other threads wait(). + while (sbp->running_threads_ != this->count_) + sbp->barrier_finished_.wait (); + } + + return 0; +} + +ACE_Thread_Barrier::ACE_Thread_Barrier (u_int count, LPCTSTR name) + : ACE_Barrier (count, name) +{ +// ACE_TRACE ("ACE_Thread_Barrier::ACE_Thread_Barrier"); +} + +void +ACE_Thread_Barrier::dump (void) const +{ +// ACE_TRACE ("ACE_Thread_Barrier::dump"); + ACE_Barrier::dump (); +} + +#if 0 +ACE_Process_Barrier::ACE_Process_Barrier (u_int count, LPCTSTR name) + : ACE_Barrier (count, USYNC_PROCESS, name) +{ +// ACE_TRACE ("ACE_Process_Barrier::ACE_Process_Barrier"); +} + +void +ACE_Process_Barrier::dump (void) const +{ +// ACE_TRACE ("ACE_Process_Barrier::dump"); + ACE_Barrier::dump (); +} + +#endif /* 0 */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Mutex) + +void +ACE_Thread_Mutex::dump (void) const +{ +// ACE_TRACE ("ACE_Thread_Mutex::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Thread_Mutex::~ACE_Thread_Mutex (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::~ACE_Thread_Mutex"); +} + +ACE_Thread_Mutex::ACE_Thread_Mutex (LPCTSTR name, void *arg) +{ +// ACE_TRACE ("ACE_Thread_Mutex::ACE_Thread_Mutex"); + + if (ACE_OS::thread_mutex_init (&this->lock_, USYNC_THREAD, name, arg) != 0) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Mutex::ACE_Mutex")); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_RW_Thread_Mutex) + +ACE_RW_Thread_Mutex::ACE_RW_Thread_Mutex (LPCTSTR name, + void *arg) + : ACE_RW_Mutex (USYNC_THREAD, name, arg) +{ +// ACE_TRACE ("ACE_RW_Thread_Mutex::ACE_RW_Thread_Mutex"); +} + +void +ACE_RW_Mutex::dump (void) const +{ +// ACE_TRACE ("ACE_RW_Mutex::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +void +ACE_RW_Thread_Mutex::dump (void) const +{ +// ACE_TRACE ("ACE_RW_Thread_Mutex::dump"); + ACE_RW_Mutex::dump (); +} + +ACE_RW_Mutex::ACE_RW_Mutex (int type, LPCTSTR name, void *arg) +{ +// ACE_TRACE ("ACE_RW_Mutex::ACE_RW_Mutex"); + if (ACE_OS::rwlock_init (&this->lock_, type, name, arg) != 0) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_RW_Mutex::~ACE_RW_Mutex")); +} + +ACE_RW_Mutex::~ACE_RW_Mutex (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::~ACE_RW_Mutex"); + if (this->remove () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_RW_Mutex::~ACE_RW_Mutex")); +} + +#endif /* ACE_HAS_THREADS */ +#endif /* ACE_SYNCH_C */ diff --git a/ace/Synch.h b/ace/Synch.h new file mode 100644 index 00000000000..01f33cd8748 --- /dev/null +++ b/ace/Synch.h @@ -0,0 +1,1019 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Synch.h +// +// = DESCRIPTION +// Wrappers for various synchronization routines. +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SYNCH_H) +#define ACE_SYNCH_H + +#include "ace/ACE.h" +#include "ace/SV_Semaphore_Complex.h" + +// Forward declarations. +class ACE_Time_Value; +// template class ACE_Condition; + +class ACE_Export ACE_File_Lock + // = TITLE + // A wrapper around the UNIX file locking mechanism. + // + // = DESCRIPTION + // Allows us to "adapt" the UNIX file locking mechanisms to work + // with all of our Guard stuff... +{ +public: + ACE_File_Lock (ACE_HANDLE handle = ACE_INVALID_HANDLE); + // Set the of the File_Lock to . Note that this + // constructor assumes ownership of the and will close it + // down in . If you want the stays open when + // is called make sure to call on the before + // closing it. + + ACE_File_Lock (const char *filename, int flags, mode_t mode = 0); + // Open the with and and set the result to + // . + + ~ACE_File_Lock (void); + // Remove a File lock by releasing it and closing down the . + + int remove (void); + // Remove a File lock by releasing it and closing down the . + + int acquire (short whence = 0, off_t start = 0, off_t len = 1); + // Note, for interface uniformity with other synchronization + // wrappers we include the method. This is implemented as + // a write-lock to be on the safe-side... + + int tryacquire (short whence = 0, off_t start = 0, off_t len = 1); + // Note, for interface uniformity with other synchronization + // wrappers we include the method. This is implemented + // as a write-lock to be on the safe-side... + + int release (short whence = 0, off_t start = 0, off_t len = 1); + // Unlock a readers/writer lock. + + int acquire_write (short whence = 0, off_t start = 0, off_t len = 1); + // Acquire a write lock, but block if any readers or a + // writer hold the lock. + + int tryacquire_write (short whence = 0, off_t start = 0, off_t len = 1); + // Conditionally acquire a write lock (i.e., won't block). + + int acquire_read (short whence = 0, off_t start = 0, off_t len = 1); + // Acquire a read lock, but block if a writer hold the lock. + + int tryacquire_read (short whence = 0, off_t start = 0, off_t len = 1); + // Conditionally acquire a read lock (i.e., won't block). + + ACE_HANDLE get_handle (void); + // Get underlying . + + void set_handle (ACE_HANDLE); + // Set underlying . Note that this method assumes + // ownership of the and will close it down in . If + // you want the stays open when is called make + // sure to call on the before closing it. + + void dump (void) const; + // Dump state of the object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + ACE_OS::flock_t lock_; + // Locking structure for OS record locks. + + // = Prevent assignment and initialization. + void operator= (const ACE_File_Lock &) {} + ACE_File_Lock (const ACE_File_Lock &) {} +}; + +#if defined (ACE_HAS_THREADS) // ACE platform supports some form of threading. + +class ACE_Export ACE_Event + // = TITLE + // A wrapper around the Win32 event locking mechanism. + // + // = DESCRIPTION + // Portable implementation of an Event mechanism, which is + // native to Win32, but must be emulated on UNIX. +{ +public: + ACE_Event (int manual_reset = 0, + int initial_state = 0, + int type = USYNC_THREAD, + LPCTSTR name = 0, + void *arg = 0); + // Constructor which will create event. + + ~ACE_Event (void); + // Implicitly destroy the event variable. + + int remove (void); + // Explicitly destroy the event variable. + + ACE_event_t handle (void) const; + // Underlying handle to event. + + int wait (void); + // if MANUAL reset + // sleep till the event becomes signaled + // event remains signaled after wait() completes. + // else AUTO reset + // sleep till the event becomes signaled + // event resets wait() completes. + + int wait (const ACE_Time_Value *abstime); + // Same as wait() above, but this one can be timed + // is absolute time-of-day. + + int signal (void); + // if MANUAL reset + // wake up all waiting threads + // set to signaled state + // else AUTO reset + // if no thread is waiting, set to signaled state + // if thread(s) are waiting, wake up one waiting thread and + // reset event + + int pulse (void); + // if MANUAL reset + // wakeup all waiting threads and + // reset event + // else AUTO reset + // wakeup one waiting thread (if present) and + // reset event + + int reset (void); + // Set to nonsignaled state. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks + +private: + + // prevent copy constructors + ACE_Event (const ACE_Event& event); + + // prevent assignment operators + const ACE_Event &operator= (const ACE_Event &rhs); + + ACE_event_t handle_; +}; + +class ACE_Export ACE_Manual_Event : public ACE_Event + // = TITLE + // Manual Events. + // + // = DESCRIPTION + // Specialization of Event mechanism which + // wakes up all on signal() +{ +public: + ACE_Manual_Event (int initial_state = 0, + int type = USYNC_THREAD, + LPCTSTR name = 0, + void *arg = 0); + // constructor which will create manual event + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks +}; + +class ACE_Export ACE_Auto_Event : public ACE_Event + // = TITLE + // Auto Events. + // + // = DESCRIPTION + // Specialization of Event mechanism which + // wakes up all on signal() +{ +public: + ACE_Auto_Event (int initial_state = 0, + int type = USYNC_THREAD, + LPCTSTR name = 0, + void *arg = 0); + // constructor which will create auto event + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks +}; + +class ACE_Export ACE_Mutex + // = TITLE + // ACE_Mutex wrapper (valid in same process or across processes + // (depending on TYPE flag)) +{ +public: + ACE_Mutex (int type = USYNC_THREAD, + LPCTSTR name = 0, + void *arg = 0); + // Initialize the mutex. + + ~ACE_Mutex (void); + // Implicitly destroy the mutex. + + int remove (void); + // Explicitly destroy the mutex. + + int acquire (void); + // Acquire lock ownership (wait on priority queue if necessary). + + int tryacquire (void); + // Conditionally acquire lock (i.e., don't wait on queue). + + int release (void); + // Release lock and unblock a thread at head of priority queue. + + int acquire_read (void); + // Acquire lock ownership (wait on priority queue if necessary). + + int acquire_write (void); + // Acquire lock ownership (wait on priority queue if necessary). + + int tryacquire_read (void); + // Conditionally acquire a lock (i.e., won't block). + + int tryacquire_write (void); + // Conditionally acquire a lock (i.e., won't block). + + const ACE_mutex_t &lock (void) const; + // Return the underlying mutex. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +//private: + ACE_mutex_t lock_; + // Mutex type supported by the OS. + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Mutex &) {} + ACE_Mutex (const ACE_Mutex &) {} +}; + +class ACE_Export ACE_Thread_Mutex + // = TITLE + // ACE_Thread_Mutex wrapper (only valid for threads in the same + // process). + // + // = DESCRIPTION + // This implementation is optimized for locking threads that are + // in the same process. It maps to s on NT + // and with set to on UNIX. +{ +public: + ACE_Thread_Mutex (LPCTSTR name = 0, void *arg = 0); + + ~ACE_Thread_Mutex (void); + // Implicitly destroy the mutex. + + int remove (void); + // Explicitly destroy the mutex. + + int acquire (void); + // Acquire lock ownership (wait on priority queue if necessary). + + int tryacquire (void); + // Conditionally acquire lock (i.e., don't wait on queue). + + int release (void); + // Release lock and unblock a thread at head of priority queue. + + int acquire_read (void); + // Acquire lock ownership (wait on priority queue if necessary). + + int acquire_write (void); + // Acquire lock ownership (wait on priority queue if necessary). + + int tryacquire_read (void); + // Conditionally acquire a lock (i.e., won't block). + + int tryacquire_write (void); + // Conditionally acquire a lock (i.e., won't block). + + const ACE_thread_mutex_t &lock (void) const; + // Return the underlying mutex. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +//private: + ACE_thread_mutex_t lock_; + // Mutex type that supports single-process locking efficiently. + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Thread_Mutex &) {} + ACE_Thread_Mutex (const ACE_Thread_Mutex &) {} +}; + +class ACE_Export ACE_Thread_Mutex_Guard + // = TITLE + // This data structure is meant to be used within a method or + // function... It performs automatic aquisition and release of + // an ACE_Mutex. + // + // = DESCRIPTION + // This should be a specialization of ACE_Guard, but compiler + // bugs in older C++ compilers preclude this... +{ +public: + ACE_Thread_Mutex_Guard (ACE_Thread_Mutex &m, int block = 1); + // Implicitly and automatically acquire the lock. + + ~ACE_Thread_Mutex_Guard (void); + // Implicitly release the lock. + + int locked (void); + // 1 if locked, 0 if couldn't acquire the lock (errno will contain + // the reason for this). + + int remove (void); + // Explicitly release the lock. + + int acquire (void); + // Explicitly acquire the lock. + + int tryacquire (void); + // Conditionally acquire the lock (i.e., won't block). + + int release (void); + // Explicitly release the lock. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + ACE_Thread_Mutex &lock_; + // Reference to the mutex. + + int owner_; + // Keeps track of whether we acquired the lock or failed. + + // = Prevent assignment and initialization. + void operator= (const ACE_Thread_Mutex_Guard &) {} + ACE_Thread_Mutex_Guard (const ACE_Thread_Mutex_Guard &g): lock_ (g.lock_) {} +}; + +class ACE_Export ACE_Condition_Thread_Mutex + // = TITLE + // ACE_Condition variable wrapper written using ACE_Mutexes This + // allows threads to block until shared data changes state. + // + // = DESCRIPTION + // This should be an instantiation of ACE_Condition but problems + // with compilers precludes this... +{ +public: + ACE_Condition_Thread_Mutex (const ACE_Thread_Mutex &m, + LPCTSTR name = 0, + void *arg = 0); + // Initialize the condition variable. + + ~ACE_Condition_Thread_Mutex (void); + // Implicitly destroy the condition variable. + + int remove (void); + // Explicitly destroy the condition variable. + + int wait (const ACE_Time_Value *abstime); + // Block on condition, or until absolute time-of-day has passed. If + // abstime == 0 use "blocking" semantics. Else, if + // != 0 and the call times out before the condition is signaled + // returns -1 and sets errno to ETIME. + + int wait (void); + // Block on condition. + + int wait (ACE_Thread_Mutex &mutex, const ACE_Time_Value *abstime = 0); + // Block on condition or until absolute time-of-day has passed. If + // abstime == 0 use "blocking" wait() semantics on the + // passed as a parameter (this is useful if you need to store the + // in shared memory). Else, if != 0 and the + // call times out before the condition is signaled returns -1 + // and sets errno to ETIME. + + int signal (void); + // Signal one waiting thread. + + int broadcast (void); + // Signal *all* waiting threads. + + ACE_Thread_Mutex &mutex (void); + // Returns a reference to the underlying mutex_; + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_cond_t cond_; + // Condition variable. + + ACE_Thread_Mutex &mutex_; + // Reference to mutex lock. + + // = Prevent assignment and initialization. + void operator= (const ACE_Condition_Thread_Mutex &) {} + ACE_Condition_Thread_Mutex (const ACE_Condition_Thread_Mutex &c): mutex_ (c.mutex_) {} +}; + +class ACE_Export ACE_Recursive_Thread_Mutex + // = TITLE + // Implement a C++ wrapper that allows calls to class + // to be nested for a nested acquire() that + // occurs in the same thread. + // + // = DESCRIPTION + // This class should be a specialization of the + // ACE_Recursive_Lock template class, but problems with some C++ + // compilers preclude this... +{ + // friend class ACE_Condition; +public: + ACE_Recursive_Thread_Mutex (LPCTSTR name = 0, + void *arg = 0); + // Initialize a recursive mutex. + + ~ACE_Recursive_Thread_Mutex (void); + // Implicitly release a recursive mutex. + + int remove (void); + // Implicitly release a recursive mutex. + + int acquire (void); + // Acquire a recursive mutex (will increment the nesting level and + // not deadmutex if the owner of the mutex calls this method more + // than once). + + int tryacquire (void); + // Conditionally acquire a recursive mutex (i.e., won't block). + + int release (void); + // Releases a recursive mutex (will not release mutex until all the + // nesting level drops to 0, which means the mutex is no longer + // held). + + ACE_thread_t get_thread_id (void); + // Return the id of the thread that currently owns the mutex. + + int get_nesting_level (void); + // Return the nesting level of the recursion. When a thread has + // acquired the mutex for the first time, the nesting level == 1. + // The nesting level is incremented every time the thread acquires + // the mutex recursively. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + // These methods should *not* be public (they hold no locks...) + void set_nesting_level (int d); + void set_thread_id (ACE_thread_t t); + + ACE_Thread_Mutex nesting_mutex_; + // Guards the state of the nesting level and thread id. + + ACE_Condition_Thread_Mutex lock_available_; + // This is the condition variable that actually suspends other + // waiting threads until the mutex is available. + + int nesting_level_; + // Current nesting level of the recursion. + + ACE_thread_t owner_id_; + // Current owner of the lock. + + // = Prevent assignment and initialization. + void operator= (const ACE_Recursive_Thread_Mutex &) {} + ACE_Recursive_Thread_Mutex (const ACE_Recursive_Thread_Mutex &); +}; + +class ACE_Export ACE_RW_Mutex + // = TITLE + // Wrapper for readers/writer locks. + // + // = DESCRIPTION + // These are most useful for applications that have many more + // parallel readers than writers... +{ +public: + ACE_RW_Mutex (int type = USYNC_THREAD, + LPCTSTR name = 0, + void *arg = 0); + // Initialize a readers/writer lock. + + ~ACE_RW_Mutex (void); + // Implicitly destroy a readers/writer lock + + int remove (void); + // Explicitly destroy a readers/writer lock. + + int acquire_read (void); + // Acquire a read lock, but block if a writer hold the lock. + + int acquire_write (void); + // Acquire a write lock, but block if any readers or a + // writer hold the lock. + + int tryacquire_read (void); + // Conditionally acquire a read lock (i.e., won't block). + + int tryacquire_write (void); + // Conditionally acquire a write lock (i.e., won't block). + + int acquire (void); + // Note, for interface uniformity with other synchronization + // wrappers we include the method. This is implemented as + // a write-lock to be on the safe-side... + + int tryacquire (void); + // Note, for interface uniformity with other synchronization + // wrappers we include the method. This is implemented + // as a write-lock to be on the safe-side... + + int release (void); + // Unlock a readers/writer lock. + + const ACE_rwlock_t &lock (void) const; + // Return the underlying lock. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_rwlock_t lock_; + // Readers/writer lock. + + // = Prevent assignment and initialization. + void operator= (const ACE_RW_Mutex &) {} + ACE_RW_Mutex (const ACE_RW_Mutex &) {} +}; + +class ACE_Export ACE_RW_Thread_Mutex : public ACE_RW_Mutex + // = TITLE + // Wrapper for readers/writer locks that exist within a process. +{ +public: + ACE_RW_Thread_Mutex (LPCTSTR name = 0, + void *arg = 0); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +class ACE_Export ACE_Semaphore + // = TITLE + // Wrapper for Dijkstra style general semaphores. +{ +public: + // = Initialization and termination. + ACE_Semaphore (u_int count, + int type = USYNC_THREAD, + LPCTSTR name = 0, + void * = 0, + int max = 0x7fffffff); + // Initialize the semaphore, with default value of "count". + + ~ACE_Semaphore (void); + // Implicitly destroy the semaphore. + + int remove (void); + // Explicitly destroy the semaphore. + + int acquire (void); + // Block the thread until the semaphore count becomes + // greater than 0, then decrement it. + + int tryacquire (void); + // Conditionally decrement the semaphore if count is greater + // than 0 (i.e., won't block). + + int release (void); + // Increment the semaphore, potentially unblocking + // a waiting thread. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + + const ACE_sema_t &lock (void) const; + // Return the underlying lock. + +private: + ACE_sema_t semaphore_; + + // = Prevent assignment and initialization. + void operator= (const ACE_Semaphore &) {} + ACE_Semaphore (const ACE_Semaphore &) {} +}; + +class ACE_Export ACE_Thread_Semaphore : public ACE_Semaphore + // = TITLE + // Wrapper for Dijkstra style general semaphores that work + // only within on process. +{ +public: + ACE_Thread_Semaphore (u_int count, LPCTSTR name = 0, + void * = 0, int max = 0x7FFFFFFF); + // Initialize the semaphore, with an initial value of and a + // maximum value of . + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +class ACE_Export ACE_Process_Semaphore + // = TITLE + // Wrapper for Dijkstra style general semaphores that work + // across processes. +{ +public: + ACE_Process_Semaphore (u_int count, LPCTSTR name = 0, + void * = 0, int max = 0x7FFFFFFF); + // Initialize the semaphore, with an initial value of and a + // maximum value of . + + ~ACE_Process_Semaphore (void); + // Implicitly destroy the semaphore. + + int remove (void); + // Explicitly destroy the semaphore. + + int acquire (void); + // Block the thread until the semaphore count becomes + // greater than 0, then decrement it. + + int tryacquire (void); + // Conditionally decrement the semaphore if count is greater + // than 0 (i.e., won't block). + + int release (void); + // Increment the semaphore, potentially unblocking + // a waiting thread. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: +#if defined (ACE_WIN32) || defined (ACE_HAS_POSIX_SEM) + ACE_Semaphore lock_; +#else + ACE_SV_Semaphore_Complex lock_; + // We need this to get the right semantics... +#endif /* ACE_WIN32 */ +}; + +struct ACE_Export ACE_Sub_Barrier +{ + // = Initialization. + ACE_Sub_Barrier (u_int count, + ACE_Thread_Mutex &lock, + LPCTSTR name = 0, + void *arg = 0); + + ACE_Condition_Thread_Mutex barrier_finished_; + // True if this generation of the barrier is done. + + int running_threads_; + // Number of threads that are still running. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +class ACE_Export ACE_Barrier + // = TITLE + // Implements "barrier synchronization". + // + // = DESCRIPTION + // This class allows number of threads to synchronize + // their completion (so-called "barrier synchronization"). The + // implementation uses a "sub-barrier generation numbering" + // scheme to avoid overhead and to ensure that all threads exit + // the barrier correct. This code is based on an article from + // SunOpsis Vol. 4, No. 1 by Richard Marejka + // (Richard.Marejka@canada.sun.com). +{ +public: + ACE_Barrier (u_int count, + LPCTSTR name = 0, + void *arg = 0); + // Initialize the barrier to synchronize threads. + + int wait (void); + // Block the caller until all threads have called and + // then allow all the caller threads to continue in parallel. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Thread_Mutex lock_; + // Serialize access to the barrier state. + + int current_generation_; + // Either 0 or 1, depending on whether we are the first generation + // of waiters or the next generation of waiters. + + int count_; + // Total number of threads that can be waiting at any one time. + + ACE_Sub_Barrier sub_barrier_1_; + ACE_Sub_Barrier sub_barrier_2_; + ACE_Sub_Barrier *sub_barrier_[2]; + // We keep two , one for the first "generation" of + // waiters, and one for the next "generation" of waiters. This + // efficiently solves the problem of what to do if all the first + // generation waiters don't leave the barrier before one of the + // threads calls wait() again (i.e., starts up the next generation + // barrier). + + // = Prevent assignment and initialization. + void operator= (const ACE_Barrier &) {} + ACE_Barrier (const ACE_Barrier &): sub_barrier_1_ (0, lock_), sub_barrier_2_ (0, lock_) {} +}; + +#if 0 +class ACE_Export ACE_Process_Barrier : public ACE_Barrier + // = TITLE + // Implements "barrier synchronization" using ACE_Process_Mutexes! + // + // = DESCRIPTION + // This class is just a simple wrapper for ACE_Barrier that + // selects the USYNC_PROCESS variant for the locks. +{ +public: + ACE_Process_Barrier (u_int count, LPCTSTR name = 0); + // Create a Process_Barrier, passing in the optional . + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; +#endif /* 0 */ + +class ACE_Export ACE_Thread_Barrier : public ACE_Barrier + // = TITLE + // Implements "barrier synchronization" using ACE_Thread_Mutexes! + // + // = DESCRIPTION + // This class is just a simple wrapper for ACE_Barrier that + // selects the USYNC_THREAD variant for the locks. +{ +public: + ACE_Thread_Barrier (u_int count, LPCTSTR name = 0); + // Create a Process_Barrier, passing in the optional . + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#endif /* ACE_HAS_THREADS */ + +class ACE_Export ACE_Process_Mutex + // = TITLE + // ACE_Mutex wrapper (valid in same process, as well as across + // processes). +{ +public: + ACE_Process_Mutex (LPCTSTR name = ACE_DEFAULT_MUTEX, void *arg = 0); + // Create a Process_Mutex, passing in the optional . + + ~ACE_Process_Mutex (void); + + int remove (void); + // Explicitly destroy the mutex. + + int acquire (void); + // Acquire lock ownership (wait on priority queue if necessary). + + int tryacquire (void); + // Conditionally acquire lock (i.e., don't wait on queue). + + int release (void); + // Release lock and unblock a thread at head of priority queue. + + int acquire_read (void); + // Acquire lock ownership (wait on priority queue if necessary). + + int acquire_write (void); + // Acquire lock ownership (wait on priority queue if necessary). + + int tryacquire_read (void); + // Conditionally acquire a lock (i.e., won't block). + + int tryacquire_write (void); + // Conditionally acquire a lock (i.e., won't block). + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +#if defined (ACE_WIN32) || defined (ACE_HAS_POSIX_SEM) + ACE_Mutex lock_; +#else + ACE_SV_Semaphore_Complex lock_; + // We need this to get the right semantics... +#endif /* ACE_WIN32 */ +}; + +class ACE_Export ACE_RW_Process_Mutex : public ACE_Process_Mutex + // = TITLE + // Wrapper for readers/writer locks that exist across processes. +{ +public: + ACE_RW_Process_Mutex (LPCTSTR name = ACE_DEFAULT_MUTEX, + void *arg = 0); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +class ACE_Null_Barrier + // = TITLE + // Implements "NULL barrier synchronization". +{ +public: + ACE_Null_Barrier (u_int, + const char * = 0, + void * = 0) {} + // Initialize the barrier to synchronize threads. + + int wait (void) { return 0; } + // Block the caller until all threads have called and + // then allow all the caller threads to continue in parallel. + + void dump (void) const {} + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + + // = Prevent assignment and initialization. + void operator= (const ACE_Null_Barrier &) {} + ACE_Null_Barrier (const ACE_Null_Barrier &) {} +}; + +class ACE_Export ACE_Null_Mutex + // = TITLE + // Implement a do nothing , i.e., all the methods are + // no ops. +{ +public: + ACE_Null_Mutex (LPCTSTR = 0) {} + ~ACE_Null_Mutex (void) {} + int remove (void) { return 0; } + + int acquire (void) { return 0; } + int tryacquire (void) { return 0; } + int release (void) { return 0; } + int acquire_write (void) { return 0; } + int tryacquire_write (void) { return 0; } + int acquire_read (void) { return 0; } + int tryacquire_read (void) { return 0; } + + void dump (void) const { } + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +class ACE_Export ACE_Null_Condition_Mutex + // = TITLE + // Implement a do nothing variable wrapper, i.e., + // all methods are no ops. This class is necessary since some + // C++ compilers are *very* lame... +{ +public: + ACE_Null_Condition_Mutex (ACE_Null_Mutex &m, int = 0, + LPCTSTR = 0, void * = 0): mutex_ (m) {} + ~ACE_Null_Condition_Mutex (void) {} + int remove (void) { return 0; } + int wait (ACE_Time_Value * = 0) { return 0; } + int signal (void) { return 0; } + int broadcast (void) { return 0; } + ACE_Null_Mutex &mutex (void) { return this->mutex_; } + + void dump (void) const {} + // Dump the state of an object. + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Null_Mutex &mutex_; // Reference to mutex lock. + + // = Prevent assignment and initialization. + void operator= (const ACE_Null_Condition_Mutex &) {} + ACE_Null_Condition_Mutex (const ACE_Null_Condition_Mutex &c): mutex_ (c.mutex_) {} +}; + +class ACE_Export ACE_Null_Mutex_Guard + // = TITLE + // This data structure is meant to be used within a method or + // function... It performs automatic aquisition and release of + // an ACE_Null_Mutex. + // + // = DESCRIPTION + // This should be a specialization of ACE_Guard, but compiler + // bugs preclude this... +{ +public: + ACE_Null_Mutex_Guard (ACE_Null_Mutex &) {} + ~ACE_Null_Mutex_Guard (void) {} + int remove (void) { return 0; } + int locked (void) { return 1; } + int acquire (void) { return 0; } + int tryacquire (void) { return 0; } + int release (void) { return 0; } + void dump (void) const { } + +protected: + // = Prevent assignment and initialization. + void operator= (const ACE_Null_Mutex_Guard &) {} + ACE_Null_Mutex_Guard (const ACE_Null_Mutex_Guard &) {} +}; + +#if defined (__ACE_INLINE__) +#include "ace/Synch.i" +#endif /* __ACE_INLINE__ */ + +// Include the templates here. +#include "ace/Synch_T.h" + +#endif /* ACE_SYNCH_H */ diff --git a/ace/Synch.i b/ace/Synch.i new file mode 100644 index 00000000000..02544228354 --- /dev/null +++ b/ace/Synch.i @@ -0,0 +1,421 @@ +/* -*- C++ -*- */ +// $Id$ + +// Synch.i + +ACE_INLINE int +ACE_File_Lock::acquire_read (short whence, off_t start, off_t len) +{ +// ACE_TRACE ("ACE_File_Lock::acquire_read"); + return ACE_OS::flock_rdlock (&this->lock_, whence, start, len); +} + +ACE_INLINE int +ACE_File_Lock::tryacquire_read (short whence, off_t start, off_t len) +{ +// ACE_TRACE ("ACE_File_Lock::tryacquire_read"); + return ACE_OS::flock_tryrdlock (&this->lock_, whence, start, len); +} + +ACE_INLINE int +ACE_File_Lock::tryacquire_write (short whence, off_t start, off_t len) +{ +// ACE_TRACE ("ACE_File_Lock::tryacquire_write"); + return ACE_OS::flock_trywrlock (&this->lock_, whence, start, len); +} + +ACE_INLINE int +ACE_File_Lock::tryacquire (short whence, off_t start, off_t len) +{ +// ACE_TRACE ("ACE_File_Lock::tryacquire"); + return this->tryacquire_write (whence, start, len); +} + +ACE_INLINE int +ACE_File_Lock::acquire_write (short whence, off_t start, off_t len) +{ +// ACE_TRACE ("ACE_File_Lock::acquire_write"); + return ACE_OS::flock_wrlock (&this->lock_, whence, start, len); +} + +ACE_INLINE int +ACE_File_Lock::acquire (short whence, off_t start, off_t len) +{ +// ACE_TRACE ("ACE_File_Lock::acquire"); + return this->acquire_write (whence, start, len); +} + +ACE_INLINE int +ACE_File_Lock::release (short whence, off_t start, off_t len) +{ +// ACE_TRACE ("ACE_File_Lock::release"); + return ACE_OS::flock_unlock (&this->lock_, whence, start, len); +} + +ACE_INLINE int +ACE_File_Lock::remove (void) +{ +// ACE_TRACE ("ACE_File_Lock::remove"); + + return ACE_OS::flock_destroy (&this->lock_); +} + +ACE_INLINE ACE_HANDLE +ACE_File_Lock::get_handle (void) +{ +// ACE_TRACE ("ACE_File_Lock::get_handle"); + return this->lock_.handle_; +} + +ACE_INLINE void +ACE_File_Lock::set_handle (ACE_HANDLE h) +{ +// ACE_TRACE ("ACE_File_Lock::set_handle"); + this->lock_.handle_ = h; +} + +#if defined (ACE_HAS_THREADS) + +ACE_INLINE const ACE_sema_t & +ACE_Semaphore::lock (void) const +{ +// ACE_TRACE ("ACE_Semaphore::lock"); + return this->semaphore_; +} + +ACE_INLINE int +ACE_Semaphore::remove (void) +{ +// ACE_TRACE ("ACE_Semaphore::remove"); + return ACE_OS::sema_destroy (&this->semaphore_); +} + +ACE_INLINE int +ACE_Semaphore::acquire (void) +{ +// ACE_TRACE ("ACE_Semaphore::acquire"); + return ACE_OS::sema_wait (&this->semaphore_); +} + +ACE_INLINE int +ACE_Semaphore::tryacquire (void) +{ +// ACE_TRACE ("ACE_Semaphore::tryacquire"); + return ACE_OS::sema_trywait (&this->semaphore_); +} + +ACE_INLINE int +ACE_Semaphore::release (void) +{ +// ACE_TRACE ("ACE_Semaphore::release"); + return ACE_OS::sema_post (&this->semaphore_); +} + +ACE_INLINE int +ACE_Mutex::acquire_read (void) +{ +// ACE_TRACE ("ACE_Mutex::acquire_read"); + return ACE_OS::mutex_lock (&this->lock_); +} + +ACE_INLINE int +ACE_Mutex::acquire_write (void) +{ +// ACE_TRACE ("ACE_Mutex::acquire_write"); + return ACE_OS::mutex_lock (&this->lock_); +} + +ACE_INLINE int +ACE_Mutex::tryacquire_read (void) +{ +// ACE_TRACE ("ACE_Mutex::tryacquire_read"); + return ACE_OS::mutex_trylock (&this->lock_); +} + +ACE_INLINE const ACE_mutex_t & +ACE_Mutex::lock (void) const +{ +// ACE_TRACE ("ACE_Mutex::lock"); + return this->lock_; +} + +ACE_INLINE int +ACE_Mutex::tryacquire_write (void) +{ +// ACE_TRACE ("ACE_Mutex::tryacquire_write"); + return ACE_OS::mutex_trylock (&this->lock_); +} + +ACE_INLINE int +ACE_Mutex::acquire (void) +{ +// ACE_TRACE ("ACE_Mutex::acquire"); + return ACE_OS::mutex_lock (&this->lock_); +} + +ACE_INLINE int +ACE_Mutex::tryacquire (void) +{ +// ACE_TRACE ("ACE_Mutex::tryacquire"); + return ACE_OS::mutex_trylock (&this->lock_); +} + +ACE_INLINE int +ACE_Mutex::release (void) +{ +// ACE_TRACE ("ACE_Mutex::release"); + return ACE_OS::mutex_unlock (&this->lock_); +} + +ACE_INLINE int +ACE_Mutex::remove (void) +{ +// ACE_TRACE ("ACE_Mutex::remove"); + return ACE_OS::mutex_destroy (&this->lock_); +} + +ACE_INLINE const ACE_thread_mutex_t & +ACE_Thread_Mutex::lock (void) const +{ +// ACE_TRACE ("ACE_Thread_Mutex::lock"); + return this->lock_; +} + +ACE_INLINE int +ACE_Thread_Mutex::acquire_read (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::acquire_read"); + return ACE_OS::thread_mutex_lock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::acquire_write (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::acquire_write"); + return ACE_OS::thread_mutex_lock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::tryacquire_read (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::tryacquire_read"); + return ACE_OS::thread_mutex_trylock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::tryacquire_write (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::tryacquire_write"); + return ACE_OS::thread_mutex_trylock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::acquire (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::acquire"); + return ACE_OS::thread_mutex_lock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::tryacquire (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::tryacquire"); + return ACE_OS::thread_mutex_trylock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::release (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::release"); + return ACE_OS::thread_mutex_unlock (&this->lock_); +} + +ACE_INLINE int +ACE_Thread_Mutex::remove (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex::remove"); + return ACE_OS::thread_mutex_destroy (&this->lock_); +} + +// Implicitly and automatically acquire the lock. + +ACE_INLINE +ACE_Thread_Mutex_Guard::ACE_Thread_Mutex_Guard (ACE_Thread_Mutex &m, + int block) + : lock_ (m) +{ +// ACE_TRACE ("ACE_Thread_Mutex_Guard::ACE_Thread_Mutex_Guard"); + this->owner_ == block ? this->lock_.acquire () : this->lock_.tryacquire (); +} + +// Implicitly release the lock. + +ACE_INLINE +ACE_Thread_Mutex_Guard::~ACE_Thread_Mutex_Guard (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex_Guard::~ACE_Thread_Mutex_Guard"); + if (this->owner_ != -1) + this->lock_.release (); +} + +ACE_INLINE int +ACE_Thread_Mutex_Guard::locked (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex_Guard::locked"); + return this->owner_ != -1; +} + +// Explicitly acquire the lock. + +ACE_INLINE int +ACE_Thread_Mutex_Guard::acquire (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex_Guard::acquire"); + return this->owner_ = this->lock_.acquire (); +} + +// Conditionally acquire the lock (i.e., won't block). + +ACE_INLINE int +ACE_Thread_Mutex_Guard::tryacquire (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex_Guard::tryacquire"); + return this->owner_ = this->lock_.tryacquire (); +} + +// Explicitly release the lock. + +ACE_INLINE int +ACE_Thread_Mutex_Guard::release (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex_Guard::release"); + this->owner_ = -1; + return this->lock_.release (); +} + +// Explicitly release the lock. + +ACE_INLINE int +ACE_Thread_Mutex_Guard::remove (void) +{ +// ACE_TRACE ("ACE_Thread_Mutex_Guard::remove"); + return this->release (); +} + +ACE_INLINE int +ACE_Condition_Thread_Mutex::remove (void) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::remove"); + + // cond_destroy() is called in a loop if the condition variable is + // BUSY. This avoids a condition where a condition is signaled and + // because of some timing problem, the thread that is to be signaled + // has called the cond_wait routine after the signal call. Since + // the condition signal is not queued in any way, deadlock occurs. + + int result = 0; + + while ((result = ACE_OS::cond_destroy (&this->cond_)) == -1 + && errno == EBUSY) + { + ACE_OS::cond_broadcast (&this->cond_); + ACE_OS::thr_yield (); + } + + return result; +} + +ACE_INLINE ACE_Thread_Mutex & +ACE_Condition_Thread_Mutex::mutex (void) +{ +// ACE_TRACE ("ACE_Condition_Thread_Mutex::mutex"); + return this->mutex_; +} + +ACE_INLINE int +ACE_Recursive_Thread_Mutex::remove (void) +{ +// ACE_TRACE ("ACE_Recursive_Thread_Mutex::remove"); + this->nesting_mutex_.remove (); + return this->lock_available_.remove (); +} + +ACE_INLINE void +ACE_Recursive_Thread_Mutex::set_thread_id (ACE_thread_t t) +{ +// ACE_TRACE ("ACE_Recursive_Thread_Mutex::set_thread_id"); + this->owner_id_ = t; +} + +ACE_INLINE void +ACE_Recursive_Thread_Mutex::set_nesting_level (int d) +{ +// ACE_TRACE ("ACE_Recursive_Thread_Mutex::set_nesting_level"); + this->nesting_level_ = d; +} + +ACE_INLINE const ACE_rwlock_t & +ACE_RW_Mutex::lock (void) const +{ +// ACE_TRACE ("ACE_RW_Mutex::lock"); + return this->lock_; +} + +ACE_INLINE int +ACE_RW_Mutex::remove (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::remove"); + return ACE_OS::rwlock_destroy (&this->lock_); +} + +ACE_INLINE int +ACE_RW_Mutex::acquire_read (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::acquire_read"); + return ACE_OS::rw_rdlock (&this->lock_); +} + +ACE_INLINE int +ACE_RW_Mutex::acquire_write (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::acquire_write"); + return ACE_OS::rw_wrlock (&this->lock_); +} + +ACE_INLINE int +ACE_RW_Mutex::acquire (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::acquire"); + return ACE_OS::rw_wrlock (&this->lock_); +} + +ACE_INLINE int +ACE_RW_Mutex::tryacquire_read (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::tryacquire_read"); + return ACE_OS::rw_tryrdlock (&this->lock_); +} + +ACE_INLINE int +ACE_RW_Mutex::tryacquire_write (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::tryacquire_write"); + return ACE_OS::rw_trywrlock (&this->lock_); +} + +ACE_INLINE int +ACE_RW_Mutex::tryacquire (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::tryacquire"); + return this->tryacquire_write (); +} + +ACE_INLINE int +ACE_RW_Mutex::release (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::release"); + return ACE_OS::rw_unlock (&this->lock_); +} + +#endif /* ACE_HAS_THREADS */ + diff --git a/ace/Synch_Options.cpp b/ace/Synch_Options.cpp new file mode 100644 index 00000000000..738d02493b1 --- /dev/null +++ b/ace/Synch_Options.cpp @@ -0,0 +1,93 @@ +// Synch_Options.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Synch_Options.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_Synch_Options) + +void +ACE_Synch_Options::dump (void) const +{ + ACE_TRACE ("ACE_Synch_Options::dump"); +} + +// Static initialization. + +/* static */ +ACE_Synch_Options ACE_Synch_Options::defaults; + +/* static */ +ACE_Synch_Options ACE_Synch_Options::synch; + +/* static */ +ACE_Synch_Options ACE_Synch_Options::asynch (ACE_Synch_Options::USE_REACTOR); + +ACE_Synch_Options::ACE_Synch_Options (u_long options, + const ACE_Time_Value &timeout, + const void *arg) +{ + ACE_TRACE ("ACE_Synch_Options::ACE_Synch_Options"); + this->set (options, timeout, arg); +} + +void +ACE_Synch_Options::set (u_long options, + const ACE_Time_Value &timeout, + const void *arg) +{ + ACE_TRACE ("ACE_Synch_Options::set"); + this->options_ = options; + this->timeout_ = (ACE_Time_Value &) timeout; + this->arg_ = arg; +} + +int +ACE_Synch_Options::operator[] (u_long option) const +{ + ACE_TRACE ("ACE_Synch_Options::operator[]"); + return (this->options_ & option) != 0; +} + +void +ACE_Synch_Options::operator= (u_long option) +{ + ACE_TRACE ("ACE_Synch_Options::operator="); + this->options_ |= option; +} + +const ACE_Time_Value & +ACE_Synch_Options::timeout (void) const +{ + ACE_TRACE ("ACE_Synch_Options::timeout"); + return this->timeout_; +} + +void +ACE_Synch_Options::timeout (ACE_Time_Value &tv) +{ + ACE_TRACE ("ACE_Synch_Options::timeout"); + this->timeout_ = tv; +} + +const ACE_Time_Value * +ACE_Synch_Options::time_value (void) const +{ + ACE_TRACE ("ACE_Synch_Options::time_value"); + return (*this)[USE_TIMEOUT] ? &this->timeout_ : 0; +} + +const void * +ACE_Synch_Options::arg (void) const +{ + ACE_TRACE ("ACE_Synch_Options::arg"); + return this->arg_; +} + +void +ACE_Synch_Options::arg (const void *a) +{ + ACE_TRACE ("ACE_Synch_Options::arg"); + this->arg_ = a; +} + diff --git a/ace/Synch_Options.h b/ace/Synch_Options.h new file mode 100644 index 00000000000..28e3300013c --- /dev/null +++ b/ace/Synch_Options.h @@ -0,0 +1,135 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// ACE_Synch_Options.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SYNCH_OPTIONS_H) +#define ACE_SYNCH_OPTIONS_H + +#include "ace/ACE.h" + +class ACE_Export ACE_Synch_Options + // = TITLE + // Contains the values of options used to determine the + // synchronous and asynchronous behavior. + // + // DESCRIPTION = + // Values support the following behavior (TV == "timeout" + // and UR == "use ACE_Reactor"): + // + // Parameters | Description + // | + // TV | UR | + // -----|----------|------------------------------- + // | | + // NULL | yes | infinite timeout (using ACE_Reactor) + // | | + // time | yes | try asynch transaction for + // | | the specified time (using ACE_Reactor) + // | | + // 0,0 | yes | poll; try, if EWOULDBLOCK, + // | | then return immediately + // | | (using ACE_Reactor) + // | | + // NULL | no | block forever (don't use ACE_Reactor) + // | | + // time | no | do a blocking transaction + // | | for the specified time + // | | (don't use ACE_Reactor) + // | | + // 0,0 | no | poll; but do not initiate a + // | | nonblocking transaction + // | | (don't use ACE_Reactor) +{ +public: + // = Options flags for controlling synchronization. Note that these + // flags can be bit-wise "or'd" together if both options are + // desired. + enum + { + USE_REACTOR = 01, + // Use the Reactor. + USE_TIMEOUT = 02 + // Interprete the Time_Value. + }; + + // = Initialization methods. + ACE_Synch_Options (u_long options = 0, + const ACE_Time_Value &timeout = ACE_Time_Value::zero, + const void *arg = 0); + // Initialize the Synch_Options based on parameters. + + void set (u_long options = 0, + const ACE_Time_Value &timeout = ACE_Time_Value::zero, + const void *arg = 0); + // Initialize the Synch_Options based on parameters. + + int operator[] (u_long option) const; + // Get method for determining which options are enabled. + + void operator= (u_long option); + // Set method for enabling certain options. + + const void *arg (void) const; + // Returns the "magic cookie" argument. + + void arg (const void *); + // Set the "magic cookie" argument. + + const ACE_Time_Value &timeout (void) const; + // Returns a reference to the . This value only makes + // sense if (*this)[USE_TIMEOUT] is true. + + void timeout (ACE_Time_Value &tv); + // Set the . + + const ACE_Time_Value *time_value (void) const; + // Returns the address of the timeout if + // (*this)[USE_TIMEOUT] is true, else 0. This should be used with + // care, e.g., the timeout pointer should not be stored in a manner + // that will lead to dangling pointers... + + // = Static data members (singletons) + + static ACE_Synch_Options defaults; + // This is the default setting for options, which will block + // synchronously. + + static ACE_Synch_Options synch; + // This is the default synchronous setting. + + static ACE_Synch_Options asynch; + // This is the default asynchronous setting. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + u_long options_; + // Keeps track of the enabled options. + + ACE_Time_Value timeout_; + // Amount of time to wait for timeouts. + + const void *arg_; + // "Magic cookie" always passed in as an argument to the ACE_Reactor's + // method. Used to communicate values for + // asynchronous programming. +}; + +#endif /* ACE_SYNCH_OPTIONS_H */ diff --git a/ace/Synch_Options.i b/ace/Synch_Options.i new file mode 100644 index 00000000000..0a31ce8c554 --- /dev/null +++ b/ace/Synch_Options.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// $Id$ + +// Synch_Options.i diff --git a/ace/Synch_T.cpp b/ace/Synch_T.cpp new file mode 100644 index 00000000000..d9389f139a2 --- /dev/null +++ b/ace/Synch_T.cpp @@ -0,0 +1,626 @@ +// Synch_T.cpp +// $Id$ + +#if !defined (ACE_SYNCH_T_C) +#define ACE_SYNCH_T_C + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Thread.h" +#include "ace/Time_Value.h" +#include "ace/Synch_T.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Synch_T.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Atomic_Op) + +template +ACE_Test_and_Set::ACE_Test_and_Set (TYPE initial_value) + : is_set_ (initial_value) +{ +} + +// Returns true if we are done, else false. +template TYPE +ACE_Test_and_Set::is_set (void) const +{ + ACE_GUARD_RETURN (LOCK, ace_mon, (LOCK &) this->lock_, this->is_set_); + return this->is_set_; +} + +// Sets the status. +template TYPE +ACE_Test_and_Set::set (TYPE status) +{ + ACE_GUARD_RETURN (LOCK, ace_mon, this->lock_, this->is_set_); + TYPE o_status = this->is_set_; + this->is_set_ = status; + return o_status; +} + +template int +ACE_Test_and_Set::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + this->set (1); + return 0; +} + +template void +ACE_Atomic_Op::dump (void) const +{ +// ACE_TRACE ("ACE_Atomic_Op::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->lock_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +template +ACE_Atomic_Op::ACE_Atomic_Op (void) + : value_ (0) +{ +// ACE_TRACE ("ACE_Atomic_Op::ACE_Atomic_Op"); +} + +template +ACE_Atomic_Op::ACE_Atomic_Op (TYPE c) +{ +// ACE_TRACE ("ACE_Atomic_Op::ACE_Atomic_Op"); + this->value_ = c; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Guard) + +template void +ACE_Guard::dump (void) const +{ +// ACE_TRACE ("ACE_Guard::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "lock_ = %x\n", this->lock_)); + ACE_DEBUG ((LM_DEBUG, "owner_ = %d\n", this->owner_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Write_Guard) + +template void +ACE_Write_Guard::dump (void) const +{ +// ACE_TRACE ("ACE_Write_Guard::dump"); + ACE_Guard::dump (); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Read_Guard) + +template void +ACE_Read_Guard::dump (void) const +{ +// ACE_TRACE ("ACE_Read_Guard::dump"); + ACE_Guard::dump (); +} + +#if defined (ACE_HAS_THREADS) + +#if defined (__osf__) && ! defined (__GNUG__) +#pragma define_template ACE_Condition +#endif + +ACE_ALLOC_HOOK_DEFINE(ACE_Condition) + +template void +ACE_Condition::dump (void) const +{ +// ACE_TRACE ("ACE_Condition::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +template +ACE_Thread_Condition::ACE_Thread_Condition (MUTEX &m, + LPCTSTR name, + void *arg) + : ACE_Condition (m, USYNC_THREAD, name, arg) +{ +// ACE_TRACE ("ACE_Thread_Condition::ACE_Thread_Condition"); +} + +template void +ACE_Thread_Condition::dump (void) const +{ +// ACE_TRACE ("ACE_Thread_Condition::dump"); + + ACE_Condition::dump (); +} + +template void +ACE_Process_Condition::dump (void) const +{ +// ACE_TRACE ("ACE_Process_Condition::dump"); + + ACE_Condition::dump (); +} + +template +ACE_Process_Condition::ACE_Process_Condition (MUTEX &m, + LPCTSTR name, + void *arg) + : ACE_Condition (m, USYNC_PROCESS, name, arg) +{ +// ACE_TRACE ("ACE_Process_Condition::ACE_Process_Condition"); +} + +template +ACE_Condition::ACE_Condition (MUTEX &m, + int type, + LPCTSTR name, + void *arg) + : mutex_ (m) +{ +// ACE_TRACE ("ACE_Condition::ACE_Condition"); + if (ACE_OS::cond_init (&this->cond_, type, name, arg) != 0) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Condition::ACE_Condition")); +} + +template +ACE_Condition::~ACE_Condition (void) +{ +// ACE_TRACE ("ACE_Condition::~ACE_Condition"); + if (this->remove () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Condition::~ACE_Condition")); +} + +template int +ACE_Condition::wait (void) +{ +// ACE_TRACE ("ACE_Condition::wait"); + return ACE_OS::cond_wait (&this->cond_, this->mutex_.lock_); +} + +template int +ACE_Condition::wait (MUTEX &mutex, + const ACE_Time_Value *abstime) +{ +// ACE_TRACE ("ACE_Condition::wait"); + if (abstime == 0) + return this->wait (); + else + return ACE_OS::cond_timedwait (&this->cond_, + &mutex.lock_, + (ACE_Time_Value *) abstime); +} + +// Peform an "alertable" timed wait. If the argument ABSTIME == 0 +// then we do a regular cond_wait(), else we do a timed wait for up to +// ABSTIME using the Solaris cond_timedwait() function. + +template int +ACE_Condition::wait (const ACE_Time_Value *abstime) +{ +// ACE_TRACE ("ACE_Condition::wait"); + return this->wait (this->mutex_, abstime); +} +#endif /* ACE_HAS_THREADS */ + +ACE_ALLOC_HOOK_DEFINE(ACE_TSS) + +template +ACE_TSS::~ACE_TSS (void) +{ + ACE_OS::thr_key_detach (this); +} + +template TYPE * +ACE_TSS::operator-> () const +{ + return this->ts_get (); +} + +template +ACE_TSS::operator TYPE *(void) const +{ + return this->ts_get (); +} + +template TYPE * +ACE_TSS::make_TSS_TYPE (void) const +{ + return new TYPE; +} + +template void +ACE_TSS::dump (void) const +{ +// ACE_TRACE ("ACE_TSS::dump"); +#if defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + this->keylock_.dump (); + ACE_DEBUG ((LM_DEBUG, "key_ = %d\n", this->key_)); + ACE_DEBUG ((LM_DEBUG, "\nonce_ = %d", this->once_)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +#endif /* defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) */ +} + +#if !(defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)) +template ACE_INLINE +ACE_TSS::ACE_TSS (TYPE *) +{ +} + +template ACE_INLINE TYPE * +ACE_TSS::ts_object (void) const +{ + return (TYPE *) &this->type_; +} + +template ACE_INLINE TYPE * +ACE_TSS::ts_object (TYPE *) +{ + return &this->type_; +} + +template ACE_INLINE TYPE * +ACE_TSS::ts_get (void) const +{ + return (TYPE *) &this->type_; +} +#else +template +ACE_TSS::ACE_TSS (TYPE *ts_obj) + : once_ (0), + key_ (0) +{ + // If caller has passed us a non-NULL TYPE *, then we'll just use + // this to initialize the thread-specific value. Thus, subsequent + // calls to operator->() will return this value. This is useful + // since it enables us to assign objects to thread-specific data + // that have arbitrarily complex constructors! + + if (ts_obj != 0) + { + ACE_ASSERT (this->once_ == 0); + + if (ACE_Thread::keycreate (&this->key_, + &ACE_TSS::cleanup, + (void *) this) != 0) + { + int errnum = errno; + // What should we do if this call fails?! + ACE_OS::fprintf (stderr, "ACE_Thread::keycreate() failed!"); + errno = errnum; + return; + } + + this->once_ = 1; + + if (ACE_Thread::setspecific (this->key_, (void *) ts_obj) != 0) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Thread::setspecific() failed!")); + } +} + +template TYPE * +ACE_TSS::ts_get (void) const +{ + // Create and initialize thread-specific ts_obj. + if (this->once_ == 0) + { + // Insure that we are serialized! + ACE_GUARD_RETURN (ACE_Mutex, ace_mon, (ACE_Mutex &) this->keylock_, 0); + + // Use the Double-Check pattern to make sure we only create the + // key once! + if (this->once_ == 0) + { + if (ACE_Thread::keycreate ((ACE_thread_key_t *) &this->key_, + &ACE_TSS::cleanup, + (void *) this) != 0) + return 0; // Major problems, this should *never* happen! + + // This *must* come last to avoid race conditions! Note + // that we need to "cast away const..." + *(int *) &this->once_ = 1; + } + } + + TYPE *ts_obj = 0; + + // Get the ts_obj from thread-specific storage. Note that no locks + // are required here... + if (ACE_Thread::getspecific (this->key_, (void **) &ts_obj) == -1) + return 0; // This should not happen! + + // Check to see if this is the first time in for this thread. + if (ts_obj == 0) + { + // Allocate memory off the heap and store it in a pointer in + // thread-specific storage (on the stack...). + + ts_obj = this->make_TSS_TYPE (); + + if (ts_obj == 0) + return 0; + + // Store the dynamically allocated pointer in thread-specific + // storage. + if (ACE_Thread::setspecific (this->key_, (void *) ts_obj) != 0) + { + delete ts_obj; + return 0; // Major problems, this should *never* happen! + } + } + + return ts_obj; +} + +// Get the thread-specific object for the key associated with this +// object. Returns 0 if the ts_obj has never been initialized, +// otherwise returns a pointer to the ts_obj. + +template TYPE * +ACE_TSS::ts_object (void) const +{ + // Ensure that we are serialized! + ACE_GUARD_RETURN (ACE_Mutex, ace_mon, (ACE_Mutex &) this->keylock_, 0); + + if (this->once_ == 0) // Return 0 if we've never been initialized. + return 0; + else + { + TYPE *ts_obj = 0; + + if (ACE_Thread::getspecific (this->key_, (void **) &ts_obj) == -1) + return 0; // This should not happen! + else + return ts_obj; + } +} + +template TYPE * +ACE_TSS::ts_object (TYPE *new_ts_obj) +{ + // Ensure that we are serialized! + ACE_GUARD_RETURN (ACE_Mutex, ace_mon, this->keylock_, 0); + + if (this->once_ == 0) // Return 0 if we've never been initialized. + return 0; + else + { + TYPE *ts_obj = 0; + + if (ACE_Thread::getspecific (this->key_, (void **) &ts_obj) == -1) + return 0; // This should not happen! + if (ACE_Thread::setspecific (this->key_, (void *) new_ts_obj) == -1) + return ts_obj; // This should not happen! + else + return ts_obj; + } +} + +/* static */ +template void +ACE_TSS::cleanup (void *ptr) +{ + // This cast is necessary to invoke the destructor (if necessary). + delete (TYPE *) ptr; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_TSS_Guard) + +template void +ACE_TSS_Guard::dump (void) const +{ +// ACE_TRACE ("ACE_TSS_Guard::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "key_ = %d", this->key_)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +template void +ACE_TSS_Guard::init_key (void) +{ +// ACE_TRACE ("ACE_TSS_Guard::init_key"); + + this->key_ = 0; + ACE_Thread::keycreate (&this->key_, + &ACE_TSS_Guard::cleanup, + (void *) this); +} + +template +ACE_TSS_Guard::ACE_TSS_Guard (void) +{ +// ACE_TRACE ("ACE_TSS_Guard::ACE_TSS_Guard"); + this->init_key (); +} + +template int +ACE_TSS_Guard::release (void) +{ +// ACE_TRACE ("ACE_TSS_Guard::release"); + + ACE_Guard *guard = 0; + ACE_Thread::getspecific (this->key_, (void **) &guard); + return guard->release (); +} + +template int +ACE_TSS_Guard::remove (void) +{ +// ACE_TRACE ("ACE_TSS_Guard::remove"); + + ACE_Guard *guard = 0; + ACE_Thread::getspecific (this->key_, (void **) &guard); + return guard->remove (); +} + +template +ACE_TSS_Guard::~ACE_TSS_Guard (void) +{ +// ACE_TRACE ("ACE_TSS_Guard::~ACE_TSS_Guard"); + + ACE_Guard *guard = 0; + ACE_Thread::getspecific (this->key_, (void **) &guard); + // Make sure that this pointer is NULL when we shut down... + ACE_Thread::setspecific (this->key_, 0); + ACE_Thread::keyfree (this->key_); + // Destructor releases lock. + delete guard; +} + +template void +ACE_TSS_Guard::cleanup (void *ptr) +{ +// ACE_TRACE ("ACE_TSS_Guard::dump"); + + // Destructor releases lock. + delete (ACE_Guard *) ptr; +} + +template +ACE_TSS_Guard::ACE_TSS_Guard (LOCK &lock, int block) +{ +// ACE_TRACE ("ACE_TSS_Guard::ACE_TSS_Guard"); + + this->init_key (); + ACE_Guard *guard; + ACE_NEW (guard, ACE_Guard (lock, block)); + ACE_Thread::setspecific (this->key_, (void *) guard); +} + +template int +ACE_TSS_Guard::acquire (void) +{ +// ACE_TRACE ("ACE_TSS_Guard::acquire"); + + ACE_Guard *guard = 0; + ACE_Thread::getspecific (this->key_, (void **) &guard); + return guard->acquire (); +} + +template int +ACE_TSS_Guard::tryacquire (void) +{ +// ACE_TRACE ("ACE_TSS_Guard::tryacquire"); + + ACE_Guard *guard = 0; + ACE_Thread::getspecific (this->key_, (void **) &guard); + return guard->tryacquire (); +} + +template +ACE_TSS_Write_Guard::ACE_TSS_Write_Guard (LOCK &lock, int block) +{ +// ACE_TRACE ("ACE_TSS_Write_Guard::ACE_TSS_Write_Guard"); + + this->init_key (); + ACE_Guard *guard; + ACE_NEW (guard, ACE_Write_Guard (lock, block)); + ACE_Thread::setspecific (this->key_, (void *) guard); +} + +template int +ACE_TSS_Write_Guard::acquire (void) +{ +// ACE_TRACE ("ACE_TSS_Write_Guard::acquire"); + + ACE_Write_Guard *guard = 0; + ACE_Thread::getspecific (this->key_, (void **) &guard); + return guard->acquire_write (); +} + +template int +ACE_TSS_Write_Guard::tryacquire (void) +{ +// ACE_TRACE ("ACE_TSS_Write_Guard::tryacquire"); + + ACE_Write_Guard *guard = 0; + ACE_Thread::getspecific (this->key_, (void **) &guard); + return guard->tryacquire_write (); +} + +template int +ACE_TSS_Write_Guard::acquire_write (void) +{ +// ACE_TRACE ("ACE_TSS_Write_Guard::acquire_write"); + + return this->acquire (); +} + +template int +ACE_TSS_Write_Guard::tryacquire_write (void) +{ +// ACE_TRACE ("ACE_TSS_Write_Guard::tryacquire_write"); + + return this->tryacquire (); +} + +template void +ACE_TSS_Write_Guard::dump (void) const +{ +// ACE_TRACE ("ACE_TSS_Write_Guard::dump"); + ACE_TSS_Guard::dump (); +} + +template +ACE_TSS_Read_Guard::ACE_TSS_Read_Guard (LOCK &lock, int block) +{ +// ACE_TRACE ("ACE_TSS_Read_Guard::ACE_TSS_Read_Guard"); + + this->init_key (); + ACE_Guard *guard; + ACE_NEW (guard, ACE_Read_Guard (lock, block)); + ACE_Thread::setspecific (this->key_, (void *) guard); +} + +template int +ACE_TSS_Read_Guard::acquire (void) +{ +// ACE_TRACE ("ACE_TSS_Read_Guard::acquire"); + + ACE_Read_Guard *guard = 0; + ACE_Thread::getspecific (this->key_, (void **) &guard); + return guard->acquire_read (); +} + +template int +ACE_TSS_Read_Guard::tryacquire (void) +{ +// ACE_TRACE ("ACE_TSS_Read_Guard::tryacquire"); + + ACE_Read_Guard *guard = 0; + ACE_Thread::getspecific (this->key_, (void **) &guard); + return guard->tryacquire_read (); +} + +template int +ACE_TSS_Read_Guard::acquire_read (void) +{ +// ACE_TRACE ("ACE_TSS_Read_Guard::acquire_read"); + + return this->acquire (); +} + +template int +ACE_TSS_Read_Guard::tryacquire_read (void) +{ +// ACE_TRACE ("ACE_TSS_Read_Guard::tryacquire_read"); + + return this->tryacquire (); +} + +template void +ACE_TSS_Read_Guard::dump (void) const +{ +// ACE_TRACE ("ACE_TSS_Read_Guard::dump"); + ACE_TSS_Guard::dump (); +} + +#endif /* defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) */ +#endif /* ACE_SYNCH_T_C */ diff --git a/ace/Synch_T.h b/ace/Synch_T.h new file mode 100644 index 00000000000..ffa705c0f70 --- /dev/null +++ b/ace/Synch_T.h @@ -0,0 +1,613 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Synch_T.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SYNCH_T_H) +#define ACE_SYNCH_T_H + +#include "ace/Event_Handler.h" +#include "ace/Synch.h" + +// Forward decl +class ACE_Time_Value; + +template +class ACE_Test_and_Set : public ACE_Event_Handler +{ + // = TITLE + // Implements the classic ``test and set'' operation. + // + // = DESCRIPTION + // This class keeps track of the status of , which can + // be set based on various events (such as receipt of a signal). +public: + ACE_Test_and_Set (TYPE initial_value = 0); + + TYPE is_set (void) const; + // Returns true if we are set, else false. + + TYPE set (TYPE); + // Sets the status, returning + + virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); + // Called when object is signaled by OS (either via UNIX signals or + // when a Win32 object becomes signaled). + +private: + TYPE is_set_; + // Keeps track of our state. + + LOCK lock_; +}; + +template +class ACE_Atomic_Op + // = TITLE + // Transparently parameterizes synchronization into basic + // arithmetic operations. + // + // = DESCRIPTION + // This class is described in an article in the July/August 1994 + // issue of the C++ Report magazine. It implements a + // templatized version of the Decorator pattern from the GoF book. +{ +public: + ACE_Atomic_Op (void); + // Initialize to 0. + + ACE_Atomic_Op (TYPE c); + // Initialize to c. + + TYPE operator++ (void); + // Atomically pre-increment . + + TYPE operator++ (int); + // Atomically post-increment . + + TYPE operator+= (const TYPE i); + // Atomically increment by inc. + + TYPE operator-- (void); + // Atomically pre-decrement . + + TYPE operator-- (int); + // Atomically post-decrement . + + TYPE operator-= (const TYPE i); + // Atomically decrement by dec. + + TYPE operator== (const TYPE i) const; + // Atomically compare with rhs. + + TYPE operator>= (const TYPE i) const; + // Atomically check if greater than or equal to rhs. + + TYPE operator> (const TYPE rhs) const; + // Atomically check if greater than rhs. + + TYPE operator<= (const TYPE rhs) const; + // Atomically check if less than or equal to rhs. + + TYPE operator< (const TYPE rhs) const; + // Atomically check if less than rhs. + + void operator= (const TYPE i); + // Atomically assign rhs to . + + void operator= (const ACE_Atomic_Op &rhs); + // Atomically assign to . + + operator TYPE () const; + // Atomically return . + + void dump (void) const; + // Dump the state of an object. + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + + ACE_Atomic_Op (const ACE_Atomic_Op &); + // Manage copying... + +private: + LOCK lock_; + // Type of synchronization mechanism. + + TYPE value_; + // Current object decorated by the atomic op. +}; + +template +class ACE_TSS + // = TITLE + // Allows objects that are "physically" in thread specific + // storage (i.e., private to a thread) to be accessed as though + // they were "logically" global to a program. + // + // = DESCRIPTION + // This class is a wrapper around the OS thread library + // thread-specific functions. It uses the C++ operator->() to + // shield applications from the details of accessing + // thread-specific storage. +{ +public: + ACE_TSS (TYPE *ts_obj = 0); + // If caller has passed us a non-NULL ts_obj *, then we'll just use + // this to initialize the thread-specific value. Thus, subsequent + // calls to operator->() will return this value. This is useful + // since it enables us to assign objects to thread-specific data + // that have arbitrarily complex constructors! + + ~ACE_TSS (void); + // Deregister with thread-key administration. + + TYPE *ts_object (void) const; + // Get the thread-specific object for the key associated with this + // object. Returns 0 if the data has never been initialized, + // otherwise returns a pointer to the data. + + TYPE *ts_object (TYPE *); + // Set the thread-specific object for the key associated with this + // object. Returns 0 if the data has never been initialized, + // otherwise returns a pointer to the previous value for the data. + + TYPE *operator-> () const; + // Use a "smart pointer" to get the thread-specific object + // associated with the . + + operator TYPE *(void) const; + // return or create and return the calling threads TYPE object. + + virtual TYPE *make_TSS_TYPE (void) const; + // hook for construction parameters. + + void dump (void) const; + // Dump the state of an object. + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + TYPE *ts_get (void) const; + // Actually implements the code that retrieves the object from + // thread-specific storage. + +#if !(defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)) + TYPE type_; + // This implementation only works for non-threading systems... +#else + ACE_Mutex keylock_; + // Avoid race conditions during initialization. + + int once_; + // "First time in" flag. + + ACE_thread_key_t key_; + // Key for the thread-specific error data. + + static void cleanup (void *ptr); + // "Destructor" that deletes internal TYPE * when thread exits. +#endif /* defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) */ + // = Disallow copying... + void operator= (const ACE_TSS &) {} + ACE_TSS (const ACE_TSS &) {} +}; + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) +class ACE_NULL_SYNCH + // = TITLE + // Implement a do nothing Synchronization wrapper that + // typedefs the and to the Null* versions. +{ +public: + typedef ACE_Null_Mutex MUTEX; + // "Do-nothing" mutex type. + + typedef ACE_Null_Condition_Mutex CONDITION; + // "Do-nothing" condition type. +}; +#else /* Necessary to support broken cfront-based C++ compilers... */ +#define ACE_NULL_SYNCH ACE_Null_Mutex, ACE_Null_Condition_Mutex +#endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ + +template +class ACE_Guard + // = TITLE + // This data structure is meant to be used within a method or + // function... It performs automatic aquisition and release of + // a parameterized synchronization object . + // + // = DESCRIPTION + // The class given as an actual parameter must provide at + // the very least the , , , and + // methods. +{ +public: + ACE_Guard (LOCK &l, int block = 1): lock_ (&l) + { + this->owner_ = block ? this->acquire () : this->tryacquire (); + } + // Implicitly and automatically acquire (or try to acquire) the + // lock. + + ~ACE_Guard (void) { if (this->owner_ != -1) this->release (); } + // Implicitly release the lock. + + int locked (void) { return this->owner_ != -1; } + // 1 if locked, 0 if couldn't acquire the lock + // (errno will contain the reason for this). + + int remove (void) { return this->release (); } + // Explicitly release the lock. + + int acquire (void) { return this->owner_ = this->lock_->acquire (); } + // Explicitly acquire the lock. + + int tryacquire (void) { return this->owner_ = this->lock_->tryacquire (); } + // Conditionally acquire the lock (i.e., won't block). + + int release (void) { this->owner_ = -1; return this->lock_->release (); } + // Explicitly release the lock. + + void dump (void) const; + // Dump the state of an object. + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + ACE_Guard (LOCK *lock): lock_ (lock) {} + // Helper, meant for subclass only. + + LOCK *lock_; + // Pointer to the LOCK we're guarding. + + int owner_; + // Keeps track of whether we acquired the lock or failed. + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Guard &) {} + ACE_Guard (const ACE_Guard &) {} +}; + +template +class ACE_Write_Guard : public ACE_Guard + // = TITLE + // This class is similar to class , though it + // acquires/releases a write lock automatically (naturally, the + // it is instantiated with must support the appropriate + // API). +{ +public: + ACE_Write_Guard (LOCK &m, int block = 1): ACE_Guard (&m) + { + this->owner_ = block ? this->acquire_write () : this->tryacquire_write (); + } + // Implicitly and automatically acquire (or try to acquire) a write + // lock. + + int acquire_write (void) { return this->owner_ = this->lock_->acquire_write (); } + // Explicitly acquire the write lock. + + int acquire (void) { return this->owner_ = this->lock_->acquire_write (); } + // Explicitly acquire the write lock. + + int tryacquire_write (void) { return this->owner_ = this->lock_->acquire_write (); } + // Conditionally acquire the write lock (i.e., won't block). + + int tryacquire (void) { return this->owner_ = this->lock_->tryacquire_write (); } + // Conditionally acquire the write lock (i.e., won't block). + + void dump (void) const; + // Dump the state of an object. + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +template +class ACE_Read_Guard : public ACE_Guard + // = TITLE + // This class is similar to class , though it + // acquires/releases a read lock automatically (naturally, the + // it is instantiated with must support the appropriate + // API). +{ +public: + ACE_Read_Guard (LOCK &m, int block = 1): ACE_Guard (&m) + { + this->owner_ = block ? this->acquire_read () : this->tryacquire_read (); + } + // Implicitly and automatically acquire (or try to acquire) a read + // lock. + + int acquire_read (void) { return this->owner_ = this->lock_->acquire_read (); } + // Explicitly acquire the read lock. + + int acquire (void) { return this->owner_ = this->lock_->acquire_read (); } + // Explicitly acquire the read lock. + + int tryacquire_read (void) { return this->owner_ = this->lock_->tryacquire_read (); } + // Conditionally acquire the read lock (i.e., won't block). + + int tryacquire (void) { return this->owner_ = this->lock_->tryacquire_read (); } + // Conditionally acquire the read lock (i.e., won't block). + + void dump (void) const; + // Dump the state of an object. + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#if !(defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)) + +#define ACE_TSS_Guard ACE_Guard +#define ACE_TSS_Write_GUARD ACE_Write_Guard +#define ACE_TSS_Read_GUARD ACE_Read_Guard + +#else // ACE platform supports some form of threading and + // thread-specific storage. + +template +class ACE_TSS_Guard + // = TITLE + // This data structure is meant to be used within a method or + // function... It performs automatic aquisition and release of + // a synchronization object. Moreover, it ensures that the lock + // is released even if a thread exits via "thr_exit()"! +{ +public: + ACE_TSS_Guard (LOCK &lock, int block = 1); + // Implicitly and automatically acquire the thread-specific lock. + + ~ACE_TSS_Guard (void); + // Implicitly release the thread-specific lock. + + int remove (void); + // Explicitly release the thread-specific lock. + + int acquire (void); + // Explicitly acquire the thread-specific lock. + + int tryacquire (void); + // Conditionally acquire the thread-specific lock (i.e., won't + // block). + + int release (void); + // Explicitly release the thread-specific lock. + + void dump (void) const; + // Dump the state of an object. + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + ACE_TSS_Guard (void); + // Helper, meant for subclass only. + + void init_key (void); + // Initialize the key. + + static void cleanup (void *ptr); + // Called when thread exits to clean up the lock. + + ACE_thread_key_t key_; + // Thread-specific key... + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_TSS_Guard &) {} + ACE_TSS_Guard (const ACE_TSS_Guard &) {} +}; + +template +class ACE_TSS_Write_Guard : public ACE_TSS_Guard + // = TITLE + // This class is similar to class ACE_TSS_Guard, though it + // acquires/releases a write-lock automatically (naturally, the + // LOCK it is instantiated with must support the appropriate + // API). +{ +public: + ACE_TSS_Write_Guard (LOCK &lock, int block = 1); + // Implicitly and automatically acquire the thread-specific write lock. + + int acquire_write (void); + // Explicitly acquire the thread-specific write lock. + + int acquire (void); + // Explicitly acquire the thread-specific write lock. + + int tryacquire_write (void); + // Conditionally acquire the thread-specific write lock (i.e., won't block). + + int tryacquire (void); + // Conditionally acquire the thread-specific write lock (i.e., won't block). + + void dump (void) const; + // Dump the state of an object. + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +template +class ACE_TSS_Read_Guard : public ACE_TSS_Guard + // = TITLE + // This class is similar to class , though it + // acquires/releases a read lock automatically (naturally, the + // it is instantiated with must support the appropriate + // API). +{ +public: + ACE_TSS_Read_Guard (LOCK &lock, int block = 1); + // Implicitly and automatically acquire the thread-specific read lock. + + int acquire_read (void); + // Explicitly acquire the thread-specific read lock. + + int acquire (void); + // Explicitly acquire the thread-specific read lock. + + int tryacquire_read (void); + // Conditionally acquire the thread-specific read lock (i.e., won't block). + + int tryacquire (void); + // Conditionally acquire the thread-specific read lock (i.e., won't block). + + void dump (void) const; + // Dump the state of an object. + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; +#endif /* !(defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)) */ + +#if defined (ACE_HAS_THREADS) // ACE platform supports some form of threading. + +template +class ACE_Condition + // = TITLE + // ACE_Condition variable wrapper, which allows threads to block + // until shared data changes state. +{ +public: + ACE_Condition (MUTEX &m, int type = USYNC_THREAD, + LPCTSTR name = 0, void *arg = 0); + // Initialize the condition variable. + + ~ACE_Condition (void); + // Implicitly destroy the condition variable. + + int remove (void); + // Explicitly destroy the condition variable. + + int wait (const ACE_Time_Value *abstime); + // Block on condition, or until absolute time-of-day has passed. If + // abstime == 0 use "blocking" semantics. Else, if + // != 0 and the call times out before the condition is signaled + // returns -1 and sets errno to ETIME. + + int wait (void); + // Block on condition. + + int wait (MUTEX &mutex, const ACE_Time_Value *abstime = 0); + // Block on condition or until absolute time-of-day has passed. If + // abstime == 0 use "blocking" wait() semantics on the + // passed as a parameter (this is useful if you need to store the + // in shared memory). Else, if != 0 and the + // call times out before the condition is signaled returns -1 + // and sets errno to ETIME. + + int signal (void); + // Signal one waiting thread. + + int broadcast (void); + // Signal *all* waiting threads. + + MUTEX &mutex (void); + // Returns a reference to the underlying mutex_; + + void dump (void) const; + // Dump the state of an object. + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_cond_t cond_; + // Condition variable. + + MUTEX &mutex_; + // Reference to mutex lock. + + // = Prevent assignment and initialization. + void operator= (const ACE_Condition &) {} + ACE_Condition (const ACE_Condition &c): mutex_ (c.mutex_) {} +}; + +template +class ACE_Process_Condition : public ACE_Condition + // = TITLE + // ACE_Condition variable wrapper that works across processes. +{ +public: + ACE_Process_Condition (MUTEX &m, LPCTSTR name = 0, void *arg = 0); + + void dump (void) const; + // Dump the state of an object. + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +template +class ACE_Thread_Condition : public ACE_Condition + // = TITLE + // ACE_Condition variable wrapper that works within processes. +{ +public: + ACE_Thread_Condition (MUTEX &m, LPCTSTR name = 0, void *arg = 0); + + void dump (void) const; + // Dump the state of an object. + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) +class ACE_MT_SYNCH + // = TITLE + // Implement a default thread safe synchronization wrapper that + // typedefs the and to the + // and versions. Note that this + // should be a template, but SunC++ 4.0.1 complains about + // this... +{ +public: + typedef ACE_Thread_Mutex MUTEX; + typedef ACE_Condition_Thread_Mutex CONDITION; +}; +#else /* Necessary to support broken cfront-based C++ compilers... */ +#define ACE_MT_SYNCH ACE_Thread_Mutex,ACE_Condition_Thread_Mutex +#endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ + +#if defined (__osf__) && ! defined (__GNUG__) +#pragma define_template ACE_Condition +#endif + +#define ACE_SYNCH ACE_MT_SYNCH +#else +#define ACE_SYNCH ACE_NULL_SYNCH +#endif /* ACE_HAS_THREADS */ + +#if defined (__ACE_INLINE__) +#include "ace/Synch_T.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Synch_T.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Synch_T.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_SYNCH_T_H */ diff --git a/ace/Synch_T.i b/ace/Synch_T.i new file mode 100644 index 00000000000..cdc6646d889 --- /dev/null +++ b/ace/Synch_T.i @@ -0,0 +1,176 @@ +/* -*- C++ -*- */ +// $Id$ + +// Synch_T.i + +#include "ace/Thread.h" + +template ACE_INLINE +ACE_Atomic_Op::ACE_Atomic_Op (const ACE_Atomic_Op &rhs) +{ +// ACE_TRACE ("ACE_Atomic_Op::ACE_Atomic_Op"); + *this = rhs; // Invoke the assignment operator. +} + +template ACE_INLINE TYPE +ACE_Atomic_Op::operator++ (void) +{ +// ACE_TRACE ("ACE_Atomic_Op::operator++"); + ACE_Guard m (this->lock_); + return ++this->value_; +} + +template ACE_INLINE TYPE +ACE_Atomic_Op::operator++ (int) +{ +// ACE_TRACE ("ACE_Atomic_Op::operator++"); + ACE_Guard m (this->lock_); + return this->value_++; +} + +template ACE_INLINE TYPE +ACE_Atomic_Op::operator+= (const TYPE i) +{ +// ACE_TRACE ("ACE_Atomic_Op::operator+="); + ACE_Guard m (this->lock_); + return this->value_ += i; +} + +template ACE_INLINE TYPE +ACE_Atomic_Op::operator-- (void) +{ +// ACE_TRACE ("ACE_Atomic_Op::operator--"); + ACE_Guard m (this->lock_); + return --this->value_; +} + +template ACE_INLINE TYPE +ACE_Atomic_Op::operator-- (int) +{ +// ACE_TRACE ("ACE_Atomic_Op::operator--"); + ACE_Guard m (this->lock_); + return this->value_--; +} + +template ACE_INLINE TYPE +ACE_Atomic_Op::operator-= (const TYPE i) +{ +// ACE_TRACE ("ACE_Atomic_Op::operator-="); + ACE_Guard m (this->lock_); + return this->value_ -= i; +} + +template ACE_INLINE TYPE +ACE_Atomic_Op::operator== (const TYPE i) const +{ +// ACE_TRACE ("ACE_Atomic_Op::operator=="); + ACE_Guard m ((LOCK &) this->lock_); + return this->value_ == i; +} + +template ACE_INLINE TYPE +ACE_Atomic_Op::operator>= (const TYPE i) const +{ +// ACE_TRACE ("ACE_Atomic_Op::operator>="); + ACE_Guard m ((LOCK &) this->lock_); + return this->value_ >= i; +} + +template ACE_INLINE TYPE +ACE_Atomic_Op::operator> (const TYPE rhs) const +{ +// ACE_TRACE ("ACE_Atomic_Op::operator>"); + ACE_Guard m ((LOCK &) this->lock_); + return this->value_ > rhs; +} + +template ACE_INLINE TYPE +ACE_Atomic_Op::operator<= (const TYPE rhs) const +{ +// ACE_TRACE ("ACE_Atomic_Op::operator<="); + ACE_Guard m ((LOCK &) this->lock_); + return this->value_ <= rhs; +} + +template ACE_INLINE TYPE +ACE_Atomic_Op::operator< (const TYPE rhs) const +{ +// ACE_TRACE ("ACE_Atomic_Op::operator<"); + ACE_Guard m ((LOCK &) this->lock_); + return this->value_ < rhs; +} + +template void +ACE_Atomic_Op::operator= (const ACE_Atomic_Op &rhs) +{ +// ACE_TRACE ("ACE_Atomic_Op::operator="); + if (&rhs == this) + return; // Avoid deadlock... + ACE_Guard m (this->lock_); + // This will call ACE_Atomic_Op::TYPE(), which will ensure the value + // of is acquired atomically. + this->value_ = rhs; +} + +template ACE_INLINE +ACE_Atomic_Op::operator TYPE () const +{ +// ACE_TRACE ("ACE_Atomic_Op::operator TYPE"); + ACE_Guard m ((LOCK &) this->lock_); + return this->value_; +} + +template ACE_INLINE void +ACE_Atomic_Op::operator= (const TYPE i) +{ +// ACE_TRACE ("ACE_Atomic_Op::operator="); + ACE_Guard m (this->lock_); + this->value_ = i; +} +#if defined (ACE_HAS_THREADS) + +template ACE_INLINE int +ACE_Condition::remove (void) +{ +// ACE_TRACE ("ACE_Condition::remove"); + + // cond_destroy() is called in a loop if the condition variable is + // BUSY. This avoids a condition where a condition is signaled and + // because of some timing problem, the thread that is to be signaled + // has called the cond_wait routine after the signal call. Since + // the condition signal is not queued in any way, deadlock occurs. + + int result = 0; + + while ((result = ACE_OS::cond_destroy (&this->cond_)) == -1 + && errno == EBUSY) + { + ACE_OS::cond_broadcast (&this->cond_); + ACE_OS::thr_yield (); + } + + return result; +} + +template ACE_INLINE MUTEX & +ACE_Condition::mutex (void) +{ +// ACE_TRACE ("ACE_Condition::mutex"); + return this->mutex_; +} + +template ACE_INLINE int +ACE_Condition::signal (void) +{ +// ACE_TRACE ("ACE_Condition::signal"); + return ACE_OS::cond_signal (&this->cond_); +} + +template ACE_INLINE int +ACE_Condition::broadcast (void) +{ +// ACE_TRACE ("ACE_Condition::broadcast"); + return ACE_OS::cond_broadcast (&this->cond_); +} +#endif /* ACE_HAS_THREADS */ + diff --git a/ace/System_Time.cpp b/ace/System_Time.cpp new file mode 100644 index 00000000000..14a13a9939f --- /dev/null +++ b/ace/System_Time.cpp @@ -0,0 +1,86 @@ +// System_Time.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Time_Value.h" +#include "ace/System_Time.h" + +ACE_System_Time::ACE_System_Time (const char *poolname) +: delta_time_ (0) +{ + ACE_TRACE ("ACE_System_Time::ACE_System_Time"); + ACE_NEW (this->shmem_, ALLOCATOR (poolname)); +} + +ACE_System_Time::~ACE_System_Time (void) +{ + delete this->shmem_; + ACE_TRACE ("ACE_System_Time::~ACE_System_Time"); +} + +// Get the local system time. + +int +ACE_System_Time::get_local_system_time (ACE_UINT32 &time_out) +{ + ACE_TRACE ("ACE_System_Time::get_local_system_time"); + time_t t = ACE_OS::time (0); + time_out = t; + return 0; +} + +// Get the system time of the central time server. + +int +ACE_System_Time::get_master_system_time (ACE_UINT32 &time_out) +{ + ACE_TRACE ("ACE_System_Time::get_master_system_time"); + if (this->delta_time_ == 0) + { + // Try to find it + void * temp; + if (this->shmem_->find (ACE_DEFAULT_TIME_SERVER_STR, temp) == -1) + { + // No time entry in shared memory (meaning no Clerk exists) + // so return the local time of the host. + return this->get_local_system_time (time_out); + } + else + { + // Extract the delta time + this->delta_time_ = (long *) temp; + } + } + ACE_UINT32 local_time; + + // If delta_time is positive, it means that the system clock is + // ahead of our local clock so add delta to the local time to get an + // approximation of the system time. Else if delta time is negative, + // it means that our local clock is ahead of the system clock, so + // return the last local time stored (to avoid time conflicts). + if (*this->delta_time_ >=0 ) + { + this->get_local_system_time (local_time); + time_out = local_time + (ACE_UINT32) *this->delta_time_; + } + else + // Return the last local time. Note that this is stored as the + // second field in shared memory. + time_out = *(this->delta_time_ + 1); + return 0; +} + +// Synchronize local system time with the central time server using +// specified mode. + +int +ACE_System_Time::sync_local_system_time (ACE_System_Time::Sync_Mode mode) +{ + ACE_TRACE ("ACE_System_Time::sync_local_system_time"); + return 0; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Malloc; +template class ACE_Allocator_Adapter >; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/ace/System_Time.h b/ace/System_Time.h new file mode 100644 index 00000000000..c8c1035fe03 --- /dev/null +++ b/ace/System_Time.h @@ -0,0 +1,73 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// System_Time.h +// +// = AUTHOR +// Prashant Jain, Tim H. Harrison and Douglas C. Schmidt +// +// ============================================================================ + +#if !defined (ACE_SYSTEM_TIME_H) +#define ACE_SYSTEM_TIME_H + +#include "ace/OS.h" +#include "ace/Malloc.h" + +class ACE_Export ACE_Date_Time + // TITLE + // This class holds internally date and time and has interfaces + // for getting month or compares of times and dates, etc. +{ +public: +}; + +class ACE_Export ACE_System_Time + // = TITLE + // Defines the timer services of the OS interface to access the + // system time either on the local host or on the central time + // server in the network. +{ +public: + enum Sync_Mode { Jump, Adjust }; + // enumeration types to specify mode of synchronization with master + // clock. Jump will set local system time directly (thus possibly + // producing time gaps or ambiguous local system times. Adjust will + // smoothly slow down or speed up the local system clock to reach + // the system time of the master clock. + + ACE_System_Time (const char *poolname = ACE_DEFAULT_BACKING_STORE); + // Default constructor. + + ~ACE_System_Time (void); + // Default destructor. + + int get_local_system_time (ACE_UINT32 &time_out); + // Get the local system time. + + int get_master_system_time (ACE_UINT32 &time_out); + // Get the system time of the central time server. + + int sync_local_system_time (ACE_System_Time::Sync_Mode mode); + // synchronize local system time with the central time server using + // specified mode. + +private: + typedef ACE_Malloc MALLOC; + typedef ACE_Allocator_Adapter ALLOCATOR; + + ALLOCATOR *shmem_; + // Our allocator (used for obtaining system time from shared memory). + + long *delta_time_; + // Pointer to delta time kept in shared memory. +}; + +#endif /* ACE_SYSTEM_TIME_H */ diff --git a/ace/TLI.cpp b/ace/TLI.cpp new file mode 100644 index 00000000000..d7724a87f6a --- /dev/null +++ b/ace/TLI.cpp @@ -0,0 +1,172 @@ +// TLI.cpp +// $Id$ + +/* Defines the member functions for the base class of the ACE_TLI + abstraction. */ + +#define ACE_BUILD_DLL +#include "ace/TLI.h" +#include "ace/Log_Msg.h" + +#if defined (ACE_HAS_TLI) + +ACE_ALLOC_HOOK_DEFINE(ACE_TLI) + +void +ACE_TLI::dump (void) const +{ + ACE_TRACE ("ACE_TLI::dump"); +} + +ACE_TLI::ACE_TLI (void) +{ + ACE_TRACE ("ACE_TLI::ACE_TLI"); +#if defined (ACE_HAS_SVR4_TLI) +// Solaris 2.4 ACE_TLI option handling is broken. Thus, we must do +// the memory allocation ourselves... Thanks to John P. Hearn +// (jph@ccrl.nj.nec.com) for the help. + + this->so_opt_req.opt.maxlen = sizeof (opthdr) + sizeof (long); + ACE_NEW (this->so_opt_req.opt.buf, char[this->so_opt_req.opt.maxlen]); + + this->so_opt_ret.opt.maxlen = sizeof (opthdr) + sizeof (long); + this->so_opt_ret.opt.buf = new char[this->so_opt_ret.opt.maxlen]; + + if (this->so_opt_ret.opt.buf == 0) + { + delete [] this->so_opt_req.opt.buf; + this->so_opt_req.opt.buf = 0; + return; + } +#endif /* ACE_HAS_SVR4_TLI */ +} + +ACE_HANDLE +ACE_TLI::open (const char device[], int oflag, struct t_info *info) +{ + ACE_TRACE ("ACE_TLI::open"); + if (oflag == 0) + oflag = O_RDWR; + this->set_handle (ACE_OS::t_open ((char *) device, oflag, info)); + + return this->get_handle (); +} + +ACE_TLI::~ACE_TLI (void) +{ + ACE_TRACE ("ACE_TLI::~ACE_TLI"); +#if defined (ACE_HAS_SVR4_TLI) + if (this->so_opt_req.opt.buf) + { + delete [] this->so_opt_req.opt.buf; + delete [] this->so_opt_ret.opt.buf; + this->so_opt_req.opt.buf = 0; + this->so_opt_ret.opt.buf = 0; + } +#endif /* ACE_HAS_SVR4_TLI */ +} + +ACE_TLI::ACE_TLI (const char device[], int oflag, struct t_info *info) +{ + ACE_TRACE ("ACE_TLI::ACE_TLI"); + if (this->open (device, oflag, info) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_TLI::ACE_TLI")); +} + +int +ACE_TLI::get_local_addr (ACE_Addr &sa) const +{ + ACE_TRACE ("ACE_TLI::get_local_addr"); +#if defined (ACE_HAS_SVR4_TLI) + struct netbuf name; + + name.maxlen = sa.get_size (); + name.buf = (char *) sa.get_addr (); + + if (ACE_OS::ioctl (this->get_handle (), TI_GETMYNAME, &name) == -1) +/* if (ACE_OS::t_getname (this->get_handle (), &name, LOCALNAME) == -1) */ +#else /* SunOS4 sucks... */ + if (0) +#endif /* ACE_HAS_SVR4_TLI */ + return -1; + else + return 0; +} + +int +ACE_TLI::close (void) +{ + ACE_TRACE ("ACE_TLI::close"); + ACE_HANDLE result = 0; + + if (this->get_handle () != ACE_INVALID_HANDLE) + { + result = ACE_OS::t_close (this->get_handle ()); + this->set_handle (ACE_INVALID_HANDLE); + } + return result; +} + +int +ACE_TLI::set_option (int level, int option, void *optval, int optlen) +{ + ACE_TRACE ("ACE_TLI::set_option"); +#if defined (ACE_HAS_SVR4_TLI) + /* Set up options for ACE_TLI */ + + struct opthdr *opthdr = 0; /* See for details on this format */ + + this->so_opt_req.flags = T_NEGOTIATE; + this->so_opt_req.opt.len = sizeof *opthdr + OPTLEN (optlen); + + if (this->so_opt_req.opt.len > this->so_opt_req.opt.maxlen) + { + t_errno = TBUFOVFLW; + return -1; + } + + opthdr = (struct opthdr *) this->so_opt_req.opt.buf; + opthdr->level = level; + opthdr->name = option; + opthdr->len = OPTLEN (optlen); + ACE_OS::memcpy (OPTVAL (opthdr), optval, optlen); + + return ACE_OS::t_optmgmt (this->get_handle (), &this->so_opt_req, &this->so_opt_ret); +#else + return -1; +#endif /* ACE_HAS_SVR4_TLI */ +} + +int +ACE_TLI::get_option (int level, int option, void *optval, int &optlen) +{ + ACE_TRACE ("ACE_TLI::get_option"); +#if defined (ACE_HAS_SVR4_TLI) + struct opthdr *opthdr = 0; /* See for details on this format */ + + this->so_opt_req.flags = T_CHECK; + this->so_opt_ret.opt.len = sizeof *opthdr + OPTLEN (optlen); + + if (this->so_opt_ret.opt.len > this->so_opt_ret.opt.maxlen) + { + t_errno = TBUFOVFLW; + return -1; + } + + opthdr = (struct opthdr *) this->so_opt_req.opt.buf; + opthdr->level = level; + opthdr->name = option; + opthdr->len = OPTLEN (optlen); + if (ACE_OS::t_optmgmt (this->get_handle (), &this->so_opt_req, &this->so_opt_ret) == -1) + return -1; + else + { + ACE_OS::memcpy (optval, OPTVAL (opthdr), optlen); + return 0; + } +#else + return -1; +#endif /* ACE_HAS_SVR4_TLI */ +} + +#endif /* ACE_HAS_TLI */ diff --git a/ace/TLI.h b/ace/TLI.h new file mode 100644 index 00000000000..0584a5b0c60 --- /dev/null +++ b/ace/TLI.h @@ -0,0 +1,98 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// TLI.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_TLI_H) +#define ACE_TLI_H + +#include "ace/IPC_SAP.h" +#include "ace/Addr.h" + +// The following is necessary since many C++ compilers don't support +// typedef'd types inside of classes used as formal template +// arguments... ;-(. Luckily, using the C++ preprocessor I can hide +// most of this nastiness! + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) +#define ACE_TLI_ACCEPTOR ACE_TLI_Acceptor +#define ACE_TLI_CONNECTOR ACE_TLI_Connector +#define ACE_TLI_STREAM ACE_TLI_Stream +#else /* TEMPLATES are broken (must be a cfront-based compiler...) */ +#define ACE_TLI_ACCEPTOR ACE_TLI_Acceptor, ACE_INET_Addr +#define ACE_TLI_CONNECTOR ACE_TLI_Connector, ACE_INET_Addr +#define ACE_TLI_STREAM ACE_TLI_Stream, ACE_INET_Addr +#endif /* ACE_TEMPLATE_TYPEDEFS */ + +#if defined (ACE_HAS_TLI) +class ACE_Export ACE_TLI : public ACE_IPC_SAP + // = TITLE + // Defines the member functions for the base class of the + // ACE_TLI abstraction. +{ +public: + // = Initialization and termination methods. + ACE_HANDLE open (const char device[], + int oflag = O_RDWR, + struct t_info *info = 0); + // Initialize a TLI endpoint. + + int close (void); + // Close a TLI endpoint and release resources. + + int set_option (int level, int option, void *optval, int optlen); + // Set underlying protocol options. + + int get_option (int level, int option, void *optval, int &optlen); + // Get underlying protocol options. + + // = Calls to underlying TLI operations. + int look (void) const; + int rcvdis (struct t_discon * = 0) const; + int snddis (struct t_call * = 0) const; + int sndrel (void) const; + int rcvrel (void) const; + + int get_local_addr (ACE_Addr &) const; + // Return our local endpoint address. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +protected: + // = Ensure we are an abstract class. + ACE_TLI (void); + // Default constructor. + ~ACE_TLI (void); + // Destructor. + + ACE_TLI (const char device[], int oflag = O_RDWR, struct t_info *info = 0); + // Initialize a TLI endpoint. + +private: +#if defined (ACE_HAS_SVR4_TLI) + // Insane TLI option management. + struct t_optmgmt so_opt_req; + struct t_optmgmt so_opt_ret; +#endif /* ACE_HAS_SVR4_TLI */ +}; + +#include "ace/TLI.i" + +#endif /* ACE_HAS_TLI */ +#endif /* ACE_TLI_H */ diff --git a/ace/TLI.i b/ace/TLI.i new file mode 100644 index 00000000000..349f9d1fc74 --- /dev/null +++ b/ace/TLI.i @@ -0,0 +1,41 @@ +/* -*- C++ -*- */ +// $Id$ + +// TLI.i + +#include "ace/TLI.h" + +inline int +ACE_TLI::look (void) const +{ + ACE_TRACE ("ACE_TLI::look"); + return ACE_OS::t_look (this->get_handle ()); +} + +inline int +ACE_TLI::rcvdis (struct t_discon *discon) const +{ + ACE_TRACE ("ACE_TLI::rcvdis"); + return ACE_OS::t_rcvdis (this->get_handle (), discon); +} + +inline int +ACE_TLI::snddis (struct t_call *call) const +{ + ACE_TRACE ("ACE_TLI::snddis"); + return ACE_OS::t_snddis (this->get_handle (), call); +} + +inline int +ACE_TLI::rcvrel (void) const +{ + ACE_TRACE ("ACE_TLI::rcvrel"); + return ACE_OS::t_rcvrel (this->get_handle ()); +} + +inline int +ACE_TLI::sndrel (void) const +{ + ACE_TRACE ("ACE_TLI::sndrel"); + return ACE_OS::t_sndrel (this->get_handle ()); +} diff --git a/ace/TLI_Acceptor.cpp b/ace/TLI_Acceptor.cpp new file mode 100644 index 00000000000..4fce1af33d2 --- /dev/null +++ b/ace/TLI_Acceptor.cpp @@ -0,0 +1,456 @@ +// TLI_Acceptor.cpp +// $Id$ + + +#define ACE_BUILD_DLL +#include "ace/TLI_Acceptor.h" +#include "ace/Log_Msg.h" + +#if defined (ACE_HAS_TLI) + +// Put the actual definitions of the ACE_TLI_Request and +// ACE_TLI_Request_Queue classes here to hide them from clients... + +struct ACE_TLI_Request +{ + struct t_call *callp_; + ACE_HANDLE handle_; + ACE_TLI_Request *next_; +}; + +class ACE_TLI_Request_Queue +{ +public: + ACE_TLI_Request_Queue (void); + + int open (int fd, int size); + int close (void); + + int enqueue (const char device[], int restart, int rwflag); + int dequeue (ACE_TLI_Request *&ptr); + int remove (int sequence_number); + + int is_empty (void) const; + int is_full (void) const; + + ACE_TLI_Request *alloc (void); + void free (ACE_TLI_Request *node); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + int handle_; + int size_; + int current_count_; + ACE_TLI_Request *base_; + ACE_TLI_Request *tail_; + ACE_TLI_Request *free_list_; +}; + +ACE_ALLOC_HOOK_DEFINE(ACE_TLI_Request_Queue) + +void +ACE_TLI_Request_Queue::dump (void) const +{ + ACE_TRACE ("ACE_TLI_Request_Queue::dump"); +} + +int +ACE_TLI_Request_Queue::is_empty (void) const +{ + ACE_TRACE ("ACE_TLI_Request_Queue::is_empty"); + return this->current_count_ == 0; +} + +int +ACE_TLI_Request_Queue::is_full (void) const +{ + ACE_TRACE ("ACE_TLI_Request_Queue::is_full"); + return this->current_count_ + 1 == this->size_; // Add 1 for the dummy. +} + +// Add a node to the free list stack. + +void +ACE_TLI_Request_Queue::free (ACE_TLI_Request *node) +{ + ACE_TRACE ("ACE_TLI_Request_Queue::free"); + node->next_ = this->free_list_; + this->free_list_ = node; +} + +// Remove a node from the free list stack. + +ACE_TLI_Request * +ACE_TLI_Request_Queue::alloc (void) +{ + ACE_TRACE ("ACE_TLI_Request_Queue::alloc"); + ACE_TLI_Request *temp = this->free_list_; + this->free_list_ = this->free_list_->next_; + return temp; +} + +ACE_ALLOC_HOOK_DEFINE(ACE_TLI_Acceptor) + +void +ACE_TLI_Acceptor::dump (void) const +{ + ACE_TRACE ("ACE_TLI_Acceptor::dump"); +} + +ACE_TLI_Acceptor::ACE_TLI_Acceptor (void) + : queue_ (0) +{ + ACE_TRACE ("ACE_TLI_Acceptor::ACE_TLI_Acceptor"); +} + +int +ACE_TLI_Request_Queue::dequeue (ACE_TLI_Request *&ptr) +{ + ACE_TRACE ("ACE_TLI_Request_Queue::dequeue"); + ptr = this->tail_->next_; + this->tail_->next_ = ptr->next_; + this->current_count_--; + return 0; +} + +// This is hideous... + +static ACE_HANDLE +open_new_endpoint (ACE_HANDLE listen_handle, const char dev[], + struct t_call *callp, int rwf) +{ + ACE_TRACE ("open_new_endpoint"); + ACE_HANDLE fd; + + if ((fd = ACE_OS::t_open ((char *) dev, O_RDWR, 0)) == ACE_INVALID_HANDLE + || ACE_OS::t_bind (fd, 0, 0) == ACE_INVALID_HANDLE) + fd = ACE_INVALID_HANDLE; +#if defined (I_PUSH) + else if (rwf != 0 && ACE_OS::ioctl (fd, I_PUSH, "tirdwr") == ACE_INVALID_HANDLE) + fd = ACE_INVALID_HANDLE; +#endif /* I_PUSH */ + + if (fd == ACE_INVALID_HANDLE) + ACE_OS::t_snddis (listen_handle, callp); + return fd; +} + +// Close down the acceptor and release resources. + +ACE_INLINE int +ACE_TLI_Request_Queue::close (void) +{ + ACE_TRACE ("ACE_TLI_Request_Queue::close"); + int res = 0; + + for (int i = 0; i < this->size_; i++) + { + ACE_TLI_Request &item = this->base_[i]; + + item.handle_ = ACE_INVALID_HANDLE; + if (ACE_OS::t_free ((char *) item.callp_, T_CALL) != 0) + res = ACE_INVALID_HANDLE; + } + delete [] this->base_; + this->base_ = 0; + return res; +} + +ACE_HANDLE +ACE_TLI_Request_Queue::open (ACE_HANDLE f, int sz) +{ + ACE_TRACE ("ACE_TLI_Request_Queue::open"); + this->handle_ = f; + this->size_ = sz + 1; // Add one more for the dummy node. + + ACE_NEW_RETURN (this->base_, ACE_TLI_Request[this->size_], ACE_INVALID_HANDLE); + + // Initialize the ACE_Queue and the free list. + + for (int i = 0; i < this->size_; i++) + { + ACE_TLI_Request *item = &this->base_[i]; + this->free (item); + + item->handle_ = ACE_INVALID_HANDLE; + item->callp_ = (t_call *) ACE_OS::t_alloc (this->handle_, T_CALL, T_ALL); + + if (item->callp_ == 0) + return ACE_INVALID_HANDLE; + } + + this->tail_ = this->alloc (); + this->tail_->next_ = this->tail_; + return 0; +} + +ACE_INLINE +ACE_TLI_Request_Queue::ACE_TLI_Request_Queue (void) + : size_ (0), + current_count_ (0), + base_ (0), + tail_ (0), + free_list_ (0) +{ + ACE_TRACE ("ACE_TLI_Request_Queue::ACE_TLI_Request_Queue"); +} + +// Listen for a new connection request and allocate appropriate data +// structures when one arrives. + +int +ACE_TLI_Request_Queue::enqueue (const char device[], + int restart, int rwflag) +{ + ACE_TRACE ("ACE_TLI_Request_Queue::enqueue"); + ACE_TLI_Request *temp = this->alloc (); + ACE_TLI_Request &req = *this->tail_; + int res; + + do + res = ACE_OS::t_listen (this->handle_, req.callp_); + while (res == ACE_INVALID_HANDLE && restart && t_errno == TSYSERR && errno == EINTR); + + if (res != ACE_INVALID_HANDLE) + { + req.handle_ = open_new_endpoint (this->handle_, device, req.callp_, rwflag); + + if (req.handle_ != ACE_INVALID_HANDLE) + { + temp->next_ = this->tail_->next_; + this->tail_->next_ = temp; + this->tail_ = temp; + this->current_count_++; + return 0; + } + } + + // Something must have gone wrong, so free up allocated space. + this->free (temp); + return ACE_INVALID_HANDLE; +} + +// Locate and remove SEQUENCE_NUMBER from the list of pending +// connections. + +int +ACE_TLI_Request_Queue::remove (int sequence_number) +{ + ACE_TRACE ("ACE_TLI_Request_Queue::remove"); + ACE_TLI_Request *prev = this->tail_; + + // Put the sequence # in the dummy node to simply the search... + prev->callp_->sequence = sequence_number; + + ACE_TLI_Request *temp; + + for (temp = this->tail_->next_; + temp->callp_->sequence != sequence_number; + temp = temp->next_) + prev = temp; + + if (temp == this->tail_) + // Sequence # was not found, since we're back at the dummy node! + return -1; + else + { + prev->next_ = temp->next_; + ACE_OS::t_close (temp->handle_); + this->current_count_--; + this->free (temp); + return 0; + } +} + +ACE_HANDLE +ACE_TLI_Acceptor::open (const ACE_Addr &remote_sap, + int reuse_addr, + int oflag, + struct t_info *info, + int qlen, + const char dev[]) +{ + ACE_TRACE ("ACE_TLI_Acceptor::open"); + int res = 0; + int one = 1; + + this->disp_ = 0; + + if ((this->device_ = ACE_OS::strdup (dev)) == 0) + res = ACE_INVALID_HANDLE; + else if (this->ACE_TLI::open (dev, oflag, info) == ACE_INVALID_HANDLE) + res = ACE_INVALID_HANDLE; + else if (reuse_addr + && this->set_option (SOL_SOCKET, SO_REUSEADDR, + &one, sizeof one) == ACE_INVALID_HANDLE) + res = ACE_INVALID_HANDLE; + else if ((this->disp_ = + (struct t_discon *) ACE_OS::t_alloc (this->get_handle (), T_DIS, T_ALL)) == 0) + res = ACE_INVALID_HANDLE; + else + { + struct t_bind req; + + this->backlog_ = qlen; + req.qlen = qlen; + req.addr.maxlen = remote_sap.get_size (); + + if (&remote_sap == &ACE_Addr::sap_any) + // Note that if addr.len == 0 then ACE_TLI selects the port number. + req.addr.len = 0; + else + { + req.addr.len = remote_sap.get_size (); + req.addr.buf = (char *) remote_sap.get_addr (); + } + + res = ACE_OS::t_bind (this->get_handle (), &req, 0); + if (res != ACE_INVALID_HANDLE) + { + ACE_NEW_RETURN (this->queue_, ACE_TLI_Request_Queue, -1); + + res = this->queue_->open (this->get_handle (), this->backlog_); + } + } + + if (res == ACE_INVALID_HANDLE) + this->close (); + return this->get_handle (); +} + + +ACE_TLI_Acceptor::ACE_TLI_Acceptor (const ACE_Addr &remote_sap, + int reuse_addr, + int oflag, + struct t_info *info, + int back, + const char dev[]) +{ + ACE_TRACE ("ACE_TLI_Acceptor::ACE_TLI_Acceptor"); + if (this->open (remote_sap, reuse_addr, oflag, + info, back, dev) == ACE_INVALID_HANDLE) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_TLI_Acceptor::ACE_TLI_Acceptor")); +} + +int +ACE_TLI_Acceptor::close (void) +{ + ACE_TRACE ("ACE_TLI_Acceptor::close"); + if (this->device_ != 0) + { + if (this->queue_ != 0) + { + this->queue_->close (); + delete this->queue_; + } + + ACE_OS::t_free ((char *) this->disp_, T_DIS); + ACE_OS::free (ACE_MALLOC_T (this->device_)); + this->disp_ = 0; + this->device_ = 0; + return this->ACE_TLI::close (); + } + return 0; +} + +// Perform the logic required to handle the arrival of asynchronous +// events while we are trying to accept a new connection request. + +int +ACE_TLI_Acceptor::handle_async_event (int restart, int rwf) +{ + ACE_TRACE ("ACE_TLI_Acceptor::handle_async_event"); + int event; + + switch (event = this->look ()) + { + case T_DISCONNECT: + this->rcvdis (this->disp_); + this->queue_->remove (this->disp_->sequence); + break; + case T_LISTEN: + this->queue_->enqueue (this->device_, restart, rwf); + break; + default: + return -1; + } + return 0; +} + +int +ACE_TLI_Acceptor::accept (ACE_TLI_Stream &new_tli_sap, + ACE_Addr *remote_addr, + ACE_Time_Value *timeout, + int restart, + int rwf, + netbuf *udata, + netbuf *opt) +{ + ACE_TRACE ("ACE_TLI_Acceptor::accept"); + ACE_TLI_Request *req = 0; + int res = 0; + + if (timeout != 0 + && ACE::handle_timed_accept (this->get_handle (), + timeout, restart) == -1) + return -1; + else if (this->queue_->is_empty ()) + { + req = this->queue_->alloc (); + + do + res = ACE_OS::t_listen (this->get_handle (), req->callp_); + while (res == ACE_INVALID_HANDLE + && restart + && errno == EINTR); + + if (res != ACE_INVALID_HANDLE) + res = req->handle_ = open_new_endpoint (this->get_handle (), + this->device_, req->callp_, rwf); + } + else + res = this->queue_->dequeue (req); + + if (udata != 0) + ACE_OS::memcpy ((void *) &req->callp_->udata, (void *) udata, sizeof *udata); + if (opt != 0) + ACE_OS::memcpy ((void *) &req->callp_->opt, (void *) opt, sizeof *opt); + + while (res != ACE_INVALID_HANDLE) + if ((res = ACE_OS::t_accept (this->get_handle (), req->handle_, + req->callp_)) != ACE_INVALID_HANDLE) + break; // Got one! + else if (t_errno == TLOOK) + res = this->handle_async_event (restart, rwf); + else if (restart && t_errno == TSYSERR && errno == EINTR) + res = 0; + + if (res == ACE_INVALID_HANDLE) + { + if (errno != EWOULDBLOCK) + { + new_tli_sap.set_handle (ACE_INVALID_HANDLE); + if (req->handle_ != ACE_INVALID_HANDLE) + ACE_OS::t_close (req->handle_); + } + } + else + { + new_tli_sap.set_handle (req->handle_); + + if (remote_addr != 0) + remote_addr->set_addr ((void *) req->callp_->addr.buf, req->callp_->addr.len); + } + + req->handle_ = ACE_INVALID_HANDLE; + this->queue_->free (req); + new_tli_sap.set_rwflag (rwf); + return new_tli_sap.get_handle () == ACE_INVALID_HANDLE ? -1 : 0; +} + +#endif /* ACE_HAS_TLI */ diff --git a/ace/TLI_Acceptor.h b/ace/TLI_Acceptor.h new file mode 100644 index 00000000000..374216c5a18 --- /dev/null +++ b/ace/TLI_Acceptor.h @@ -0,0 +1,109 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// TLI_Acceptor.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_TLI_ACCEPTOR_H) +#define ACE_TLI_ACCEPTOR_H + +#include "ace/TLI.h" +#include "ace/Time_Value.h" +#include "ace/TLI_Stream.h" + +#if defined (ACE_HAS_TLI) + +/* Oh what I wouldn't do for namespaces... */ + +// Forward reference... +class ACE_TLI_Request_Queue; + +class ACE_Export ACE_TLI_Acceptor : public ACE_TLI + // = TITLE + // Defines the member functions for ACE_TLI_Acceptor abstraction. + // + // = DESCRIPTION + // This class implements the algorithm described in Steve Rago's + // book on System V UNIX network programming. It basically + // makes TLI look like the C++ SOCK_SAP socket wrappers with + // respect to establishing passive-mode listener endpoints. +{ +friend class ACE_Request_Queue; +public: + // = Initialization and termination methods. + ACE_TLI_Acceptor (void); + // Default constructor. + + ACE_TLI_Acceptor (const ACE_Addr &remote_sap, + int reuse_addr = 0, + int oflag = O_RDWR, + struct t_info *info = 0, + int backlog = 5, + const char device[] = "/dev/tcp"); + // Initiate a passive mode socket. + + ACE_HANDLE open (const ACE_Addr &remote_sap, + int reuse_addr = 0, + int oflag = O_RDWR, + struct t_info *info = 0, + int backlog = 5, + const char device[] = "/dev/tcp"); + // Initiate a passive mode socket. + + int close (void); + // Close down the acceptor and release resources. + + // = Passive connection acceptance method. + + int accept (ACE_TLI_Stream &new_tli_sap, + ACE_Addr *remote_addr = 0, + ACE_Time_Value *timeout = 0, + int restart = 1, + int rwflag = 1, + netbuf *udata = 0, + netbuf *opt = 0); + // Accept a new data transfer connection. A of 0 means + // block forever, a of {0, 0} means poll. == 1 + // means "restart if interrupted." + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + const char *device_; + // Network "device" we are using. + + int backlog_; + // Number of connections to queue. + + int rwflag_; + // Are we using "tirdwr" mod? + + int handle_async_event (int restart, int rwflag); + // Handle TLI accept insanity... + + ACE_TLI_Request_Queue *queue_; + // Used for queueing up pending requests. + + struct t_discon *disp_; + // Used for handling disconnects +}; + +#include "ace/TLI_Acceptor.i" + +#endif /* ACE_HAS_TLI */ +#endif /* ACE_TLI_ACCEPTOR_H */ diff --git a/ace/TLI_Acceptor.i b/ace/TLI_Acceptor.i new file mode 100644 index 00000000000..b9dbe6a1a1a --- /dev/null +++ b/ace/TLI_Acceptor.i @@ -0,0 +1,5 @@ +/* -*- C++ -*- */ +// $Id$ + +// TLI_Acceptor.i + diff --git a/ace/TLI_Connector.cpp b/ace/TLI_Connector.cpp new file mode 100644 index 00000000000..2a03693b5d9 --- /dev/null +++ b/ace/TLI_Connector.cpp @@ -0,0 +1,211 @@ +// TLI_Connector.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Handle_Set.h" +#include "ace/TLI_Connector.h" +#include "ace/Time_Value.h" + +#if defined (ACE_HAS_TLI) + +ACE_ALLOC_HOOK_DEFINE(ACE_TLI_Connector) + +void +ACE_TLI_Connector::dump (void) const +{ + ACE_TRACE ("ACE_TLI_Connector::dump"); +} + +ACE_TLI_Connector::ACE_TLI_Connector (void) +{ + ACE_TRACE ("ACE_TLI_Connector::ACE_TLI_Connector"); +} + +// Connect the to the , waiting up to +// amount of time if necessary. It's amazing how +// complicated this is to do in TLI... + +int +ACE_TLI_Connector::connect (ACE_TLI_Stream &new_stream, + const ACE_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms, + const char device[], + struct t_info *info, + int rwf, + netbuf *udata, + netbuf *opt) +{ + ACE_TRACE ("ACE_TLI_Connector::connect"); + int result = 0; + + // Only open a new endpoint if we don't already have a valid handle. + + if (new_stream.get_handle () == ACE_INVALID_HANDLE) + { + if (ACE_TLI::open (device, flags, info) == -1) + return -1; + } + else // Borrow the handle from the NEW_STREAM. + this->set_handle (new_stream.get_handle ()); + + if (&local_sap != &ACE_Addr::sap_any) + { + // Bind the local endpoint to a specific addr. + + struct t_bind *localaddr; + + localaddr = (struct t_bind *) + ::t_alloc (this->get_handle (), T_BIND, T_ADDR); + + if (localaddr == 0) + result = -1; + else + { + int one = 1; + if (reuse_addr && this->set_option (SOL_SOCKET, SO_REUSEADDR, + &one, sizeof one) == -1) + result = -1; + else + { + // localaddr->glen = 0; + localaddr->addr.maxlen = local_sap.get_size (); + localaddr->addr.len = local_sap.get_size (); + localaddr->addr.buf = (char *) local_sap.get_addr (); + + if (ACE_OS::t_bind (this->get_handle (), localaddr, localaddr) == -1) + result = -1; + + ACE_OS::t_free ((char *) localaddr, T_BIND); + } + } + + if (result == -1) + { + this->close (); + return -1; + } + } + // Let TLI select the local endpoint addr. + else if (ACE_OS::t_bind (this->get_handle (), 0, 0) == -1) + return -1; + + struct t_call *callptr = 0; + + callptr = (struct t_call *) + ACE_OS::t_alloc (this->get_handle (), T_CALL, T_ADDR); + + if (callptr == 0) + { + this->close (); + return -1; + } + callptr->addr.maxlen = remote_sap.get_size (); + callptr->addr.len = remote_sap.get_size (); + callptr->addr.buf = (char *) remote_sap.get_addr (); + + if (udata != 0) + ACE_OS::memcpy ((void *) &callptr->udata, (void *) udata, sizeof *udata); + if (opt != 0) + ACE_OS::memcpy ((void *) &callptr->opt, (void *) opt, sizeof *opt); + + // Connect to remote endpoint. + + if (timeout != 0) // Enable non-blocking, if required. + { + if (this->enable (ACE_NONBLOCK) == -1) + result = -1; + + // Do a non-blocking connect. + if (ACE_OS::t_connect (this->get_handle (), callptr, 0) == -1) + { + result = -1; + + // Check to see if we simply haven't connected yet on a + // non-blocking handle or whether there's really an error. + if (t_errno == TNODATA) + { + if (timeout->sec () == 0 && timeout->usec () == 0) + errno = EWOULDBLOCK; + else + result = this->complete (new_stream, 0, timeout); + } + else if (t_errno == TLOOK && this->look () == T_DISCONNECT) + this->rcvdis (); + } + } + // Do a blocking connect to the server. + else if (ACE_OS::t_connect (this->get_handle (), callptr, 0) == -1) + result = -1; + + if (result != -1) + { + // If everything succeeded transfer ownership to . + new_stream.set_handle (this->get_handle ()); + this->set_handle (ACE_INVALID_HANDLE); + new_stream.set_rwflag (rwf); +#if defined (I_PUSH) + if (new_stream.get_rwflag ()) + result = ACE_OS::ioctl (new_stream.get_handle (), I_PUSH, "tirdwr"); +#endif /* I_PUSH */ + } + else if (!(errno == EWOULDBLOCK || errno == ETIMEDOUT)) + { + // If things have gone wrong, close down and return an error. + this->close (); + new_stream.set_handle (ACE_INVALID_HANDLE); + } + + if (ACE_OS::t_free ((char *) callptr, T_CALL) == -1) + return -1; + return result; +} + +// Try to complete a non-blocking connection. + +int +ACE_TLI_Connector::complete (ACE_TLI_Stream &new_stream, + ACE_Addr *remote_sap, + ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_TLI_Connector::complete"); + ACE_HANDLE h = ACE::handle_timed_complete (this->get_handle (), tv); + + if (h == ACE_INVALID_HANDLE) + { + this->close (); + return -1; + } + else // We've successfully connected! + { + if (remote_sap != 0) + { +#if defined (ACE_HAS_SVR4_TLI) + struct netbuf name; + + name.maxlen = remote_sap->get_size (); + name.buf = (char *) remote_sap->get_addr (); + + if (ACE_OS::ioctl (this->get_handle (), TI_GETPEERNAME, &name) == -1) +#else /* SunOS4 sucks... */ + if (0) +#endif /* ACE_HAS_SVR4_TLI */ + { + this->close (); + return -1; + } + } + new_stream.set_handle (this->get_handle ()); + + // Start out with non-blocking disabled on the . + new_stream.disable (ACE_NONBLOCK); + + this->set_handle (ACE_INVALID_HANDLE); + return 0; + } +} + +#endif /* ACE_HAS_TLI */ diff --git a/ace/TLI_Connector.h b/ace/TLI_Connector.h new file mode 100644 index 00000000000..4120cccd58d --- /dev/null +++ b/ace/TLI_Connector.h @@ -0,0 +1,104 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// TLI_Connector.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_TLI_CONNECTOR_H) +#define ACE_TLI_CONNECTOR_H + +#include "ace/TLI_Stream.h" + +#if defined (ACE_HAS_TLI) + +class ACE_Export ACE_TLI_Connector : public ACE_TLI + // = TITLE + // Defines an active connection factory for the ACE_TLI C++ wrappers. +{ +public: + // = Initialization methods. + ACE_TLI_Connector (void); + // Default constructor. + + ACE_TLI_Connector (ACE_TLI_Stream &new_stream, + const ACE_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0, + const char device[] = "/dev/tcp", + struct t_info *info = 0, + int rw_flag = 1, + struct netbuf *udata = 0, + struct netbuf *opt = 0); + // Actively connect and produce a if things go well. + // The is the address that we are trying to connect + // with. The is the amount of time to wait to connect. + // If it's 0 then we block indefinitely. If *timeout == {0, 0} then + // the connection is done using non-blocking mode. In this case, if + // the connection can't be made immediately the value of -1 is + // returned with . If *timeout > {0, 0} then + // this is the amount of time to wait before timing out. If the + // time expires before the connection is made . + // The is the value of local address to bind to. If + // it's the default value of then the user is + // letting the OS do the binding. If == 1 then the + // is reused, even if it hasn't been cleanedup yet. + + int connect (ACE_TLI_Stream &new_stream, + const ACE_Addr &remote_sap, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0, + const char device[] = "/dev/tcp", + struct t_info *info = 0, + int rw_flag = 1, + struct netbuf *udata = 0, + struct netbuf *opt = 0); + // Actively connect and produce a if things go well. + // The is the address that we are trying to connect + // with. The is the amount of time to wait to connect. + // If it's 0 then we block indefinitely. If *timeout == {0, 0} then + // the connection is done using non-blocking mode. In this case, if + // the connection can't be made immediately the value of -1 is + // returned with . If *timeout > {0, 0} then + // this is the amount of time to wait before timing out. If the + // time expires before the connection is made . + // The is the value of local address to bind to. If + // it's the default value of then the user is + // letting the OS do the binding. If == 1 then the + // is reused, even if it hasn't been cleanedup yet. + + int complete (ACE_TLI_Stream &new_stream, + ACE_Addr *remote_sap, + ACE_Time_Value *tv); + // Try to complete a non-blocking connection. + // If connection completion is successful then contains + // the connected ACE_SOCK_Stream. If is non-NULL then it + // will contain the address of the connected peer. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#include "ace/TLI_Connector.i" + +#endif /* ACE_HAS_TLI */ +#endif /* ACE_TLI_CONNECTOR_H */ diff --git a/ace/TLI_Connector.i b/ace/TLI_Connector.i new file mode 100644 index 00000000000..8cfb13e193e --- /dev/null +++ b/ace/TLI_Connector.i @@ -0,0 +1,29 @@ +/* -*- C++ -*- */ +// $Id$ + +// TLI_Connector.i + +#include "ace/Log_Msg.h" + +inline +ACE_TLI_Connector::ACE_TLI_Connector (ACE_TLI_Stream &new_stream, + const ACE_Addr &remote_sap, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms, + const char device[], + struct t_info *info, + int rwf, + netbuf *udata, + netbuf *opt) +{ + ACE_TRACE ("ACE_TLI_Connector::ACE_TLI_Connector"); + if (this->connect (new_stream, remote_sap, timeout, local_sap, reuse_addr, + flags, perms, device, + info, rwf, + udata, opt) == ACE_INVALID_HANDLE + && timeout != 0 && !(errno == EWOULDBLOCK || errno == ETIMEDOUT)) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_TLI_Stream::ACE_TLI_Stream")); +} diff --git a/ace/TLI_Stream.cpp b/ace/TLI_Stream.cpp new file mode 100644 index 00000000000..babca46d529 --- /dev/null +++ b/ace/TLI_Stream.cpp @@ -0,0 +1,99 @@ +// TLI_Stream.cpp +// $Id$ + +/* Defines the member functions for the base class of the ACE_TLI_Stream + abstraction. */ + +#define ACE_BUILD_DLL +#include "ace/TLI_Stream.h" +#include "ace/Log_Msg.h" + +#if defined (ACE_HAS_TLI) + +ACE_ALLOC_HOOK_DEFINE(ACE_TLI_Stream) + +void +ACE_TLI_Stream::dump (void) const +{ + ACE_TRACE ("ACE_TLI_Stream::dump"); +} + +ACE_TLI_Stream::ACE_TLI_Stream (void) +{ + ACE_TRACE ("ACE_TLI_Stream::ACE_TLI_Stream"); +} + +int +ACE_TLI_Stream::get_remote_addr (ACE_Addr &sa) const +{ + ACE_TRACE ("ACE_TLI_Stream::get_remote_addr"); + struct netbuf name; + + name.maxlen = sa.get_size (); + name.buf = (char *) sa.get_addr (); + +#if defined (ACE_HAS_SVR4_TLI) + if (ACE_OS::ioctl (this->get_handle (), TI_GETPEERNAME, &name) == -1) +/* if (ACE_OS::t_getname (this->get_handle (), &name, REMOTENAME) == -1) */ + +#else /* SunOS4 sucks... */ + if (0) +#endif /* ACE_HAS_SVR4_TLI */ + return -1; + else + return 0; +} + +/* Send a release and then await the release from the other side */ + +int +ACE_TLI_Stream::active_close (void) +{ + ACE_TRACE ("ACE_TLI_Stream::active_close"); + char buf; + + if (this->sndrel () == ACE_INVALID_HANDLE) + return ACE_INVALID_HANDLE; + if (this->recv (&buf, sizeof buf) == ACE_INVALID_HANDLE) + { + if (t_errno == TLOOK && this->look () == T_ORDREL) + { + if (this->rcvrel () == ACE_INVALID_HANDLE) + return ACE_INVALID_HANDLE; + } + else + return ACE_INVALID_HANDLE; + } + return this->close (); +} + +/* Acknowledge the release from the other side and then send the release to + the other side. */ + +int +ACE_TLI_Stream::passive_close (void) +{ + ACE_TRACE ("ACE_TLI_Stream::passive_close"); + if (this->rcvrel () == ACE_INVALID_HANDLE) + return ACE_INVALID_HANDLE; + if (this->sndrel () == ACE_INVALID_HANDLE) + return ACE_INVALID_HANDLE; + return this->close (); +} + + +int +ACE_TLI_Stream::close (void) +{ + ACE_TRACE ("ACE_TLI_Stream::close"); + int fd = this->get_handle (); + + this->set_handle (ACE_INVALID_HANDLE); + + if (this->rwflag_) + return ACE_OS::close (fd); + else + return ACE_OS::t_close (fd); +} + +#endif /* ACE_HAS_TLI */ diff --git a/ace/TLI_Stream.h b/ace/TLI_Stream.h new file mode 100644 index 00000000000..73a7391a3fd --- /dev/null +++ b/ace/TLI_Stream.h @@ -0,0 +1,93 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// TLI_Stream.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_TLI_STREAM_H) +#define ACE_TLI_STREAM_H + +#include "ace/TLI.h" +#include "ace/INET_Addr.h" + +#if defined (ACE_HAS_TLI) + +class ACE_Export ACE_TLI_Stream : public ACE_TLI + // = TITLE + // Defines the member functions for ACE_TLI_Stream abstraction. +{ +friend class ACE_TLI_Acceptor; +friend class ACE_TLI_Connector; +public: + // = Initialization and termination methods. + ACE_TLI_Stream (void); + // Default constructor. + + // = TLI-specific shutdown operations. + int close (void); + // Close down and release resources. + + int active_close (void); + // Send a release and then await the release from the other side. + + int passive_close (void); + // Acknowledge the release from the other side and then send the + // release to the other side. + + int get_remote_addr (ACE_Addr &) const; + // Return address of remotely connected peer. + + // = timod bindings + ssize_t send (const void *buf, size_t n, int flags) const; + // Send an n byte buffer to the connected socket (uses t_snd(3)). + ssize_t recv (void *buf, size_t n, int *flags) const; + // Recv an n byte buffer from the connected socket (uses t_rcv(3)). + + ssize_t send_n (const void *buf, size_t n, int flags) const; + // Send exactly n bytes to the connected socket (uses t_snd(3)). + ssize_t recv_n (void *buf, size_t n, int *flags) const; + // Recv exactly n bytes from the connected socket (uses t_rcv(3)). + + // = tirdwr bindings + ssize_t send (const void *buf, size_t n) const; + // Send an n byte buffer to the connected socket (uses write(2)). + + ssize_t recv (void *buf, size_t n) const; + // Recv an n byte buffer from the connected socket (uses read(2)). + + ssize_t send_n (const void *buf, size_t n) const; + // Send n bytes, keep trying until n are sent (uses write(2)). + + ssize_t recv_n (void *buf, size_t n) const; + // Recv n bytes, keep trying until n are received (uses read (2)). + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + int rwflag_; + // Indicates whether the tirdwr module should be pushed + + // = Get/set rwflag + int get_rwflag (void); + void set_rwflag (int); +}; + +#include "ace/TLI_Stream.i" + +#endif /* ACE_HAS_TLI */ +#endif /* ACE_TLI_STREAM_H */ diff --git a/ace/TLI_Stream.i b/ace/TLI_Stream.i new file mode 100644 index 00000000000..646c25d8008 --- /dev/null +++ b/ace/TLI_Stream.i @@ -0,0 +1,105 @@ +/* -*- C++ -*- */ +// $Id$ + +// TLI_Stream.i + +#include "ace/TLI_Stream.h" + +inline ssize_t +ACE_TLI_Stream::send (const void *buf, size_t n) const +{ + ACE_TRACE ("ACE_TLI_Stream::send"); + return ACE_OS::write (this->get_handle (), (const char *) buf, n); +} + +inline ssize_t +ACE_TLI_Stream::send (const void *buf, size_t n, int flags) const +{ + ACE_TRACE ("ACE_TLI_Stream::send"); + return ACE_OS::t_snd (this->get_handle (), (char *) buf, n, flags); +} + +inline ssize_t +ACE_TLI_Stream::recv (void *buf, size_t n) const +{ + ACE_TRACE ("ACE_TLI_Stream::recv"); + return ACE_OS::read (this->get_handle (), (char *) buf, n); +} + +inline ssize_t +ACE_TLI_Stream::recv (void *buf, size_t n, int *flags) const +{ + ACE_TRACE ("ACE_TLI_Stream::recv"); + int f = 0; + + if (flags == 0) + flags = &f; + return ACE_OS::t_rcv (this->get_handle (), (char *) buf, n, flags); +} + +inline ssize_t +ACE_TLI_Stream::send_n (const void *buf, size_t n) const +{ + ACE_TRACE ("ACE_TLI_Stream::send_n"); + return ACE::send_n (this->get_handle (), buf, n); +} + +inline ssize_t +ACE_TLI_Stream::send_n (const void *buf, size_t n, int flags) const +{ + ACE_TRACE ("ACE_TLI_Stream::send_n"); + int b_sent; + int b_written; + + for (b_sent = 0; b_sent < n; b_sent += b_written) + if ((b_written = ACE_OS::t_snd (this->get_handle (), + (char *) buf + b_sent, + n - b_sent, flags)) == -1) + return -1; + + return b_sent; +} + +inline ssize_t +ACE_TLI_Stream::recv_n (void *buf, size_t n) const +{ + ACE_TRACE ("ACE_TLI_Stream::recv_n"); + return ACE::recv_n (this->get_handle (), buf, n); +} + +inline ssize_t +ACE_TLI_Stream::recv_n (void *buf, size_t n, int *flags) const +{ + ACE_TRACE ("ACE_TLI_Stream::recv_n"); + int b_read = 0; + int b_recv = 0; + int f = 0; + + if (flags == 0) + flags = &f; + + for (b_read = 0; b_read < n; b_read += b_recv) + if ((b_recv = ACE_OS::t_rcv (this->get_handle (), + (char *) buf + b_read, + n - b_read, flags)) == -1) + return -1; + else if (b_recv == 0) + break; + + return b_read; +} + +inline void +ACE_TLI_Stream::set_rwflag (int value) +{ + ACE_TRACE ("ACE_TLI_Stream::set_rwflag"); + this->rwflag_ = value; +} + +inline int +ACE_TLI_Stream::get_rwflag (void) +{ + ACE_TRACE ("ACE_TLI_Stream::get_rwflag"); + return this->rwflag_; +} + diff --git a/ace/TTY_IO.cpp b/ace/TTY_IO.cpp new file mode 100644 index 00000000000..96d63e80618 --- /dev/null +++ b/ace/TTY_IO.cpp @@ -0,0 +1,211 @@ +// TTY_IO.cpp +// $Id$ + + +#define ACE_BUILD_DLL +#include "ace/TTY_IO.h" + +// Interface for reading/writing serial device parameters + +int +ACE_TTY_IO::control (Control_Mode cmd, + Serial_Params *arg) const +{ +#if defined (ACE_HAS_TERM_IOCTLS) + struct termios devpar; + u_long c_iflag; + u_long c_oflag; + u_long c_cflag; + u_long c_lflag; + u_long c_line; + u_char ivmin_cc4; + u_char ivtime_cc5; + + c_iflag=0; + c_oflag=0; + c_cflag=0; + c_lflag=0; + c_line=0; + + // Get default device parameters. + + if (this->ACE_IO_SAP::control (TCGETS, (void *) &devpar) == -1) + return -1; + + switch (cmd) + { + case SETPARAMS: + switch (arg->baudrate) + { + case 600: + c_cflag |= B600; + break; + case 1200: + c_cflag |= B1200; + break; + case 2400: + c_cflag |= B2400; + break; + case 4800: + c_cflag |= B4800; + break; + case 9600: + c_cflag |= B9600; + break; + case 19200: + c_cflag |= B19200; + break; + + case 38400: + c_cflag |= B38400; + break; + default: + return -1; + } + switch (arg->databits) + { + case 5: + c_cflag |= CS5; + break; + case 6: + c_cflag |= CS6; + break; + case 7: + c_cflag |= CS7; + break; + case 8: + c_cflag |= CS8; + break; + default: + return -1; + } + switch (arg->stopbits) + { + case 1: + break; + case 2: + c_cflag |= CSTOPB; + break; + default: + return -1; + } + if (arg->parityenb) + { + c_cflag |= PARENB; + if (strcmp((char *) arg->paritymode,"ODD")==0 || + strcmp((char *) arg->paritymode,"odd")==0) + c_cflag |= PARODD; + } + if (arg->ctsenb) /* enable CTS/RTS protocoll */ + c_cflag |= CRTSCTS; + if (arg->rcvenb) /* enable receiver */ + c_cflag |= CREAD; + + c_oflag=0; + c_iflag=IGNPAR|INPCK|ISTRIP; + c_lflag=0; + + ivmin_cc4 =(u_char)0; + ivtime_cc5=(u_char)(arg->readtimeoutmsec/100); + devpar.c_iflag = c_iflag; + devpar.c_oflag = c_oflag; + devpar.c_cflag = c_cflag; + devpar.c_lflag = c_lflag; + devpar.c_cc[4] = ivmin_cc4; + devpar.c_cc[5] = ivtime_cc5; + + return this->ACE_IO_SAP::control (TCSETS, (void *) &devpar); + + case GETPARAMS: + return -1; // Not yet implemented. + + default: + return -1; // Wrong cmd. + } +#elif defined (ACE_WIN32) + switch (cmd) + { + case SETPARAMS: + DCB dcb ; + dcb.DCBlength = sizeof dcb ; + ::GetCommState (this->get_handle (), &dcb); + + switch (arg->baudrate) + { + case 600: dcb.BaudRate = CBR_600; break; + case 1200: dcb.BaudRate = CBR_1200; break; + case 2400: dcb.BaudRate = CBR_2400; break; + case 4800: dcb.BaudRate = CBR_4800; break; + case 9600: dcb.BaudRate = CBR_9600; break; + case 19200: dcb.BaudRate = CBR_19200; break; + case 38400: dcb.BaudRate = CBR_38400; break; + default: return -1; + } + + switch (arg->databits) + { + case 4: + case 5: + case 6: + case 7: + case 8: + dcb.ByteSize = arg->databits; + break; + default: + return -1; + } + + switch (arg->stopbits) + { + case 1: dcb.StopBits = ONESTOPBIT ; break ; + case 2: dcb.StopBits = TWOSTOPBITS; break ; + break; + default: + return -1; + } + + if (arg->parityenb) + { + dcb.fParity = TRUE ; + if (ACE_OS::strcmp ((char *) arg->paritymode, "ODD") == 0 + || ACE_OS::strcmp ((char *) arg->paritymode, "odd") == 0) + dcb.Parity = ODDPARITY ; + else if (ACE_OS::strcmp ((char *) arg->paritymode, "EVEN") == 0 + || ACE_OS::strcmp ((char *) arg->paritymode, "even") == 0) + dcb.Parity = EVENPARITY ; + } + else + { + dcb.fParity = FALSE ; + dcb.Parity = NOPARITY ; + } + + if (arg->ctsenb) // enable CTS/RTS protocol. + { + dcb.fOutxCtsFlow = TRUE ; + dcb.fRtsControl = RTS_CONTROL_HANDSHAKE ; + } + else + { + dcb.fOutxCtsFlow = FALSE ; + dcb.fRtsControl = RTS_CONTROL_DISABLE ; + } + dcb.fBinary = TRUE ; + return ::SetCommState (this->get_handle (), &dcb); + + case GETPARAMS: + ACE_NOTSUP_RETURN (-1); // Not yet implemented. + default: + return -1; // Wrong cmd. + + } // arg switch +#else + ACE_NOTSUP_RETURN (-1); +#endif /* ACE_HAS_TERM_IOCTLS */ +} + +ACE_TTY_IO::operator ACE_DEV_IO &() +{ + return (ACE_DEV_IO &) *this; +} + diff --git a/ace/TTY_IO.h b/ace/TTY_IO.h new file mode 100644 index 00000000000..0e348f244cb --- /dev/null +++ b/ace/TTY_IO.h @@ -0,0 +1,67 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// TTY_IO.h +// +// = DESCRIPTION +// +// = AUTHOR +// Douglas C. Schmidt +// +// ============================================================================ + +#if !defined (ACE_TTY_H) +#define ACE_TTY_H + +#include "ace/Log_Msg.h" +#include "ace/OS.h" +#include "ace/DEV_Addr.h" +#include "ace/DEV_Connector.h" +#include "ace/DEV_IO.h" + +class ACE_TTY_IO : public ACE_DEV_IO + // = TITLE + // Class definitions for TTY-specific features. + // + // = DESCRIPTION + // This class represents an example interface for a specific + // device (a serial line) It extends the capability of the + // underlying DEV_IO class by adding a control method that takes + // a special structure (Serial_Params) as argument to allow a + // comfortable user interface (away from that annoying termios + // structure, which is very specific to UNIX). +{ +public: + enum Control_Mode + { + SETPARAMS, // Set control parameters. + GETPARAMS // Get control parameters. + }; + + struct Serial_Params + { + int baudrate; + int parityenb; + char *paritymode; + int databits; + int stopbits; + int readtimeoutmsec; + int ctsenb; + int rcvenb; + }; + + int control (Control_Mode cmd, Serial_Params * arg) const; + // Interface for reading/writing serial device parameters. + + operator ACE_DEV_IO &(); + // This is necessary to pass ACE_TTY_IO as parameter to DEV_Connector. +}; + +#endif /* ACE_TTY_H */ diff --git a/ace/Task.cpp b/ace/Task.cpp new file mode 100644 index 00000000000..e726a234af3 --- /dev/null +++ b/ace/Task.cpp @@ -0,0 +1,305 @@ +// Task.cpp +// $Id$ + +#if !defined (ACE_TASK_C) +#define ACE_TASK_C + +#define ACE_BUILD_DLL +#include "ace/Task.h" +#include "ace/Module.h" +#include "ace/Service_Config.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Task.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_MT_SAFE) && !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) +// Lock the creation of the Singleton. +template +ACE_Thread_Mutex ACE_Task_Exit::ace_task_lock_; +#endif /* defined (ACE_MT_SAFE) && !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */ + +template ACE_Task_Exit * +ACE_Task_Exit::instance (void) +{ + ACE_TRACE ("ACE_Task_Exit::instance"); + +#if defined (ACE_MT_SAFE) && defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + // Lock the creation of the Singleton. This should be inside of + // ACE_Svc_Handler, but GNU G++ is too lame to handle this... + static ACE_Thread_Mutex ace_task_lock_; +#endif /* defined (ACE_MT_SAFE) && defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */ + + // Determines if we were dynamically allocated. + static ACE_TSS_TYPE (ACE_Task_Exit) *instance_; + + // Implement the Double Check pattern. + + if (instance_ == 0) + { + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, ace_task_lock_, 0)); + + if (instance_ == 0) + ACE_NEW_RETURN (instance_, ACE_TSS_TYPE (ACE_Task_Exit), 0); + } + + return ACE_TSS_GET (instance_, ACE_Task_Exit); + +} + +// Grab hold of the Task * so that we can close() it in the +// destructor. + +template +ACE_Task_Exit::ACE_Task_Exit (void) + : t_ (0), + status_ ((void *) -1) +{ + ACE_TRACE ("ACE_Task_Exit::ACE_Task_Exit"); +} + +// Set the this pointer... + +template void +ACE_Task_Exit::set_this (ACE_Task *t) +{ + ACE_TRACE ("ACE_Task_Exit::set_this"); + this->t_ = t; + + if (t != 0) + this->tc_.insert (t->thr_mgr ()); +} + +// Set the thread exit status value. + +template void * +ACE_Task_Exit::status (void *s) +{ + ACE_TRACE ("ACE_Task_Exit::status"); + return this->status_ = s; +} + +template void * +ACE_Task_Exit::status (void) +{ + ACE_TRACE ("ACE_Task_Exit::status"); + return this->status_; +} + +// When this object is destroyed the Task is automatically closed +// down! + +template +ACE_Task_Exit::~ACE_Task_Exit (void) +{ + ACE_TRACE ("ACE_Task_Exit::~ACE_Task_Exit"); + + if (this->t_ != 0) + { + // The thread count must be decremented first in case the + // close() hook does something crazy like "delete this". + this->t_->thr_count_dec (); + this->t_->close (u_long (this->status_)); + } +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Task) + +template ACE_INLINE void +ACE_Task::dump (void) const +{ + ACE_TRACE ("ACE_Task::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\nthr_mgr_ = %x", this->thr_mgr_)); + this->msg_queue_->dump (); + ACE_DEBUG ((LM_DEBUG, "delete_msg_queue_ = %d\n", this->delete_msg_queue_)); + ACE_DEBUG ((LM_DEBUG, "\nflags = %x", this->flags_)); + ACE_DEBUG ((LM_DEBUG, "\nmod_ = %x", this->mod_)); + ACE_DEBUG ((LM_DEBUG, "\nnext_ = %x", this->next_)); + ACE_DEBUG ((LM_DEBUG, "\ngrp_id_ = %d", this->grp_id_)); + ACE_DEBUG ((LM_DEBUG, "\nthr_count_ = %d", this->thr_count_)); +#if defined (ACE_MT_SAFE) + this->lock_.dump (); +#endif /* ACE_MT_SAFE */ + + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// If the user doesn't supply a ACE_Message_Queue pointer then we'll +// allocate one dynamically. Otherwise, we'll use the one they give. + +template +ACE_Task::ACE_Task (ACE_Thread_Manager *thr_man, + ACE_Message_Queue *mq) + : delete_msg_queue_ (0), + thr_mgr_ (thr_man), + mod_ (0), + flags_ (0), + grp_id_ (0), + thr_count_ (0), + msg_queue_ (0), + next_ (0) +{ + ACE_TRACE ("ACE_Task::ACE_Task"); + + if (mq == 0) + { + ACE_NEW (mq, ACE_Message_Queue); + this->delete_msg_queue_ = 1; + } + + this->msg_queue_ = mq; +} + +template +ACE_Task::~ACE_Task (void) +{ + ACE_TRACE ("ACE_Task::~ACE_Task"); + if (this->delete_msg_queue_) + delete this->msg_queue_; + + // These assignments aren't strickly necessary but they help guard + // against odd race conditions... + this->delete_msg_queue_ = 0; + this->msg_queue_ = 0; + this->thr_mgr_ = 0; + this->mod_ = 0; +} + +// Note that this routine often does not return since the thread that +// is executing it will do an ACE_Thread::exit() first! + +template void * +ACE_Task::svc_run (ACE_Task *t) +{ + ACE_TRACE ("ACE_Task::svc_run"); + + // Obtain our thread-specific exit hook and make sure that it knows + // how to clean us up! + ACE_Task_Exit *exit_hook = + ACE_Task_Exit::instance (); + + exit_hook->set_this (t); + + // Call the Task's svc() method. + void *status = (void *) t->svc (); + + return exit_hook->status (status); + /* NOTREACHED */ +} + +template ACE_Task * +ACE_Task::sibling (void) +{ + ACE_TRACE ("ACE_Task::sibling"); + if (this->mod_ == 0) + return 0; + else + return this->mod_->sibling (this); +} + +template const char * +ACE_Task::name (void) const +{ + ACE_TRACE ("ACE_Task::name"); + if (this->mod_ == 0) + return 0; + else + return this->mod_->name (); +} + +template ACE_Module * +ACE_Task::module (void) const +{ + ACE_TRACE ("ACE_Task::module"); + return this->mod_; +} + +// Get the current group id. +template ACE_INLINE int +ACE_Task::grp_id (void) +{ + ACE_TRACE ("ACE_Task::grp_id"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + return this->grp_id_; +} + +// Set the current group id. +template ACE_INLINE void +ACE_Task::grp_id (int id) +{ + ACE_TRACE ("ACE_Task::grp_id"); + ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->lock_)); + this->grp_id_ = id; +} + +// Suspend a task. +template int +ACE_Task::suspend (void) +{ + ACE_TRACE ("ACE_Task::suspend"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + if (this->thr_count_ > 0) + return this->thr_mgr_->suspend_grp (this->grp_id_); + else + return 0; +} + +// Resume a suspended task. +template int +ACE_Task::resume (void) +{ + ACE_TRACE ("ACE_Task::resume"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); + if (this->thr_count_ > 0) + return this->thr_mgr_->resume_grp (this->grp_id_); + else + return 0; +} + +template int +ACE_Task::activate (long flags, + int n_threads, + int force_active, + u_int priority, + int grp_id) +{ + ACE_TRACE ("ACE_Task::activate"); + +#if defined (ACE_MT_SAFE) + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + if (this->thr_count_ > 0 && force_active == 0) + return 1; // Already active. + else + this->thr_count_ = n_threads; + + // Use the ACE_Thread_Manager singleton if we're running as an + // active object and the caller didn't supply us with a + // Thread_Manager. + if (this->thr_mgr_ == 0) + this->thr_mgr_ = ACE_Service_Config::thr_mgr (); + + this->grp_id_ = this->thr_mgr_->spawn_n (n_threads, + ACE_THR_FUNC (&ACE_Task::svc_run), + (void *) this, + flags, + priority, + grp_id); + if (this->grp_id_ == -1) + return -1; + else + return 0; +#else + { + // Keep the compiler from complaining. + n_threads = n_threads; + force_active = force_active; + flags = flags; + errno = EINVAL; + return -1; + } +#endif /* ACE_MT_SAFE */ +} + +#endif /* ACE_TASK_C */ diff --git a/ace/Task.h b/ace/Task.h new file mode 100644 index 00000000000..5290c67b354 --- /dev/null +++ b/ace/Task.h @@ -0,0 +1,299 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Task.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_TASK_H) +#define ACE_TASK_H + +#include "ace/Service_Object.h" +#include "ace/Message_Queue.h" +#include "ace/Thread_Manager.h" +#include "ace/Synch_T.h" + +// Forward decls... +template class ACE_Module; +template class ACE_Task_Exit; + +class ACE_Task_Flags + // = TITLE + // These flags are used within the ACE_Task. + // + // = DESCRIPTION + // These flags should be hidden within ACE_Task. Unfortunately, the + // HP/UX C++ compiler can't grok this... Fortunately, there's no + // code defined here, so we don't have to worry about multiple + // definitions. +{ +public: + enum + { + ACE_READER = 01, // Identifies a Task as being the "reader" in a Module. + ACE_FLUSHDATA = 02, // Just flush data messages in the queue. + ACE_FLUSHALL = 04, // Flush all messages in the Queue. + ACE_FLUSHR = 010, // flush read queue + ACE_FLUSHW = 020, // flush write queue + ACE_FLUSHRW = 030 // flush both queues + }; +}; + +template +class ACE_Task : public ACE_Service_Object + // = TITLE + // Primary interface for application message processing, as well + // as input and output message queueing. + // + // = DESCRIPTION + // This class serves as the basis for passive and active objects + // in ACE. +{ +friend class ACE_Module; +friend class ACE_Module_Type; +friend class ACE_Task_Exit; +public: + // = Initialization/termination methods. + ACE_Task (ACE_Thread_Manager *thr_mgr = 0, + ACE_Message_Queue *mq = 0); + // Initialize a Task, supplying a thread manager and a message + // queue. If the user doesn't supply a ACE_Message_Queue pointer + // then we'll allocate one dynamically. Otherwise, we'll use the + // one they give. + + // = Initialization and termination hooks (note that these *must* be + // defined by subclasses). + virtual int open (void *args = 0) = 0; + // Hook called to open a Task. can be used to pass arbitrary + // information into . + + virtual int close (u_long flags = 0) = 0; + // Hook called to close a Task. + + virtual ~ACE_Task (void); + // Destructor. + + // = Immediate and deferred processing methods, respectively. + virtual int put (ACE_Message_Block *, ACE_Time_Value *tv = 0) = 0; + // Transfer msg into the queue to handle immediate processing. + + virtual int svc (void); + // Run by a daemon thread to handle deferred processing. + + // = Active object activation method. + virtual int activate (long flags = THR_NEW_LWP, + int n_threads = 1, + int force_active = 0, + u_int priority = 0, + int grp_id = -1); + // Turn the task into an active object, i.e., having of + // control, all running at the level with the same + // , all of which invoke . Returns -1 if failure + // occurs, returns 1 if Task is already an active object and + // is false (doesn't *not* create a new thread in + // this case), and returns 0 if Task was not already an active + // object and a thread is created successfully or thread is an + // active object and is true. + + // = Suspend/resume a Task + virtual int suspend (void); + // Suspend a task. + virtual int resume (void); + // Resume a suspended task. + + int grp_id (void); + // Get the current group id. + + void grp_id (int); + // Set the current group id. + + ACE_Thread_Manager *thr_mgr (void); + // Gets the thread manager associated with this Task. + + void thr_mgr (ACE_Thread_Manager *); + // Set the thread manager associated with this Task. + + ACE_Message_Queue *msg_queue (void); + // Gets the message queue associated with this task. + + void msg_queue (ACE_Message_Queue *); + // Sets the message queue associated with this task. + + size_t thr_count (void); + // Returns the number of threads currently running within a task. + // If we're a passive object this value is 0, else it's > 0. + +public: /* Should be protected: */ + static void *svc_run (ACE_Task *); + // Routine that runs the service routine as a daemon thread. + + // = Message queue manipulation methods. + + int can_put (ACE_Message_Block *); + // Tests whether we can enqueue a message without blocking. + + int putq (ACE_Message_Block *, ACE_Time_Value *tv = 0); + // Insert message into the message list. + + int getq (ACE_Message_Block *&mb, ACE_Time_Value *tv = 0); + // Extract the first message from the list (blocking). + + int ungetq (ACE_Message_Block *, ACE_Time_Value *tv = 0); + // Return a message to the queue. + + int put_next (ACE_Message_Block *msg, ACE_Time_Value *tv = 0); + // Transfer message to the adjacent ACE_Task in a ACE_Stream. + + int reply (ACE_Message_Block *, ACE_Time_Value *tv = 0); + // Turn the message back around. + + // = ACE_Task utility routines to identify names et al. + const char *name (void) const; + // Return the name of the enclosing Module if there's one associated + // with the Task, else returns 0. + + ACE_Task *sibling (void); + // Return the Task's sibling if there's one associated with the + // Task's Module, else returns 0. + + ACE_Module *module (void) const; + // Return the Task's Module if there is one, else returns 0. + + int is_reader (void); + // True if queue is a reader, else false. + + int is_writer (void); + // True if queue is a writer, else false. + + // = Pointers to next ACE_Queue (if ACE is part of an ACE_Stream). + ACE_Task *next (void); + // Get next Task pointer. + void next (ACE_Task *); + // Set next Task pointer. + + int flush (u_long flag = ACE_Task_Flags::ACE_FLUSHALL); /* Flush the queue */ + // Special routines corresponding to certain message types. + + void water_marks (ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds, size_t); + // Manipulate watermarks. + + void thr_count_dec (void); + // Atomically decrement the thread count by 1. This should only be + // called by the class destructor. + + // = Internal data (should be private...). +// private: + + size_t thr_count_; + // Count of the number of threads running within the task. If this + // value is > 0 then we're an active object and the value of + // is the number of active threads at this instant. If + // the value == 0, then we're a passive object. + + ACE_Thread_Manager *thr_mgr_; + // Multi-threading manager. + + ACE_Message_Queue *msg_queue_; + // List of messages on the ACE_Task.. + + int delete_msg_queue_; + // 1 if should delete Message_Queue, 0 otherwise. + + u_long flags_; + // ACE_Task flags. + + ACE_Module *mod_; + // Back-pointer to the enclosing module. + + ACE_Task *next_; + // Pointer to adjacent ACE_Task. + + int grp_id_; + // This maintains the group id of the + +#if defined (ACE_MT_SAFE) + ACE_Thread_Mutex lock_; + // Protect the state of a Task during concurrent operations, but + // only if we're configured as MT safe... +#endif /* ACE_MT_SAFE */ + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +template +class ACE_Task_Exit + // = TITLE + // Keep exit information for a Task in thread specific storage so + // that the Task::close() method will get called no matter how + // the thread exits (e.g., via Thread::exit() or by "falling off + // the end of Task::svc_run"). + // + // = DESCRIPTION + // This clever little helper class is stored in thread-specific + // storage using the ACE_TSS wrapper. When a thread + // exits the ACE_TSS::cleanup() function calls + // "delete" on this object, thereby closing it down gracefully. +{ +public: + ACE_Task_Exit (void); + // Capture the Task object that will be cleaned up automatically. + + void set_this (ACE_Task *t); + // Set the this pointer... + + void *status (void *s); + // Set the exit status. + + void *status (void); + // Get the exit status. + + ~ACE_Task_Exit (void); + // Destructor calls the method of the captured Task on exit. + + static ACE_Task_Exit *instance (void); + // Singleton access point. + +private: + ACE_Task *t_; + // Pointer to the captured Task. + + void *status_; + // Exit status... + + ACE_Thread_Control tc_; + // This is used to make sure that an ACE_Task registers and + // deregisters with the ACE_Thread_Manager correctly. + +#if defined (ACE_MT_SAFE) && !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + static ACE_Thread_Mutex ace_task_lock_; + // Lock the creation of the Singleton. +#endif /* defined (ACE_MT_SAFE) && !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */ +}; + +#if defined (__ACE_INLINE__) +#include "ace/Task.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Task.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Task.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_TASK_H */ diff --git a/ace/Task.i b/ace/Task.i new file mode 100644 index 00000000000..22d2c6cfb09 --- /dev/null +++ b/ace/Task.i @@ -0,0 +1,160 @@ +/* -*- C++ -*- */ +// $Id$ + +// Task.i + +#include "ace/Log_Msg.h" + +// Return the count of the current number of threads. +template ACE_INLINE size_t +ACE_Task::thr_count (void) +{ + ACE_TRACE ("ACE_Task::thr_count"); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0)); + + return this->thr_count_; +} + +// Decrement the count of the active threads by 1. + +template ACE_INLINE void +ACE_Task::thr_count_dec (void) +{ + ACE_TRACE ("ACE_Task::thr_count_dec"); + ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->lock_)); + + this->thr_count_--; +} + +template ACE_INLINE void +ACE_Task::water_marks (ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds cmd, + size_t size) +{ + ACE_TRACE ("ACE_Task::water_marks"); + if (cmd == ACE_IO_Cntl_Msg::SET_LWM) + this->msg_queue_->low_water_mark (size); + else /* cmd == ACE_IO_Cntl_Msg::SET_HWM */ + this->msg_queue_->high_water_mark (size); +} + +template ACE_INLINE int +ACE_Task::getq (ACE_Message_Block *&mb, ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Task::getq"); + return this->msg_queue_->dequeue_head (mb, tv); +} + +template ACE_INLINE int +ACE_Task::can_put (ACE_Message_Block *) +{ + ACE_TRACE ("ACE_Task::can_put"); + assert (!"not implemented"); + return -1; +} + +template ACE_INLINE int +ACE_Task::putq (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Task::putq"); + return this->msg_queue_->enqueue_tail (mb, tv); +} + +template ACE_INLINE int +ACE_Task::ungetq (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Task::ungetq"); + return this->msg_queue_->enqueue_head (mb, tv); +} + +template ACE_INLINE int +ACE_Task::is_reader (void) +{ + ACE_TRACE ("ACE_Task::is_reader"); + return (ACE_BIT_ENABLED (this->flags_, ACE_Task_Flags::ACE_READER)); +} + +template ACE_INLINE int +ACE_Task::is_writer (void) +{ + ACE_TRACE ("ACE_Task::is_writer"); + return (ACE_BIT_DISABLED (this->flags_, ACE_Task_Flags::ACE_READER)); +} + +template ACE_INLINE int +ACE_Task::flush (u_long flag) +{ + ACE_TRACE ("ACE_Task::flush"); + if (ACE_BIT_ENABLED (flag, ACE_Task_Flags::ACE_FLUSHALL)) + return this->msg_queue_ != 0 && this->msg_queue_->close (); + else + return -1; // Note, need to be more careful about what we free... +} + +// Default ACE_Task service routine + +template ACE_INLINE int +ACE_Task::svc (void) +{ + ACE_TRACE ("ACE_Task::svc"); + return 0; +} + +template ACE_INLINE ACE_Task * +ACE_Task::next (void) +{ + ACE_TRACE ("ACE_Task::next"); + return this->next_; +} + +template ACE_INLINE void +ACE_Task::next (ACE_Task *q) +{ + ACE_TRACE ("ACE_Task::next"); + this->next_ = q; +} + +template ACE_INLINE ACE_Thread_Manager * +ACE_Task::thr_mgr (void) +{ + ACE_TRACE ("ACE_Task::thr_mgr"); + return this->thr_mgr_; +} + +template ACE_INLINE void +ACE_Task::thr_mgr (ACE_Thread_Manager *thr_mgr) +{ + ACE_TRACE ("ACE_Task::thr_mgr"); + this->thr_mgr_ = thr_mgr; +} + +template ACE_INLINE void +ACE_Task::msg_queue (ACE_Message_Queue *mq) +{ + ACE_TRACE ("ACE_Task::msg_queue"); + this->msg_queue_ = mq; +} + +template ACE_Message_Queue * +ACE_Task::msg_queue (void) +{ + ACE_TRACE ("ACE_Task::msg_queue"); + return this->msg_queue_; +} + +// Transfer msg to the next ACE_Task. + +template ACE_INLINE int +ACE_Task::put_next (ACE_Message_Block *msg, ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Task::put_next"); + return this->next_ == 0 ? -1 : this->next_->put (msg, tv); +} + +template ACE_INLINE int +ACE_Task::reply (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + ACE_TRACE ("ACE_Task::reply"); + return this->sibling ()->put_next (mb, tv); +} + + diff --git a/ace/Thread.cpp b/ace/Thread.cpp new file mode 100644 index 00000000000..ad3cffca16e --- /dev/null +++ b/ace/Thread.cpp @@ -0,0 +1,68 @@ +// Thread.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Thread.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Thread.i" +#endif /* !defined (__ACE_INLINE__) */ + +#if defined (ACE_HAS_THREADS) + +int +ACE_Thread::spawn_n (size_t n, + ACE_THR_FUNC func, + void *arg, + long flags, + u_int priority, + void *stack[], + size_t stack_size[]) +{ + ACE_TRACE ("ACE_Thread::spawn_n"); + ACE_thread_t t_id; + size_t i; + + for (i = 0; i < n; i++) + // Bail out if error occurs. + if (ACE_OS::thr_create (func, arg, flags, &t_id, 0, priority, + stack == 0 ? 0 : stack[i], + stack_size == 0 ? 0 : stack_size[i]) != 0) + break; + + return i; +} + +int +ACE_Thread::spawn_n (ACE_thread_t thread_ids[], + size_t n, + ACE_THR_FUNC func, + void *arg, + long flags, + u_int priority, + void **stack, + size_t stack_size[]) +{ + ACE_TRACE ("ACE_Thread::spawn_n"); + size_t i; + + for (i = 0; i < n; i++) + { + ACE_thread_t t_id; + + int result = ACE_OS::thr_create + (func, arg, flags, &t_id, 0, priority, + stack == 0 ? 0 : stack[i], + stack_size == 0 ? 0 : stack_size[i]); + + if (result == 0) + thread_ids[i] = t_id; + else + // Bail out if error occurs. + break; + } + + return i; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/ace/Thread.h b/ace/Thread.h new file mode 100644 index 00000000000..0d90998570b --- /dev/null +++ b/ace/Thread.h @@ -0,0 +1,183 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Thread.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_THREAD_H) +#define ACE_THREAD_H + +#include "ace/ACE.h" + +#if !defined (ACE_HAS_THREADS) +class ACE_Export ACE_Thread +{ +public: + static ACE_thread_t self (void); + // Return the unique ID of the thread. + + static void self (ACE_hthread_t &t_id); + // Return the unique kernel ID of the thread. + + static void exit (void *status = 0); + // Exit the current thread and return "status". + +private: + ACE_Thread (void); + // Ensure that we don't get instantiated. +}; +#else +class ACE_Export ACE_Thread +{ + // = TITLE + // Provides a wrapper for threads. + // + // = DESCRIPTION + // This class provides a common interface that is mapped onto + // either POSIX Pthreads, Solaris threads, or Win32 threads. + +public: + static int spawn (ACE_THR_FUNC func, + void *arg = 0, + long flags = THR_NEW_LWP, + ACE_thread_t *t_id = 0, + ACE_hthread_t *t_handle = 0, + u_int priority = 0, + void *stack = 0, + size_t stack_size = 0); + // Spawn a new thread, which executes "func" with argument "arg". + + static int spawn_n (size_t n, + ACE_THR_FUNC func, + void *arg = 0, + long flags = THR_NEW_LWP, + u_int priority = 0, + void *stack[] = 0, + size_t stack_size[] = 0); + // Spawn N new threads, which execute with argument . + // If != 0 it is assumed to be an array of pointers to + // the base of the stacks to use for the threads being spawned. + // Likewise, if != 0 it is assumed to be an array of + // values indicating how big each of the corresponding s + // are. Returns the number of threads actually spawned (if this + // doesn't equal the number requested then something has gone wrong + // and will explain...). + + static int spawn_n (ACE_thread_t thread_ids[], + size_t n, + ACE_THR_FUNC func, + void *arg, + long flags, + u_int priority = 0, + void *stack[] = 0, + size_t stack_size[] = 0); + // Spawn N new threads, which execute with argument . + // The thread_ids of successfully spawned threads will be placed + // into the buffer, which must be the same size as . + // If != 0 it is assumed to be an array of pointers to + // the base of the stacks to use for the threads being spawned. + // Likewise, if != 0 it is assumed to be an array of + // values indicating how big each of the corresponding s + // are. Returns the number of threads actually spawned (if this + // doesn't equal the number requested then something has gone wrong + // and will explain...). + + static int join (ACE_thread_t, + ACE_thread_t *, + void ** = 0); + // Wait for one or more threads to exit. + + static int join (ACE_hthread_t, + void ** = 0); + // Wait for one thread to exit. + + static int resume (ACE_hthread_t); + // Continue the execution of a previously suspended thread. + + static int suspend (ACE_hthread_t); + // Suspend the execution of a particular thread. + + static int kill (ACE_thread_t, int signum); + // Send a signal to the thread. + + static void yield (void); + // Yield the thread to another. + + static void self (ACE_hthread_t &t_id); + // Return the unique kernel ID of the thread. + + static ACE_thread_t self (void); + // Return the unique ID of the thread. + + static void exit (void *status = 0); + // Exit the current thread and return "status". + + static int getconcurrency (void); + // Get the LWP concurrency level of the process. + + static int setconcurrency (int new_level); + // Set the LWP concurrency level of the process. + + static int sigsetmask (int how, + const sigset_t *set, + sigset_t *oset = 0); + // Change and/or examine calling thread's signal mask. + + static int keycreate (ACE_thread_key_t *keyp, + void (*destructor)(void *value), + void * = 0); + // Allocates a that is used to identify data that is specific + // to each thread in the process. The key is global to all threads + // in the process. + + static int keyfree (ACE_thread_key_t key); + // Free up the key so that other threads can reuse it. + + static int setspecific (ACE_thread_key_t key, + void *value); + // Bind value to the thread-specific data key, , for the calling + // thread. + + static int getspecific (ACE_thread_key_t key, + void **valuep); + // Stores the current value bound to for the calling thread + // into the location pointed to by . + + static int disablecancel (struct cancel_state *old_state); + // Disable thread cancellation. + + static int enablecancel (struct cancel_state *old_state, + int flag); + // Enable thread cancellation. + + static int setcancelstate (struct cancel_state &new_state, + struct cancel_state *old_state); + // Set the cancellation state. + + static int cancel (ACE_thread_t t_id); + // Cancel a thread. + + static void testcancel (void); + // Test the cancel. + +private: + ACE_Thread (void); + // Ensure that we don't get instantiated. +}; +#endif /* ACE_HAS_THREADS */ + +#if defined (__ACE_INLINE__) +#include "ace/Thread.i" +#endif /* __ACE_INLINE__ */ +#endif /* ACE_THREAD_H */ diff --git a/ace/Thread.i b/ace/Thread.i new file mode 100644 index 00000000000..c2842516a02 --- /dev/null +++ b/ace/Thread.i @@ -0,0 +1,266 @@ +/* -*- C++ -*- */ +// $Id$ + +// Thread.i + +#if !defined (ACE_HAS_THREADS) + +ACE_INLINE ACE_thread_t +ACE_Thread::self (void) +{ +// ACE_TRACE ("ACE_Thread::self"); + return ACE_OS::thr_self (); +} + +ACE_INLINE void +ACE_Thread::self (ACE_hthread_t &t_id) +{ +// ACE_TRACE ("ACE_Thread::self"); + ACE_OS::thr_self (t_id); +} + +ACE_INLINE void +ACE_Thread::exit (void *status) +{ + ACE_TRACE ("ACE_Thread::exit"); + ACE_OS::exit (*((int *) status)); +} +#else + +// Allocates a that is used to identify data that is specific +// to each thread in the process. The key is global to all threads in +// the process. + +ACE_INLINE int +ACE_Thread::keycreate (ACE_thread_key_t *keyp, + void (*destructor)(void *value), + void *inst) +{ + ACE_TRACE ("ACE_Thread::keycreate"); + return ACE_OS::thr_keycreate (keyp, destructor, inst); +} + +// Free up the key so that other threads can reuse it. + +ACE_INLINE int +ACE_Thread::keyfree (ACE_thread_key_t key) +{ + ACE_TRACE ("ACE_Thread::keyfree"); + return ACE_OS::thr_keyfree (key); +} + +// Bind value to the thread-specific data key, , for the calling +// thread. + +ACE_INLINE int +ACE_Thread::setspecific (ACE_thread_key_t key, void *value) +{ + ACE_TRACE ("ACE_Thread::setspecific"); + return ACE_OS::thr_setspecific (key, value); +} + +// Stores the current value bound to for the calling thread +// into the location pointed to by . + +ACE_INLINE int +ACE_Thread::getspecific (ACE_thread_key_t key, void **valuep) +{ + ACE_TRACE ("ACE_Thread::getspecific"); + return ACE_OS::thr_getspecific (key, valuep); +} + +ACE_INLINE ACE_thread_t +ACE_Thread::self (void) +{ +// ACE_TRACE ("ACE_Thread::self"); + return ACE_OS::thr_self (); +} + +ACE_INLINE void +ACE_Thread::exit (void *status) +{ + ACE_TRACE ("ACE_Thread::exit"); + ACE_OS::thr_exit (status); +} + +ACE_INLINE void +ACE_Thread::yield (void) +{ + ACE_TRACE ("ACE_Thread::yield"); + ACE_OS::thr_yield (); +} + +ACE_INLINE int +ACE_Thread::spawn (ACE_THR_FUNC func, + void *arg, + long flags, + ACE_thread_t *t_id, + ACE_hthread_t *t_handle, + u_int priority, + void *stack, + size_t stack_size) +{ + ACE_TRACE ("ACE_Thread::spawn"); + return ACE_OS::thr_create (func, arg, flags, t_id, t_handle, + priority, stack, stack_size); +} + +ACE_INLINE int +ACE_Thread::resume (ACE_hthread_t t_id) +{ + ACE_TRACE ("ACE_Thread::resume"); + return ACE_OS::thr_continue (t_id); +} + +ACE_INLINE int +ACE_Thread::suspend (ACE_hthread_t t_id) +{ + ACE_TRACE ("ACE_Thread::suspend"); + return ACE_OS::thr_suspend (t_id); +} + +ACE_INLINE int +ACE_Thread::kill (ACE_thread_t t_id, int signum) +{ + ACE_TRACE ("ACE_Thread::kill"); + return ACE_OS::thr_kill (t_id, signum); +} + +ACE_INLINE int +ACE_Thread::join (ACE_thread_t wait_for, + ACE_thread_t *departed, + void **status) +{ + ACE_TRACE ("ACE_Thread::join"); + return ACE_OS::thr_join (wait_for, departed, status); +} + +ACE_INLINE int +ACE_Thread::join (ACE_hthread_t wait_for, + void **status) +{ + ACE_TRACE ("ACE_Thread::join"); + return ACE_OS::thr_join (wait_for, status); +} + +ACE_INLINE int +ACE_Thread::getconcurrency (void) +{ + ACE_TRACE ("ACE_Thread::getconcurrency"); + return ACE_OS::thr_getconcurrency (); +} + +ACE_INLINE int +ACE_Thread::setconcurrency (int new_level) +{ + ACE_TRACE ("ACE_Thread::setconcurrency"); + return ACE_OS::thr_setconcurrency (new_level); +} + +ACE_INLINE int +ACE_Thread::sigsetmask (int how, + const sigset_t *set, + sigset_t *oset) +{ + ACE_TRACE ("ACE_Thread::sigsetmask"); + return ACE_OS::thr_sigsetmask (how, set, oset); +} + +ACE_INLINE int +ACE_Thread::disablecancel (struct cancel_state *old_state) +{ + ACE_TRACE ("ACE_Thread::disablecancel"); + int old_cstate; + int retval; + if ((retval = ACE_OS::thr_setcancelstate (THR_CANCEL_DISABLE, + &old_cstate)) == 0) + if (old_state != 0) + { + ACE_OS::memset (old_state, 0, sizeof(old_state)); + old_state->cancelstate = old_cstate; + } + + return retval; +} + +ACE_INLINE int +ACE_Thread::enablecancel (struct cancel_state *old_state, + int flag) +{ + ACE_TRACE ("ACE_Thread::enablecancel"); + int old_cstate; + int old_ctype; + int retval; + + retval = ACE_OS::thr_setcancelstate (THR_CANCEL_ENABLE, &old_cstate); + + if (retval != 0) + return retval; + + retval = ACE_OS::thr_setcanceltype (flag, &old_ctype); + + if (retval != 0) + return retval; + + if (old_state != 0) + { + old_state->cancelstate = old_cstate; + old_state->canceltype = old_ctype; + } + + return 0; +} + +ACE_INLINE int +ACE_Thread::setcancelstate (struct cancel_state &new_state, + struct cancel_state *old_state) +{ + ACE_TRACE ("ACE_Thread::setcancelstate"); + int old_cstate; + int old_ctype; + + if (new_state.cancelstate != 0 + && ACE_OS::thr_setcancelstate (new_state.cancelstate, &old_cstate) == 0) + return -1; + + if (new_state.canceltype != 0 + && ACE_OS::thr_setcanceltype (new_state.canceltype, &old_ctype) == 0) + { + int o_cstate; + ACE_OS::thr_setcancelstate (old_cstate, &o_cstate); + return -1; + } + + if (old_state != 0) + { + old_state->cancelstate = old_cstate; + old_state->canceltype = old_ctype; + } + + return 0; +} + +ACE_INLINE int +ACE_Thread::cancel (ACE_thread_t t_id) +{ + ACE_TRACE ("ACE_Thread::cancel"); + + return ACE_OS::thr_cancel (t_id); +} + +ACE_INLINE void +ACE_Thread::testcancel (void) +{ + ACE_TRACE ("ACE_Thread::testcancel"); + + ACE_OS::thr_testcancel (); +} + +ACE_INLINE void +ACE_Thread::self (ACE_hthread_t &t_id) +{ +// ACE_TRACE ("ACE_Thread::self"); + ACE_OS::thr_self (t_id); +} + +#endif /* !defined (ACE_HAS_THREADS) */ diff --git a/ace/Thread_Manager.cpp b/ace/Thread_Manager.cpp new file mode 100644 index 00000000000..bad4f22aa2f --- /dev/null +++ b/ace/Thread_Manager.cpp @@ -0,0 +1,767 @@ +// Thread_Manager.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Thread_Manager.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Thread_Manager.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Control) +ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Manager) + +#if defined (ACE_HAS_THREADS) + +void +ACE_Thread_Manager::dump (void) const +{ + ACE_TRACE ("ACE_Thread_Manager::dump"); +} + +ACE_Thread_Descriptor::ACE_Thread_Descriptor (void) + : thr_id_ (ACE_OS::NULL_thread), + grp_id_ (0), + thr_state_ (ACE_THR_IDLE) +{ + ACE_TRACE ("ACE_Thread_Descriptor::ACE_Thread_Descriptor"); +} + +// Return the thread descriptor (indexed by ACE_thread_t). + +int +ACE_Thread_Manager::thread_descriptor_i (ACE_thread_t thr_id, + ACE_Thread_Descriptor &descriptor) +{ + ACE_TRACE ("ACE_Thread_Descriptor::thread_descriptor_i"); + + for (size_t i = 0; i < this->current_count_; i++) + if (ACE_OS::thr_equal (thr_id, this->thr_table_[i].thr_id_)) + { + descriptor = this->thr_table_[i]; + return 0; + } + + return -1; +} + +int +ACE_Thread_Manager::thread_descriptor (ACE_thread_t thr_id, + ACE_Thread_Descriptor &descriptor) +{ + ACE_TRACE ("ACE_Thread_Descriptor::thread_descriptor"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + return this->thread_descriptor_i (thr_id, descriptor); +} + +// Return the thread descriptor (indexed by ACE_hthread_t). + +int +ACE_Thread_Manager::hthread_descriptor_i (ACE_hthread_t thr_handle, + ACE_Thread_Descriptor &descriptor) +{ + ACE_TRACE ("ACE_Thread_Descriptor::hthread_descriptor_i"); + + for (size_t i = 0; i < this->current_count_; i++) + if (ACE_OS::thr_cmp (thr_handle, this->thr_table_[i].thr_handle_)) + { + descriptor = this->thr_table_[i]; + return 0; + } + + return -1; +} + +int +ACE_Thread_Manager::hthread_descriptor (ACE_hthread_t thr_handle, + ACE_Thread_Descriptor &descriptor) +{ + ACE_TRACE ("ACE_Thread_Descriptor::hthread_descriptor"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + return this->hthread_descriptor_i (thr_handle, descriptor); +} + +// Return the thread descriptor (indexed by ACE_hthread_t). + +int +ACE_Thread_Manager::thr_self (ACE_hthread_t &self) +{ + ACE_TRACE ("ACE_Thread_Descriptor::thr_self"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + // Try to get the cached HANDLE out of TSS to avoid lookup. + ACE_hthread_t *handle = ACE_LOG_MSG->thr_handle (); + + // Wasn't in the cache, so we'll have to look it up and cache it. + if (handle == 0) + { + ACE_Thread_Descriptor td; + ACE_thread_t id = ACE_OS::thr_self (); + + int i = this->thread_descriptor_i (id, td); + + if (i == -1) + return -1; + handle = &this->thr_table_[i].thr_handle_; + + // Update the TSS cache. + ACE_LOG_MSG->thr_handle (handle); + } + self = *handle; + return 0; +} + +int +ACE_Thread_Manager::resize (size_t size) +{ + ACE_TRACE ("ACE_Thread_Manager::resize"); + ACE_Thread_Descriptor *temp; + + ACE_NEW_RETURN (temp, ACE_Thread_Descriptor[size], -1); + + for (size_t i = 0; i < this->max_table_size_; i++) + temp[i] = this->thr_table_[i]; // Structure assignment. + + this->max_table_size_ = size; + + delete [] this->thr_table_; + + this->thr_table_ = temp; + return 0; +} + +// Create and initialize the table to keep track of the thread pool. + +int +ACE_Thread_Manager::open (size_t size) +{ + ACE_TRACE ("ACE_Thread_Manager::open"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + if (this->max_table_size_ < size) + this->resize (size); + return 0; +} + +// Initialize the synchronization variables. + +ACE_Thread_Manager::ACE_Thread_Manager (size_t size) + : zero_cond_ (lock_), + max_table_size_ (0), + thr_table_ (0), + current_count_ (0), + grp_id_ (1) +{ + ACE_TRACE ("ACE_Thread_Manager::ACE_Thread_Manager"); + if (this->open (size) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Thread_Manager")); +} + +// Close up and release all resources. + +int +ACE_Thread_Manager::close (void) +{ + ACE_TRACE ("ACE_Thread_Manager::close"); + if (this->thr_table_ != 0) + { + delete [] this->thr_table_; + this->thr_table_ = 0; + this->max_table_size_ = 0; + this->current_count_ = 0; + } + return 0; +} + +ACE_Thread_Manager::~ACE_Thread_Manager (void) +{ + ACE_TRACE ("ACE_Thread_Manager::~ACE_Thread_Manager"); + this->close (); +} + +// Call the appropriate OS routine to spawn a thread. Should *not* be +// called with the lock_ held... + +int +ACE_Thread_Manager::spawn_i (ACE_THR_FUNC func, + void *args, + long flags, + ACE_thread_t *t_id, + ACE_hthread_t *t_handle, + u_int priority, + int grp_id, + void *stack, + size_t stack_size) +{ + ACE_TRACE ("ACE_Thread_Manager::spawn_i"); + ACE_thread_t thr_id; + ACE_hthread_t thr_handle; + + if (t_id == 0) + t_id = &thr_id; + + if (t_handle == 0) + t_handle = &thr_handle; + + int result = ACE_Thread::spawn (func, args, flags, + t_id, t_handle, priority, + stack, stack_size); + if (result != 0) + { + errno = result; + return -1; + } + else + return this->append_thr (*t_id, *t_handle, + ACE_THR_SPAWNED, + grp_id); +} + +// Create a new thread running FUNC. *Must* be called with the lock_ +// held... + +int +ACE_Thread_Manager::spawn (ACE_THR_FUNC func, + void *args, + long flags, + ACE_thread_t *t_id, + ACE_hthread_t *t_handle, + u_int priority, + int grp_id, + void *stack, + size_t stack_size) +{ + ACE_TRACE ("ACE_Thread_Manager::spawn"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + if (grp_id == -1) + grp_id = this->grp_id_++; // Increment the group id. + + if (this->spawn_i (func, args, flags, t_id, t_handle, + priority, grp_id, stack, stack_size) == -1) + return -1; + else + return grp_id; +} + +// Create N new threads running FUNC. + +int +ACE_Thread_Manager::spawn_n (int n, + ACE_THR_FUNC func, + void *args, + long flags, + u_int priority, + int grp_id) +{ + ACE_TRACE ("ACE_Thread_Manager::spawn_n"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + if (grp_id == -1) + grp_id = this->grp_id_++; // Increment the group id. + + for (int i = 0; i < n; i++) + { + // @@ What should happen if this fails?! e.g., should we try to + // cancel the other threads that we've already spawned or what? + if (this->spawn_i (func, args, flags, 0, 0, priority, grp_id) == -1) + return -1; + } + + return grp_id; +} + +// Append a thread into the pool (does not check for duplicates). +// Must be called with locks held. + +int +ACE_Thread_Manager::append_thr (ACE_thread_t t_id, + ACE_hthread_t t_handle, + ACE_Thread_State thr_state, + int grp_id) +{ + ACE_TRACE ("ACE_Thread_Manager::append_thr"); + // Try to resize the array to twice its existing size if we run out + // of space... + if (this->current_count_ >= this->max_table_size_ + && this->resize (this->max_table_size_ * 2) == -1) + return -1; + else + { + ACE_Thread_Descriptor &thr_desc = + this->thr_table_[this->current_count_]; + + thr_desc.thr_id_ = t_id; + thr_desc.thr_handle_ = t_handle; + thr_desc.grp_id_ = grp_id; + thr_desc.thr_state_ = thr_state; + + this->current_count_++; + return 0; + } +} + +// Insert a thread into the pool (checks for duplicates and doesn't +// allow them to be inserted twice). + +int +ACE_Thread_Manager::insert_thr (ACE_thread_t t_id, + ACE_hthread_t t_handle, + int grp_id) +{ + ACE_TRACE ("ACE_Thread_Manager::insert_thr"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + // Check for duplicates and bail out if they're already + // registered... + if (this->find (t_id) != -1) + return -1; + + if (grp_id == -1) + grp_id = this->grp_id_++; + + if (this->append_thr (t_id, t_handle, + ACE_THR_SPAWNED, + grp_id) == -1) + return -1; + else + return grp_id; +} + +// Remove a thread from the pool. Must be called with locks held. + +void +ACE_Thread_Manager::remove_thr (int i) +{ + ACE_TRACE ("ACE_Thread_Manager::remove_thr"); + if (this->current_count_ > 1) + // Structure assignment. + this->thr_table_[i] = this->thr_table_[this->current_count_ - 1]; + + this->current_count_--; + + // Tell all waiters when there are no more threads left in the pool. + if (this->current_count_ == 0) + this->zero_cond_.broadcast (); +} + +// Factory out some common behavior to simplify the following methods. +#define ACE_THR_OP(OP,STATE) \ + int result = OP (this->thr_table_[i].thr_handle_); \ + if (result != 0) { \ + this->remove_thr (i); \ + errno = result; \ + return -1; \ + } \ + else { \ + this->thr_table_[i].thr_state_ = STATE; \ + return 0; \ + } + +int +ACE_Thread_Manager::suspend_thr (int i) +{ + ACE_TRACE ("ACE_Thread_Manager::suspend_thr"); + + ACE_THR_OP (ACE_Thread::suspend, ACE_THR_SUSPENDED); +} + +int +ACE_Thread_Manager::resume_thr (int i) +{ + ACE_TRACE ("ACE_Thread_Manager::resume_thr"); + + ACE_THR_OP (ACE_Thread::resume, ACE_THR_RUNNING); +} + +int +ACE_Thread_Manager::cancel_thr (int i) +{ + ACE_TRACE ("ACE_Thread_Manager::cancel_thr"); + this->thr_table_[i].thr_state_ = ACE_THR_CANCELLED; + return 0; +} + +int +ACE_Thread_Manager::kill_thr (int i, int signum) +{ + ACE_TRACE ("ACE_Thread_Manager::kill_thr"); + + int result = ACE_Thread::kill ((ACE_thread_t) this->thr_table_[i].thr_handle_, + signum); + + if (result != 0) + { + this->remove_thr (i); + errno = result; + return -1; + } + else + return 0; +} + +// Locate the index in the table associated with . Must be +// called with the lock held. + +int +ACE_Thread_Manager::find (ACE_thread_t t_id) +{ + ACE_TRACE ("ACE_Thread_Manager::find"); + + for (size_t i = 0; i < this->current_count_; i++) + if (ACE_OS::thr_equal (t_id, this->thr_table_[i].thr_id_)) + return i; + + return -1; +} + +#define ACE_EXECUTE_OP(OP) \ + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); \ + int i = this->find (t_id); \ + if (i == -1) return -1; \ + return OP (i); + +// Suspend a single thread. + +int +ACE_Thread_Manager::suspend (ACE_thread_t t_id) +{ + ACE_TRACE ("ACE_Thread_Manager::suspend"); + ACE_EXECUTE_OP (this->suspend_thr); +} + +// Resume a single thread. + +int +ACE_Thread_Manager::resume (ACE_thread_t t_id) +{ + ACE_TRACE ("ACE_Thread_Manager::resume"); + ACE_EXECUTE_OP (this->resume_thr); +} + +// Cancel a single thread. + +int +ACE_Thread_Manager::cancel (ACE_thread_t t_id) +{ + ACE_TRACE ("ACE_Thread_Manager::cancel"); + ACE_EXECUTE_OP (this->cancel_thr); +} + +// Send a signal to a single thread. + +int +ACE_Thread_Manager::kill (ACE_thread_t t_id, int signum) +{ + ACE_TRACE ("ACE_Thread_Manager::kill"); + return ACE_Thread::kill (t_id, signum); +} + +int +ACE_Thread_Manager::check_state (ACE_Thread_State state, + ACE_thread_t id) +{ + ACE_TRACE ("ACE_Thread_Manager::check_state"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + ACE_Thread_State *thr_state = 0; +#if 0 + int self_check = ACE_OS::thr_equal (id, ACE_OS::thr_self ()); + + // If we're checking the state of our thread, try to get the cached + // value out of TSS to avoid lookup. + if (self_check) + thr_state = ACE_LOG_MSG->thr_state (); + + // Wasn't in the cache, so we'll have to look it up. + if (thr_state == 0) + { + int i = this->find (id); + + if (i == -1) + return -1; + thr_state = &this->thr_table_[i].thr_state_; + + if (self_check) // Update the TSS cache. + ACE_LOG_MSG->thr_state (thr_state); + } +#else + // Turn off caching for the time being until we figure out + // how to do it correctly in the face of deletions... + int i = this->find (id); + + if (i == -1) + return -1; + thr_state = &this->thr_table_[i].thr_state_; +#endif /* 0 */ + return *thr_state == state; +} + +// Test if a single thread is suspended. + +int +ACE_Thread_Manager::testsuspend (ACE_thread_t t_id) +{ + ACE_TRACE ("ACE_Thread_Manager::testsuspend"); + return this->check_state (ACE_THR_SUSPENDED, t_id); +} + +// Test if a single thread is active (i.e., resumed). + +int +ACE_Thread_Manager::testresume (ACE_thread_t t_id) +{ + ACE_TRACE ("ACE_Thread_Manager::testresume"); + return this->check_state (ACE_THR_RUNNING, t_id); +} + +// Test if a single thread is cancelled. + +int +ACE_Thread_Manager::testcancel (ACE_thread_t t_id) +{ + ACE_TRACE ("ACE_Thread_Manager::testcancel"); + return this->check_state (ACE_THR_CANCELLED, t_id); +} + +// Get group ids for a particular thread id. + +int +ACE_Thread_Manager::get_grp (ACE_thread_t t_id, int &grp_id) +{ + ACE_TRACE ("ACE_Thread_Manager::get_grp"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + int i = this->find (t_id); + if (i == -1) + return -1; + grp_id = this->thr_table_[i].grp_id_; + return 0; +} + +// Set group ids for a particular thread id. + +int +ACE_Thread_Manager::set_grp (ACE_thread_t t_id, int grp_id) +{ + ACE_TRACE ("ACE_Thread_Manager::set_grp"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + int i = this->find (t_id); + if (i == -1) + return -1; + this->thr_table_[i].grp_id_ = grp_id; + return 0; +} + +// Suspend a group of threads. + +int +ACE_Thread_Manager::apply_grp (int grp_id, + THR_FUNC func, + int arg) +{ + ACE_TRACE ("ACE_Thread_Manager::apply_grp"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + int result = 0; + + for (size_t i = 0; i < this->current_count_; i++) + if (this->thr_table_[i].grp_id_ == grp_id + && (this->*func)(i, arg) == -1) + result = -1; + + return result; +} + +int +ACE_Thread_Manager::suspend_grp (int grp_id) +{ + ACE_TRACE ("ACE_Thread_Manager::suspend_grp"); + return this->apply_grp (grp_id, + THR_FUNC (&ACE_Thread_Manager::suspend_thr)); +} + +// Resume a group of threads. + +int +ACE_Thread_Manager::resume_grp (int grp_id) +{ + ACE_TRACE ("ACE_Thread_Manager::resume_grp"); + return this->apply_grp (grp_id, + THR_FUNC (&ACE_Thread_Manager::resume_thr)); +} + +// Kill a group of threads. + +int +ACE_Thread_Manager::kill_grp (int grp_id, int signum) +{ + ACE_TRACE ("ACE_Thread_Manager::kill_grp"); + return this->apply_grp (grp_id, + THR_FUNC (&ACE_Thread_Manager::kill_thr), signum); +} + +// Cancel a group of threads. + +int +ACE_Thread_Manager::cancel_grp (int grp_id) +{ + ACE_TRACE ("ACE_Thread_Manager::resume_grp"); + return this->apply_grp (grp_id, + THR_FUNC (&ACE_Thread_Manager::cancel_thr)); +} + +int +ACE_Thread_Manager::apply_all (THR_FUNC func, int arg) +{ + ACE_TRACE ("ACE_Thread_Manager::apply_all"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + int result = 0; + + for (size_t i = 0; i < this->current_count_; i++) + if ((this->*func)(i, arg) == -1) + result = -1; + + return result; +} + +// Resume all threads that are suspended. + +int +ACE_Thread_Manager::resume_all (void) +{ + ACE_TRACE ("ACE_Thread_Manager::resume_all"); + return this->apply_all (THR_FUNC (&ACE_Thread_Manager::resume_thr)); +} + +int +ACE_Thread_Manager::suspend_all (void) +{ + ACE_TRACE ("ACE_Thread_Manager::suspend_all"); + return this->apply_all (THR_FUNC (&ACE_Thread_Manager::suspend_thr)); +} + +int +ACE_Thread_Manager::kill_all (int sig) +{ + ACE_TRACE ("ACE_Thread_Manager::kill_all"); + return this->apply_all (&ACE_Thread_Manager::kill_thr, sig); +} + +int +ACE_Thread_Manager::cancel_all (void) +{ + ACE_TRACE ("ACE_Thread_Manager::cancel_all"); + return this->apply_all (THR_FUNC (&ACE_Thread_Manager::cancel_thr)); +} + +// Must be called when thread goes out of scope to clean up its table +// slot. + +void * +ACE_Thread_Manager::exit (void *status, int do_thr_exit) +{ + ACE_TRACE ("ACE_Thread_Manager::exit"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0); + + int i = this->find (ACE_Thread::self ()); + + // Locate thread id. + if (i != -1) + this->remove_thr (i); + + if (do_thr_exit) + { + // Note, destructor is never called, so we must manually release + // the lock... + + ACE_MT (ace_mon.release ()); + + ACE_Thread::exit (status); + // On reasonable systems ACE_Thread::exit() should not return. + // However, due to horrible semantics with Win32 thread-specific + // storage this call can return (don't ask...). Therefore, we + // need to reacquire the mutex so that we don't get burned when + // the Guard automatically releases it when this method returns. + ACE_MT (ace_mon.acquire ()); + } + return 0; +} + +// Wait for all the threads to exit. + +int +ACE_Thread_Manager::wait (const ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_Thread_Manager::wait"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + while (this->current_count_ > 0) + if (this->zero_cond_.wait (timeout) == -1) + return -1; + + return 0; +} + +void +ACE_Thread_Control::dump (void) const +{ + ACE_TRACE ("ACE_Thread_Control::dump"); +} + +int +ACE_Thread_Control::insert (ACE_Thread_Manager *tm) +{ + ACE_TRACE ("ACE_Thread_Control::insert"); + + ACE_hthread_t t_id; + ACE_Thread::self (t_id); + this->tm_ = tm; + + return this->tm_->insert_thr (ACE_Thread::self (), t_id); +} + +// Initialize the thread controller. + +ACE_Thread_Control::ACE_Thread_Control (ACE_Thread_Manager *t, + int insert) + : tm_ (t), + status_ (0) +{ + ACE_TRACE ("ACE_Thread_Control::ACE_Thread_Control"); + if (this->tm_ != 0 && insert) + { + ACE_hthread_t t_id; + ACE_Thread::self (t_id); + this->tm_->insert_thr (ACE_Thread::self (), t_id); + } +} + +// Automatically kill thread on exit. + +ACE_Thread_Control::~ACE_Thread_Control (void) +{ + ACE_TRACE ("ACE_Thread_Control::~ACE_Thread_Control"); + this->exit (this->status_); +} + +// Exit from thread (but clean up first). + +void * +ACE_Thread_Control::exit (void *exit_status) +{ + ACE_TRACE ("ACE_Thread_Control::exit"); + if (this->tm_ != 0) + return this->tm_->exit (exit_status); + else + { + ACE_Thread::exit (exit_status); + return 0; + } +} + +#endif /* !defined (ACE_HAS_THREADS) */ diff --git a/ace/Thread_Manager.h b/ace/Thread_Manager.h new file mode 100644 index 00000000000..ca1b8b4125e --- /dev/null +++ b/ace/Thread_Manager.h @@ -0,0 +1,403 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Thread_Manager.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_THREAD_MANAGER_H) +#define ACE_THREAD_MANAGER_H + +#include "ace/Log_Msg.h" +#include "ace/Thread.h" +#include "ace/Synch.h" + +class ACE_Thread_Manager; + +class ACE_Export ACE_Thread_Descriptor + // = Title + // Information for controlling threads that run under the control + // of the . +{ +friend class ACE_Thread_Manager; +public: + // = Initialization method. + ACE_Thread_Descriptor (void); + + // = Accessor methods. + ACE_thread_t self (void); + // Unique thread id. + + void self (ACE_hthread_t &); + // Unique handle to thread (used by Win32 and AIX). + + int grp_id (void); + // Group ID. + + ACE_Thread_State state (void); + // Current state of the thread. + +private: + + ACE_thread_t thr_id_; + // Unique thread ID. + + ACE_hthread_t thr_handle_; + // Unique handle to thread (used by Win32 and AIX). + + int grp_id_; + // Group ID. + + ACE_Thread_State thr_state_; + // Current state of the thread. +}; + +#if !defined (ACE_HAS_THREADS) + +class ACE_Export ACE_Thread_Manager +{ +public: + enum + { + DEFAULT_SIZE = 100 + }; + + ACE_Thread_Manager (int = 0) {} + ~ACE_Thread_Manager (void) {} + + int open (size_t = DEFAULT_SIZE) { return -1; } + int close (void) { return -1; } + int spawn (ACE_THR_FUNC, + void * = 0, + long = 0, + ACE_thread_t * = 0, + ACE_hthread_t * = 0, + u_int = 0, + int = -1, + void * = 0, + size_t = 0) { return -1;} + int spawn_n (int, + ACE_THR_FUNC, + void * = 0, + long = 0, + u_int = 0, + int = -1) { return -1;} + void *exit (void *) { return 0; } + void wait (const ACE_Time_Value * = 0) {} + int thread_descriptor (ACE_thread_t, ACE_Thread_Descriptor &) { return -1;} + int hthread_descriptor (ACE_hthread_t, ACE_Thread_Descriptor &) { return -1;} + int suspend_all (void) { return -1; } + int suspend (ACE_thread_t) { return -1; } + int suspend_grp (ACE_thread_t) { return -1; } + int resume_all (void) { return -1; } + int resume (ACE_thread_t) { return -1; } + int resume_grp (ACE_thread_t) { return -1; } + int kill_all (int) { return -1; } + int kill (ACE_thread_t) { return -1; } + int kill_grp (ACE_thread_t) { return -1; } + int cancel_all (void) { return -1; } + int cancel (int) { return -1; } + int cancel_grp (int) { return -1; } + void dump (void) const { } +}; + +class ACE_Export ACE_Thread_Control +{ +public: + ACE_Thread_Control (ACE_Thread_Manager * = 0, int = 0) {} + ~ACE_Thread_Control (void) {} + ACE_Thread_Manager *thr_mgr (void) { return 0; } + ACE_Thread_Manager *thr_mgr (ACE_Thread_Manager *) { return 0; } + void *exit (void *) { return 0; } + int insert (ACE_Thread_Manager *) { return 0; } + void *status (void *) { return 0; } + void *status (void) { return 0; } + void dump (void) const { } +}; +#else + +// Forward declaration. +class ACE_Thread_Control; + +class ACE_Export ACE_Thread_Manager + // = TITLE + // Manages a pool of threads. + // + // = DESCRIPTION + // This class allows operations on groups of threads atomically. +{ +friend class ACE_Thread_Control; +public: + enum + { + DEFAULT_SIZE = 100 + }; + + // = Initialization and termination methods. + ACE_Thread_Manager (size_t size = ACE_Thread_Manager::DEFAULT_SIZE); + ~ACE_Thread_Manager (void); + + int open (size_t size = DEFAULT_SIZE); + // Initialize the manager with room for SIZE threads. + + int close (void); + // Release all resources. + + int spawn (ACE_THR_FUNC func, + void *args = 0, + long flags = THR_NEW_LWP, + ACE_thread_t * = 0, + ACE_hthread_t *t_handle = 0, + u_int priority = 0, + int grp_id = -1, + void *stack = 0, + size_t stack_size = 0); + // Create a new thread, which executes . + + // Returns: on success a unique group id that can be used to control + // other threads added to the same group. On failure, returns -1. + + int spawn_n (int n, + ACE_THR_FUNC func, + void *args = 0, + long flags = THR_NEW_LWP, + u_int priority = 0, + int grp_id = -1); + // Create N new threads, all of which execute . + + // Returns: on success a unique group id that can be used to control + // all of the threads in the same group. On failure, returns -1. + + void *exit (void *status, int do_thread_exit = 1); + // Called to clean up when a thread exits. If is + // non-0 then is called to exit the thread, in + // which case is passed as the exit value of the thread. + + int wait (const ACE_Time_Value *timeout = 0); + // Block until there are no more threads running in the + // or expires. Returns 0 on success and + // -1 on failure. + + // = Accessors for . + int thread_descriptor (ACE_thread_t, ACE_Thread_Descriptor &); + // Return the thread descriptor (indexed by ACE_thread_t). Returns 0 on + // success and -1 if not found. + + int hthread_descriptor (ACE_hthread_t, ACE_Thread_Descriptor &); + // Return the thread descriptor (indexed by ACE_hthread_t). Returns 0 + // on success and -1 if not found. + + int thr_self (ACE_hthread_t &); + // Passes out the "real" handle to the thread, caching it if + // necessary in TSS to speed up subsequent lookups. + + // = Suspend methods, which isn't supported on POSIX pthreads (will + // not block). + int suspend_all (void); + // Suspend all threads + int suspend (ACE_thread_t); + // Suspend a single thread. + int suspend_grp (int grp_id); + // Suspend a group of threads. + int testsuspend (ACE_thread_t t_id); + // True if is inactive (i.e., suspended), else false. + + // = Resume methods, which isn't supported on POSIX pthreads (will + // not block). + int resume_all (void); + // Resume all stopped threads + int resume (ACE_thread_t); + // Resume a single thread. + int resume_grp (int grp_id); + // Resume a group of threads. + int testresume (ACE_thread_t t_id); + // True if is active (i.e., resumed), else false. + + // = Kill methods, send signals -- which isn't supported on Win32 + // (will not block). + int kill_all (int signum); + // Send signum to all stopped threads + int kill (ACE_thread_t, int signum); + // Kill a single thread. + int kill_grp (int grp_id, int signum); + // Kill a group of threads. + + // = Cancel methods, which provides a cooperative thread-termination + // mechanism (will not block). + int cancel_all (void); + // Send signum to all stopped threads + int cancel (ACE_thread_t); + // Cancel a single thread. + int cancel_grp (int grp_id); + // Cancel a group of threads. + int testcancel (ACE_thread_t t_id); + // True if is cancelled, else false. + + // = Set/get group ids for a particular thread id. + int set_grp (ACE_thread_t, int grp_id); + int get_grp (ACE_thread_t, int &grp_id); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + int resize (size_t); + // Resize the pool of Thread_Descriptors. + + int spawn_i (ACE_THR_FUNC func, + void *args, + long flags, + ACE_thread_t * = 0, + ACE_hthread_t *t_handle = 0, + u_int priority = 0, + int grp_id = -1, + void *stack = 0, + size_t stack_size = 0); + // Create a new thread (must be called with locks held). + + int find (ACE_thread_t t_id); + // Locate the index of the table slot occupied by . Returns + // -1 if is not in the table doesn't contain . + + int insert_thr (ACE_thread_t t_id, ACE_hthread_t, int grp_id = -1); + // Insert a thread in the table (checks for duplicates). + + int append_thr (ACE_thread_t t_id, ACE_hthread_t, + ACE_Thread_State, + int grp_id); + // Append a thread in the table (adds at the end, growing the table + // if necessary). + + void remove_thr (int i); + // Remove thread from the table. + + int thread_descriptor_i (ACE_thread_t, ACE_Thread_Descriptor &); + // Implements the lookup function for the . Note + // that this version assumes that the lock is held. We need this to + // avoid intra-class method deadlock on systems that lack recursive + // mutexes. + + int hthread_descriptor_i (ACE_hthread_t, ACE_Thread_Descriptor &); + // Implements the lookup function for the . + // Note that this version assumes that the lock is held. We need + // this to avoid intra-class method deadlock on systems that lack + // recursive mutexes. + + // = The following four methods implement a simple scheme for + // operating on a collection of threads atomically. + + typedef int (ACE_Thread_Manager::*THR_FUNC)(int, int); + + int check_state (ACE_Thread_State state, ACE_thread_t thread); + // Efficiently check whether is in a particular . + // This call updates the TSS cache if possible to speed up + // subsequent searches. + + int apply_grp (int grp_id, THR_FUNC, int = 0); + // Apply to all members of the table that match the . + + int apply_all (THR_FUNC, int = 0); + // Apply to all members of the table. + + int resume_thr (int i); + // Resume the thread at index . + + int suspend_thr (int i); + // Suspend the thread at index . + + int kill_thr (int i, int signum); + // Send signal to the thread at index . + + int cancel_thr (int i); + // Set the cancellation flag for the thread at index . + + ACE_Thread_Descriptor *thr_table_; + // Vector that describes thread state within the Thread_Manager. + + size_t max_table_size_; + // Maximum number of threads we can manage (should be dynamically + // allocated). + + size_t current_count_; + // Current number of threads we are managing. + + int grp_id_; + // Keeps track of the next group id to assign. + + // = ACE_Thread_Mutex and condition variable for synchronizing + // termination. + ACE_Thread_Mutex lock_; + ACE_Condition_Thread_Mutex zero_cond_; +}; + + +class ACE_Export ACE_Thread_Control + // = TITLE + // Used to keep track of a thread's activities within its entry + // point function. +{ +public: + ACE_Thread_Control (ACE_Thread_Manager *tm = 0, + int insert = 0); + // Initialize the thread control object. If != 0, then + // register the thread with the Thread_Manager. + + ~ACE_Thread_Control (void); + // Implicitly kill the thread on exit and remove it from its + // associated ThreadManager. + + void *exit (void *status); + // Explicitly kill the thread on exit and remove it from its + // associated . + + int insert (ACE_Thread_Manager *tm); + // Store the and use it to register ourselves for + // correct shutdown. + + ACE_Thread_Manager *thr_mgr (void); + // Returns the current . + + ACE_Thread_Manager *thr_mgr (ACE_Thread_Manager *); + // Atomically set a new and return the old + // . + + void *status (void *status); + // Set the exit status (and return existing status). + + void *status (void); + // Get the current exit status. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Thread_Manager *tm_; + // Pointer to the thread manager for this block of code. + + void *status_; + // Keeps track of the exit status for the thread. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Thread_Manager.i" +#endif /* __ACE_INLINE__ */ + +#endif /* !defined (ACE_HAS_THREADS) */ +#endif /* ACE_THREAD_MANAGER_H */ + diff --git a/ace/Thread_Manager.i b/ace/Thread_Manager.i new file mode 100644 index 00000000000..041b74cea66 --- /dev/null +++ b/ace/Thread_Manager.i @@ -0,0 +1,83 @@ +/* -*- C++ -*- */ +// $Id$ + +// Thread_Manager.i + +#include "ace/Log_Msg.h" + +// Unique thread id. +ACE_INLINE ACE_thread_t +ACE_Thread_Descriptor::self (void) +{ + ACE_TRACE ("ACE_Thread_Descriptor::self"); + return this->thr_id_; +} + +// Unique kernel-level thread handle. + +ACE_INLINE void +ACE_Thread_Descriptor::self (ACE_hthread_t &handle) +{ + ACE_TRACE ("ACE_Thread_Descriptor::self"); + handle = this->thr_handle_; +} + +// Group ID. + +ACE_INLINE int +ACE_Thread_Descriptor::grp_id (void) +{ + ACE_TRACE ("ACE_Thread_Descriptor::grp_id"); + return grp_id_; +} + +// Current state of the thread. +ACE_INLINE ACE_Thread_State +ACE_Thread_Descriptor::state (void) +{ + ACE_TRACE ("ACE_Thread_Descriptor::state"); + return thr_state_; +} + +#if defined (ACE_HAS_THREADS) + +// Set the exit status. + +ACE_INLINE void * +ACE_Thread_Control::status (void *s) +{ + ACE_TRACE ("ACE_Thread_Control::status"); + return this->status_ = s; +} + +// Get the exit status. + +ACE_INLINE void * +ACE_Thread_Control::status (void) +{ + ACE_TRACE ("ACE_Thread_Control::status"); + return this->status_; +} + +// Returns the current . + +ACE_INLINE ACE_Thread_Manager * +ACE_Thread_Control::thr_mgr (void) +{ + ACE_TRACE ("ACE_Thread_Control::thr_mgr"); + return this->tm_; +} + +// Atomically set a new and return the old +// . + +ACE_INLINE ACE_Thread_Manager * +ACE_Thread_Control::thr_mgr (ACE_Thread_Manager *tm) +{ + ACE_TRACE ("ACE_Thread_Control::thr_mgr"); + ACE_Thread_Manager *o_tm = this->tm_; + return this->tm_ = tm; + return o_tm; +} + +#endif /* !defined (ACE_HAS_THREADS) */ diff --git a/ace/Time_Request_Reply.cpp b/ace/Time_Request_Reply.cpp new file mode 100644 index 00000000000..46bce6553c6 --- /dev/null +++ b/ace/Time_Request_Reply.cpp @@ -0,0 +1,187 @@ +// Time_Request_Reply.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Time_Request_Reply.h" + +// Default "do nothing" constructor. + +ACE_Time_Request::ACE_Time_Request (void) +{ + ACE_TRACE ("ACE_Time_Request::ACE_Time_Request"); +} + +// Create a ACE_Time_Request message. + +ACE_Time_Request::ACE_Time_Request (ACE_UINT32 t, // Type of request. + const ACE_UINT32 time, + ACE_Time_Value *timeout) // Max time waiting for request. +{ + ACE_TRACE ("ACE_Time_Request::ACE_Time_Request"); + this->msg_type (t); + + // If timeout is a NULL pointer, then block forever... + if (timeout == 0) + { + this->transfer_.block_forever_ = 1; + this->transfer_.sec_timeout_ = 0; + this->transfer_.usec_timeout_ = 0; + } + else // Do a "timed wait." + { + this->block_forever (0); + // Keep track of how long client is willing to wait. + this->transfer_.sec_timeout_ = timeout->sec (); + this->transfer_.usec_timeout_ = timeout->usec (); + } + + // Copy time into request + this->time_ = this->transfer_.time_ = time; +} + +// Initialize length_ in order to avoid problems with byte-ordering +void +ACE_Time_Request::init (void) +{ + ACE_TRACE ("ACE_Time_Request::init"); +// this->length (sizeof this->transfer_); +} + +// Get the fixed size of message +ssize_t +ACE_Time_Request::size (void) const +{ + ACE_TRACE ("ACE_Time_Request::size"); + return sizeof (this->transfer_); +} + +// = Set/get the type of the message. +ACE_UINT32 +ACE_Time_Request::msg_type (void) const +{ + ACE_TRACE ("ACE_Time_Request::msg_type"); + return this->transfer_.msg_type_; +} + +void +ACE_Time_Request::msg_type (ACE_UINT32 t) +{ + ACE_TRACE ("ACE_Time_Request::msg_type"); + this->transfer_.msg_type_ = t; +} + +// = Set/get the blocking semantics. +ACE_UINT32 +ACE_Time_Request::block_forever (void) const +{ + ACE_TRACE ("ACE_Time_Request::block_forever"); + return this->transfer_.block_forever_; +} + +void +ACE_Time_Request::block_forever (ACE_UINT32 bs) +{ + ACE_TRACE ("ACE_Time_Request::block_forever"); + this->transfer_.block_forever_ = bs; +} + +// = Set/get the timeout. +ACE_Time_Value +ACE_Time_Request::timeout (void) const +{ + ACE_TRACE ("ACE_Time_Request::timeout"); + return ACE_Time_Value (this->transfer_.sec_timeout_, this->transfer_.usec_timeout_); +} + +void +ACE_Time_Request::timeout (const ACE_Time_Value timeout) +{ + ACE_TRACE ("ACE_Time_Request::timeout"); + this->transfer_.sec_timeout_ = timeout.sec (); + this->transfer_.usec_timeout_ = timeout.usec (); +} + +// = Set/get the time +const ACE_UINT32 +ACE_Time_Request::time (void) const +{ + ACE_TRACE ("ACE_Time_Request::time"); + return this->time_; +} + +void +ACE_Time_Request::time (const ACE_UINT32 t) +{ + ACE_TRACE ("ACE_Time_Request::time"); + this->time_ = t; +} + +// Encode the transfer buffer into network byte order +// so that it can be sent to the server. +int +ACE_Time_Request::encode (void *&buf) +{ + ACE_TRACE ("ACE_Time_Request::encode"); + // Compute the length *before* doing the marshaling. + + buf = (void *) &this->transfer_; + this->transfer_.block_forever_ = htonl (this->transfer_.block_forever_); + this->transfer_.usec_timeout_ = htonl (this->transfer_.usec_timeout_); + this->transfer_.sec_timeout_ = htonl (this->transfer_.sec_timeout_); + this->transfer_.msg_type_ = htonl (this->transfer_.msg_type_); + this->transfer_.time_ = htonl (this->transfer_.time_); + + return this->size (); // Always fixed +} + +// Decode the transfer buffer into host byte byte order +// so that it can be used by the server. +int +ACE_Time_Request::decode (void) +{ + ACE_TRACE ("ACE_Time_Request::decode"); + // Decode + this->transfer_.block_forever_ = ntohl (this->transfer_.block_forever_); + this->transfer_.usec_timeout_ = ntohl (this->transfer_.usec_timeout_); + this->transfer_.sec_timeout_ = ntohl (this->transfer_.sec_timeout_); + this->transfer_.msg_type_ = ntohl (this->transfer_.msg_type_); + this->transfer_.time_ = ntohl (this->transfer_.time_); + + this->time_ = this->transfer_.time_; + return 0; +} + +// Print out the current values of the ACE_Time_Request. + +void +ACE_Time_Request::dump (void) const +{ + ACE_TRACE ("ACE_Time_Request::dump"); + ACE_DEBUG ((LM_DEBUG, "*******\nlength = %d\n", + this->size ())); + ACE_DEBUG ((LM_DEBUG, "message-type = ")); + + switch (this->msg_type ()) + { + case ACE_Time_Request::TIME_UPDATE: + ACE_DEBUG ((LM_DEBUG, "TIME_UPDATE\n")); + break; + default: + ACE_DEBUG ((LM_DEBUG, " = %d\n", this->msg_type ())); + break; + } + + if (this->block_forever ()) + ACE_DEBUG ((LM_DEBUG, "blocking forever\n")); + else + { + ACE_Time_Value tv = this->timeout (); + ACE_DEBUG ((LM_DEBUG, "waiting for %ld secs and %ld usecs\n", + tv.sec (), tv.usec ())); + } + ACE_DEBUG ((LM_DEBUG, "*******\ntime = %d\n", + this->time ())); + ACE_DEBUG ((LM_DEBUG, "+++++++\n")); +} + diff --git a/ace/Time_Request_Reply.h b/ace/Time_Request_Reply.h new file mode 100644 index 00000000000..7bd3219d6e7 --- /dev/null +++ b/ace/Time_Request_Reply.h @@ -0,0 +1,119 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// ACE_Time_Request_Reply.h +// +// = DESCRIPTION +// Define the format used to exchange messages between the +// ACE_Time_Server and clerks. +// +// = AUTHOR +// Prashant Jain +// +// ============================================================================ + +#if !defined (ACE_TIME_REQUEST_REPLY_H) +#define ACE_TIME_REQUEST_REPLY_H + +#include "ace/Time_Value.h" +#include "ace/SString.h" + +class ACE_Export ACE_Time_Request + // = TITLE + // Message format for delivering requests to the ACE_Time Server. + // + // = DESCRIPTION + // This class is implemented to minimize data copying. + // In particular, all marshaling is done in situ... +{ +public: + enum Constants + { + // Request message types. + TIME_UPDATE = 01, + FAILURE = 05, + + // Class-specific constant values. + MAX_TIME_LEN = MAXPATHLEN + 1 + }; + + ACE_Time_Request (void); + // Default constructor. + + ACE_Time_Request (ACE_UINT32 msg_type, // Type of request. + const ACE_UINT32 time, + ACE_Time_Value *timeout = 0); // Max time waiting for request. + // Create a message. + + void init (void); + // Initialize length_ in order to ensure correct byte ordering + // before a request is sent. + + // Get the fixed size of message + ssize_t size (void) const; + + // = Set/get the type of the message. + ACE_UINT32 msg_type (void) const; + void msg_type (ACE_UINT32); + + // = Set/get the time + const ACE_UINT32 time (void) const; + void time (const ACE_UINT32 t); + + // = Set/get the blocking semantics. + ACE_UINT32 block_forever (void) const; + void block_forever (ACE_UINT32); + + // = Set/get the timeout. + ACE_Time_Value timeout (void) const; + void timeout (const ACE_Time_Value timeout); + + int encode (void *&); + // Encode the message before transmission. + + int decode (void); + // Decode message after reception. + + void dump (void) const; + // Print out the values of the message for debugging purposes. + +private: + // = The 5 fields in the struct are transmitted to the server. + // The remaining 2 fields are not tranferred -- they are used only on + // the server-side to simplify lookups. + + struct Transfer + { + ACE_UINT32 msg_type_; + // Type of the request (i.e., ) + + ACE_UINT32 block_forever_; + // Indicates if we should block forever. If 0, then + // and indicates how long we should wait. + + ACE_UINT32 sec_timeout_; + // Max seconds willing to wait for name if not blocking forever. + + ACE_UINT32 usec_timeout_; + // Max micro seconds to wait for name if not blocking forever. + + ACE_UINT32 time_; + // The data portion contains + }; + + Transfer transfer_; + // Transfer buffer. + + ACE_UINT32 time_; + // Time +}; + + +#endif /* ACE_TIME_REQUEST_REPLY_H */ diff --git a/ace/Time_Value.cpp b/ace/Time_Value.cpp new file mode 100644 index 00000000000..c6aef0b8fa4 --- /dev/null +++ b/ace/Time_Value.cpp @@ -0,0 +1,231 @@ +// Time_Value.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/ACE.h" +#include "ace/Time_Value.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Time_Value.i" +#endif /* __ACE_INLINE__ */ + +// Static constant representing `zero-time'. +const ACE_Time_Value ACE_Time_Value::zero; + +ACE_ALLOC_HOOK_DEFINE(ACE_Time_Value) + +/* Initializes the ACE_Time_Value object from a timeval. */ + +ACE_Time_Value::ACE_Time_Value (const timeval &tv) +{ + ACE_TRACE ("ACE_Time_Value::ACE_Time_Value"); + this->set (tv); +} + +#if defined(ACE_WIN32) +// Initializes the ACE_Time_Value object from a Win32 FILETIME + +ACE_Time_Value::ACE_Time_Value (const FILETIME &file_time) +{ + ACE_TRACE ("ACE_Time_Value::ACE_Time_Value"); + this->set (file_time); +} + +void ACE_Time_Value::set (const FILETIME &file_time) +{ + // Initializes the ACE_Time_Value object from a Win32 FILETIME + ACE_QWORD _100ns = ACE_MAKE_QWORD (file_time.dwLowDateTime, + file_time.dwHighDateTime); + // Convert 100ns units to seconds; + this->tv_sec_ = long (_100ns / (10000 * 1000)); + // Convert remainder to microseconds; + this->tv_usec_ = long ((_100ns - (this->tv_sec_ * (10000 * 1000))) / 10); +} + +// Returns the value of the object as a Win32 FILETIME. + +ACE_Time_Value::operator FILETIME () const +{ + ACE_TRACE ("ACE_Time_Value::operator FILETIME"); + ACE_QWORD _100ns = ((ACE_QWORD) this->tv_sec_ * (1000 * 1000) + this->tv_usec_) * 10; + FILETIME file_time; + file_time.dwLowDateTime = ACE_LOW_DWORD (_100ns); + file_time.dwHighDateTime = ACE_HIGH_DWORD (_100ns); + return file_time; +} + +#endif + +void +ACE_Time_Value::dump (void) const +{ + ACE_TRACE ("ACE_Time_Value::dump"); +#if 0 + if (tv.usec () < 0 || tv.sec () < 0) + stream << "-"; + + stream << dec << abs (int (tv.sec ())) << "." +// << setw (6) << setfill ('0') + << dec << abs (int (tv.usec ())); +// I assume + inline int abs(int d) { return (d>0)?d:-d; } + is defined somewhere */ +#endif /* 0 */ +} + +void +ACE_Time_Value::set (long sec, long usec) +{ + ACE_TRACE ("ACE_Time_Value::set"); + this->tv_sec_ = sec; + this->tv_usec_ = usec; +} + +ACE_Time_Value::ACE_Time_Value (long sec, long usec) +{ + ACE_TRACE ("ACE_Time_Value::ACE_Time_Value"); + this->set (sec, usec); + this->normalize (); +} + +// Returns the value of the object as a timeval. + +ACE_Time_Value::operator timeval () const +{ + ACE_TRACE ("ACE_Time_Value::operator timeval"); + timeval tv; + tv.tv_sec = this->tv_sec_; + tv.tv_usec = this->tv_usec_; + return tv; +} + +// Add TV to this. + +void +ACE_Time_Value::operator+= (const ACE_Time_Value &tv) +{ + ACE_TRACE ("ACE_Time_Value::operator+="); + this->tv_sec_ += tv.tv_sec_; + this->tv_usec_ += tv.tv_usec_; + this->normalize (); +} + +// Subtract TV to this. + +void +ACE_Time_Value::operator-= (const ACE_Time_Value &tv) +{ + ACE_TRACE ("ACE_Time_Value::operator-="); + this->tv_sec_ -= tv.tv_sec_; + this->tv_usec_ -= tv.tv_usec_; + this->normalize (); +} + +// Adds two ACE_Time_Value objects together, returns the sum. + +ACE_Time_Value +operator + (const ACE_Time_Value &tv1, const ACE_Time_Value &tv2) +{ + ACE_TRACE ("operator +"); + ACE_Time_Value sum (tv1.tv_sec_ + tv2.tv_sec_, + tv1.tv_usec_ + tv2.tv_usec_); + + sum.normalize (); + return sum; +} + +// Subtracts two ACE_Time_Value objects, returns the difference. + +ACE_Time_Value +operator - (const ACE_Time_Value &tv1, const ACE_Time_Value &tv2) +{ + ACE_TRACE ("operator -"); + ACE_Time_Value delta (tv1.tv_sec_ - tv2.tv_sec_, + tv1.tv_usec_ - tv2.tv_usec_); + delta.normalize (); + return delta; +} + +// True if tv1 > tv2. + +int +operator > (const ACE_Time_Value &tv1, const ACE_Time_Value &tv2) +{ + ACE_TRACE ("operator >"); + if (tv1.tv_sec_ > tv2.tv_sec_) + return 1; + else if (tv1.tv_sec_ == tv2.tv_sec_ + && tv1.tv_usec_ > tv2.tv_usec_) + return 1; + else + return 0; +} + +// True if tv1 >= tv2. + +int +operator >= (const ACE_Time_Value &tv1, const ACE_Time_Value &tv2) +{ + ACE_TRACE ("operator >="); + if (tv1.tv_sec_ > tv2.tv_sec_) + return 1; + else if (tv1.tv_sec_ == tv2.tv_sec_ + && tv1.tv_usec_ >= tv2.tv_usec_) + return 1; + else + return 0; +} + +void +ACE_Time_Value::normalize (void) +{ + ACE_TRACE ("ACE_Time_Value::normalize"); + // New code from Hans Rohnert... + + if (this->tv_usec_ >= ONE_SECOND) + { + do + { + this->tv_sec_++; + this->tv_usec_ -= ONE_SECOND; + } + while (this->tv_usec_ >= ONE_SECOND); + } + else if (this->tv_usec_ <= -ONE_SECOND) + { + do + { + this->tv_sec_--; + this->tv_usec_ += ONE_SECOND; + } + while (this->tv_usec_ <= -ONE_SECOND); + } + + if (this->tv_sec_ >= 1 && this->tv_usec_ < 0) + { + this->tv_sec_--; + this->tv_usec_ += ONE_SECOND; + } + else if (this->tv_sec_ < 0 && this->tv_usec_ > 0) + { + this->tv_sec_++; + this->tv_usec_ -= ONE_SECOND; + } + +#if 0 + // Old code... + while ((this->tv_usec_ >= ONE_SECOND) + || (this->tv_sec_ < 0 && this->tv_usec_ > 0 )) + { + this->tv_usec_ -= ONE_SECOND; + this->tv_sec_++; + } + + while ((this->tv_usec_ <= -ONE_SECOND) + || (this->tv_sec_ > 0 && this->tv_usec_ < 0)) + { + this->tv_usec_ += ONE_SECOND; + this->tv_sec_--; + } +#endif +} diff --git a/ace/Time_Value.h b/ace/Time_Value.h new file mode 100644 index 00000000000..900c169eff6 --- /dev/null +++ b/ace/Time_Value.h @@ -0,0 +1,247 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Time_Value.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_TIME_VALUE_H) +#define ACE_TIME_VALUE_H + +// This file should be a link to the platform/compiler-specific +// configuration file (e.g., config-sunos5-sunc++-4.x.h). By +// including this here we avoid nasty circular include problems... +#include "ace/config.h" + +#if defined (__ACE_INLINE__) +#define ACE_INLINE inline +#else +#define ACE_INLINE +#endif /* __ACE_INLINE__ */ + +// Nasty macro stuff to account for Microsoft Win32 DLL nonsense. We +// use these macros so that we don't end up with ACE software +// hard-coded to Microsoft proprietary extensions to C++. + +#if defined (ACE_HAS_DLL) +#if defined (ACE_BUILD_DLL) +#if !defined (_MSC_VER) /* Mark classes as exported, Borland. */ +#define ACE_Export _export +#else /* Microsoft: */ +#define ACE_Export __declspec (dllexport) +#endif /* !_MSC_VER */ +#else /* Using the DLL. */ +#if !defined _MSC_VER +#define ACE_Export _import +#else +#define ACE_Export __declspec (dllimport) +#endif /* !_MSC_VER */ +#endif /* ACE_BUILD_DLL */ + +#else /* We're not building a DLL! */ +#define ACE_Export +#endif /* ACE_HAS_DLL */ + +#if defined (ACE_HAS_DLL) +#if defined (ACE_BUILD_SVC_DLL) +#if !defined (_MSC_VER) /* Mark classes as exported, Borland. */ +#define ACE_Svc_Export _export +#else /* Microsoft: */ +#define ACE_Svc_Export __declspec (dllexport) +#endif /* !_MSC_VER */ +#else /* Using the DLL. */ +#if !defined _MSC_VER +#define ACE_Svc_Export _import +#else +#define ACE_Svc_Export __declspec (dllimport) +#endif /* !_MSC_VER */ +#endif /* ACE_BUILD_DLL || ACE_BUILD_SVC_DLL */ + +#else /* We're not building a DLL! */ +#define ACE_Svc_Export +#endif /* ACE_HAS_DLL */ + +// This needs to go here *first* to avoid problems with AIX. +// Just to be safe we'll do it with pthreads, too -- jwr +#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) +extern "C" { +#include +} +#endif /* ACE_HAS_DCETHREADS */ + +#if (ACE_NTRACE == 1) +#define ACE_TRACE(X) +#else +#define ACE_TRACE(X) ACE_Trace ____ (X, __LINE__, __FILE__) +#endif /* ACE_NTRACE */ + +#include +#if defined (ACE_NEEDS_SYSTIME_H) +// Some platforms may need to include this, but I suspect that most +// will get it from +#if defined (VXWORKS) +#include +#else +#include +#endif /* VXWORKS */ +#endif /* ACE_NEEDS_SYSTIME_H */ + +#if !defined (ACE_HAS_POSIX_TIME) +// Definition per POSIX. +typedef struct timespec +{ + time_t tv_sec; // Seconds + long tv_nsec; // Nanoseconds +} timespec_t; +#elif defined (ACE_HAS_BROKEN_POSIX_TIME) +// OSF/1 defines struct timespec in - Tom Marrs +#include +#endif /* ACE_HAS_POSIX_TIME */ + +#if !defined (ACE_HAS_SVR4_TIME) +// Definition per SVr4. +typedef struct timespec timestruc_t; +#endif /* ACE_HAS_SVR4_TIME */ + +class ACE_Export ACE_Time_Value + // = TITLE + // Operations on "timeval" structures. + // + // = DESCRIPTION + // This class centralizes all the time-related processing in + // ACE. These timers are typically used in conjunction with + // lower-level OS mechanisms like select(), poll(), or + // cond_timedwait(). ACE_Time_Value help make the use of these + // mechanisms portable across OS platforms, +{ +public: + // = Useful constants. + static const ACE_Time_Value zero; + // Constant "0". + + // = Initialization method. + ACE_Time_Value (long sec = 0, long usec = 0); + // Default constructor. + + // = Methods for converting to/from various time formats. + ACE_Time_Value (const struct timeval &t); + // Construct a Time_Value from a timeval. + + ACE_Time_Value (const timestruc_t &t); + // Initializes the ACE_Time_Value object from a timestruc_t. + + ACE_Time_Value (const ACE_Time_Value &tv); + // Copy constructor. + +#if defined(ACE_WIN32) + ACE_Time_Value (const FILETIME &ft); + // Initializes the ACE_Time_Value object from a Win32 FILETIME +#endif + + void set (long sec = 0, long usec = 0); + // Construct a Time_Value from a timeval. + + void set (const timeval &t); + // Construct a Time_Value from a timeval. + + void set (const timestruc_t &t); + // Initializes the ACE_Time_Value object from a timestruc_t. + +#if defined(ACE_WIN32) + void set (const FILETIME &ft); + // Initializes the ACE_Time_Value object from a timestruc_t. +#endif + + long msec (void) const; + // Converts from Time_Value format into milli-seconds format. + + void msec (long); + // Converts from milli-seconds format into Time_Value format. + + operator timestruc_t () const; + // Returns the value of the object as a timestruc_t. + + operator timeval () const; + // Returns the value of the object as a timeval. + +#if defined(ACE_WIN32) + operator FILETIME () const; + // Returns the value of the object as a Win32 FILETIME. +#endif + + // = The following are accessor/mutator methods. + + long sec (void) const; + // Get seconds. + + void sec (long sec); + // Set seconds. + + long usec (void) const; + // Get microseconds. + + void usec (long usec); + // Set microseconds. + + // = The following are arithmetic methods for operating on + // Time_Values. + + void operator += (const ACE_Time_Value &tv); + // Add to this. + + void operator -= (const ACE_Time_Value &tv); + // Subtract to this. + + friend ACE_Export ACE_Time_Value operator + (const ACE_Time_Value &tv1, const ACE_Time_Value &tv2); + // Adds two ACE_Time_Value objects together, returns the sum. + + friend ACE_Export ACE_Time_Value operator - (const ACE_Time_Value &tv1, const ACE_Time_Value &tv2); + // Subtracts two ACE_Time_Value objects, returns the difference. + + friend ACE_Export int operator < (const ACE_Time_Value &tv1, const ACE_Time_Value &tv2); + // True if tv1 < tv2. + + friend ACE_Export int operator > (const ACE_Time_Value &tv1, const ACE_Time_Value &tv2); + // True if tv1 > tv2. + + friend ACE_Export int operator <= (const ACE_Time_Value &tv1, const ACE_Time_Value &tv2); + // True if tv1 <= tv2. + + friend ACE_Export int operator >= (const ACE_Time_Value &tv1, const ACE_Time_Value &tv2); + // True if tv1 >= tv2. + + friend ACE_Export int operator == (const ACE_Time_Value &tv1, const ACE_Time_Value &tv2); + // True if tv1 == tv2. + + friend ACE_Export int operator != (const ACE_Time_Value &tv1, const ACE_Time_Value &tv2); + // True if tv1 != tv2. + + void dump (void) const; + // Dump the state of an object. + +private: + void normalize (void); + // Put the timevalue into a canonical form. + + long tv_sec_; + // Seconds. + + long tv_usec_; + // Microseconds. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Time_Value.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_TIME_VALUE */ diff --git a/ace/Time_Value.i b/ace/Time_Value.i new file mode 100644 index 00000000000..9d88167b1c0 --- /dev/null +++ b/ace/Time_Value.i @@ -0,0 +1,166 @@ +/* -*- C++ -*- */ +// $Id$ + +// Time_Value.i + +#include "ace/Trace.h" + +// Don't put this in the class since it will expand the size! Also, +// can't make this an enum due to compiler bugs on some platforms... +static const long ONE_SECOND = 1000000L; + +// Initializes the ACE_Time_Value object. + +// Initializes a timestruc_t. Note that this approach loses precision +// since it converts the nano-seconds into micro-seconds. But then +// again, do any real systems have nano-second timer precision +// anyway?! + +ACE_INLINE void +ACE_Time_Value::set (const timestruc_t &tv) +{ + ACE_TRACE ("ACE_Time_Value::set"); + this->tv_sec_ = tv.tv_sec; + this->tv_usec_ = tv.tv_nsec / 1000; + + this->normalize (); +} + +// Returns the value of the object as a timestruc_t. + +ACE_INLINE +ACE_Time_Value::operator timestruc_t () const +{ + ACE_TRACE ("ACE_Time_Value::operator timestruc_t"); + timestruc_t tv; + tv.tv_sec = this->tv_sec_; + tv.tv_nsec = this->tv_usec_ * 1000; + return tv; +} + +// Initializes the ACE_Time_Value object from a timestruc_t. + +ACE_INLINE +ACE_Time_Value::ACE_Time_Value (const timestruc_t &tv) +{ + ACE_TRACE ("ACE_Time_Value::ACE_Time_Value"); + this->set (tv); +} + +ACE_INLINE void +ACE_Time_Value::set (const timeval &tv) +{ + ACE_TRACE ("ACE_Time_Value::set"); + this->tv_sec_ = tv.tv_sec; + this->tv_usec_ = tv.tv_usec; + + this->normalize (); +} + +// Initializes the ACE_Time_Value object from another ACE_Time_Value + +ACE_INLINE +ACE_Time_Value::ACE_Time_Value (const ACE_Time_Value &tv) + : tv_sec_ (tv.tv_sec_), + tv_usec_ (tv.tv_usec_) +{ + ACE_TRACE ("ACE_Time_Value::ACE_Time_Value"); +} + +// Returns number of seconds. + +ACE_INLINE long +ACE_Time_Value::sec (void) const +{ + ACE_TRACE ("ACE_Time_Value::sec"); + return this->tv_sec_; +} + +// Sets the number of seconds. + +ACE_INLINE void +ACE_Time_Value::sec (long sec) +{ + ACE_TRACE ("ACE_Time_Value::sec"); + this->tv_sec_ = sec; +} + +// Converts from Time_Value format into milli-seconds format. + +ACE_INLINE long +ACE_Time_Value::msec (void) const +{ + ACE_TRACE ("ACE_Time_Value::msec"); + return this->tv_sec_ * 1000 + this->tv_usec_ / 1000; +} + +// Converts from milli-seconds format into Time_Value format. + +ACE_INLINE void +ACE_Time_Value::msec (long milliseconds) +{ + ACE_TRACE ("ACE_Time_Value::msec"); + // Convert millisecond units to seconds; + this->tv_sec_ = milliseconds / 1000; + // Convert remainder to microseconds; + this->tv_usec_ = (milliseconds - (this->tv_sec_ * 1000)) * 1000; +} + +// Returns number of micro-seconds. + +ACE_INLINE long +ACE_Time_Value::usec (void) const +{ + ACE_TRACE ("ACE_Time_Value::usec"); + return this->tv_usec_; +} + +// Sets the number of micro-seconds. + +ACE_INLINE void +ACE_Time_Value::usec (long usec) +{ + ACE_TRACE ("ACE_Time_Value::usec"); + this->tv_usec_ = usec; +} + +// True if tv1 < tv2. + +ACE_INLINE int +operator < (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2) +{ + ACE_TRACE ("operator <"); + return tv2 > tv1; +} + +// True if tv1 >= tv2. + +ACE_INLINE int +operator <= (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2) +{ + ACE_TRACE ("operator <="); + return tv2 >= tv1; +} + +// True if tv1 == tv2. + +ACE_INLINE int +operator == (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2) +{ + ACE_TRACE ("operator =="); + return tv1.tv_sec_ == tv2.tv_sec_ + && tv1.tv_usec_ == tv2.tv_usec_; +} + +// True if tv1 != tv2. + +ACE_INLINE int +operator != (const ACE_Time_Value &tv1, + const ACE_Time_Value &tv2) +{ + ACE_TRACE ("operator !="); + return !(tv1 == tv2); +} diff --git a/ace/Timer_Queue.cpp b/ace/Timer_Queue.cpp new file mode 100644 index 00000000000..9a26fb4bbf0 --- /dev/null +++ b/ace/Timer_Queue.cpp @@ -0,0 +1,332 @@ +// Timer_Queue.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Timer_Queue.h" + +ACE_ALLOC_HOOK_DEFINE(ACE_Timer_Node) + +void +ACE_Timer_Node::dump (void) const +{ + ACE_TRACE ("ACE_Timer_Node::dump"); +} + +ACE_Timer_Node::ACE_Timer_Node (ACE_Event_Handler *h, + const void *a, + const ACE_Time_Value &t, + const ACE_Time_Value &i, + ACE_Timer_Node *n, + int timer_id) + : handler_ (h), + arg_ (a), + timer_value_ (t), + interval_ (i), + next_ (n), + timer_id_ (timer_id) +{ + ACE_TRACE ("ACE_Timer_Node::ACE_Timer_Node"); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Timer_Queue) + +void +ACE_Timer_Queue::dump (void) const +{ + ACE_TRACE ("ACE_Timer_Queue::dump"); +} + +// Create an empty queue. + +ACE_Timer_Queue::ACE_Timer_Queue (void) + : head_ (0), + timer_id_ (0) +{ + ACE_TRACE ("ACE_Timer_Queue::ACE_Timer_Queue"); +} + +// Checks if queue is empty. + +int +ACE_Timer_Queue::is_empty (void) const +{ + ACE_TRACE ("ACE_Timer_Queue::is_empty"); + return this->head_ == 0; +} + +// Returns earliest time in a non-empty queue. + +const ACE_Time_Value & +ACE_Timer_Queue::earliest_time (void) const +{ + ACE_TRACE ("ACE_Timer_Queue::earliest_time"); + return this->head_->timer_value_; +} + +// Remove all remaining items in the queue. + +ACE_Timer_Queue::~ACE_Timer_Queue (void) +{ + ACE_TRACE ("ACE_Timer_Queue::~ACE_Timer_Queue"); + ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_)); + + ACE_Timer_Node *curr = this->head_; + + while (curr != 0) + { + ACE_Timer_Node *next = curr->next_; + delete curr; + curr = next; + } +} + +// Reschedule a periodic timer. This function must be called with the +// mutex lock held. + +void +ACE_Timer_Queue::reschedule (ACE_Timer_Node *expired) +{ + ACE_TRACE ("ACE_Timer_Queue::reschedule"); + if (this->is_empty () || expired->timer_value_ < this->earliest_time ()) + { + expired->next_ = this->head_; + this->head_ = expired; + } + else + { + ACE_Timer_Node *prev = this->head_; + ACE_Timer_Node *after = this->head_->next_; + + // Locate the proper position in the queue. + + while (after != 0 + && expired->timer_value_ > after->timer_value_) + { + prev = after; + after = after->next_; + } + + expired->next_ = after; + prev->next_ = expired; + } +} + +// Insert a new handler that expires at time future_time; if interval +// is > 0, the handler will be reinvoked periodically. + +int +ACE_Timer_Queue::schedule (ACE_Event_Handler *handler, + const void *arg, + const ACE_Time_Value &future_time, + const ACE_Time_Value &interval) +{ + ACE_TRACE ("ACE_Timer_Queue::schedule"); + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); + + // Increment the sequence number (it will wrap around). + this->timer_id_++; + + if (this->is_empty () || future_time < this->earliest_time ()) + { + // Place at the beginning of the list. + ACE_NEW_RETURN (this->head_, + ACE_Timer_Node (handler, + arg, + future_time, + interval, + this->head_, + this->timer_id_), + -1); + return this->head_ ? this->timer_id_ : -1; + } + else // Place in the middle of the list somewhere. + { + ACE_Timer_Node *prev = this->head_; + ACE_Timer_Node *after = this->head_->next_; + + while (after != 0 && future_time > after->timer_value_) + { + prev = after; + after = after->next_; + } + + ACE_NEW_RETURN (prev->next_, + ACE_Timer_Node (handler, + arg, + future_time, + interval, + after, + this->timer_id_), + -1); + return prev->next_ ? this->timer_id_ : -1; + } +} + +// Locate and remove the single with a value of +// from the timer queue. + +int +ACE_Timer_Queue::cancel (int timer_id, const void **arg) +{ + ACE_TRACE ("ACE_Timer_Queue::cancel"); + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); + + ACE_Timer_Node *prev = 0; + ACE_Timer_Node *curr = 0; + + // Try to locate the ACE_Timer_Node that matches the timer_id. + + for (curr = this->head_; + curr != 0 && curr->timer_id_ != timer_id; + curr = curr->next_) + prev = curr; + + if (curr != 0) + { + if (prev == 0) + this->head_ = curr->next_; + else + prev->next_ = curr->next_; + + if (arg != 0) + *arg = curr->arg_; + + delete curr; + return 0; + } + else + return -1; +} + +// Locate and remove all values of from the timer queue. + +int +ACE_Timer_Queue::cancel (ACE_Event_Handler *handler) +{ + ACE_TRACE ("ACE_Timer_Queue::cancel"); + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); + + ACE_Timer_Node *prev = 0; + ACE_Timer_Node *curr = this->head_; + + while (curr != 0) + { + if (curr->handler_ == handler) + { + if (prev == 0) + { + this->head_ = curr->next_; + delete curr; + curr = this->head_; + } + else + { + prev->next_ = curr->next_; + delete curr; + curr = prev->next_; + } + } + else + { + prev = curr; + curr = curr->next_; + } + } + + return 0; +} + +// Run the method for all Timers whose values are <= +// . + +int +ACE_Timer_Queue::expire (const ACE_Time_Value &cur_time) +{ + ACE_TRACE ("ACE_Timer_Queue::expire"); + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1)); + + for (;;) + { + if (this->is_empty () || this->earliest_time () > cur_time) + break; // There aren't any more timers eligible to expire. + + ACE_Timer_Node *expired = this->head_; + ACE_Event_Handler *handler = + (ACE_Event_Handler *) expired->handler_; + const void *arg = expired->arg_; + int reclaim = 1; + int result; + + this->head_ = this->head_->next_; + + // Check whether this is an interval timer. + if (expired->interval_ > ACE_Time_Value::zero) + { + // Make sure that we skip past values that have already + // "expired". + do + expired->timer_value_ += expired->interval_; + while (expired->timer_value_ <= cur_time); + + // Since this is an interval timer, we need to reschedule + // it. + this->reschedule (expired); + reclaim = 0; + } + + // Perform the callback. + result = handler->handle_timeout (cur_time, arg); + + if (result == -1) + this->cancel (handler); + + if (reclaim) + delete expired; + } + return 0; +} + +// Determines the maximum amount of time that the Reactor must wait +// before timing out. This is computed as the smaller of (1) the +// amount the caller requested when calling handle_events() and (2) +// the earliest time registered in the Timer Queue (if any). Must be +// called with locks held since it returns a pointer to a Time_Value +// object stored in the Timer_Queue object itself. If the lock isn't +// held we'll have reentrancy problems!) + +ACE_Time_Value * +ACE_Timer_Queue::calculate_timeout (ACE_Time_Value *max_wait_time) +{ + ACE_TRACE ("ACE_Timer_Queue::calculate_timeout"); + ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, max_wait_time)); + + if (this->is_empty ()) + // Nothing on the Timer_Queue, so use whatever the caller gave us. + return max_wait_time; + else + { + ACE_Time_Value cur_time = ACE_OS::gettimeofday (); + + if (this->earliest_time () > cur_time) + { + // The earliest item on the Timer_Queue is still in the + // future. Therefore, use the smaller of (1) caller's wait + // time or (2) the delta time between now and the earliest + // time on the Timer_Queue. + + this->timeout_ = this->earliest_time () - cur_time; + if (max_wait_time == 0 || *max_wait_time > timeout_) + return &this->timeout_; + else + return max_wait_time; + } + else + { + // The earliest item on the Timer_Queue is now in the past. + // Therefore, we've got to "poll" the Reactor, i.e., it must + // just check the descriptors and then dispatch timers, etc. + this->timeout_ = ACE_Time_Value::zero; + return &this->timeout_; + } + } +} diff --git a/ace/Timer_Queue.h b/ace/Timer_Queue.h new file mode 100644 index 00000000000..90972f34598 --- /dev/null +++ b/ace/Timer_Queue.h @@ -0,0 +1,154 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Timer_Queue.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_TIMER_QUEUE_H) +#define ACE_TIMER_QUEUE_H + +#include "ace/Event_Handler.h" +#include "ace/Time_Value.h" +#include "ace/Synch.h" + +// This should be nested within the ACE_Timer_Queue class but some C++ +// compilers still don't like this... + +struct ACE_Timer_Node + // = TITLE + // Maintains the state associated with a Timer entry. +{ +friend class ACE_Timer_Queue; +private: + ACE_Timer_Node (ACE_Event_Handler *h, + const void *a, + const ACE_Time_Value &t, + const ACE_Time_Value &i, + ACE_Timer_Node *n, + int timer_id); + // Constructor. + + ACE_Event_Handler *handler_; + // Handler to invoke on when a timeout occurs. + + const void *arg_; + // Argument to pass to . + + ACE_Time_Value timer_value_; + // Time until the timer expires. + + ACE_Time_Value interval_; + // If this is a periodic timer this holds the time until the next + // timeout. + + ACE_Timer_Node *next_; + // Pointer to next timer. + + int timer_id_; + // Id of this timer (used to cancel timers before they expire). + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + + void dump (void) const; + // Dump the state of an object. +}; + +class ACE_Export ACE_Timer_Queue + // = TITLE + // Provides an interface to timers. + // + // = DESCRIPTION + // This is a simple implementation that uses a linked list of + // absolute times. A more clever implementation would use a + // delta-list, a heap, or timing wheels, etc. +{ +public: + // = Initialization and termination methods. + ACE_Timer_Queue (void); + // Default constructor. + virtual ~ACE_Timer_Queue (void); + + int is_empty (void) const; + // True if queue is empty, else false. + + const ACE_Time_Value &earliest_time (void) const; + // Returns the time of the earlier node in the Timer_Queue. + + virtual int schedule (ACE_Event_Handler *event_handler, + const void *arg, + const ACE_Time_Value &delay, + const ACE_Time_Value &interval = ACE_Time_Value::zero); + // Schedule an that will expire after amount + // of time. If it expires then is passed in as the value to + // the 's callback method. If + // is != to then it is used to + // reschedule the automatically. This method + // returns a timer handle that uniquely identifies the + // in an internal list. This timer handle can be + // used to cancel an before it expires. The + // cancellation ensures that timer_ids are unique up to values of + // greater than 2 billion timers. As long as timers don't stay + // around longer than this there should be no problems with + // accidentally deleting the wrong timer. + + virtual int cancel (ACE_Event_Handler *event_handler); + // Cancel all that match the address of + // . + + virtual int cancel (int timer_id, const void **arg = 0); + // Cancel the single that matches the + // value (which was returned from the method). If arg is + // non-NULL then it will be set to point to the ``magic cookie'' + // argument passed in when the was registered. This + // makes it possible to free up the memory and avoid memory leaks. + + virtual int expire (const ACE_Time_Value ¤t_time); + // Run the method for all Timers whose values are + // <= . + + virtual ACE_Time_Value *calculate_timeout (ACE_Time_Value *max); + // Determine the next event to timeout. Returns if there are + // no pending timers or if all pending timers are longer than max. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Time_Value timeout_; + // Returned by calculate_timeout. + + virtual void reschedule (ACE_Timer_Node *); + // Reschedule a "period" Timer_Node. + + ACE_Timer_Node *head_; + // Pointer to linked list of ACE_Timer_Handles. + + int timer_id_; + // Keeps track of the timer id that uniquely identifies each timer. + // This id can be used to cancel a timer via the + // method. + +#if defined (ACE_MT_SAFE) + ACE_Recursive_Thread_Mutex lock_; + // Synchronization variable for the MT_SAFE ACE_Reactor +#endif /* ACE_MT_SAFE */ +}; + +#include "ace/Timer_Queue.i" + +#endif /* ACE_TIMER_QUEUE_H */ diff --git a/ace/Timer_Queue.i b/ace/Timer_Queue.i new file mode 100644 index 00000000000..f2733b140a4 --- /dev/null +++ b/ace/Timer_Queue.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// $Id$ + +// Timer_Queue.i diff --git a/ace/Token.cpp b/ace/Token.cpp new file mode 100644 index 00000000000..30cf2943169 --- /dev/null +++ b/ace/Token.cpp @@ -0,0 +1,346 @@ +// Token.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Thread.h" +#include "ace/Time_Value.h" +#include "ace/Token.h" + +#if defined (ACE_HAS_THREADS) + +#if !defined (__ACE_INLINE__) +#include "ace/Token.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Token) + +void +ACE_Token::dump (void) const +{ + ACE_TRACE ("ACE_Token::dump"); +} + +ACE_Token::ACE_Queue_Entry::ACE_Queue_Entry (ACE_Thread_Mutex &m, + ACE_thread_t t_id) + : cv_ (m), + next_ (0), + thread_id_ (t_id), + runable_ (0) +{ + ACE_TRACE ("ACE_Token::ACE_Queue_Entry::ACE_Queue_Entry"); +} + +ACE_Token::ACE_Token (const char *name, void *any) + : head_ (0), + tail_ (0), + lock_ (name, any), + in_use_ (0), + waiters_ (0), + nesting_level_ (0) +{ +// ACE_TRACE ("ACE_Token::ACE_Token"); +} + +ACE_Token::~ACE_Token (void) +{ + ACE_TRACE ("ACE_Token::~ACE_Token"); +} + +// Remove an entry from the list. Must be +// called with locks held. + +void +ACE_Token::remove_entry (ACE_Token::ACE_Queue_Entry *entry) +{ + ACE_TRACE ("ACE_Token::remove_entry"); + ACE_Token::ACE_Queue_Entry *curr = 0; + ACE_Token::ACE_Queue_Entry *prev = 0; + + if (this->head_ == 0) + return; + + for (curr = this->head_; + curr != 0 && curr != entry; + curr = curr->next_) + prev = curr; + + if (curr == 0) // Didn't find the entry... + return; + else if (prev == 0) // Delete at the head. + this->head_ = this->head_->next_; + else // Delete in the middle. + prev->next_ = curr->next_; + + // We need to update the tail of the list + // if we've deleted the last entry. + + if (curr->next_ == 0) + this->tail_ = curr; +} + +int +ACE_Token::shared_acquire (void (*sleep_hook_func)(void *), + void *arg, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_Token::shared_acquire"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + ACE_thread_t thr_id = ACE_Thread::self (); + +#if defined (DEBUGGING) + cerr << '(' << ACE_Thread::self () << ')' + << " acquire: owner_ = " << this->owner_ + << ", owner_ addr = " << &this->owner_ + << ", nesting level = " << this->nesting_level_ << endl; +#endif /* DEBUGGING */ + + if (this->in_use_) // Someone already holds the token. + { + if (ACE_OS::thr_equal (thr_id, this->owner_)) // I own it! + { + this->nesting_level_++; + return 0; + } + // Do a quick check for "polling" behavior. + else if (timeout != 0 && timeout->sec () == 0 && timeout->usec () == 0) + { + errno = ETIME; + return -1; + } + else // We've got to sleep until we get the token. + { + // Allocate q entry on stack. This works since we don't + // exit this method's activation record until we've got the + // token. + ACE_Token::ACE_Queue_Entry my_entry (this->lock_, thr_id); + int ret = 0; + + if (this->head_ == 0) // I'm first and only waiter in line... + { + this->head_ = &my_entry; + this->tail_ = &my_entry; + } + else // I'm queued at the end of the list. + { + this->tail_->next_ = &my_entry; + this->tail_ = &my_entry; + } + + this->waiters_++; + + // Execute appropriate callback. + // (@@ should these methods return a success/failure + // status, and if so, what should we do with it?) + + if (sleep_hook_func) + { + (*sleep_hook_func) (arg); + ret++; + } + else // Execute virtual method. + { + this->sleep_hook (); + ret++; + } + + // Sleep until we've got the token (ignore signals). + + while (my_entry.cv_.wait (timeout) == -1) + { + // Note, this should obey whatever thread-specific + // interrupt policy is currently in place... + if (errno == EINTR) + continue; +#if defined (DEBUGGING) + cerr << '(' << ACE_Thread::self () << ')' + << " acquire: " + << (errno == ETIME ? "timed out" : "error occurred") + << endl; +#endif /* DEBUGGING */ + // We come here if a timeout occurs or some serious + // ACE_Condition object error. + this->remove_entry (&my_entry); + return -1; + } + + ACE_ASSERT (my_entry.runable_); +#if defined (DEBUGGING) + cerr << '(' << ACE_Thread::self () << ')' + << " acquire (UNBLOCKED)" << endl; +#endif /* DEBUGGING */ + return ret; + } + } + else + { + this->in_use_ = 1; + this->owner_ = thr_id; // Its mine! + return 0; + } +} + +// By default this is a no-op. + +/* virtual */ +void +ACE_Token::sleep_hook (void) +{ + ACE_TRACE ("ACE_Token::sleep_hook"); +} + +int +ACE_Token::acquire (ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_Token::acquire"); + return this->shared_acquire (0, 0, timeout); +} + +// Acquire the token, sleeping until it is obtained or until +// expires. + +int +ACE_Token::acquire (void (*sleep_hook_func)(void *), + void *arg, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_Token::acquire"); + return this->shared_acquire (sleep_hook_func, arg, timeout); +} + +// Try to renew the token. + +int +ACE_Token::renew (int requeue_position, ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_Token::renew"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + +#if defined (DEBUGGING) + cerr << '(' << ACE_Thread::self () << ')' + << " renew: owner_ thr = " << this->owner_ + << ", owner_ addr = " << &this->owner_ + << ", nesting level = " << this->nesting_level_ << endl; +#endif /* DEBUGGING */ + ACE_ASSERT (ACE_OS::thr_equal (ACE_Thread::self (), this->owner_)); + + // Check to see if there are any waiters. If not, we just keep the token. + if (this->head_ != 0) + { + ACE_Token::ACE_Queue_Entry my_entry (this->lock_, this->owner_); + int save_nesting_level_ = this->nesting_level_; + + this->owner_ = this->head_->thread_id_; + this->nesting_level_ = 0; + + // Wake up next waiter and make it runable. + this->head_->cv_.signal (); + this->head_->runable_ = 1; + + this->head_ = this->head_->next_; + + if (this->head_ == 0) // No other threads - just add me + { + this->head_ = &my_entry; + this->tail_ = &my_entry; + } + else if (requeue_position == -1) // Insert at the end of the queue. + { + this->tail_->next_ = &my_entry; + this->tail_ = &my_entry; + } + else if (requeue_position == 0) // Insert at head of queue. + { + my_entry.next_ = this->head_; + this->head_ = &my_entry; + } + else // Insert in the middle of the queue somewhere. + { + ACE_Token::ACE_Queue_Entry *insert_after = this->head_; + + // Determine where our thread should go in the queue of + // waiters. + + while (requeue_position-- && insert_after->next_ != 0) + insert_after = insert_after->next_; + + my_entry.next_ = insert_after->next_; + + if (my_entry.next_ == 0) + this->tail_ = &my_entry; + + insert_after->next_ = &my_entry; + } + + // Sleep until we've got the token (ignore signals). + + while (my_entry.cv_.wait (timeout) == -1) + { + // Note, this should obey whatever thread-specific + // interrupt policy is currently in place... + if (errno == EINTR) + continue; +#if defined (DEBUGGING) + cerr << '(' << ACE_Thread::self () << ')' + << " renew: " + << (errno == ETIME ? "timed out" : "error occurred") << endl; +#endif /* DEBUGGING */ + // We come here if a timeout occurs or + // some serious ACE_Condition object error. + this->remove_entry (&my_entry); + return -1; + } + + ACE_ASSERT (my_entry.runable_); + this->nesting_level_ = save_nesting_level_; + this->owner_ = my_entry.thread_id_; + } + return 0; +} + +// Release the current holder of the token (which had +// better be the caller's thread!). + +int +ACE_Token::release (void) +{ + ACE_TRACE ("ACE_Token::release"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + ACE_ASSERT (ACE_OS::thr_equal (ACE_Thread::self (), this->owner_)); + +#if defined (DEBUGGING) + cerr << '(' << ACE_Thread::self () << ')' + << " release: owner_ thr = " << this->owner_ + << ", owner_ addr = " << &this->owner_ + << ", nesting level = " << this->nesting_level_ << endl; +#endif /* DEBUGGING */ + + if (this->nesting_level_ > 0) + --this->nesting_level_; + else + { + if (this->head_ == 0) + this->in_use_ = 0; // No more waiters... + else + { + this->owner_ = this->head_->thread_id_; + --this->waiters_; + + // Wake up waiter and make it runable. + this->head_->cv_.signal (); + this->head_->runable_ = 1; + + this->head_ = this->head_->next_; + + if (this->head_ == 0) + this->tail_ = 0; + } + } + return 0; +} + +#endif /* ACE_HAS_THREADS */ + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/ace/Token.h b/ace/Token.h new file mode 100644 index 00000000000..a29d3f95d43 --- /dev/null +++ b/ace/Token.h @@ -0,0 +1,173 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Token.h +// +// = AUTHOR +// Original author -- Karl-Heinz Dorn (kdorn@erlh.siemens.de) +// Ported to ACE by Douglas C. Schmidt (schmidt@cs.wustl.edu) +// +// ============================================================================ + +#if !defined (ACE_TOKEN_H) +#define ACE_TOKEN_H + +#include "ace/Synch.h" + +#if defined (ACE_HAS_THREADS) + +class ACE_Export ACE_Token + // = TITLE + // Class that acquires, renews, and releases a synchronization + // token that is local to the process. + // + // = DESCRIPTION + // This class is a more general-purpose synchronization mechanism + // than SunOS 5.x mutexes. For example, it implements "recursive + // mutex" semantics, where a thread that owns the token can + // reacquire it without deadlocking. In addition, threads that are + // blocked awaiting the token are serviced in strict FIFO order as + // other threads release the token (SunOS 5.x mutexes don't strictly + // enforce an acquisition order). +{ +public: + // = Initialization and termination. + + ACE_Token (const char *name = 0, void * = 0); + ~ACE_Token (void); + + // = Synchronization operations. + + int acquire (void (*sleep_hook)(void *), + void *arg = 0, + ACE_Time_Value *timeout = 0); + // Acquire the token, sleeping until it is obtained or until + // expires. If some other thread currently holds the + // token then is called before our thread goes to + // sleep. This can be used by the requesting thread to + // unblock a token-holder that is sleeping, e.g., by means of + // writing to a pipe (the ACE ACE_Reactor uses this functionality). + // Return values: + // 0 if acquires without calling + // 1 if is called. + // -1 if failure or timeout occurs (if timeout occurs errno == ETIME) + // If == <&ACE_Time_Value::zero> then acquire has polling + // semantics (and does *not* call ). + + int acquire (ACE_Time_Value *timeout = 0); + // This behaves just like the previous method, except + // that it invokes the virtual function called + // that can be overridden by a subclass of ACE_Token. + + virtual void sleep_hook (void); + // This should be overridden by a subclass to define + // the appropriate behavior before goes to sleep. + // By default, this is a no-op... + + int renew (int requeue_position = 0, ACE_Time_Value *timeout = 0); + // An optimized method that efficiently reacquires the token if no + // other threads are waiting. This is useful for situations where + // you don't want to degrad the quality of service if there are + // other threads waiting to get the token. If == + // -1 and there are other threads waiting to obtain the token we are + // queued at the end of the list of waiters. If + // > -1 then it indicates how many entries to skip over before + // inserting our thread into the list of waiters (e.g., + // == 0 means "insert at front of the queue"). + // Renew has the rather odd semantics such that if there are other + // waiting threads it will give up the token even if the + // nesting_level_ > 1. I'm not sure if this is really the right + // thing to do (since it makes it possible for shared data to be + // changed unexpectedly) so use with caution... + + int tryacquire (void); + // Become interface-compliant with other lock mechanisms (implements + // a non-blocking ). + + int remove (void); + // Shuts down the ACE_Token instance. + + int release (void); + // Relinquish the token. If there are any waiters then the next one + // in line gets it. + + // = Accessor methods. + + int waiters (void); + // Return the number of threads that are currently waiting to get + // the token. + + ACE_thread_t current_owner (void); + // Return the id of the current thread that owns the token. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + // = The following structure implements a ACE_FIFO of waiter threads + // that are asleep waiting to obtain the token. + + struct ACE_Queue_Entry + { + ACE_Queue_Entry (ACE_Thread_Mutex &m, ACE_thread_t t_id); + + ACE_Queue_Entry *next_; + // Pointer to next waiter. + + ACE_thread_t thread_id_; + // ACE_Thread id of this waiter. + + ACE_Condition_Thread_Mutex cv_; + // ACE_Condition object used to wake up waiter when it can run again. + + int runable_; + // Ok to run. + }; + + int shared_acquire (void (*sleep_hook_func)(void *), + void *arg, + ACE_Time_Value *timeout); + // Implements the and methods above. + + void remove_entry (ACE_Queue_Entry *); + // Remove a waiter from the queue (used when a timeout occurs). + + ACE_Queue_Entry *head_; + // Head of the list of waiting threads. + + ACE_Queue_Entry *tail_; + // Tail of the list of waiting threads. + + ACE_Thread_Mutex lock_; + // ACE_Thread_Mutex used to lock internal data structures. + + ACE_thread_t owner_; + // Current owner of the token. + + int in_use_; + // Some thread (i.e., ) is using the token. We need this + // extra variable to deal with POSIX pthreads madness... + + int waiters_; + // Number of waiters. + + int nesting_level_; + // Current nesting level. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Token.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_THREADS */ +#endif /* ACE_TOKEN_H */ diff --git a/ace/Token.i b/ace/Token.i new file mode 100644 index 00000000000..74669037a45 --- /dev/null +++ b/ace/Token.i @@ -0,0 +1,41 @@ +/* -*- C++ -*- */ +// $Id$ + +// Token.i + +ACE_INLINE int +ACE_Token::remove (void) +{ + ACE_TRACE ("ACE_Token::remove"); + // Don't have an implementation for this yet... + errno = ENOTSUP; + return -1; +} + +ACE_INLINE int +ACE_Token::tryacquire (void) +{ + ACE_TRACE ("ACE_Token::tryacquire"); + return this->shared_acquire + (0, 0, (ACE_Time_Value *) &ACE_Time_Value::zero); +} + +ACE_INLINE int +ACE_Token::waiters (void) +{ + ACE_TRACE ("ACE_Token::waiters"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); + + int ret = this->waiters_; + return ret; +} + +ACE_INLINE ACE_thread_t +ACE_Token::current_owner (void) +{ + ACE_TRACE ("ACE_Token::current_owner"); + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, this->owner_); + + return this->owner_; +} + diff --git a/ace/Token_Collection.cpp b/ace/Token_Collection.cpp new file mode 100644 index 00000000000..c9f325ccb4c --- /dev/null +++ b/ace/Token_Collection.cpp @@ -0,0 +1,292 @@ +// Token_Collection.cpp +// $Id$ + + +#define ACE_BUILD_DLL +#include "ace/Token_Collection.h" +#include "ace/Log_Msg.h" + +#if !defined (__INLINE__) +#include "ace/Token_Collection.i" +#endif /* __INLINE__ */ + +ACE_Token_Collection::ACE_Token_Collection (int debug, + const char *name) +: debug_ (debug) +{ + ACE_TRACE ("ACE_Token_Collection::ACE_Token_Collection"); + + if (name == 0) + name = "no name"; + + int n = ACE_OS::strlen (name) + 1; + + if (n >= ACE_MAXTOKENNAMELEN) + n = ACE_MAXTOKENNAMELEN - 1; + + ACE_OS::strncpy (this->name_, (char *) name, n); + this->name_[ACE_MAXTOKENNAMELEN - 1] = '\0'; +} + +int +ACE_Token_Collection::insert (ACE_Token_Proxy &new_token) +{ + ACE_TRACE ("ACE_Token_Collection::insert"); + + TOKEN_NAME name (new_token.name ()); + + // Check if the new_proxy is already in the list. + if (collection_.find (name) == 1) + // One already exists, so fail. + return -1; + + // Clone the new token. + ACE_Token_Proxy *temp = new_token.clone (); + + if (collection_.bind (name, temp) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "bind failed\n"), -1); + return 0; +} + +int +ACE_Token_Collection::extract (const char *token_name, ACE_Token_Proxy *&proxy) +{ + ACE_TRACE ("ACE_Token_Collection::extract"); + TOKEN_NAME name (token_name); + return collection_.unbind (token_name, proxy); +} + +ACE_Token_Proxy * +ACE_Token_Collection::is_member (const char *token_name) +{ + ACE_TRACE ("ACE_Token_Collection::is_member"); + TOKEN_NAME name (token_name); + ACE_Token_Proxy *temp; + // Get the token from the collection. + return collection_.find (name, temp) == -1 ? 0 : temp; +} + +int +ACE_Token_Collection::is_member (const ACE_Token_Proxy &token) +{ + ACE_TRACE ("ACE_Token_Collection::is_member"); + TOKEN_NAME token_name (token.name ()); + return collection_.find (token_name) == 0; +} + +int +ACE_Token_Collection::acquire (int notify, + void (*sleep_hook)(void *), + ACE_Synch_Options &options) +{ + ACE_TRACE ("ACE_Token_Collection::acquire"); + + COLLECTION_ITERATOR iterator (collection_); + + for (COLLECTION_ENTRY *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + if (debug_) + ACE_DEBUG ((LM_DEBUG, "collection acquiring %s\n", + temp->int_id_->name ())); + if (temp->int_id_->acquire (notify, sleep_hook, options) == -1) + { + int error = errno; + this->release (); + errno = error; + ACE_RETURN (-1); + } + } + + return 0; +} + +int +ACE_Token_Collection::acquire (const char *token_name, + int notify, + void (*sleep_hook)(void *), + ACE_Synch_Options &options) +{ + ACE_TRACE ("ACE_Token_Collection::acquire"); + TOKEN_NAME name (token_name); + ACE_Token_Proxy *temp; + // Get the token from the collection. + int result = collection_.find (name, temp); + // did we find it? + if (result == -1) + return result; + // perform the operation + return temp->acquire (notify, sleep_hook, options); +} + + +int +ACE_Token_Collection::tryacquire (const char *token_name, + void (*sleep_hook)(void *)) +{ + ACE_TRACE ("ACE_Token_Collection::tryacquire"); + TOKEN_NAME name (token_name); + ACE_Token_Proxy *temp; + // Get the token from the collection. + int result = collection_.find (name, temp); + // did we find it? + if (result == -1) + return result; + + // perform the operation + return temp->tryacquire (sleep_hook); +} + +int +ACE_Token_Collection::tryacquire (void (*sleep_hook)(void *)) +{ + ACE_TRACE ("ACE_Token_Collection::tryacquire"); + + COLLECTION_ITERATOR iterator (collection_); + + for (COLLECTION_ENTRY *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + if (debug_) + ACE_DEBUG ((LM_DEBUG, "collection acquiring %s\n", + temp->int_id_->name ())); + // We will fail if _any_ token is not free. + if (temp->int_id_->tryacquire (sleep_hook) == -1) + return -1; + } + + return 0; +} + +int +ACE_Token_Collection::renew (int requeue_position, + ACE_Synch_Options &options) +{ + ACE_TRACE ("ACE_Token_Collection::renew"); + + COLLECTION_ITERATOR iterator (collection_); + + for (COLLECTION_ENTRY *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + if (debug_) + ACE_DEBUG ((LM_DEBUG, "collection renewing %s\n", + temp->int_id_->name ())); + if (temp->int_id_->renew (requeue_position, options) == -1) + return -1; + } + + return 0; +} + +int +ACE_Token_Collection::renew (const char *token_name, + int requeue_position, + ACE_Synch_Options &options) +{ + ACE_TRACE ("ACE_Token_Collection::renew"); + TOKEN_NAME name (token_name); + ACE_Token_Proxy *temp; + + // Get the token from the collection. + int result = collection_.find (name, temp); + + // Did we find it? + if (result == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p %s\n", + "not in collection ", + token_name), -1); + // perform the operation + return temp->renew (requeue_position, options); +} + +int +ACE_Token_Collection::release (ACE_Synch_Options &options) + +{ + ACE_TRACE ("ACE_Token_Collection::release"); + COLLECTION_ITERATOR iterator (collection_); + + for (COLLECTION_ENTRY *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + if (debug_) + ACE_DEBUG ((LM_DEBUG, "collection releasing %s\n", + temp->int_id_->name ())); + temp->int_id_->release (); + } + + return 0; +} + +int +ACE_Token_Collection::release (const char *token_name, + ACE_Synch_Options &options) +{ + ACE_TRACE ("ACE_Token_Collection::release"); + TOKEN_NAME name (token_name); + ACE_Token_Proxy *temp; + // get the token from the collection + int result = collection_.find (name, temp); + // did we find it? + if (result != 0) + return result; + // perform the operation + return temp->release (options); +} + +ACE_Token_Collection::~ACE_Token_Collection (void) +{ + ACE_TRACE ("ACE_Token_Collection::~ACE_Token_Collection"); + COLLECTION_ITERATOR iterator (collection_); + + for (COLLECTION_ENTRY *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + delete temp->int_id_; + // The ext_id_'s delete themselves when the array of + // COLLECTION_ENTRYs goes away. + } +} + + +// This method doesn't mean anything for a collection. +ACE_Token_Proxy * +ACE_Token_Collection::clone (void) const +{ + ACE_TRACE ("ACE_Token_Collection::clone"); + return (ACE_Token_Proxy *) 0; +} + +// This method doesn't mean anything for a collection. +ACE_Tokens * +ACE_Token_Collection::create_token (const char *name) +{ + ACE_TRACE ("ACE_Token_Collection::create_token"); + return (ACE_Tokens *) 0; +} + +void +ACE_Token_Collection::dump (void) const +{ + ACE_TRACE ("ACE_Token_Collection::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "ACE_Token_Collection::dump:\n" + " debug_ = %d\n", debug_)); + ACE_DEBUG ((LM_DEBUG, "collection_\n")); + collection_.dump (); + ACE_DEBUG ((LM_DEBUG, "base:\n")); + ACE_Token_Proxy::dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Map_Manager; +template class ACE_Map_Iterator; +template class ACE_Map_Entry; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/ace/Token_Collection.h b/ace/Token_Collection.h new file mode 100644 index 00000000000..c31147c927e --- /dev/null +++ b/ace/Token_Collection.h @@ -0,0 +1,216 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// ACE_Token_Collection.h +// +// = DESCRIPTION +// The ACE_Token class offers methods for acquiring, renewing, +// and releasing a synchronization token on a per-token basis. The +// ACE_Token_Collection offers an interface for performing +// operations on groups of tokens as a whole, or on a single token +// within the collection. +// +// The atomic group operations are not yet implemented. +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) and +// Tim Harrison (harrison@cs.wustl.edu) +// +// ============================================================================ + +#if !defined (ACE_TOKEN_COLLECTION_H) +#define ACE_TOKEN_COLLECTION_H + +#include "ace/Map_Manager.h" +#include "ace/Local_Tokens.h" +#include "ace/SString.h" + +class ACE_Export ACE_Token_Collection : public ACE_Token_Proxy + // = TITLE + // Allows atomic token group operations AND + // provides a ACE_Token manager interface. + // + // = DESCRIPTION + // There are two types of operations offered by + // ACE_Token_Collection. The first is atomic operations on + // collections of Token_Proxies. In this respect, the + // ACE_Token_Collection can be thought of as a single token + // consisting of multiple Token_Proxies. The second role of the + // ACE_Token_Collection is as a ACE_Token manager. + // ACE_Token_Collection allows individual operations on single + // members of a collection of Token_Proxies. This provides a + // single access point for operations on multiple tokens. + + // = Bugs + // Although ACE_Token_Collection inherits from ACE_Token_Proxy, it + // can not be including in a collection. This is because clone() + // returns zero for now. + +{ +public: + + ACE_Token_Collection (int debug = 0, + const char *name = 0); + // print out verbose debugging messages. will give a + // name to the collection. Collections don't really need names, but + // are sometimes useful for debugging. + +// Collection Management operations + + int insert (ACE_Token_Proxy &token); + + // Insert a Token into the collection. All ACE_Token type + // operations performed on the collection will also be performed on + // the new_proxy until it is removed. Note that no operations + // performed prior to the insertion will be performed. Returns: 0 + // on success, -1 on failure with == problem. If a token + // proxy already exists in the collection with the same name, the + // insertion will fail. Also, is copied. Note that during + // the copy, client_id's are *not* inherited. The client ID of the + // thread using the collection will be used. Client ID's can be + // changed explicity on each proxy using is_member. + + int extract (const char *token_name, ACE_Token_Proxy *&proxy); + // removes the ACE_Token matching the given token_name from the + // collection. On success, extract returns 0. On failure + // (token_name was not in the collection,) extract returns -1. On + // success, the state of the token found is copied into proxy. + // The returned ACE_Token_Proxy* must be deleted by the user. + + ACE_Token_Proxy *is_member (const char *token_name); + // returns the proxy if true. 0 otherwise. + + int is_member (const ACE_Token_Proxy &token); + // Is the specified token in the collection? + // 1, yes. + // 0, no. + +// = Collective operation semantics. + +// For acquire, renew, and release, there are two interfaces. Once +// interface allows an operation on a single token in the +// collection. The collective interfaces perform atomic operations +// on the entire collection. For instance, a collective acquire +// will perform an acquire for each and every token in the +// collection or the operation will fail. Currently, these +// operations are performed with no ordering heuristics. That is, +// the Collection steps through the tokens in the order they were +// inserted. For each one it performs the operation (acquire, +// renew, or release). + + virtual int acquire (int notify = 0, + void (*sleep_hook)(void *) = 0, + ACE_Synch_Options &options = + ACE_Synch_Options::defaults); + // Acquire "atomically" all resources in the collection. This is + // only successfull if all tokens in the collection could be + // acquired. options contains the blocking semantics, timeout + // value, etc. Returns: 0 on success, -1 on failure with == + // problem. If and error or deadlock occurs for one of the tokens, + // all the tokens will be released and the method will return -1. + // Note that returning on detection of deadlock prevents livelock + // between competing collections. If a collection returns after + // detecting deadlock, it is the application's responsibility to not + // to blindly loop on the collection::acquire operation. In other + // words, once the collection reports deadlock, it is out of our + // hands. + + virtual int acquire (const char *token_name, + int notify = 0, + void (*sleep_hook)(void *) = 0, + ACE_Synch_Options &options = + ACE_Synch_Options::defaults); + // Acquire the token corresponding to . The other + // parameters are passed to ::acquire. + + virtual int tryacquire (void (*sleep_hook)(void *) = 0); + // Try to acquire all tokens in collection. + + virtual int tryacquire (const char *token_name, + void (*sleep_hook)(void *) = 0); + // Try to acquire . + + virtual int renew (int requeue_position = 0, + ACE_Synch_Options &options = + ACE_Synch_Options::defaults); + // Renews "atomically" all resources in the collection. This is + // only successfull if all tokens in the collection could be + // renewed. options contains the blocking semantics, timeout + // value, etc. Returns: 0 on success, -1 on failure with == + // problem. + + + virtual int renew (const char *token_name, + int requeue_position = 0, + ACE_Synch_Options &options = + ACE_Synch_Options::defaults); + // Renew the token corresponding to . The other + // parameters are passed to ::renew. + + virtual int release (ACE_Synch_Options &options = + ACE_Synch_Options::defaults); + // Releases "atomically" all resources in the collection. This is + // only successfull if all tokens in the collection could be + // released. options contains the blocking semantics, timeout + // value, etc. Returns: 0 on success, -1 on failure with == + // problem. + + + virtual int release (const char *token_name, + ACE_Synch_Options &options = + ACE_Synch_Options::defaults); + // Release the token corresponding to . The other + // parameters are passed to ::release. + + ~ACE_Token_Collection (void); + + void dump (void) const; + // Dump the state of the class. + + virtual const char *name (void) const; + // Return the name of the collection. Not very functionally + // important, but sometimes a useful debugging tool. + +protected: + + typedef ACE_Token_Name TOKEN_NAME; + + typedef ACE_Map_Manager + COLLECTION; + // COLLECTION maintains a mapping from token names to ACE_Tokens* + + typedef ACE_Map_Iterator + COLLECTION_ITERATOR; + // Allows iterations through collection_ + + typedef ACE_Map_Entry + COLLECTION_ENTRY; + // Allows iterations through collection_ + + COLLECTION collection_; + // COLLECTION maintains a mapping from token names to ACE_Tokens*. + + int debug_; + // Whether to print out debug messages or not. + + char name_[ACE_MAXTOKENNAMELEN]; + // Name of the collection. + + // = I'm not sure what these mean, but they have to be defined since they're + // pure virtual in ACE_Token_Proxy. + virtual ACE_Token_Proxy *clone (void) const; + virtual ACE_Tokens *create_token (const char *name); +}; + +#if defined (__INLINE__) +#include "ace/Token_Collection.i" +#endif /* __INLINE__ */ + +#endif /* ACE_TOKEN_COLLECTION_H */ diff --git a/ace/Token_Collection.i b/ace/Token_Collection.i new file mode 100644 index 00000000000..f871206c4d8 --- /dev/null +++ b/ace/Token_Collection.i @@ -0,0 +1,11 @@ +/* -*- C++ -*- */ +// $Id$ + +// Token_Collection.i + +ACE_INLINE const char * +ACE_Token_Collection::name (void) const +{ + return name_; +} + diff --git a/ace/Token_Invariants.cpp b/ace/Token_Invariants.cpp new file mode 100644 index 00000000000..5687d0dfe37 --- /dev/null +++ b/ace/Token_Invariants.cpp @@ -0,0 +1,338 @@ +// Token_Invariants.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Token_Invariants.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Token_Invariants.i" +#endif /* __ACE_INLINE__ */ + +ACE_Token_Invariant_Manager * +ACE_Token_Invariant_Manager::instance (void) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::instance"); + static ACE_Token_Invariant_Manager *instance = 0; + + static ACE_TOKEN_CONST::MUTEX lock; + + // Perform the Double-Check pattern... + if (instance == 0) + { + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, lock, 0); + + if (instance == 0) + ACE_NEW_RETURN (instance, ACE_Token_Invariant_Manager, 0); + } + + return instance; +} + +ACE_Token_Invariant_Manager::ACE_Token_Invariant_Manager (void) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::ACE_Token_Invariant_Manager"); +} + +int +ACE_Token_Invariant_Manager::mutex_acquired (const char *token_name) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::mutex_acquired"); + + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1); + + ACE_Mutex_Invariants *inv = 0; + if (this->get_mutex (token_name, inv) == -1) + return -1; + else + return inv->acquired (); +} + +int +ACE_Token_Invariant_Manager::acquired (const ACE_Token_Proxy *proxy) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::acquired"); + + // Reach into the proxy to find the token type. + if (proxy->token_->type () == ACE_Tokens::MUTEX) + return this->mutex_acquired (proxy->name ()); + else // ACE_Tokens::RWLOCK. + { + if (proxy->type () == ACE_RW_Token::READER) + return this->reader_acquired (proxy->name ()); + else // ACE_RW_Token::WRITER. + return this->writer_acquired (proxy->name ()); + } +} + +void +ACE_Token_Invariant_Manager::releasing (const ACE_Token_Proxy *proxy) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::releasing"); + + // Reach into the proxy to find the token type. + if (proxy->token_->type () == ACE_Tokens::MUTEX) + this->mutex_releasing (proxy->name ()); + else // ACE_Tokens::RWLOCK. + this->rwlock_releasing (proxy->name ()); +} + +void +ACE_Token_Invariant_Manager::mutex_releasing (const char *token_name) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::mutex_releasing"); + ACE_GUARD (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_); + + ACE_Mutex_Invariants *inv = 0; + if (this->get_mutex (token_name, inv) == 0) + inv->releasing (); +} + +int +ACE_Token_Invariant_Manager::reader_acquired (const char *token_name) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::reader_acquired"); + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1); + + ACE_RWLock_Invariants *inv = 0; + if (this->get_rwlock (token_name, inv) == -1) + return -1; + else + return inv->reader_acquired (); +} + +int +ACE_Token_Invariant_Manager::writer_acquired (const char *token_name) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::writer_acquired"); + + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1); + + ACE_RWLock_Invariants *inv = 0; + if (this->get_rwlock (token_name, inv) == -1) + return -1; + else + return inv->writer_acquired (); +} + +void +ACE_Token_Invariant_Manager::rwlock_releasing (const char *token_name) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::rwlock_releasing"); + + ACE_GUARD (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_); + + ACE_RWLock_Invariants *inv = 0; + if (this->get_rwlock (token_name, inv) == 0) + inv->releasing (); +} + +void +ACE_Token_Invariant_Manager::dump (void) const +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "mutex_collection_:\n")); + mutex_collection_.dump (); + ACE_DEBUG ((LM_DEBUG, "rwlock_collection_:\n")); + rwlock_collection_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + + +int +ACE_Token_Invariant_Manager::get_mutex (const char *token_name, + ACE_Mutex_Invariants *&inv) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::get_mutex"); + TOKEN_NAME name (token_name); + if (mutex_collection_.find (name, inv) == -1) + // We did not find one in the collection. + { + ACE_Mutex_Invariants *new_invariant; + + ACE_NEW_RETURN (new_invariant, ACE_Mutex_Invariants, -1); + + if (mutex_collection_.bind (name, new_invariant) == -1) + { + delete new_invariant; + return -1; + } + + if (mutex_collection_.find (name, inv) == -1) + // We did not find one in the collection. + return -1; + } + + return 0; +} + +int +ACE_Token_Invariant_Manager::get_rwlock (const char *token_name, + ACE_RWLock_Invariants *&inv) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::get_rwlock"); + TOKEN_NAME name (token_name); + if (rwlock_collection_.find (name, inv) == -1) + // We did not find one in the collection. + { + ACE_RWLock_Invariants *new_invariant; + + ACE_NEW_RETURN (new_invariant, ACE_RWLock_Invariants, -1); + + if (rwlock_collection_.bind (name, new_invariant) == -1) + return -1; + + if (rwlock_collection_.find (name, inv) == -1) + // We did not find one in the collection. + return -1; + } + + return 0; +} + + +ACE_Token_Invariant_Manager::~ACE_Token_Invariant_Manager (void) +{ + ACE_TRACE ("ACE_Token_Invariant_Manager::~ACE_Token_Invariant_Manager"); + MUTEX_COLLECTION_ITERATOR iterator (mutex_collection_); + + for (MUTEX_COLLECTION_ENTRY *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + delete temp->int_id_; + + RWLOCK_COLLECTION_ITERATOR iterator2 (rwlock_collection_); + + for (RWLOCK_COLLECTION_ENTRY *temp2 = 0; + iterator2.next (temp2) != 0; + iterator2.advance ()) + delete temp2->int_id_; +} + +// ************************************************** +// ************************************************** +// ************************************************** + +ACE_Mutex_Invariants::ACE_Mutex_Invariants (void) +: owners_ (0) +{ +} + +int +ACE_Mutex_Invariants::acquired (void) +{ + if (++owners_ > 1) + { + owners_ = 42; + return 0; + } + else + return 1; +} + +void +ACE_Mutex_Invariants::releasing (void) +{ + if (owners_ == 1) + --owners_; +} + +ACE_Mutex_Invariants::ACE_Mutex_Invariants (const ACE_Mutex_Invariants &rhs) +: owners_ (rhs.owners_) +{ +} + +void +ACE_Mutex_Invariants::operator= (const ACE_Mutex_Invariants &rhs) +{ + owners_ = rhs.owners_; +} + +void +ACE_Mutex_Invariants::dump (void) const +{ + ACE_TRACE ("ACE_Mutex_Invariants::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "owners_ = %d\n", owners_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// ************************************************** +// ************************************************** +// ************************************************** + +ACE_RWLock_Invariants::ACE_RWLock_Invariants (void) +: writers_ (0), + readers_ (0) +{ +} + +int +ACE_RWLock_Invariants::writer_acquired (void) +{ + if (readers_ > 0) + { + writers_ = readers_ = 42; + return 0; + } + else if (++writers_ > 1) + { + writers_ = readers_ = 42; + return 0; + } + else + return 1; +} + +int +ACE_RWLock_Invariants::reader_acquired (void) +{ + if (writers_ > 0) + { + writers_ = readers_ = 42; + return 0; + } + else + { + ++readers_; + return 1; + } +} + +void +ACE_RWLock_Invariants::releasing (void) +{ + if (writers_ == 1) + writers_ = 0; + else if (readers_ > 0) + --readers_; +} + +ACE_RWLock_Invariants::ACE_RWLock_Invariants (const ACE_RWLock_Invariants &rhs) +: writers_ (rhs.writers_), + readers_ (rhs.readers_) +{ +} + +void +ACE_RWLock_Invariants::operator= (const ACE_RWLock_Invariants &rhs) +{ + writers_ = rhs.writers_; + readers_ = rhs.readers_; +} + +void +ACE_RWLock_Invariants::dump (void) const +{ + ACE_TRACE ("ACE_RWLock_Invariants::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "writers_ = %d\n", + "readers_ = %d\n", + writers_, readers_)); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +// template class ACE_TSS ; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/ace/Token_Invariants.h b/ace/Token_Invariants.h new file mode 100644 index 00000000000..eb40c9524a0 --- /dev/null +++ b/ace/Token_Invariants.h @@ -0,0 +1,217 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Token_Invariants +// +// = AUTHOR +// Tim Harrison (harrison@cs.wustl.edu) +// +// = DESCRIPTION +// Allows applications to test that invariants are always +// satisfied. Can test mutexes and readers/writer locks. Does +// not test recursive acquisition. +// +// ============================================================================ + +#if !defined (ACE_TOKEN_INVARIANTS_H) +#define ACE_TOKEN_INVARIANTS_H + +#include "ace/Synch.h" +#include "ace/Map_Manager.h" +#include "ace/Local_Tokens.h" + + +class ACE_Mutex_Invariants + // = TITLE + // Mutex Invariants + // + // = INVARIANTS + // 1. Only one owner at a time. +{ +public: + ACE_Mutex_Invariants (void); + // Default construction. + + int acquired (void); + // Returns 1 on success, 0 when an invariant has been violated and + // -1 on error. + + void releasing (void); + // Updates internal database. + + // = Map_Manager operations. + + ACE_Mutex_Invariants (const ACE_Mutex_Invariants &rhs); + // Copy construction. + + void operator= (const ACE_Mutex_Invariants &rhs); + // Copy. + + void dump (void) const; + // Dump the state of the class. + +private: + int owners_; + // Number of owners. This had better be 0 >= owners_ <= 1; +}; + +class ACE_RWLock_Invariants + // = TITLE + // RWLock Invariants + // + // = INVARIANTS + // 1. Only one writer at a time. + // 2. If there is an owning writer, there are no owning readers. +{ +public: + ACE_RWLock_Invariants (void); + // Default construction. + + int writer_acquired (void); + // Returns 1 on success, 0 when an invariant has been violated and + // -1 on error. + + int reader_acquired (void); + // Returns 1 on success, 0 when an invariant has been violated and + // -1 on error. + + void releasing (void); + // Updates internal database. + + // = Map_Manager operations. + + ACE_RWLock_Invariants (const ACE_RWLock_Invariants &rhs); + // Copy construction. + + void operator= (const ACE_RWLock_Invariants &rhs); + // Copy. + + void dump (void) const; + // Dump the state of the class. + +private: + int readers_; + // Number of owning readers. + + int writers_; + // Number of owning writers. +}; + +class ACE_Export ACE_Token_Invariant_Manager + // = TITLE + // Token Invariants + // + // = DESCRIPTION + // The Token Invariant Manager allows applications to test that + // invariants are always satisfied. Currently, Token_Invariants + // can test mutexes and readers/writer locks. Does not test + // recursive acquisition. + // + // Note that this class does not ever clean its database. Until + // destroyed, it's size will forever increase. +{ +public: + + static ACE_Token_Invariant_Manager *instance (void); + // Singleton access point. + + // = Polymorphic methods. Just pass in the proxy and the method + // figures out the type of the token. + + int acquired (const ACE_Token_Proxy *proxy); + // Returns 1 on success, 0 when an invariant has been violated and + // -1 on error. + + void releasing (const ACE_Token_Proxy *proxy); + // Updates internal database. + + // = Explicit methods. These to not require actual proxies in order + // to test a scenario. + + int mutex_acquired (const char *token_name); + // Returns 1 on success, 0 when an invariant has been violated and + // -1 on error. + + void mutex_releasing (const char *token_name); + // Updates internal database. + + int reader_acquired (const char *token_name); + // Returns 1 on success, 0 when an invariant has been violated and + // -1 on error. + + int writer_acquired (const char *token_name); + // Returns 1 on success, 0 when an invariant has been violated and + // -1 on error. + + void rwlock_releasing (const char *token_name); + // Updates internal database. + + void dump (void) const; + // Dump the state of the class. + + // = The following two method should be in the protected part of the + // class. Bugs with certain compilers preclude this. + ACE_Token_Invariant_Manager (void); + // Prevent non-singleton construction. + + ~ACE_Token_Invariant_Manager (void); + // Destruction. + +protected: + int get_mutex (const char *token_name, + ACE_Mutex_Invariants *&inv); + // Return or create. + + int get_rwlock (const char *token_name, + ACE_RWLock_Invariants *&inv); + // Return or create. + + ACE_TOKEN_CONST::MUTEX lock_; + // ACE_Mutex_Token used to lock internal data structures. + + typedef ACE_Token_Name TOKEN_NAME; + // This may be changed to a template type. + + typedef ACE_Map_Manager + MUTEX_COLLECTION; + // COLLECTION maintains a mapping from token names to mutexes. + + typedef ACE_Map_Iterator + MUTEX_COLLECTION_ITERATOR; + // Allows iterations through collection. + + typedef ACE_Map_Entry + MUTEX_COLLECTION_ENTRY; + // Allows iterations through collection. + + MUTEX_COLLECTION mutex_collection_; + // MUTEX_COLLECTION maintains a mapping from token names to mutexes. + + typedef ACE_Map_Manager + RWLOCK_COLLECTION; + // COLLECTION maintains a mapping from token names to mutexes. + + typedef ACE_Map_Iterator + RWLOCK_COLLECTION_ITERATOR; + // Allows iterations through collection. + + typedef ACE_Map_Entry + RWLOCK_COLLECTION_ENTRY; + // Allows iterations through collection. + + RWLOCK_COLLECTION rwlock_collection_; + // MUTEX_COLLECTION maintains a mapping from token names to mutexes. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Token_Invariants.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_TOKEN_INVARIANTS_H */ diff --git a/ace/Token_Invariants.i b/ace/Token_Invariants.i new file mode 100644 index 00000000000..53e10294181 --- /dev/null +++ b/ace/Token_Invariants.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// $Id$ + +// Token_Invariants.i diff --git a/ace/Token_Manager.cpp b/ace/Token_Manager.cpp new file mode 100644 index 00000000000..b144a71505a --- /dev/null +++ b/ace/Token_Manager.cpp @@ -0,0 +1,259 @@ +// Token_Manager.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Token_Manager.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Token_Manager.i" +#endif /* __ACE_INLINE__ */ + +// singleton token manager +ACE_Token_Manager *ACE_Token_Manager::token_manager_ = 0; + +ACE_TOKEN_CONST::MUTEX ACE_Token_Manager::creation_lock_; + +ACE_Token_Manager::ACE_Token_Manager () +{ + ACE_TRACE ("ACE_Token_Manager::ACE_Token_Manager"); +} + +ACE_Token_Manager::~ACE_Token_Manager () +{ + ACE_TRACE ("ACE_Token_Manager::~ACE_Token_Manager"); + + COLLECTION_ITERATOR iterator (collection_); + + for (COLLECTION_ENTRY *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + // @ should I be doing an unbind here? + delete temp->int_id_; + // The ext_id_'s delete themselves when the array of + // COLLECTION_ENTRYs goes away. + } +} + +ACE_Token_Manager * +ACE_Token_Manager::instance (void) +{ + ACE_TRACE ("ACE_Token_Manager::token_manager"); + + // This first check is to avoid acquiring the mutex in the common + // case. Double-Check pattern rules. + if (token_manager_ == 0) + { + ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, ACE_Token_Manager::creation_lock_, 0); + + if (token_manager_ == 0) + ACE_NEW_RETURN (token_manager_, ACE_Token_Manager, 0); + } + + return token_manager_; +} + +void +ACE_Token_Manager::get_token (ACE_Token_Proxy *proxy, + const char *token_name) +{ + ACE_TRACE ("ACE_Token_Manager::get"); + // Hmm. I think this makes sense. We perform our own locking here + // (see safe_acquire.) We have to make sure that only one thread + // uses the collection at a time. + + ACE_GUARD (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_); + + TOKEN_NAME name (token_name); + + if (collection_.find (name, proxy->token_) == -1) + // We did not find one in the collection. + { + // Make one. + proxy->token_ = proxy->create_token (token_name); + + // Put it in the collection. + if (collection_.bind (name, proxy->token_) == -1) + { + delete proxy->token_; + proxy->token_ = 0; + } + } + + if (proxy->token_ != 0) + proxy->token_->inc_reference (); + + // We may be returning proxy->token_ == 0 if new failed, caller must + // check. +} + +// 0. check_deadlock (TOKEN) +// 1. if TOKEN->visited (), return 0. +// 2. mark TOKEN visited. +// 3. get ALL_OWNERS +// 4. if CLIENT in ALL_OWNERS, return *DEADLOCK*. +// 5. for each OWNER in ALL_OWNERS, +// 6. if OWNER is not waiting for a NEW_TOKEN, continue. +// 7. else, if check_deadlock (NEW_TOKEN) == 1, return *DEADLOCK* +// 8. return 0. + +int +ACE_Token_Manager::check_deadlock (ACE_Token_Proxy *proxy) +{ + ACE_TRACE ("ACE_Token_Manager::check_deadlock"); + + // Start the recursive deadlock detection algorithm. + int result = this->check_deadlock (proxy->token_, proxy); + + // Whether or not we detect deadlock, we have to unmark all tokens + // for the next time. + COLLECTION_ITERATOR iterator (collection_); + for (COLLECTION_ENTRY *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + temp->int_id_->visit (0); + + return result; +} + +int +ACE_Token_Manager::check_deadlock (ACE_Tokens *token, ACE_Token_Proxy *proxy) +{ + ACE_TRACE ("ACE_Token_Manager::check_deadlock"); + + if (token->visited ()) + return 0; + + token->visit (1); + + ACE_Tokens::OWNER_STACK owners; + + int is_owner = token->owners (owners, proxy->client_id ()); + + switch (is_owner) + { + case -1: + // Error. + return -1; + case 1: + // The caller is an owner, so we have a deadlock situation. + if (debug_) + { + ACE_DEBUG ((LM_DEBUG, "(%t) Deadlock detected.\n")); + ACE_DEBUG ((LM_DEBUG, "%s owns %s and is waiting for %s.\n", + proxy->client_id (), + token->name (), + proxy->token_->name ())); + } + + return 1; + case 0: + default: + // Recurse on each owner. + while (!owners.is_empty ()) + { + ACE_TPQ_Entry *e; + owners.pop (e); + // If the owner is waiting on another token, recurse. + ACE_Tokens *twf = this->token_waiting_for (e->client_id ()); + if ((twf != 0) && + (this->check_deadlock (twf, proxy) == 1)) + { + if (debug_) + { + ACE_DEBUG ((LM_DEBUG, + "%s owns %s and is waiting for %s.\n", + e->client_id (), + token->name (), + twf->name ())); + } + return 1; + } + // else, check the next owner. + } + + // We've checked all the owners and found no deadlock. + return 0; + } +} + + +ACE_Tokens * +ACE_Token_Manager::token_waiting_for (const char *client_id) +{ + COLLECTION_ITERATOR iterator (collection_); + for (COLLECTION_ENTRY *temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + if (temp->int_id_->is_waiting_for (client_id)) + return temp->int_id_; + } + + // nothing was found, return NULL. + return 0; +} + +// Notify the token manager that a token is has been released. If +// as a result, there is no owner of the token, the token is +// deleted. +void +ACE_Token_Manager::release_token (ACE_Tokens *&token) +{ + ACE_TRACE ("ACE_Token_Manager::release"); + // again, let's perform our own locking here. + + ACE_GUARD (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_); + + if (token->dec_reference () == 0) + { + // No one has the token, so we can delete it and remove it from + // our collection. First, let's get it from the collection. + TOKEN_NAME token_name (token->name ()); + + ACE_Tokens *temp; + + if (collection_.unbind (token_name, temp) == -1) + // we did not find one in the collection + { + errno = ENOENT; + ACE_ERROR ((LM_ERROR, "Token Manager could not release %s:%d\n", + token->name (), token->type ())); + // @@ bad + } + else + // we found it + { + // sanity pointer comparison. The token referenced by the + // proxy better be the one we found in the list. + ACE_ASSERT (token == temp); + delete token; // or delete temp + // we set their token to zero. if the calling proxy is + // still going to be used, it had better check it's token + // value before calling a method on it! + token = 0; + } + } + // else + // someone is still interested in the token, so keep it around. +} + +void +ACE_Token_Manager::dump (void) const +{ + ACE_TRACE ("ACE_Token_Manager::dump"); + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "ACE_Token_Manager::dump:\n")); + ACE_DEBUG ((LM_DEBUG, "lock_\n")); + lock_.dump (); + ACE_DEBUG ((LM_DEBUG, "collection_\n")); + collection_.dump (); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Map_Manager ; +template class ACE_Map_Iterator; +template class ACE_Map_Entry ; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/ace/Token_Manager.h b/ace/Token_Manager.h new file mode 100644 index 00000000000..d1f004ab06f --- /dev/null +++ b/ace/Token_Manager.h @@ -0,0 +1,124 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Token_Manager +// +// = AUTHOR +// Tim Harrison (harrison@cs.wustl.edu) +// +// ============================================================================ + +#if !defined (ACE_TOKEN_MANAGER_H) +#define ACE_TOKEN_MANAGER_H + +#include "ace/Synch.h" +#include "ace/Map_Manager.h" +#include "ace/Local_Tokens.h" + +class ACE_Local_Mutex; +class ACE_Mutex_Token; + +class ACE_Export ACE_Token_Manager +// = TITLE +// Manages all tokens in a process space. +// +// = DESCRIPTION +// Factory: Proxies use the token manager to obtain token +// references. This allows multiple proxies to reference the same +// logical token. +// Deadlock detection: Tokens use the manager to check for +// deadlock situations during acquires. +// = EXTENDING TOKENS +// To add a new type of token (e.g. semaphore), do the following +// steps: 1. Create a new derivation of ACE_Token. This class +// defines the semantics of the new Token. 2. Create a +// derivation of ACE_Token_Manager. You will only need to +// redefine make_mutex. +{ +public: + ACE_Token_Manager (void); + ~ACE_Token_Manager (void); + + // Set/get a pointer to token manager singleton. + static ACE_Token_Manager *instance (void); + void instance (ACE_Token_Manager *); + + void get_token (ACE_Token_Proxy *, const char *token_name); + // The Token manager uses ACE_Token_Proxy::token_id_ to look for + // an existing token. If none is found, the Token Manager calls + // ACE_Token_Proxy::create_token to create a new one. When + // finished, sets ACE_Token_Proxy::token_. uniquely + // id's the token name. + + int check_deadlock (ACE_Token_Proxy *proxy); + int check_deadlock (ACE_Tokens *token, ACE_Token_Proxy *proxy); + // returns 1 if the acquire will _not_ cause deadlock. + // returns 0 if the acquire _will_ cause deadlock. + // this method ignores recursive acquisition. That is, it will not + // report deadlock if the client holding the token requests the + // token again. Thus, it assumes recursive mutexes. + + void release_token (ACE_Tokens *&token); + // notify the token manager that a token has been released. If as a + // result, there is no owner of the token, the token is deleted. + + ACE_TOKEN_CONST::MUTEX &mutex (void); + // This is to allow Tokens to perform atomic transactions. The + // typical usage is to acquire this mutex, check for a safe_acquire, + // perform some queueing (if need be) and then release the lock. + // This is necessary since safe_acquire is implemented in terms of + // the Token queues. + + void dump (void) const; + // Dump the state of the class. + + void debug (int d); + // Turn debug mode on/off. + +private: + int debug_; + // Wether to print debug messages or not. + + static ACE_Token_Manager *token_manager_; + // pointer to singleton token manager. + + static ACE_TOKEN_CONST::MUTEX creation_lock_; + // make sure that token_manager_ is created atomically (only once!) + + ACE_Tokens *token_waiting_for (const char *client_id); + // return the token that the given client_id is waiting for, if any + + ACE_TOKEN_CONST::MUTEX lock_; + // ACE_Mutex_Token used to lock internal data structures. + + typedef ACE_Token_Name TOKEN_NAME; + // This may be changed to a template type. + + typedef ACE_Map_Manager + COLLECTION; + // COLLECTION maintains a mapping from token names to ACE_Tokens* + + typedef ACE_Map_Iterator + COLLECTION_ITERATOR; + // Allows iterations through collection_ + + typedef ACE_Map_Entry + COLLECTION_ENTRY; + // Allows iterations through collection_ + + COLLECTION collection_; + // COLLECTION maintains a mapping from token names to ACE_Tokens*. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Token_Manager.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_TOKEN_MANAGER_H */ diff --git a/ace/Token_Manager.i b/ace/Token_Manager.i new file mode 100644 index 00000000000..572d439f289 --- /dev/null +++ b/ace/Token_Manager.i @@ -0,0 +1,19 @@ +/* -*- C++ -*- */ +// $Id$ + +// Token_Manager.i + +ACE_INLINE ACE_TOKEN_CONST::MUTEX & +ACE_Token_Manager::mutex (void) +{ + ACE_TRACE ("ACE_Token_Manager::mutex"); + return lock_; +} + +ACE_INLINE void +ACE_Token_Manager::debug (int d) +{ + ACE_TRACE ("ACE_Token_Manager::debug"); + debug_ = d; +} + diff --git a/ace/Token_Request_Reply.cpp b/ace/Token_Request_Reply.cpp new file mode 100644 index 00000000000..1aa160466ad --- /dev/null +++ b/ace/Token_Request_Reply.cpp @@ -0,0 +1,167 @@ +// Token_Request_Reply.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Token_Request_Reply.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Token_Request_Reply.i" +#endif /* __ACE_INLINE__ */ + +// Default "do nothing" constructor. + +ACE_Token_Request::ACE_Token_Request (void) + : client_id_ (0), + token_name_ (0) +{ +} + +// Create a ACE_Token_Request message. + +ACE_Token_Request::ACE_Token_Request (int token_type, + int proxy_type, + ACE_UINT32 operation_type, + const char token_name[], + const char client_id[], + const ACE_Synch_Options &options) +{ + this->token_type (token_type); + this->proxy_type (proxy_type); + this->operation_type (operation_type); + this->options (options); + this->token_name (token_name, client_id); +} + +// Encode the transfer buffer into network byte order +// so that it can be sent to the server. + +int +ACE_Token_Request::encode (void *&buf) +{ + buf = (void *) &this->transfer_; + return this->length (); +} + +// Decode the transfer buffer into host byte byte order +// so that it can be used by the server. + +int +ACE_Token_Request::decode (void) +{ + this->token_name_ = this->transfer_.data_; + + options_.set (transfer_.use_timeout_ == 1 ? ACE_Synch_Options::USE_TIMEOUT : 0, + ACE_Time_Value (transfer_.sec_, transfer_.usec_), + (void *) transfer_.arg_); + + // Decode the variable-sized portion. + int token_len = ACE_OS::strlen (this->token_name_); + + // Check to make sure this->tokenName_ isn't too long! + if (token_len >= ACE_MAXTOKENNAMELEN) + { + errno = ENAMETOOLONG; + return -1; + } + else // Skip this->tokenName_ + '\0' + ':'. + this->client_id_ = &this->token_name_[token_len + 2]; + + size_t data_size = ((sizeof this->transfer_ + - sizeof this->transfer_.data_) // Fixed-size header. + + ACE_OS::strlen (this->token_name_) + 1 // this->tokenName_ + '\0' + + ACE_OS::strlen (this->client_id_) + 1 // this->clientId_ + '\0' + + 1); // Space for ':' + // Make sure the message was correctly received and framed. + return this->length () == data_size ? 0 : -1; +} + +// Print out the current values of the ACE_Token_Request. + +void +ACE_Token_Request::dump (void) const +{ + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "*******\nlength = %d\ntoken name = %s\nclient id = %s\n", + this->length (), this->token_name (), this->client_id ())); + ACE_DEBUG ((LM_DEBUG, "type = ")); + + if (this->token_type () == ACE_Tokens::MUTEX) + ACE_DEBUG ((LM_DEBUG, "MUTEX\n")); + else // == ACE_Tokens::RWLOCK + { + if (this->proxy_type () == ACE_RW_Token::READER) + ACE_DEBUG ((LM_DEBUG, "RLOCK\n")); + else // == WRITER + ACE_DEBUG ((LM_DEBUG, "WLOCK\n")); + } + + ACE_DEBUG ((LM_DEBUG, "operation = ")); + switch (this->operation_type ()) + { + case ACE_Token_Request::ACQUIRE: + ACE_DEBUG ((LM_DEBUG, "ACQUIRE\n")); + break; + case ACE_Token_Request::RELEASE: + ACE_DEBUG ((LM_DEBUG, "RELEASE\n")); + break; + case ACE_Token_Request::RENEW: + ACE_DEBUG ((LM_DEBUG, "RENEW\n")); + break; + default: + ACE_DEBUG ((LM_DEBUG, " = %d\n", this->operation_type ())); + break; + } + + if (this->options ()[ACE_Synch_Options::USE_TIMEOUT] == 0) + ACE_DEBUG ((LM_DEBUG, "blocking forever\n")); + else + { + ACE_DEBUG ((LM_DEBUG, "waiting for %ld secs and %ld usecs\n", + this->options ().timeout ().sec (), this->options ().timeout ().usec ())); + } + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +// ************************************************************ +// ************************************************************ +// ************************************************************ + +// Create a ACE_Token_Reply message. + +ACE_Token_Reply::ACE_Token_Reply (void) // Type of reply. +{ + this->arg (0); + this->errnum (0); + this->length (sizeof (Transfer)); +} + +// Encode the transfer buffer into network byte order +// so that it can be sent to the client. + +int +ACE_Token_Reply::encode (void *&buf) +{ + buf = (void *) &this->transfer_; + return this->length (); +} + +// Decode the transfer buffer into host byte order +// so that it can be used by the client. + +int +ACE_Token_Reply::decode (void) +{ + return 0; +} + +// Print out current values of the ACE_Token_Reply object. + +void +ACE_Token_Reply::dump (void) const +{ + ACE_DEBUG ((LM_DEBUG, "*******\nlength = %d\nerrnum = %d", + this->length (), this->errnum ())); + ACE_DEBUG ((LM_DEBUG, "arg = %d", this->arg ())); +} + diff --git a/ace/Token_Request_Reply.h b/ace/Token_Request_Reply.h new file mode 100644 index 00000000000..526a308e1e5 --- /dev/null +++ b/ace/Token_Request_Reply.h @@ -0,0 +1,230 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// Token_Request_Reply.h +// +// = DESCRIPTION +// Define the format used to exchange messages between the +// ACE_Token Server and its clients. +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) +// Tim Harrison (harrison@cs.wustl.edu) +// +// ============================================================================ + +#if !defined (_TOKEN_REQUEST_REPLY_H) +#define _TOKEN_REQUEST_REPLY_H + +#include "ace/Local_Tokens.h" +#include "ace/Time_Value.h" + +class ACE_Export ACE_Token_Request + // = TITLE + // Message format for delivering requests to the ACE_Token Server. + // + // = DESCRIPTION + // This class is implemented to minimize data copying. + // In particular, all marshaling is done in situ... +{ +public: + enum OPERATION + { + // Operation types. + ACQUIRE, // Acquire the token. + RELEASE, // Release the token. + RENEW, // Renew the token. + REMOVE, // Remove the token. + TRY_ACQUIRE + }; + + ACE_Token_Request (void); + // Default constructor. + + ACE_Token_Request (int token_type, + int proxy_type, + ACE_UINT32 operation, + const char token_name[], + const char client_id[], + const ACE_Synch_Options &options); + // token_type - MUTEX, RWLOCK + // proxy_type - MUTEX, RLOCK, WLOCK (acquires mean different things) + // operation - method + // token_name + // client_id + // options - we check USE_TIMEOUT and use the arg. + + // = Set/get the length of the encoded/decoded message. + ACE_UINT32 length (void) const; + void length (ACE_UINT32); + + // = Set/get the type of proxy + int proxy_type (void) const; + void proxy_type (int proxy_type); + + // = Set/get the type of token + int token_type (void) const; + void token_type (int token_type); + + // = Set/get the type of the operation. + ACE_UINT32 operation_type (void) const; + void operation_type (ACE_UINT32); + + // = Set/get the requeue position. These should be used when renew + // is the operation type. + ACE_UINT32 requeue_position (void) const; + void requeue_position (ACE_UINT32); + + // = Set/get notify. These should be used when acquire is the operation type. + ACE_UINT32 notify (void) const; + void notify (ACE_UINT32); + + // = Set/get the timeout. + ACE_Synch_Options &options (void) const; + void options (const ACE_Synch_Options &options); + + // = Set/get the name of the token and the client id. The set + // method is combined to make it easier on us. We're copying the + // names as a contiguous buffer. + char *token_name (void) const; + char *client_id (void) const; + void token_name (const char *token_name, const char* client_id); + + int encode (void *&); + // Encode the message before transmission. + + int decode (void); + // Decode message after reception. This must be called to set the + // internal options. + + void dump (void) const; + // Print out the values of the message for debugging purposes. + +private: + // = The 5 fields in the struct are transmitted to the server. + // The remaining 2 fields are not tranferred -- they are used only on + // the server-side to simplify lookups. + + struct Transfer + { + ACE_UINT32 length_; + // Length of entire request. + + ACE_UINT32 token_type_; + // Type of the request (i.e., MUTEX, RLOCK, WLOCK... + + ACE_UINT32 proxy_type_; + // Type of the request (i.e., MUTEX, RLOCK, WLOCK... + + ACE_UINT32 operation_type_; + // Type of the request (i.e., , , , and ). + + ACE_UINT32 requeue_position_; + // this only makes sense when operation type is renew + + ACE_UINT32 notify_; + // this only makes sense when operation type is renew + + // = ACE_Synch_Options stuff + + ACE_UINT32 use_timeout_; + // Indicates if we should block forever. If 1, then + // and indicates how long we should wait. If 0, + // then we block forever. + + ACE_UINT32 sec_; + // Max seconds willing to wait for token if not blocking forever. + + ACE_UINT32 usec_; + // Max micro seconds to wait for token if not blocking forever. + + ACE_UINT32 arg_; + // value returned in Token_Reply::arg (); + + char data_[ACE_MAXTOKENNAMELEN + ACE_MAXCLIENTIDLEN + 1]; + // The data portion contains the followed by a ':' + // followed by the . + } transfer_; + + char *token_name_; + // Pointer to the beginning of the token name in this->data_. + + char *client_id_; + // Pointer to the beginning of the client id in this->data_; + + ACE_Synch_Options options_; + // Holds arg, sec, usec, etc. +}; + +class ACE_Export ACE_Token_Reply + // = TITLE + // Message format for delivering replies from the ACE_Token Server. + // + // = DESCRIPTION + // This class is implemented to minimize data copying. + // In particular, all marshaling is done in situ... +{ +public: + enum Constants + { + SUCCESS = 0 // this MUST be zero!!! + }; + + ACE_Token_Reply (void); + // Default constructor. + + // = Set/get the length of the encoded/decoded message. + ACE_UINT32 length (void) const; + void length (ACE_UINT32); + + // = Set/get the errno of a reply. + ACE_UINT32 errnum (void) const; + void errnum (ACE_UINT32); + + // = Set/get the arg of a reply. + ACE_UINT32 arg (void) const; + void arg (ACE_UINT32); + + int encode (void *&); + // Encode the message before transfer. + + int decode (void); + // Decode a message after reception. + + void dump (void) const; + // Print out the values of the message for debugging purposes. + +private: + // = The 2 fields in the struct are transmitted to the server. + + struct Transfer + { + ACE_UINT32 length_; + // Length of entire reply. + + ACE_UINT32 errno_; + // Indicates why error occurred if type_> == . + // Typical reasons include: + // (if client requested a non-blocking check for the token). + // (if the client timed out after waiting for the token). + // (if the token lock was removed out from underneath a waiter). + // (attempt to renew a token that isn't owned by the client). + + ACE_UINT32 arg_; + // magic cookie + + } transfer_; +}; + +#if defined (__ACE_INLINE__) +#include "ace/Token_Request_Reply.i" +#endif /* __ACE_INLINE__ */ + +#endif /* _TOKEN_REQUEST_REPLY_H */ diff --git a/ace/Token_Request_Reply.i b/ace/Token_Request_Reply.i new file mode 100644 index 00000000000..66428003359 --- /dev/null +++ b/ace/Token_Request_Reply.i @@ -0,0 +1,190 @@ +/* -*- C++ -*- */ +// $Id$ + +// Token_Request_Reply.i + +// = Set/get the length of the encoded/decoded message. + +ACE_INLINE ACE_UINT32 +ACE_Token_Request::length (void) const +{ + return ntohl (this->transfer_.length_); +} + +ACE_INLINE void +ACE_Token_Request::length (ACE_UINT32 l) +{ + this->transfer_.length_ = htonl (l); +} + +// = Set/get the type of the message. +ACE_INLINE int +ACE_Token_Request::token_type (void) const +{ + return (int) ntohl (this->transfer_.token_type_); +} + +ACE_INLINE void +ACE_Token_Request::token_type (int t) +{ + this->transfer_.token_type_ = htonl ((ACE_UINT32) t); +} + +// = Set/get the type of the message. +ACE_INLINE int +ACE_Token_Request::proxy_type (void) const +{ + return (int) ntohl (this->transfer_.proxy_type_); +} + +ACE_INLINE void +ACE_Token_Request::proxy_type (int t) +{ + this->transfer_.proxy_type_ = htonl ((ACE_UINT32) t); +} + +// = Set/get the type of the message. +ACE_INLINE ACE_UINT32 +ACE_Token_Request::operation_type (void) const +{ + return ntohl (this->transfer_.operation_type_); +} + +ACE_INLINE void +ACE_Token_Request::operation_type (ACE_UINT32 t) +{ + this->transfer_.operation_type_ = htonl (t); +} + +// = Set/get the requeue position +ACE_INLINE ACE_UINT32 +ACE_Token_Request::requeue_position (void) const +{ + return ntohl (this->transfer_.requeue_position_); +} + +ACE_INLINE void +ACE_Token_Request::requeue_position (ACE_UINT32 rq) +{ + this->transfer_.requeue_position_ = htonl (rq); +} + +// = Set/get the requeue position +ACE_INLINE ACE_UINT32 +ACE_Token_Request::notify (void) const +{ + return ntohl (this->transfer_.notify_); +} + +ACE_INLINE void +ACE_Token_Request::notify (ACE_UINT32 rq) +{ + this->transfer_.notify_ = htonl (rq); +} + +// = Set/get the blocking semantics. +ACE_INLINE ACE_Synch_Options & +ACE_Token_Request::options (void) const +{ + return (ACE_Synch_Options &) options_; +} + +ACE_INLINE void +ACE_Token_Request::options (const ACE_Synch_Options &opt) +{ + // fight the friggin const from hell + ACE_Synch_Options *options = (ACE_Synch_Options *) &opt; + + transfer_.use_timeout_ = options->operator[](ACE_Synch_Options::USE_TIMEOUT); + if (transfer_.use_timeout_ == 1) + { + transfer_.usec_ = options->timeout ().usec (); + transfer_.sec_ = options->timeout ().sec (); + } + else + { + transfer_.usec_ = 0; + transfer_.sec_ = 0; + } +} + +// = Set/get the name of the token. +ACE_INLINE char * +ACE_Token_Request::token_name (void) const +{ + return token_name_; +} + +ACE_INLINE void +ACE_Token_Request::token_name (const char *token_name, const char *client_id) +{ + size_t token_name_length = ACE_OS::strlen (token_name) + 1; // Add 1 for '\0'. + size_t client_id_length = ACE_OS::strlen (client_id) + 1; // Add 1 for '\0'. + + // Set up pointers and copy token_name and client_id into request. + token_name_ = this->transfer_.data_; + client_id_ = &this->token_name_[token_name_length + 1]; // Add 1 for ':'; + client_id_[-1] = ':'; // Insert the ':' before this->clientId_. + + (void) ACE_OS::memcpy (token_name_, token_name, token_name_length); + (void) ACE_OS::memcpy (client_id_, client_id, client_id_length); + + // Compute size of the fixed portion of the message... + size_t len = sizeof this->transfer_ - sizeof this->transfer_.data_; + + // ... then add in the amount of the variable-sized portion. + len += token_name_length + client_id_length + 1; + + this->length (len); +} + +// = Set/get the id of the client. +ACE_INLINE char * +ACE_Token_Request::client_id (void) const +{ + return this->client_id_; +} + +// ************************************************************ +// ************************************************************ +// ************************************************************ + +// = Set/get the length of the encoded/decoded message. +ACE_INLINE ACE_UINT32 +ACE_Token_Reply::length (void) const +{ + return ntohl (this->transfer_.length_); +} + +ACE_INLINE void +ACE_Token_Reply::length (ACE_UINT32 l) +{ + this->transfer_.length_ = htonl (l); +} + +// = Set/get the errno of a failed reply. +ACE_INLINE ACE_UINT32 +ACE_Token_Reply::errnum (void) const +{ + return ntohl (this->transfer_.errno_); +} + +ACE_INLINE void +ACE_Token_Reply::errnum (ACE_UINT32 e) +{ + this->transfer_.errno_ = htonl (e); +} + +// = Set/get the length of the encoded/decoded message. +ACE_INLINE ACE_UINT32 +ACE_Token_Reply::arg (void) const +{ + return ntohl (this->transfer_.arg_); +} + +ACE_INLINE void +ACE_Token_Reply::arg (ACE_UINT32 arg) +{ + this->transfer_.arg_ = htonl (arg); +} + diff --git a/ace/Trace.cpp b/ace/Trace.cpp new file mode 100644 index 00000000000..1053a45159f --- /dev/null +++ b/ace/Trace.cpp @@ -0,0 +1,115 @@ +// Trace.cpp +// $Id$ + +// We need this to get the status of ACE_NTRACE... + +#define ACE_BUILD_DLL +#include "ace/config.h" + +// Turn off tracing for the duration of this file. +#if defined (ACE_NTRACE) +#undef ACE_NTRACE +#endif /* ACE_NTRACE */ +#define ACE_NTRACE 1 + +// This must come first to avoid "order of include" problems... + +#if !defined (ACE_HAS_INLINED_OSCALLS) && !defined (ACE_WIN32) +#define ACE_HAS_INLINED_OSCALLS +#include "ace/ACE.h" +#undef ACE_HAS_INLINED_OSCALLS +#else +#include "ace/ACE.h" +#endif /* !ACE_HAS_INLINED_OSCALLS */ + +#include "ace/Log_Msg.h" + +#include "ace/Trace.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Trace.i" +#endif /* __ACE_INLINE__ */ + +// = Static initialization. + +// Keeps track of how far to indent per trace call. +int ACE_Trace::nesting_indent_ = ACE_Trace::DEFAULT_INDENT; + +// Is tracing enabled? +int ACE_Trace::enable_tracing_ = ACE_Trace::DEFAULT_TRACING; + +ACE_ALLOC_HOOK_DEFINE(ACE_Trace) + +void +ACE_Trace::dump (void) const +{ +} + +// Enable the tracing facility. + +void +ACE_Trace::start_tracing (void) +{ + ACE_Trace::enable_tracing_ = 1; +} + +// Disable the tracing facility. + +void +ACE_Trace::stop_tracing (void) +{ + ACE_Trace::enable_tracing_ = 0; +} + +// Change the nesting indentation level. + +void +ACE_Trace::set_nesting_indent (int indent) +{ + ACE_Trace::nesting_indent_ = indent; +} + +// Perform the first part of the trace, which prints out the string N, +// the LINE, and the ACE_FILE as the function is entered. + +ACE_Trace::ACE_Trace (const char *n, + int line, + const char *file) +{ + this->name_ = n; + + if (ACE_Trace::enable_tracing_) + { + ACE_Log_Msg *lm = ACE_LOG_MSG; + if (lm->tracing_enabled () + && lm->trace_active () == 0) + { + lm->trace_active (1); + ACE_DEBUG ((LM_DEBUG, "%*s(%t) calling %s in file `%s' on line %d\n", + ACE_Trace::nesting_indent_ * lm->inc (), + "", this->name_, file, line)); + lm->trace_active (0); + } + } +} + +// Perform the second part of the trace, which prints out the NAME as +// the function is exited. + +ACE_Trace::~ACE_Trace (void) +{ + if (ACE_Trace::enable_tracing_) + { + ACE_Log_Msg *lm = ACE_LOG_MSG; + if (lm->tracing_enabled () + && lm->trace_active () == 0) + { + lm->trace_active (1); + ACE_DEBUG ((LM_DEBUG, "%*s(%t) leaving %s\n", + ACE_Trace::nesting_indent_ * lm->dec (), + "", this->name_)); + lm->trace_active (0); + } + } +} + diff --git a/ace/Trace.h b/ace/Trace.h new file mode 100644 index 00000000000..8943b7a8055 --- /dev/null +++ b/ace/Trace.h @@ -0,0 +1,77 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Trace.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_TRACE_H) +#define ACE_TRACE_H + +class ACE_Export ACE_Trace + // = TITLE + // A C++ trace facility that keeps track of which methods are + // entered and exited. + // + // = DESCRIPTION + // This class uses C++ constructors and destructors to automate + // the ACE_Trace nesting. In addition, thread-specific storage + // is used to enable multiple threads to work correctly. +{ +public: + // = Initialization and termination methods. + + ACE_Trace (const char *n, int line = 0, const char *file = ""); + // Perform the first part of the trace, which prints out the string + // N, the LINE, and the ACE_FILE as the function is entered. + + ~ACE_Trace (void); + // Perform the second part of the trace, which prints out the NAME + // as the function is exited. + + // = Control the tracing level. + static void start_tracing (void); + // Enable the tracing facility. + + static void stop_tracing (void); + // Disable the tracing facility. + + static void set_nesting_indent (int indent); + // Change the nesting indentation level. + + void dump (void) const; + // Dump the state of an object. + +private: + // Keeps track of how deeply the call stack is nested (this is + // maintained in thread-specific storage to ensure correctness in + // multiple threads of control. + + const char *name_; + // Name of the method we are in. + + static int nesting_indent_; + // Keeps track of how far to indent per trace call. + + static int enable_tracing_; + // Is tracing enabled? + + // Default values. + enum + { + DEFAULT_INDENT = 3, + DEFAULT_TRACING = 1 + }; +}; + +#endif /* ACE_TRACE_H */ diff --git a/ace/Trace.i b/ace/Trace.i new file mode 100644 index 00000000000..a480d9af351 --- /dev/null +++ b/ace/Trace.i @@ -0,0 +1,7 @@ +/* -*- C++ -*- */ +// $Id$ + +// Trace.i + + + diff --git a/ace/Typed_SV_Message.cpp b/ace/Typed_SV_Message.cpp new file mode 100644 index 00000000000..29e227b43c5 --- /dev/null +++ b/ace/Typed_SV_Message.cpp @@ -0,0 +1,21 @@ +// Typed_SV_Message.cpp +// $Id$ + +#if !defined (ACE_TYPED_SV_MESSAGE_C) +#define ACE_TYPED_SV_MESSAGE_C +#define ACE_BUILD_DLL +#include "ace/Typed_SV_Message.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Typed_SV_Message.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Typed_SV_Message) + +template void +ACE_Typed_SV_Message::dump (void) const +{ + ACE_TRACE ("ACE_Typed_SV_Message::dump"); +} + +#endif /* ACE_TYPED_SV_MESSAGE_C */ diff --git a/ace/Typed_SV_Message.h b/ace/Typed_SV_Message.h new file mode 100644 index 00000000000..08e5ffc70dc --- /dev/null +++ b/ace/Typed_SV_Message.h @@ -0,0 +1,88 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Typed_SV_Message.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_TYPED_SV_MESSAGE_H) +#define ACE_TYPED_SV_MESSAGE_H + +#include "ace/ACE.h" + +template +class ACE_Typed_SV_Message + // = TITLE + // Defines the header file for the C++ wrapper for System V + // message queues. +{ +public: + // = Initialization and termination methods. + ACE_Typed_SV_Message (long type = 0, + int length = sizeof (T), + int max_size = sizeof (T)); + ACE_Typed_SV_Message (const T &data, + long type = 0, + int length = sizeof (T), + int max_size = sizeof (T)); + ~ACE_Typed_SV_Message (void); + + // = Get/set the type of the message. + long type (void) const; + void type (long type); + + // = Get/set the length of the message. + int length (void) const; + void length (int l); + + // = Get/set the maximum size of the message. + int max_size (void) const; + void max_size (int m); + + // = Get/set a pointer to the data in the message. + T &data (void); + void data (const T &data); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + long type_; + // Type of message. + + int length_; + // Length of this message. + + int max_; + // Maximum length of any message. + + T data_; + // Data stored in a message. +}; + +#if defined (__ACE_INLINE__) +#include "ace/Typed_SV_Message.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Typed_SV_Message.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Typed_SV_Message.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_TYPED_SV_MESSAGE_H */ diff --git a/ace/Typed_SV_Message.i b/ace/Typed_SV_Message.i new file mode 100644 index 00000000000..5717dcc2d50 --- /dev/null +++ b/ace/Typed_SV_Message.i @@ -0,0 +1,91 @@ +/* -*- C++ -*- */ +// $Id$ + +// Typed_SV_Message.i + +template ACE_INLINE +ACE_Typed_SV_Message::ACE_Typed_SV_Message (long t, + int l, + int m) + : type_ (t) +{ + ACE_TRACE ("ACE_Typed_SV_Message::ACE_Typed_SV_Message"); + this->length (l); + this->max_size (m); +} + +template ACE_INLINE +ACE_Typed_SV_Message::ACE_Typed_SV_Message (const T &d, + long t, + int l, + int m) + : data_ (d), + type_ (t) +{ + ACE_TRACE ("ACE_Typed_SV_Message::ACE_Typed_SV_Message"); + this->length (l); + this->max_size (m); +} + +template ACE_INLINE +ACE_Typed_SV_Message::~ACE_Typed_SV_Message (void) +{ + ACE_TRACE ("ACE_Typed_SV_Message::~ACE_Typed_SV_Message"); +} + +template ACE_INLINE long +ACE_Typed_SV_Message::type (void) const +{ + ACE_TRACE ("ACE_Typed_SV_Message::type"); + return this->type_; +} + +template ACE_INLINE void +ACE_Typed_SV_Message::type (long t) +{ + ACE_TRACE ("ACE_Typed_SV_Message::type"); + this->type_ = t; +} + +template ACE_INLINE int +ACE_Typed_SV_Message::length (void) const +{ + ACE_TRACE ("ACE_Typed_SV_Message::length"); + return this->length_; +} + +template ACE_INLINE void +ACE_Typed_SV_Message::length (int len) +{ + ACE_TRACE ("ACE_Typed_SV_Message::length"); + this->length_ = len + (sizeof *this - (sizeof this->type_ + sizeof this->data_)); +} + +template ACE_INLINE int +ACE_Typed_SV_Message::max_size (void) const +{ + ACE_TRACE ("ACE_Typed_SV_Message::max_size"); + return this->max_; +} + +template ACE_INLINE void +ACE_Typed_SV_Message::max_size (int m) +{ + ACE_TRACE ("ACE_Typed_SV_Message::max_size"); + this->max_ = m + (sizeof *this - (sizeof this->type_ + sizeof this->data_)); +} + +template T & +ACE_Typed_SV_Message::data (void) +{ + ACE_TRACE ("ACE_Typed_SV_Message::data"); + return this->data_; +} + +template void +ACE_Typed_SV_Message::data (const T &d) +{ + ACE_TRACE ("ACE_Typed_SV_Message::data"); + this->data_ = d; +} + diff --git a/ace/Typed_SV_Message_Queue.cpp b/ace/Typed_SV_Message_Queue.cpp new file mode 100644 index 00000000000..b77f07de62e --- /dev/null +++ b/ace/Typed_SV_Message_Queue.cpp @@ -0,0 +1,46 @@ +// Typed_SV_Message_Queue.cpp +// $Id$ + +#if !defined (ACE_TYPED_SV_MESSAGE_QUEUE_C) +#define ACE_TYPED_SV_MESSAGE_QUEUE_C + +#define ACE_BUILD_DLL +#include "ace/Typed_SV_Message.h" +#include "ace/Typed_SV_Message_Queue.h" + +#if !defined (__ACE_INLINE__) +#include "ace/Typed_SV_Message_Queue.i" +#endif /* __ACE_INLINE__ */ + +ACE_ALLOC_HOOK_DEFINE(ACE_Typed_SV_Message_Queue) + +template void +ACE_Typed_SV_Message_Queue::dump (void) const +{ + ACE_TRACE ("ACE_Typed_SV_Message_Queue::dump"); +} + +template +ACE_Typed_SV_Message_Queue::ACE_Typed_SV_Message_Queue (void) +{ + ACE_TRACE ("ACE_Typed_SV_Message_Queue::ACE_Typed_SV_Message_Queue"); +} + +template +ACE_Typed_SV_Message_Queue::ACE_Typed_SV_Message_Queue (key_t external_id, + int create, + int perms) +{ + ACE_TRACE ("ACE_Typed_SV_Message_Queue::ACE_Typed_SV_Message_Queue"); + if (this->open (external_id, create, perms) == -1) + ACE_ERROR ((LM_ERROR, + "ACE_Typed_SV_Message_Queue::ACE_Typed_SV_Message_Queue")); +} + +template +ACE_Typed_SV_Message_Queue::~ACE_Typed_SV_Message_Queue (void) +{ + ACE_TRACE ("ACE_Typed_SV_Message_Queue::~ACE_Typed_SV_Message_Queue"); +} + +#endif /* ACE_TYPED_SV_MESSAGE_QUEUE_C */ diff --git a/ace/Typed_SV_Message_Queue.h b/ace/Typed_SV_Message_Queue.h new file mode 100644 index 00000000000..40b4f36cfee --- /dev/null +++ b/ace/Typed_SV_Message_Queue.h @@ -0,0 +1,78 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Typed_SV_Message_Queue.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_TYPED_MESSAGE_QUEUE_H) +#define ACE_TYPED_MESSAGE_QUEUE_H + +#include "ace/SV_Message_Queue.h" +#include "ace/Typed_SV_Message.h" + +template +class ACE_Typed_SV_Message_Queue + // = TITLE + // Defines the header file for the C++ wrapper for message queues. +{ +public: + enum + { + ACE_CREATE = IPC_CREAT, + ACE_OPEN = 0, + ACE_NOWAIT = IPC_NOWAIT + }; + + // = Initialization and termination operations. + ACE_Typed_SV_Message_Queue (void); + ACE_Typed_SV_Message_Queue (key_t external_id, + int create = ACE_OPEN, + int perms = ACE_DEFAULT_PERMS); + int open (key_t external_id, + int create = ACE_OPEN, + int perms = ACE_DEFAULT_PERMS); + int close (void); + int remove (void); + ~ACE_Typed_SV_Message_Queue (void); + + // = Send and recv methods. + int send (const ACE_Typed_SV_Message &mb, int mflags = 0); + int recv (ACE_Typed_SV_Message &mb, int mflags = 0); + + int control (int option, void *arg = 0); + // Control the underlying message queue. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_SV_Message_Queue message_queue_; +}; + +#if defined (__ACE_INLINE__) +#include "ace/Typed_SV_Message_Queue.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "ace/Typed_SV_Message_Queue.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("Typed_SV_Message_Queue.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* ACE_TYPED_MESSAGE_QUEUE_H */ diff --git a/ace/Typed_SV_Message_Queue.i b/ace/Typed_SV_Message_Queue.i new file mode 100644 index 00000000000..9dcbb07075c --- /dev/null +++ b/ace/Typed_SV_Message_Queue.i @@ -0,0 +1,63 @@ +/* -*- C++ -*- */ +// $Id$ + +// Typed_SV_Message_Queue.i + +#include "ace/SV_Message_Queue.h" +#include "ace/Log_Msg.h" + +template ACE_INLINE int +ACE_Typed_SV_Message_Queue::open (key_t external_id, + int create, + int perms) +{ + ACE_TRACE ("ACE_Typed_SV_Message_Queue::open"); + return this->message_queue_.open (external_id, create, perms); +} + +/* What does it mean to close a message queue?! */ + +template ACE_INLINE int +ACE_Typed_SV_Message_Queue::close (void) +{ + ACE_TRACE ("ACE_Typed_SV_Message_Queue::close"); + return 1; +} + +template ACE_INLINE int +ACE_Typed_SV_Message_Queue::recv (ACE_Typed_SV_Message &mb, + int mflags) +{ + ACE_TRACE ("ACE_Typed_SV_Message_Queue::recv"); + int length = this->message_queue_.recv ((ACE_SV_Message &) mb, + mb.max_size (), mb.type (), mflags); + + if (length != -1) + mb.length (length); + + return length; +} + +template ACE_INLINE int +ACE_Typed_SV_Message_Queue::send (const ACE_Typed_SV_Message &mb, + int mflags) +{ + ACE_TRACE ("ACE_Typed_SV_Message_Queue::send"); + return this->message_queue_.send ((ACE_SV_Message &) mb, + mb.length (), mflags); +} + +template ACE_INLINE int +ACE_Typed_SV_Message_Queue::remove (void) +{ + ACE_TRACE ("ACE_Typed_SV_Message_Queue::remove"); + return this->message_queue_.remove (); +} + +template ACE_INLINE int +ACE_Typed_SV_Message_Queue::control (int option, + void *arg) +{ + ACE_TRACE ("ACE_Typed_SV_Message_Queue::control"); + return this->message_queue_.control (option, arg); +} diff --git a/ace/UNIX_Addr.cpp b/ace/UNIX_Addr.cpp new file mode 100644 index 00000000000..fdabb40c219 --- /dev/null +++ b/ace/UNIX_Addr.cpp @@ -0,0 +1,104 @@ +// UNIX_Addr.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/UNIX_Addr.h" + +#if !defined (__ACE_INLINE__) +#include "ace/UNIX_Addr.i" +#endif /* __ACE_INLINE__ */ + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +ACE_ALLOC_HOOK_DEFINE(ACE_UNIX_Addr) + +// Set a pointer to the address. +void +ACE_UNIX_Addr::set_addr (void *addr, int len) +{ + ACE_TRACE ("ACE_UNIX_Addr::set_addr"); + + this->ACE_Addr::base_set (AF_UNIX, len); + ACE_OS::memcpy ((void *) &this->unix_addr_, + (void *) addr, + len); +} + +void +ACE_UNIX_Addr::dump (void) const +{ +} + +// Do nothing constructor. + +ACE_UNIX_Addr::ACE_UNIX_Addr (void) + : ACE_Addr (AF_UNIX, sizeof this->unix_addr_) +{ + (void) ACE_OS::memset ((void *) &this->unix_addr_, 0, sizeof this->unix_addr_); +} + +// Copy constructor. + +ACE_UNIX_Addr::ACE_UNIX_Addr (const ACE_UNIX_Addr &sa) + : ACE_Addr (AF_UNIX, sa.get_size ()) +{ + size_t size = sa.get_size (); + + // Add one extra byte to account for the NUL at the end of the + // pathname. + if (size < sizeof this->unix_addr_) + size = sa.get_size () + 1; + + this->unix_addr_.sun_family = AF_UNIX; + ACE_OS::strcpy (this->unix_addr_.sun_path, sa.unix_addr_.sun_path); +} + +void +ACE_UNIX_Addr::set (const sockaddr_un *un, int len) +{ + (void) ACE_OS::memset ((void *) &this->unix_addr_, 0, + sizeof this->unix_addr_); + this->unix_addr_.sun_family = AF_UNIX; + ACE_OS::strcpy (this->unix_addr_.sun_path, un->sun_path); + this->base_set (AF_UNIX, len); +} + +ACE_UNIX_Addr::ACE_UNIX_Addr (const sockaddr_un *un, int len) +{ + this->set (un, len); +} + +void +ACE_UNIX_Addr::set (const char rendezvous_point[]) +{ + (void) ACE_OS::memset ((void *) &this->unix_addr_, 0, + sizeof this->unix_addr_); + int len = ACE_OS::strlen (rendezvous_point); + + this->unix_addr_.sun_family = AF_UNIX; + + if (len >= sizeof this->unix_addr_.sun_path) + { + /* At this point, things are screwed up, so let's make sure we + don't crash. */ + (void) ACE_OS::strncpy (this->unix_addr_.sun_path, + rendezvous_point, + sizeof this->unix_addr_.sun_path); + len = sizeof this->unix_addr_.sun_path; + this->unix_addr_.sun_path[len - 1] = '\0'; + // Don't count the NUL byte at the end of the string. + len -= 2; + } + else + (void) ACE_OS::strcpy (this->unix_addr_.sun_path, rendezvous_point); + this->ACE_Addr::base_set (AF_UNIX, len + sizeof this->unix_addr_.sun_family); +} + +// Create a ACE_Addr from a UNIX pathname. + +ACE_UNIX_Addr::ACE_UNIX_Addr (const char rendezvous_point[]) +{ + this->set (rendezvous_point); +} + +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ diff --git a/ace/UNIX_Addr.h b/ace/UNIX_Addr.h new file mode 100644 index 00000000000..07d7874ebff --- /dev/null +++ b/ace/UNIX_Addr.h @@ -0,0 +1,85 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// UNIX_Addr.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_UNIX_ADDR_H) +#define ACE_UNIX_ADDR_H +#include "ace/Addr.h" + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +class ACE_Export ACE_UNIX_Addr : public ACE_Addr + // = TITLE + // Defines the ``UNIX domain address family'' address format. +{ +public: + // = Initialization methods. + ACE_UNIX_Addr (void); + // Default constructor. + + ACE_UNIX_Addr (const ACE_UNIX_Addr &sa); + // Copy constructor. + + ACE_UNIX_Addr (const char rendezvous_point[]); + // Creates an ACE_UNIX_Addr from a string. + + ACE_UNIX_Addr (const sockaddr_un *, int len); + // Creates an ACE_INET_Addr from a sockaddr_un structure. + + void set (const char rendezvous_point[]); + // Creates an ACE_UNIX_Addr from a string. + + void set (const sockaddr_un *, int len); + // Creates an ACE_INET_Addr from a sockaddr_un structure. + + virtual void *get_addr (void) const; + // Return a pointer to the underlying network address. + + virtual void set_addr (void *addr, int len); + // Set a pointer to the underlying network address. + + virtual int addr_to_string (char addr[], size_t) const; + // Transform the current address into string format. + + virtual int string_to_addr (const char addr[]); + // Transform the string into the current addressing format. + + virtual int operator == (const ACE_Addr &SAP) const; + // Compare two addresses for equality. + + virtual int operator != (const ACE_Addr &SAP) const; + // Compare two addresses for inequality. + + const char *get_path_name (void) const; + // Return the path name of the underlying rendezvous point. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + sockaddr_un unix_addr_; + // Underlying socket address. +}; + +#if defined (__ACE_INLINE__) +#include "ace/UNIX_Addr.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ +#endif /* ACE_UNIX_ADDR_H */ diff --git a/ace/UNIX_Addr.i b/ace/UNIX_Addr.i new file mode 100644 index 00000000000..88fcc688cc5 --- /dev/null +++ b/ace/UNIX_Addr.i @@ -0,0 +1,61 @@ +/* -*- C++ -*- */ +// $Id$ + +// UNIX_Addr.i + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +// Return a pointer to the underlying address. + +ACE_INLINE void * +ACE_UNIX_Addr::get_addr (void) const +{ + return (void *) &this->unix_addr_; +} + +// Transform the string into the current addressing format. + +ACE_INLINE int +ACE_UNIX_Addr::string_to_addr (const char addr[]) +{ + ACE_OS::strncpy (this->unix_addr_.sun_path, addr, + sizeof this->unix_addr_.sun_path); + return 0; +} + +// Transform the current address into string format. + +ACE_INLINE int +ACE_UNIX_Addr::addr_to_string (char s[], size_t len) const +{ + ACE_OS::strncpy (s, this->unix_addr_.sun_path, len); + return 0; +} + +// Compare two addresses for equality. + +ACE_INLINE int +ACE_UNIX_Addr::operator == (const ACE_Addr &sap) const +{ + return ACE_OS::strncmp (this->unix_addr_.sun_path, + ((const ACE_UNIX_Addr &) sap).unix_addr_.sun_path, + sizeof this->unix_addr_.sun_path) == 0; +} + +// Compare two addresses for inequality. + +ACE_INLINE int +ACE_UNIX_Addr::operator != (const ACE_Addr &sap) const +{ + return !((*this) == sap); // This is lazy, of course... ;-) +} + +// Return the path name used for the rendezvous point. + +ACE_INLINE const char * +ACE_UNIX_Addr::get_path_name (void) const +{ + return this->unix_addr_.sun_path; +} + +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ diff --git a/ace/UPIPE_Acceptor.cpp b/ace/UPIPE_Acceptor.cpp new file mode 100644 index 00000000000..9d3f97fcb77 --- /dev/null +++ b/ace/UPIPE_Acceptor.cpp @@ -0,0 +1,115 @@ +// UPIPE_Acceptor.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/UPIPE_Acceptor.h" +#include "ace/Log_Msg.h" + +#if defined (ACE_HAS_THREADS) + +ACE_ALLOC_HOOK_DEFINE(ACE_UPIPE_Acceptor) + +void +ACE_UPIPE_Acceptor::dump (void) const +{ + ACE_TRACE ("ACE_UPIPE_Acceptor::dump"); +} + +/* Do nothing routine for constructor. */ + +ACE_UPIPE_Acceptor::ACE_UPIPE_Acceptor (void) + : mb_ (sizeof (ACE_UPIPE_Stream *)) +{ + ACE_TRACE ("ACE_UPIPE_Acceptor::ACE_UPIPE_Acceptor"); +} + +ACE_UPIPE_Acceptor::~ACE_UPIPE_Acceptor (void) +{ + ACE_TRACE ("ACE_UPIPE_Acceptor::~ACE_UPIPE_Acceptor"); +} + +// General purpose routine for performing server ACE_UPIPE. + +int +ACE_UPIPE_Acceptor::open (const ACE_UPIPE_Addr &local_addr, + int reuse_addr) +{ + ACE_TRACE ("ACE_UPIPE_Acceptor::open"); + return this->ACE_SPIPE_Acceptor::open (local_addr, reuse_addr); +} + +int +ACE_UPIPE_Acceptor::close (void) +{ + ACE_TRACE ("ACE_UPIPE_Acceptor::close"); + return this->ACE_SPIPE_Acceptor::close (); +} + +// General purpose routine for accepting new connections. + +ACE_UPIPE_Acceptor::ACE_UPIPE_Acceptor (const ACE_UPIPE_Addr &local_addr, + int reuse_addr) + : mb_ (sizeof (ACE_UPIPE_Stream *)) +{ + ACE_TRACE ("ACE_UPIPE_Acceptor::ACE_UPIPE_Acceptor"); + + if (this->open (local_addr, reuse_addr) == -1) + ACE_ERROR ( (LM_ERROR, "%p\n", "ACE_UPIPE_Acceptor")); +} + +int +ACE_UPIPE_Acceptor::accept (ACE_UPIPE_Stream &new_stream, + ACE_UPIPE_Addr *remote_addr, + ACE_Time_Value *timeout, + int restart) +{ + ACE_TRACE ("ACE_UPIPE_Acceptor::accept"); + ACE_SPIPE_Stream new_io; + + if (this->ACE_SPIPE_Acceptor::accept (new_io, remote_addr, + timeout, restart) == -1) + return -1; + else + { + ACE_UPIPE_Stream *remote_stream = 0; + // Transfer address ownership. + new_stream.set_handle (new_io.get_handle ()); + + new_io.get_local_addr (new_stream.local_addr_); + new_io.get_remote_addr (new_stream.remote_addr_); + + // Now that we got the fd, we'll read the address of the + // connector-side ACE_UPIPE_Stream out of the pipe and link that + // ACE_UPIPE_Stream to our ACE_UPIPE_Stream + + if (ACE_OS::read (new_stream.get_handle (), + (char *) &remote_stream, + sizeof remote_stream) == -1) + ACE_ERROR ((LM_ERROR, + "ACE_UPIPE_Acceptor: %p\n", + "read stream address failed")); + else if (new_stream.stream_.link (remote_stream->stream_) == -1) + ACE_ERROR ((LM_ERROR, + "ACE_UPIPE_Acceptor: %p\n", + "link streams failed")); + // Send a message over the new streampipe to confirm acceptance. + else if (new_stream.send (&mb_, 0) == -1) + ACE_ERROR ((LM_ERROR, + "ACE_UPIPE_Acceptor: %p\n", + "linked stream.put failed")); + + // Close down the new_stream at this point in order to conserve + // handles. Note that we don't need the SPIPE connection + // anymore since we're now linked via the . + new_stream.ACE_SPIPE::close (); + return 0; + } +} + +#endif /* ACE_HAS_THREADS */ + + + + + + diff --git a/ace/UPIPE_Acceptor.h b/ace/UPIPE_Acceptor.h new file mode 100644 index 00000000000..b855285f76e --- /dev/null +++ b/ace/UPIPE_Acceptor.h @@ -0,0 +1,81 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// UPIPE_Acceptor.h +// +// = AUTHOR +// Gerhard Lenzer and Douglas C. Schmidt +// +// ============================================================================ + +#if !defined (ACE_UPIPE_ACCEPTOR_H) +#define ACE_UPIPE_ACCEPTOR_H + +#include "ace/UPIPE_Stream.h" +#include "ace/Synch.h" +#include "ace/SPIPE_Acceptor.h" +#include "ace/Thread_Manager.h" + +#if defined (ACE_HAS_THREADS) + +class ACE_Export ACE_UPIPE_Acceptor : public ACE_SPIPE_Acceptor + // = TITLE + // Defines the format and interface for the listener side of the + // ACE_UPIPE_Stream. +{ +public: + // = Initialization and termination. + ACE_UPIPE_Acceptor (void); + // Default constructor. + + ACE_UPIPE_Acceptor (const ACE_UPIPE_Addr &local_sap, + int reuse_addr = 0); + // Initialize passive endpoint. + + int open (const ACE_UPIPE_Addr &local_sap, + int reuse_addr = 0); + // Initialize passive endpoint. + + ~ACE_UPIPE_Acceptor (void); + // Close down and release resources. + + int close (void); + // Close down and release resources. + + int remove (void); + // Close down and release resources and remove the underlying SPIPE + // rendezvous point. + + // = Passive connection acceptance method. + int accept (ACE_UPIPE_Stream &server_stream, + ACE_UPIPE_Addr *remote_addr = 0, + ACE_Time_Value *timeout = 0, + int restart = 1); + // Accept a new data transfer connection. A of 0 means + // block forever, a of {0, 0} means poll. == 1 + // means "restart if interrupted." + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Thread_Manager tm; + // Manage threads. + + ACE_Message_Block mb_; + // To confirm connection establishment. +}; + +#include "ace/UPIPE_Acceptor.i" +#endif /* ACE_HAS_THREADS */ +#endif /* ACE_UPIPE_ACCEPTOR_H */ diff --git a/ace/UPIPE_Acceptor.i b/ace/UPIPE_Acceptor.i new file mode 100644 index 00000000000..7a395658212 --- /dev/null +++ b/ace/UPIPE_Acceptor.i @@ -0,0 +1,11 @@ +/* -*- C++ -*- */ +// $Id$ + +// UPIPE_Acceptor.i + +inline int +ACE_UPIPE_Acceptor::remove (void) +{ + ACE_TRACE ("ACE_UPIPE_Acceptor::remove"); + return this->ACE_SPIPE_Acceptor::remove (); +} diff --git a/ace/UPIPE_Addr.h b/ace/UPIPE_Addr.h new file mode 100644 index 00000000000..6f86a99547f --- /dev/null +++ b/ace/UPIPE_Addr.h @@ -0,0 +1,25 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// UPIPE_Addr.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_UPIPE_ADDR_H) +#define ACE_UPIPE_ADDR_H + +#include "ace/SPIPE_Addr.h" + +typedef ACE_SPIPE_Addr ACE_UPIPE_Addr; + +#endif /* ACE_UPIPE_ADDR_H */ diff --git a/ace/UPIPE_Connector.cpp b/ace/UPIPE_Connector.cpp new file mode 100644 index 00000000000..e4aad1a28a3 --- /dev/null +++ b/ace/UPIPE_Connector.cpp @@ -0,0 +1,86 @@ +// UPIPE_Connector.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/UPIPE_Connector.h" + +#if defined (ACE_HAS_THREADS) + +ACE_ALLOC_HOOK_DEFINE(ACE_UPIPE_Connector) + +void +ACE_UPIPE_Connector::dump (void) const +{ + ACE_TRACE ("ACE_UPIPE_Connector::dump"); +} + +ACE_UPIPE_Connector::ACE_UPIPE_Connector (void) +{ + ACE_TRACE ("ACE_UPIPE_Connector::ACE_UPIPE_Connector"); +} + +int +ACE_UPIPE_Connector::connect (ACE_UPIPE_Stream &new_stream, + const ACE_UPIPE_Addr &addr, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_UPIPE_Connector::connect"); + ACE_ASSERT (new_stream.get_handle () == ACE_INVALID_HANDLE); + + ACE_HANDLE handle = ACE::handle_timed_open (timeout, + addr.get_path_name (), + flags, perms); + + if (handle == ACE_INVALID_HANDLE) + return -1; +#if !defined (ACE_WIN32) + else if (ACE_OS::isastream (handle) != 1) + return -1; +#endif + else // We're connected! + { + ACE_UPIPE_Stream *ustream = &new_stream; + + new_stream.set_handle (handle); + new_stream.remote_addr_ = addr; // class copy. + + // Now send the address of our ACE_UPIPE_Stream over this pipe + // to our corresponding ACE_UPIPE_Acceptor, so he may link the + // two streams. + ssize_t result = ACE_OS::write (handle, + (const char *) &ustream, + sizeof ustream); + if (result == -1) + ACE_ERROR ((LM_ERROR, + "ACE_UPIPE_Connector %p\n", + "write to pipe failed")); + + // Wait for confirmation of stream linking. + ACE_Message_Block *mb_p = 0; + + // Our part is done, wait for server to confirm connection. + result = new_stream.recv (mb_p, 0); + + // Do *not* coalesce the following two checks for result == -1. + // They perform different checks and cannot be merged. + if (result == -1) + ACE_ERROR ((LM_ERROR, "ACE_UPIPE_Connector %p\n", + "no confirmation from server")); + + if (result == -1) + this->close (); + else + // Close down the new_stream at this point in order to + // conserve handles. Note that we don't need the SPIPE + // connection anymore since we're linked via the Message_Queue + // now. + new_stream.ACE_SPIPE::close (); + return result; + } +} +#endif /* ACE_HAS_THREADS */ + diff --git a/ace/UPIPE_Connector.h b/ace/UPIPE_Connector.h new file mode 100644 index 00000000000..56fe8cb5b15 --- /dev/null +++ b/ace/UPIPE_Connector.h @@ -0,0 +1,92 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// UPIPE_Connector.h +// +// = AUTHOR +// Gerhard Lenzer and Douglas C. Schmidt +// +// ============================================================================ + +#if !defined (ACE_UPIPE_CONNECTOR_H) +#define ACE_UPIPE_CONNECTOR_H + +#include "ace/UPIPE_Stream.h" +#include "ace/Synch.h" +#include "ace/SPIPE_Stream.h" + +#if defined (ACE_HAS_THREADS) + +class ACE_Export ACE_UPIPE_Connector : public ACE_SPIPE + // = TITLE + // Defines an active connection factory for the + // wrappers. +{ +public: + // = Initialization methods. + ACE_UPIPE_Connector (void); + // Default constructor. + + ACE_UPIPE_Connector (ACE_UPIPE_Stream &new_stream, + const ACE_UPIPE_Addr &addr, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0); + // Actively connect and produce a if things go well. + // The is the address that we are trying to connect + // with. The is the amount of time to wait to connect. + // If it's 0 then we block indefinitely. If *timeout == {0, 0} then + // the connection is done using non-blocking mode. In this case, if + // the connection can't be made immediately the value of -1 is + // returned with . If *timeout > {0, 0} then + // this is the amount of time to wait before timing out. If the + // time expires before the connection is made . + // The is the value of local address to bind to. If + // it's the default value of then the user is + // letting the OS do the binding. If == 1 then the + // is reused, even if it hasn't been cleanedup yet. + // The and arguments are passed down to the open() + // method. + + int connect (ACE_UPIPE_Stream &new_stream, + const ACE_UPIPE_Addr &addr, + ACE_Time_Value *timeout = 0, + const ACE_Addr &local_sap = ACE_Addr::sap_any, + int reuse_addr = 0, + int flags = O_RDWR, + int perms = 0); + // Actively connect and produce a if things go well. + // The is the address that we are trying to connect + // with. The is the amount of time to wait to connect. + // If it's 0 then we block indefinitely. If *timeout == {0, 0} then + // the connection is done using non-blocking mode. In this case, if + // the connection can't be made immediately the value of -1 is + // returned with . If *timeout > {0, 0} then + // this is the amount of time to wait before timing out. If the + // time expires before the connection is made . + // The is the value of local address to bind to. If + // it's the default value of then the user is + // letting the OS do the binding. If == 1 then the + // is reused, even if it hasn't been cleanedup yet. + // The and arguments are passed down to the open() + // method. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +#include "ace/UPIPE_Connector.i" +#endif /* ACE_HAS_THREADS */ +#endif /* ACE_UPIPE_CONNECTOR_H */ diff --git a/ace/UPIPE_Connector.i b/ace/UPIPE_Connector.i new file mode 100644 index 00000000000..5404622af03 --- /dev/null +++ b/ace/UPIPE_Connector.i @@ -0,0 +1,30 @@ +/* -*- C++ -*- */ +// $Id$ + +// UPIPE_Connector.i + +#include "ace/Log_Msg.h" + +// Creates a Local ACE_UPIPE. + +inline +ACE_UPIPE_Connector::ACE_UPIPE_Connector (ACE_UPIPE_Stream &new_stream, + const ACE_UPIPE_Addr &addr, + ACE_Time_Value *timeout, + const ACE_Addr &local_sap, + int reuse_addr, + int flags, + int perms) +{ + ACE_TRACE ("ACE_UPIPE_Connector::ACE_UPIPE_Connector"); + if (this->connect (new_stream, addr, timeout, local_sap, + reuse_addr, flags, perms) == -1 + && timeout != 0 && !(errno == EWOULDBLOCK || errno == ETIMEDOUT)) + ACE_ERROR ((LM_ERROR, "address %s, %p\n", + addr.get_path_name (), "ACE_UPIPE_Connector")); +} + + + + + diff --git a/ace/UPIPE_Stream.cpp b/ace/UPIPE_Stream.cpp new file mode 100644 index 00000000000..3c9bed43494 --- /dev/null +++ b/ace/UPIPE_Stream.cpp @@ -0,0 +1,206 @@ +// UPIPE_Stream.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/UPIPE_Stream.h" + +#if defined (ACE_HAS_THREADS) + +#if !defined (__ACE_INLINE__) +#include "ace/UPIPE_Stream.i" +#endif /* __ACE_INLINE__ */ + + +ACE_ALLOC_HOOK_DEFINE(ACE_UPIPE_Stream) + +int +ACE_UPIPE_Stream::control (ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds cmd, + void * val) +{ + ACE_TRACE ("ACE_UPIPE_Stream::control"); + return this->stream_.control (cmd, val); +} + +void +ACE_UPIPE_Stream::dump (void) const +{ + ACE_TRACE ("ACE_UPIPE_Stream::dump"); +} + +int +ACE_UPIPE_Stream::close (void) +{ + ACE_TRACE ("ACE_UPIPE_Stream::close"); + // Since the UPIPE should have been closed earlier we won't bother + // checking to see if closing it now fails. + + if (this->ACE_SPIPE::get_handle () != ACE_INVALID_HANDLE) + this->ACE_SPIPE::close (); + + // Close down the ACE_stream. + return this->stream_.close (0); +} + +int +ACE_UPIPE_Stream::get_remote_addr (ACE_UPIPE_Addr &remote_sap) const +{ + ACE_TRACE ("ACE_UPIPE_Stream::get_remote_addr"); + remote_sap = this->remote_addr_; + return 0; +} + +int +ACE_UPIPE_Stream::send (ACE_Message_Block *mb_p, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_UPIPE_Stream::send_msg"); + return this->stream_.put (mb_p, timeout) == -1 ? -1 : 0; +} + +int ACE_UPIPE_Stream::recv (ACE_Message_Block *& mb_p, + ACE_Time_Value *timeout) +{ + return this->stream_.get (mb_p, timeout) == -1 ? -1 : 0; +} + +// Send a buffer. + +int +ACE_UPIPE_Stream::send (const char *buffer, + size_t n, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_UPIPE_Stream::send"); + + ACE_Message_Block *mb_p; + + ACE_NEW_RETURN (mb_p, ACE_Message_Block (n), -1); + + mb_p->copy (buffer, n); + return this->stream_.put (mb_p, timeout) == -1 ? -1 : n; +} + +// Receive a buffer. + +int +ACE_UPIPE_Stream::recv (char *buffer, + size_t n, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_UPIPE_Stream::recv"); + // Index in buffer. + size_t bytes_read = 0; + + while (bytes_read < n) + if (this->mb_last_ != 0) + { + // We have remaining data in our last read Message_Buffer. + + if (this->remaining_ < n) + { + // The remaining data is not enough. + + ACE_OS::memcpy ((void *) &buffer[bytes_read], + this->mb_last_->rd_ptr (), + this->remaining_); + bytes_read += this->remaining_; + this->remaining_ = 0; + delete this->mb_last_; + this->mb_last_ = 0; + return bytes_read; + } + else + { + // The remaining data is at least enough. If there's + // more, we'll get it the next time through. + + ACE_OS::memcpy (&buffer[bytes_read], + this->mb_last_->rd_ptr (), + n); + bytes_read += n; + + // Advance rd_ptr. + this->mb_last_->rd_ptr (n); + this->remaining_ -= n; + + if (this->remaining_ == 0) + { + // Now the Message_Buffer is empty. + + delete this->mb_last_; + this->mb_last_ = 0; + } + } + } + else + { + // We have to get a new Message_Buffer from our stream. + + int result = this->stream_.get (this->mb_last_, timeout); + + if (result == -1) + { + if (errno == EWOULDBLOCK && bytes_read > 0) + // Return the number of bytes read before we timed out. + return bytes_read; + else + return -1; + } + this->remaining_ = this->mb_last_->size (); + } + + return bytes_read; +} + +int +ACE_UPIPE_Stream::send_n (const char *buf, + size_t n, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_UPIPE_Stream::send_n"); + + size_t bytes_written; + ssize_t len; + + for (bytes_written = 0; + bytes_written < n; + bytes_written += len) + { + len = this->send (buf + bytes_written, + n - bytes_written, + timeout); + + if (len == -1) + return -1; + } + + return bytes_written; +} + +int +ACE_UPIPE_Stream::recv_n (char *buf, + size_t n, + ACE_Time_Value *timeout) +{ + ACE_TRACE ("ACE_UPIPE_Stream::recv_n"); + size_t bytes_read; + ssize_t len; + + for (bytes_read = 0; + bytes_read < n; + bytes_read += len) + { + len = this->recv (buf + bytes_read, + n - bytes_read, + timeout); + if (len == -1) + return -1; + else if (len == 0) + break; + } + + return bytes_read; +} + +#endif /* ACE_HAS_THREADS */ + diff --git a/ace/UPIPE_Stream.h b/ace/UPIPE_Stream.h new file mode 100644 index 00000000000..23f084851c7 --- /dev/null +++ b/ace/UPIPE_Stream.h @@ -0,0 +1,117 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// UPIPE_Stream.h +// +// = AUTHOR +// Gerhard Lenzer and Douglas C. Schmidt +// +// ============================================================================ + +#if !defined ACE_UPIPE_STREAM_H +#define ACE_UPIPE_STREAM_H + +#include "ace/Stream.h" +#include "ace/Synch.h" +#include "ace/SPIPE.h" +#include "ace/Message_Queue.h" +#include "ace/UPIPE_Addr.h" + +#if defined (ACE_HAS_THREADS) + +// Use a typedef to make life easier later on. +typedef ACE_Stream MT_Stream; + +class ACE_Export ACE_UPIPE_Stream : public ACE_SPIPE + // = TITLE + // Defines the method that transfer data on a UPIPE. +{ + friend class ACE_UPIPE_Acceptor; + friend class ACE_UPIPE_Connector; +public: + // = Termination. + + int close (void); + // Shut down the UPIPE and release resources. + + ACE_HANDLE get_handle (void) const; + // Return the underlying I/O handle. + + // = Send/recv ACE Message_Blocks. + int send (ACE_Message_Block *mb_p, + ACE_Time_Value *timeout = 0); + // Send a message through the message queue. Returns -1 on error, + // else 0. + + int recv (ACE_Message_Block *&mb_p, + ACE_Time_Value *timeout = 0); + // Recv a message from the message queue. Returns -1 on error, else + // 0. + + // = Send/recv char buffers. + int send (const char *buffer, + size_t n, + ACE_Time_Value *timeout = 0); + // Send a buffer of bytes through the message queue. Returns -1 + // on error, else number of bytes sent. + + int recv (char *buffer, + size_t n, + ACE_Time_Value *timeout = 0); + // Recv a buffer of upto bytes from the message queue. Returns + // -1 on error, else number of bytes read. + + int send_n (const char *buffer, + size_t n, + ACE_Time_Value *timeout = 0); + // Send a buffer of exactly bytes to the message queue. Returns + // -1 on error, else number of bytes written (which should == n). + + int recv_n (char *buffer, + size_t n, + ACE_Time_Value *timeout = 0); + // Recv a buffer of exactly bytes from the message queue. + // Returns -1 on error, else the number of bytes read. + + int control (ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds cmd, + void *val); + // Perform control operations on the UPIPE_Stream. + + int get_remote_addr (ACE_UPIPE_Addr &remote_sap) const; + // Return the remote address we are connected to. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Message_Block *mb_last_; + // To hold the last ACE_Message_Block read out of the stream. Thus + // allowing subsequent reads from one ACE_Message_Block + + size_t remaining_; + // Holds the number of bytes that are still available in mb_last_. + + ACE_UPIPE_Addr remote_addr_; + // Address of who we are connected to. + + MT_Stream stream_; + // Stream component used by the and + // to link together two UPIPE_Streams. +}; + +#if defined (__ACE_INLINE__) +#include "ace/UPIPE_Stream.i" +#endif /* __ACE_INLINE__ */ + +#endif /* ACE_HAS_THREADS */ +#endif /*ACE_UPIPE_STREAM_H */ diff --git a/ace/UPIPE_Stream.i b/ace/UPIPE_Stream.i new file mode 100644 index 00000000000..c2297fcffce --- /dev/null +++ b/ace/UPIPE_Stream.i @@ -0,0 +1,12 @@ +/* -*- C++ -*- */ +// $Id$ + +// UPIPE_Stream.i + +ACE_INLINE ACE_HANDLE +ACE_UPIPE_Stream::get_handle (void) const +{ + ACE_TRACE ("ACE_UPIPE_Stream::get_handle"); + return this->ACE_SPIPE::get_handle (); +} + diff --git a/ace/XtReactor.cpp b/ace/XtReactor.cpp new file mode 100644 index 00000000000..ac497c64e40 --- /dev/null +++ b/ace/XtReactor.cpp @@ -0,0 +1,327 @@ +// XtReactor.cpp +// $Id$ + +#define ACE_BUILD_DLL +#include "ace/Log_Msg.h" +#include "ace/Synch_T.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/SOCK_Connector.h" +#include "ace/XtReactor.h" + +#if defined (ACE_HAS_XT) + +struct ACE_XtReactorID +{ + XtInputId id; + int good_id; +}; + +ACE_ALLOC_HOOK_DEFINE (ACE_XtReactor) + +// Must be called with lock held +ACE_XtReactor::ACE_XtReactor (XtAppContext context, + size_t size, + int restart, + ACE_Sig_Handler *h) + : ACE_Reactor (size, restart, h), + context_ (context), + id_len_ (0), + ids_ (0) +{ +} + +ACE_XtReactor::~ACE_XtReactor (void) +{ + delete this->ids_; +} + +// This is just the wait_for_multiple_events from ace/Reactor.cpp but +// we use the Xt functions to wait for an event, not select () +// +// FIXME - someday re-write this to use poll as well. + +int +ACE_XtReactor::wait_for_multiple_events (ACE_Handle_Set &rmask, + ACE_Handle_Set &wmask, + ACE_Handle_Set &emask, + ACE_Time_Value *max_wait_time) +{ + ACE_TRACE ("ACE_Reactor::wait_for_multiple_events"); +#if defined (ACE_USE_POLL) + u_long width = 0; +#endif /* ACE_USE_POLL */ + int nfound; + + do + { + max_wait_time = this->timer_queue_->calculate_timeout (max_wait_time); + +#if defined (ACE_USE_POLL) + pollfd *phandles = this->handle_sets_to_poll_fds (width); + nfound = ACE_OS::poll (phandles, width, max_wait_time); +#else /* USE SELECT */ + size_t width = this->handler_rep_.max_handlep1 (); + rmask = this->rd_handle_mask_; + wmask = this->wr_handle_mask_; + emask = this->ex_handle_mask_; +#if 0 + nfound = ACE_OS::select (int (width), rmask, wmask, emask, max_wait_time); +#else + nfound = XtWaitForMultipleEvents (width, rmask, wmask, emask, max_wait_time); +#endif +#endif /* ACE_USE_POLL */ + } while (nfound == -1 && this->handle_error () > 0); + +#if defined (ACE_USE_POLL) + this->poll_fds_to_handle_sets (width, rmask, wmask, emask, nfound); +#endif /* ACE_USE_POLL */ + + if (nfound > 0) + { +#if !defined (ACE_WIN32) + rmask.sync (this->handler_rep_.max_handlep1 ()); + wmask.sync (this->handler_rep_.max_handlep1 ()); + emask.sync (this->handler_rep_.max_handlep1 ()); +#endif /* ACE_REACTOR_ALTERANTIVE_IMPL */ + } + return nfound; // Timed out or input available +} + +void +ACE_XtReactor::TimerCallbackProc (XtPointer closure, XtIntervalId *id) +{ + ACE_XtReactor *self = (ACE_XtReactor*)closure; + self->timeout_ = 0; + + ACE_DEBUG ((LM_DEBUG, "ACE_XtReactor::Timer on id %d\n", (int) *id)); + + ACE_Time_Value zero = ACE_Time_Value::zero; // my copy isn't const + + // Deal with any timer events + ACE_Handle_Set r, w, e; + self->dispatch (0, r, w, e); + self->reset_timeout (); +} + +// This could be made shorter if we know which *kind* of event we +// were about to get. Here we use select () to find out which one +// might be available. + +void ACE_XtReactor::InputCallbackProc (XtPointer closure, + int * source, + XtInputId *id) +{ + ACE_XtReactor * self = (ACE_XtReactor*)closure; + + ACE_DEBUG ((LM_DEBUG, "ACE_XtReactor::Input on fd %d\n", *source)); + + ACE_Time_Value zero = ACE_Time_Value::zero; // my copy isn't const + + ACE_Handle_Set r, w, e; + ACE_Handle_Set r2, w2, e2; + + // Deal with one file event + + // - read which kind of event + if (self->rd_handle_mask_.is_set (*source)) + r.set_bit (*source); + if (self->wr_handle_mask_.is_set (*source)) + w.set_bit (*source); + if (self->ex_handle_mask_.is_set (*source)) + e.set_bit (*source); + + int result = ACE_OS::select (*source+1, r, w, e, &zero); + + // - Use only that one file event (removes events for other files) + if (result > 0) + { + if (r.is_set (*source)) + r2.set_bit (*source); + if (w.is_set (*source)) + w2.set_bit (*source); + if (e.is_set (*source)) + e2.set_bit (*source); + + self->dispatch (1, r2, w2, e2); + } +} + +int ACE_XtReactor::XtWaitForMultipleEvents (int width, + ACE_Handle_Set &rmask, + ACE_Handle_Set &wmask, + ACE_Handle_Set &emask, + ACE_Time_Value *max_wait_time) +{ + // Check to make sure our fd's are all usable + + ACE_Handle_Set r (rmask), w (wmask), e (emask); + ACE_Time_Value zero = ACE_Time_Value::zero; // my copy isn't const + int result = ACE_OS::select (width, r, w, e, &zero); + + if (result < 0) // Bad file arguments... + return result; + + // Instead of waiting using select, just use the Xt mechanism to wait + // for a single event. + + // Wait for something to happen. + XtAppProcessEvent (context_, XtIMAll); + + // Now actually read the result needed by the Reactor using select. + result = ACE_OS::select (int (width), rmask, wmask, emask, &zero); + return result; +} + +XtAppContext ACE_XtReactor::context (void) +{ + return this->context_; +} + +int +ACE_XtReactor::attach (ACE_HANDLE handle, + ACE_Event_Handler *handler, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_XtReactor::attach"); + + ACE_DEBUG ((LM_DEBUG, "+++%d\n", handle)); + + int result = ACE_Reactor::attach (handle, handler, mask); + + if (result < 0) + return -1; + + // Ensure the list of InputId's is big enough + if (ids_ == 0 || id_len_ < handle + 1) + { + ACE_XtReactorID *more; + ACE_NEW_RETURN (more, ACE_XtReactorID[handle + 1], -1); + int i; + for (i = 0; i < this->id_len_; i++) + more[i] = ids_[i]; + for (i = this->id_len_; i < handle + 1; i++) + more[i].good_id = 0; + id_len_ = handle + 1; + delete this->ids_; + ids_ = more; + } + + int condition = 0; + if (mask & ACE_Event_Handler::READ_MASK) + condition |= XtInputReadMask; + if (mask & ACE_Event_Handler::WRITE_MASK) + condition |= XtInputWriteMask; + if (mask & ACE_Event_Handler::EXCEPT_MASK) + condition |= XtInputExceptMask; + if (condition != 0) + { + if (ids_[handle].good_id) + XtRemoveInput (ids_[handle].id); + + ids_[handle].id = XtAppAddInput (context_, + handle, + (XtPointer)condition, + InputCallbackProc, + (XtPointer)this); + ids_[handle].good_id = 1; + } + return 0; +} + + +int +ACE_XtReactor::detach (ACE_HANDLE handle, + ACE_Reactor_Mask mask) +{ + ACE_TRACE ("ACE_XtReactor::detach"); + ACE_DEBUG ((LM_DEBUG, "---%d\n", handle)); + + int result = ACE_Reactor::detach (handle, mask); + + if (handle <= id_len_) + { + if (ids_[handle].good_id) + XtRemoveInput (ids_[handle].id); + else + ACE_DEBUG ((LM_DEBUG, "Handle id is not good %d\n", handle)); + ids_[handle].good_id = 0; + } + else + ACE_DEBUG ((LM_DEBUG, "Handle out of range %d\n", handle)); + + if (result < 0) + return result; + else + return 0; +} + +// The following functions ensure that there is an Xt timeout for the +// first timeout in the Reactor's Timer_Queue. + +void ACE_XtReactor::reset_timeout (void) +{ + if (timeout_) + XtRemoveTimeOut (timeout_); + timeout_ = 0; + + ACE_Time_Value *max_wait_time; + max_wait_time = this->timer_queue_->calculate_timeout (0); + + if (max_wait_time) + { + ACE_DEBUG ((LM_DEBUG, " %ld\n", max_wait_time->msec ())); + + timeout_ = + XtAppAddTimeOut (context_, max_wait_time->msec (), + TimerCallbackProc, (XtPointer) this); + } +} + +int +ACE_XtReactor::schedule_timer (ACE_Event_Handler *handler, + const void *arg, + const ACE_Time_Value &delta_time, + const ACE_Time_Value &interval) +{ + ACE_TRACE ("ACE_XtReactor::schedule_timer"); + ACE_GUARD_RETURN (ACE_REACTOR_MUTEX, ace_mon, this->token_, -1); + + int result = + ACE_Reactor::schedule_timer (handler, arg, delta_time, interval); + + if (result < 0) + return result; + + this->reset_timeout (); + return 0; +} + +int +ACE_XtReactor::cancel_timer (ACE_Event_Handler *handler) +{ + ACE_TRACE ("ACE_XtReactor::cancel_timer"); + + int result = ACE_Reactor::cancel_timer (handler); + + if (result < 0) + return -1; + + this->reset_timeout (); + return 0; +} + +int +ACE_XtReactor::cancel_timer (int timer_id, const void **arg) +{ + ACE_TRACE ("ACE_XtReactor::cancel_timer"); + + int result = ACE_Reactor::cancel_timer (timer_id, arg); + + if (result < 0) + return -1; + + this->reset_timeout (); + return 0; +} + +#endif /* ACE_HAS_XT */ diff --git a/ace/XtReactor.h b/ace/XtReactor.h new file mode 100644 index 00000000000..c26bf0677d6 --- /dev/null +++ b/ace/XtReactor.h @@ -0,0 +1,96 @@ +/* -*- C++ -*- */ +// $Id$ + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// XtReactor.h +// +// = AUTHOR +// Eric C. Newton's and Douglas C. Schmidt +// +// ============================================================================ + +#if !defined (ACE_XTREACTOR_H) +#define ACE_XTREACTOR_H + +#include "ace/Reactor.h" + +#if defined (ACE_HAS_XT) + +#define String XtString +#include +#undef String + +// Forward decl. +struct ACE_XtReactorID; + +class ACE_XtReactor : public ACE_Reactor + // = TITLE + // An object oriented event demultiplexor and event handler + // dispatcher that uses the X Toolkit functions. + // + // = DESCRIPTION + // The ACE_Reactor is an object-oriented event demultiplexor + // and event handler dispatcher. The sources of events that the + // ACE_Reactor waits for and dispatches includes I/O events, + // signals, and timer events. +{ +public: + // = Initialization and termination methods. + ACE_XtReactor (XtAppContext context, + size_t size = DEFAULT_SIZE, + int restart = 0, + ACE_Sig_Handler * = 0); + virtual ~ACE_XtReactor (void); + + XtAppContext context (void); + + // Register timers/handles with Xt. + virtual int attach (ACE_HANDLE handle, + ACE_Event_Handler *handler, + ACE_Reactor_Mask mask); + + virtual int detach (ACE_HANDLE handle, ACE_Reactor_Mask mask); + + virtual int schedule_timer (ACE_Event_Handler *handler, + const void *arg, + const ACE_Time_Value &delta_time, + const ACE_Time_Value &interval); + + virtual int cancel_timer (ACE_Event_Handler *handler); + virtual int cancel_timer (int timer_id, const void **arg); + +protected: + + virtual int wait_for_multiple_events (ACE_Handle_Set &, + ACE_Handle_Set &, + ACE_Handle_Set &, + ACE_Time_Value *); + + virtual int XtWaitForMultipleEvents (int, + ACE_Handle_Set &, + ACE_Handle_Set &, + ACE_Handle_Set &, + ACE_Time_Value *); + + ACE_XtReactor (const ACE_Reactor &); + ACE_XtReactor &operator = (const ACE_Reactor &); + + XtAppContext context_; + struct ACE_XtReactorID *ids_; + int id_len_; + XtIntervalId timeout_; + +private: + void reset_timeout (void); + static void TimerCallbackProc (XtPointer closure, XtIntervalId *id); + static void InputCallbackProc (XtPointer closure, int* source, XtInputId *id); +}; +#endif /* ACE_HAS_XT */ + +#endif /* ACE_XTREACTOR_H */ diff --git a/ace/ace.mak b/ace/ace.mak new file mode 100644 index 00000000000..d67501e1148 --- /dev/null +++ b/ace/ace.mak @@ -0,0 +1,2197 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +!IF "$(CFG)" == "" +CFG=ace - Win32 Debug +!MESSAGE No configuration specified. Defaulting to ace - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "ace - Win32 Release" && "$(CFG)" != "ace - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "ace.mak" CFG="ace - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ace - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "ace - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "ace - Win32 Debug" +RSC=rc.exe +MTL=mktyplib.exe +CPP=cl.exe + +!IF "$(CFG)" == "ace - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +OUTDIR=. +INTDIR=.\Release + +ALL : "$(OUTDIR)\ace.dll" + +CLEAN : + -@erase ".\ace.dll" + -@erase ".\Release\DEV_IO.obj" + -@erase ".\Release\SOCK_Acceptor.obj" + -@erase ".\Release\Profile_Timer.obj" + -@erase ".\Release\Read_Buffer.obj" + -@erase ".\Release\Time_Request_Reply.obj" + -@erase ".\Release\LSOCK_Acceptor.obj" + -@erase ".\Release\Time_Value.obj" + -@erase ".\Release\LSOCK_Dgram.obj" + -@erase ".\Release\Process.obj" + -@erase ".\Release\ReactorEx.obj" + -@erase ".\Release\Handle_Set.obj" + -@erase ".\Release\FILE_IO.obj" + -@erase ".\Release\Token_Collection.obj" + -@erase ".\Release\LSOCK_CODgram.obj" + -@erase ".\Release\SOCK.obj" + -@erase ".\Release\LSOCK.obj" + -@erase ".\Release\SOCK_Dgram_Bcast.obj" + -@erase ".\Release\SPIPE_Connector.obj" + -@erase ".\Release\FILE_Addr.obj" + -@erase ".\Release\SV_Message.obj" + -@erase ".\Release\TLI.obj" + -@erase ".\Release\Addr.obj" + -@erase ".\Release\Process_Manager.obj" + -@erase ".\Release\Service_Main.obj" + -@erase ".\Release\SPIPE.obj" + -@erase ".\Release\TLI_Connector.obj" + -@erase ".\Release\Get_Opt.obj" + -@erase ".\Release\IO_Cntl_Msg.obj" + -@erase ".\Release\Pipe.obj" + -@erase ".\Release\UPIPE_Acceptor.obj" + -@erase ".\Release\Signal.obj" + -@erase ".\Release\FIFO.obj" + -@erase ".\Release\LSOCK_Stream.obj" + -@erase ".\Release\FIFO_Send.obj" + -@erase ".\Release\SString.obj" + -@erase ".\Release\Naming_Context.obj" + -@erase ".\Release\Memory_Pool.obj" + -@erase ".\Release\Log_Msg.obj" + -@erase ".\Release\Mem_Map.obj" + -@erase ".\Release\SV_Semaphore_Complex.obj" + -@erase ".\Release\FIFO_Recv_Msg.obj" + -@erase ".\Release\Synch.obj" + -@erase ".\Release\Thread_Manager.obj" + -@erase ".\Release\SV_Message_Queue.obj" + -@erase ".\Release\TLI_Acceptor.obj" + -@erase ".\Release\Shared_Object.obj" + -@erase ".\Release\SOCK_Dgram.obj" + -@erase ".\Release\ACE.obj" + -@erase ".\Release\Service_Object.obj" + -@erase ".\Release\Token.obj" + -@erase ".\Release\SOCK_CODgram.obj" + -@erase ".\Release\Name_Proxy.obj" + -@erase ".\Release\Service_Repository.obj" + -@erase ".\Release\Event_Handler.obj" + -@erase ".\Release\Date_Time.obj" + -@erase ".\Release\SPIPE_Addr.obj" + -@erase ".\Release\Malloc.obj" + -@erase ".\Release\SOCK_Dgram_Mcast.obj" + -@erase ".\Release\Token_Invariants.obj" + -@erase ".\Release\DEV_Connector.obj" + -@erase ".\Release\FILE_Connector.obj" + -@erase ".\Release\Log_Record.obj" + -@erase ".\Release\Multiplexor.obj" + -@erase ".\Release\Shared_Memory_MM.obj" + -@erase ".\Release\Message_Block.obj" + -@erase ".\Release\Proactor.obj" + -@erase ".\Release\Remote_Tokens.obj" + -@erase ".\Release\Service_Record.obj" + -@erase ".\Release\Timer_Queue.obj" + -@erase ".\Release\SV_Shared_Memory.obj" + -@erase ".\Release\Remote_Name_Space.obj" + -@erase ".\Release\UPIPE_Connector.obj" + -@erase ".\Release\SPIPE_Stream.obj" + -@erase ".\Release\TLI_Stream.obj" + -@erase ".\Release\OS.obj" + -@erase ".\Release\Service_Config.obj" + -@erase ".\Release\IPC_SAP.obj" + -@erase ".\Release\Trace.obj" + -@erase ".\Release\Obstack.obj" + -@erase ".\Release\High_Res_Timer.obj" + -@erase ".\Release\Name_Request_Reply.obj" + -@erase ".\Release\SOCK_Connector.obj" + -@erase ".\Release\Local_Name_Space.obj" + -@erase ".\Release\FILE.obj" + -@erase ".\Release\DEV_Addr.obj" + -@erase ".\Release\UPIPE_Stream.obj" + -@erase ".\Release\SOCK_IO.obj" + -@erase ".\Release\SPIPE_Acceptor.obj" + -@erase ".\Release\FIFO_Send_Msg.obj" + -@erase ".\Release\System_Time.obj" + -@erase ".\Release\INET_Addr.obj" + -@erase ".\Release\FIFO_Recv.obj" + -@erase ".\Release\CORBA_Handler.obj" + -@erase ".\Release\Reactor.obj" + -@erase ".\Release\DEV.obj" + -@erase ".\Release\ARGV.obj" + -@erase ".\Release\Token_Request_Reply.obj" + -@erase ".\Release\Token_Manager.obj" + -@erase ".\Release\Name_Space.obj" + -@erase ".\Release\Thread.obj" + -@erase ".\Release\Dump.obj" + -@erase ".\Release\Svc_Conf_l.obj" + -@erase ".\Release\Shared_Memory_SV.obj" + -@erase ".\Release\Synch_Options.obj" + -@erase ".\Release\SOCK_Stream.obj" + -@erase ".\Release\Service_Manager.obj" + -@erase ".\Release\IO_SAP.obj" + -@erase ".\Release\Dynamic.obj" + -@erase ".\Release\SV_Semaphore_Simple.obj" + -@erase ".\Release\Local_Tokens.obj" + -@erase ".\Release\Svc_Conf_y.obj" + -@erase ".\Release\Parse_Node.obj" + -@erase ".\Release\UNIX_Addr.obj" + -@erase ".\Release\LSOCK_Connector.obj" + -@erase ".\Release\TTY_IO.obj" + -@erase ".\ace.lib" + -@erase ".\ace.exp" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MDd /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +CPP_PROJ=/nologo /MDd /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/ace.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS= +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/ace.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib /nologo /subsystem:windows /dll /incremental:no\ + /pdb:"$(OUTDIR)/ace.pdb" /machine:I386 /out:"$(OUTDIR)/ace.dll"\ + /implib:"$(OUTDIR)/ace.lib" +LINK32_OBJS= \ + "$(INTDIR)/DEV_IO.obj" \ + "$(INTDIR)/SOCK_Acceptor.obj" \ + "$(INTDIR)/Profile_Timer.obj" \ + "$(INTDIR)/Read_Buffer.obj" \ + "$(INTDIR)/Time_Request_Reply.obj" \ + "$(INTDIR)/LSOCK_Acceptor.obj" \ + "$(INTDIR)/Time_Value.obj" \ + "$(INTDIR)/LSOCK_Dgram.obj" \ + "$(INTDIR)/Process.obj" \ + "$(INTDIR)/ReactorEx.obj" \ + "$(INTDIR)/Handle_Set.obj" \ + "$(INTDIR)/FILE_IO.obj" \ + "$(INTDIR)/Token_Collection.obj" \ + "$(INTDIR)/LSOCK_CODgram.obj" \ + "$(INTDIR)/SOCK.obj" \ + "$(INTDIR)/LSOCK.obj" \ + "$(INTDIR)/SOCK_Dgram_Bcast.obj" \ + "$(INTDIR)/SPIPE_Connector.obj" \ + "$(INTDIR)/FILE_Addr.obj" \ + "$(INTDIR)/SV_Message.obj" \ + "$(INTDIR)/TLI.obj" \ + "$(INTDIR)/Addr.obj" \ + "$(INTDIR)/Process_Manager.obj" \ + "$(INTDIR)/Service_Main.obj" \ + "$(INTDIR)/SPIPE.obj" \ + "$(INTDIR)/TLI_Connector.obj" \ + "$(INTDIR)/Get_Opt.obj" \ + "$(INTDIR)/IO_Cntl_Msg.obj" \ + "$(INTDIR)/Pipe.obj" \ + "$(INTDIR)/UPIPE_Acceptor.obj" \ + "$(INTDIR)/Signal.obj" \ + "$(INTDIR)/FIFO.obj" \ + "$(INTDIR)/LSOCK_Stream.obj" \ + "$(INTDIR)/FIFO_Send.obj" \ + "$(INTDIR)/SString.obj" \ + "$(INTDIR)/Naming_Context.obj" \ + "$(INTDIR)/Memory_Pool.obj" \ + "$(INTDIR)/Log_Msg.obj" \ + "$(INTDIR)/Mem_Map.obj" \ + "$(INTDIR)/SV_Semaphore_Complex.obj" \ + "$(INTDIR)/FIFO_Recv_Msg.obj" \ + "$(INTDIR)/Synch.obj" \ + "$(INTDIR)/Thread_Manager.obj" \ + "$(INTDIR)/SV_Message_Queue.obj" \ + "$(INTDIR)/TLI_Acceptor.obj" \ + "$(INTDIR)/Shared_Object.obj" \ + "$(INTDIR)/SOCK_Dgram.obj" \ + "$(INTDIR)/ACE.obj" \ + "$(INTDIR)/Service_Object.obj" \ + "$(INTDIR)/Token.obj" \ + "$(INTDIR)/SOCK_CODgram.obj" \ + "$(INTDIR)/Name_Proxy.obj" \ + "$(INTDIR)/Service_Repository.obj" \ + "$(INTDIR)/Event_Handler.obj" \ + "$(INTDIR)/Date_Time.obj" \ + "$(INTDIR)/SPIPE_Addr.obj" \ + "$(INTDIR)/Malloc.obj" \ + "$(INTDIR)/SOCK_Dgram_Mcast.obj" \ + "$(INTDIR)/Token_Invariants.obj" \ + "$(INTDIR)/DEV_Connector.obj" \ + "$(INTDIR)/FILE_Connector.obj" \ + "$(INTDIR)/Log_Record.obj" \ + "$(INTDIR)/Multiplexor.obj" \ + "$(INTDIR)/Shared_Memory_MM.obj" \ + "$(INTDIR)/Message_Block.obj" \ + "$(INTDIR)/Proactor.obj" \ + "$(INTDIR)/Remote_Tokens.obj" \ + "$(INTDIR)/Service_Record.obj" \ + "$(INTDIR)/Timer_Queue.obj" \ + "$(INTDIR)/SV_Shared_Memory.obj" \ + "$(INTDIR)/Remote_Name_Space.obj" \ + "$(INTDIR)/UPIPE_Connector.obj" \ + "$(INTDIR)/SPIPE_Stream.obj" \ + "$(INTDIR)/TLI_Stream.obj" \ + "$(INTDIR)/OS.obj" \ + "$(INTDIR)/Service_Config.obj" \ + "$(INTDIR)/IPC_SAP.obj" \ + "$(INTDIR)/Trace.obj" \ + "$(INTDIR)/Obstack.obj" \ + "$(INTDIR)/High_Res_Timer.obj" \ + "$(INTDIR)/Name_Request_Reply.obj" \ + "$(INTDIR)/SOCK_Connector.obj" \ + "$(INTDIR)/Local_Name_Space.obj" \ + "$(INTDIR)/FILE.obj" \ + "$(INTDIR)/DEV_Addr.obj" \ + "$(INTDIR)/UPIPE_Stream.obj" \ + "$(INTDIR)/SOCK_IO.obj" \ + "$(INTDIR)/SPIPE_Acceptor.obj" \ + "$(INTDIR)/FIFO_Send_Msg.obj" \ + "$(INTDIR)/System_Time.obj" \ + "$(INTDIR)/INET_Addr.obj" \ + "$(INTDIR)/FIFO_Recv.obj" \ + "$(INTDIR)/CORBA_Handler.obj" \ + "$(INTDIR)/Reactor.obj" \ + "$(INTDIR)/DEV.obj" \ + "$(INTDIR)/ARGV.obj" \ + "$(INTDIR)/Token_Request_Reply.obj" \ + "$(INTDIR)/Token_Manager.obj" \ + "$(INTDIR)/Name_Space.obj" \ + "$(INTDIR)/Thread.obj" \ + "$(INTDIR)/Dump.obj" \ + "$(INTDIR)/Svc_Conf_l.obj" \ + "$(INTDIR)/Shared_Memory_SV.obj" \ + "$(INTDIR)/Synch_Options.obj" \ + "$(INTDIR)/SOCK_Stream.obj" \ + "$(INTDIR)/Service_Manager.obj" \ + "$(INTDIR)/IO_SAP.obj" \ + "$(INTDIR)/Dynamic.obj" \ + "$(INTDIR)/SV_Semaphore_Simple.obj" \ + "$(INTDIR)/Local_Tokens.obj" \ + "$(INTDIR)/Svc_Conf_y.obj" \ + "$(INTDIR)/Parse_Node.obj" \ + "$(INTDIR)/UNIX_Addr.obj" \ + "$(INTDIR)/LSOCK_Connector.obj" \ + "$(INTDIR)/TTY_IO.obj" + +"$(OUTDIR)\ace.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "ace - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +OUTDIR=. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\ace.dll" + +CLEAN : + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + -@erase ".\ace.dll" + -@erase ".\Debug\Date_Time.obj" + -@erase ".\Debug\Token_Collection.obj" + -@erase ".\Debug\LSOCK_Connector.obj" + -@erase ".\Debug\SOCK_Dgram_Bcast.obj" + -@erase ".\Debug\LSOCK_Dgram.obj" + -@erase ".\Debug\SPIPE_Acceptor.obj" + -@erase ".\Debug\Event_Handler.obj" + -@erase ".\Debug\Synch_Options.obj" + -@erase ".\Debug\Process.obj" + -@erase ".\Debug\FILE_IO.obj" + -@erase ".\Debug\Trace.obj" + -@erase ".\Debug\Signal.obj" + -@erase ".\Debug\TLI_Acceptor.obj" + -@erase ".\Debug\DEV_Addr.obj" + -@erase ".\Debug\SOCK_CODgram.obj" + -@erase ".\Debug\SPIPE_Connector.obj" + -@erase ".\Debug\ACE.obj" + -@erase ".\Debug\Remote_Name_Space.obj" + -@erase ".\Debug\IO_Cntl_Msg.obj" + -@erase ".\Debug\Process_Manager.obj" + -@erase ".\Debug\SOCK.obj" + -@erase ".\Debug\Timer_Queue.obj" + -@erase ".\Debug\Name_Space.obj" + -@erase ".\Debug\Get_Opt.obj" + -@erase ".\Debug\Svc_Conf_l.obj" + -@erase ".\Debug\Message_Block.obj" + -@erase ".\Debug\Service_Repository.obj" + -@erase ".\Debug\Addr.obj" + -@erase ".\Debug\Remote_Tokens.obj" + -@erase ".\Debug\Pipe.obj" + -@erase ".\Debug\SString.obj" + -@erase ".\Debug\IO_SAP.obj" + -@erase ".\Debug\FIFO.obj" + -@erase ".\Debug\Svc_Conf_y.obj" + -@erase ".\Debug\Log_Msg.obj" + -@erase ".\Debug\Mem_Map.obj" + -@erase ".\Debug\SV_Message_Queue.obj" + -@erase ".\Debug\Token_Request_Reply.obj" + -@erase ".\Debug\Parse_Node.obj" + -@erase ".\Debug\SV_Semaphore_Complex.obj" + -@erase ".\Debug\System_Time.obj" + -@erase ".\Debug\INET_Addr.obj" + -@erase ".\Debug\LSOCK_Acceptor.obj" + -@erase ".\Debug\FIFO_Recv.obj" + -@erase ".\Debug\Time_Value.obj" + -@erase ".\Debug\Malloc.obj" + -@erase ".\Debug\FILE_Connector.obj" + -@erase ".\Debug\LSOCK_Stream.obj" + -@erase ".\Debug\Handle_Set.obj" + -@erase ".\Debug\FIFO_Send_Msg.obj" + -@erase ".\Debug\CORBA_Handler.obj" + -@erase ".\Debug\SOCK_Dgram_Mcast.obj" + -@erase ".\Debug\SV_Message.obj" + -@erase ".\Debug\SOCK_Stream.obj" + -@erase ".\Debug\Token_Invariants.obj" + -@erase ".\Debug\Token_Manager.obj" + -@erase ".\Debug\SV_Semaphore_Simple.obj" + -@erase ".\Debug\Shared_Memory_MM.obj" + -@erase ".\Debug\OS.obj" + -@erase ".\Debug\UPIPE_Acceptor.obj" + -@erase ".\Debug\Service_Config.obj" + -@erase ".\Debug\LSOCK.obj" + -@erase ".\Debug\Multiplexor.obj" + -@erase ".\Debug\SV_Shared_Memory.obj" + -@erase ".\Debug\DEV.obj" + -@erase ".\Debug\SOCK_Connector.obj" + -@erase ".\Debug\SPIPE.obj" + -@erase ".\Debug\UNIX_Addr.obj" + -@erase ".\Debug\Naming_Context.obj" + -@erase ".\Debug\Read_Buffer.obj" + -@erase ".\Debug\Thread_Manager.obj" + -@erase ".\Debug\ReactorEx.obj" + -@erase ".\Debug\UPIPE_Connector.obj" + -@erase ".\Debug\Local_Name_Space.obj" + -@erase ".\Debug\SOCK_Acceptor.obj" + -@erase ".\Debug\Profile_Timer.obj" + -@erase ".\Debug\IPC_SAP.obj" + -@erase ".\Debug\FILE_Addr.obj" + -@erase ".\Debug\Service_Object.obj" + -@erase ".\Debug\Obstack.obj" + -@erase ".\Debug\DEV_Connector.obj" + -@erase ".\Debug\SOCK_Dgram.obj" + -@erase ".\Debug\LSOCK_CODgram.obj" + -@erase ".\Debug\Local_Tokens.obj" + -@erase ".\Debug\Name_Proxy.obj" + -@erase ".\Debug\Thread.obj" + -@erase ".\Debug\Synch.obj" + -@erase ".\Debug\SOCK_IO.obj" + -@erase ".\Debug\TLI_Connector.obj" + -@erase ".\Debug\SPIPE_Addr.obj" + -@erase ".\Debug\FILE.obj" + -@erase ".\Debug\FIFO_Send.obj" + -@erase ".\Debug\Shared_Memory_SV.obj" + -@erase ".\Debug\Time_Request_Reply.obj" + -@erase ".\Debug\SPIPE_Stream.obj" + -@erase ".\Debug\Token.obj" + -@erase ".\Debug\Reactor.obj" + -@erase ".\Debug\Memory_Pool.obj" + -@erase ".\Debug\Log_Record.obj" + -@erase ".\Debug\Service_Main.obj" + -@erase ".\Debug\TLI.obj" + -@erase ".\Debug\ARGV.obj" + -@erase ".\Debug\Service_Record.obj" + -@erase ".\Debug\UPIPE_Stream.obj" + -@erase ".\Debug\DEV_IO.obj" + -@erase ".\Debug\Name_Request_Reply.obj" + -@erase ".\Debug\Dump.obj" + -@erase ".\Debug\Service_Manager.obj" + -@erase ".\Debug\FIFO_Recv_Msg.obj" + -@erase ".\Debug\Proactor.obj" + -@erase ".\Debug\Dynamic.obj" + -@erase ".\Debug\TLI_Stream.obj" + -@erase ".\Debug\High_Res_Timer.obj" + -@erase ".\Debug\Shared_Object.obj" + -@erase ".\Debug\TTY_IO.obj" + -@erase ".\ace.ilk" + -@erase ".\ace.lib" + -@erase ".\ace.exp" + -@erase ".\ace.pdb" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +CPP_PROJ=/nologo /MDd /W3 /Gm /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/ace.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/ace.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib advapi32.lib /nologo /subsystem:windows /dll /debug /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib wsock32.lib advapi32.lib /nologo /subsystem:windows /dll\ + /incremental:yes /pdb:"$(OUTDIR)/ace.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/ace.dll" /implib:"$(OUTDIR)/ace.lib" +LINK32_OBJS= \ + "$(INTDIR)/Date_Time.obj" \ + "$(INTDIR)/Token_Collection.obj" \ + "$(INTDIR)/LSOCK_Connector.obj" \ + "$(INTDIR)/SOCK_Dgram_Bcast.obj" \ + "$(INTDIR)/LSOCK_Dgram.obj" \ + "$(INTDIR)/SPIPE_Acceptor.obj" \ + "$(INTDIR)/Event_Handler.obj" \ + "$(INTDIR)/Synch_Options.obj" \ + "$(INTDIR)/Process.obj" \ + "$(INTDIR)/FILE_IO.obj" \ + "$(INTDIR)/Trace.obj" \ + "$(INTDIR)/Signal.obj" \ + "$(INTDIR)/TLI_Acceptor.obj" \ + "$(INTDIR)/DEV_Addr.obj" \ + "$(INTDIR)/SOCK_CODgram.obj" \ + "$(INTDIR)/SPIPE_Connector.obj" \ + "$(INTDIR)/ACE.obj" \ + "$(INTDIR)/Remote_Name_Space.obj" \ + "$(INTDIR)/IO_Cntl_Msg.obj" \ + "$(INTDIR)/Process_Manager.obj" \ + "$(INTDIR)/SOCK.obj" \ + "$(INTDIR)/Timer_Queue.obj" \ + "$(INTDIR)/Name_Space.obj" \ + "$(INTDIR)/Get_Opt.obj" \ + "$(INTDIR)/Svc_Conf_l.obj" \ + "$(INTDIR)/Message_Block.obj" \ + "$(INTDIR)/Service_Repository.obj" \ + "$(INTDIR)/Addr.obj" \ + "$(INTDIR)/Remote_Tokens.obj" \ + "$(INTDIR)/Pipe.obj" \ + "$(INTDIR)/SString.obj" \ + "$(INTDIR)/IO_SAP.obj" \ + "$(INTDIR)/FIFO.obj" \ + "$(INTDIR)/Svc_Conf_y.obj" \ + "$(INTDIR)/Log_Msg.obj" \ + "$(INTDIR)/Mem_Map.obj" \ + "$(INTDIR)/SV_Message_Queue.obj" \ + "$(INTDIR)/Token_Request_Reply.obj" \ + "$(INTDIR)/Parse_Node.obj" \ + "$(INTDIR)/SV_Semaphore_Complex.obj" \ + "$(INTDIR)/System_Time.obj" \ + "$(INTDIR)/INET_Addr.obj" \ + "$(INTDIR)/LSOCK_Acceptor.obj" \ + "$(INTDIR)/FIFO_Recv.obj" \ + "$(INTDIR)/Time_Value.obj" \ + "$(INTDIR)/Malloc.obj" \ + "$(INTDIR)/FILE_Connector.obj" \ + "$(INTDIR)/LSOCK_Stream.obj" \ + "$(INTDIR)/Handle_Set.obj" \ + "$(INTDIR)/FIFO_Send_Msg.obj" \ + "$(INTDIR)/CORBA_Handler.obj" \ + "$(INTDIR)/SOCK_Dgram_Mcast.obj" \ + "$(INTDIR)/SV_Message.obj" \ + "$(INTDIR)/SOCK_Stream.obj" \ + "$(INTDIR)/Token_Invariants.obj" \ + "$(INTDIR)/Token_Manager.obj" \ + "$(INTDIR)/SV_Semaphore_Simple.obj" \ + "$(INTDIR)/Shared_Memory_MM.obj" \ + "$(INTDIR)/OS.obj" \ + "$(INTDIR)/UPIPE_Acceptor.obj" \ + "$(INTDIR)/Service_Config.obj" \ + "$(INTDIR)/LSOCK.obj" \ + "$(INTDIR)/Multiplexor.obj" \ + "$(INTDIR)/SV_Shared_Memory.obj" \ + "$(INTDIR)/DEV.obj" \ + "$(INTDIR)/SOCK_Connector.obj" \ + "$(INTDIR)/SPIPE.obj" \ + "$(INTDIR)/UNIX_Addr.obj" \ + "$(INTDIR)/Naming_Context.obj" \ + "$(INTDIR)/Read_Buffer.obj" \ + "$(INTDIR)/Thread_Manager.obj" \ + "$(INTDIR)/ReactorEx.obj" \ + "$(INTDIR)/UPIPE_Connector.obj" \ + "$(INTDIR)/Local_Name_Space.obj" \ + "$(INTDIR)/SOCK_Acceptor.obj" \ + "$(INTDIR)/Profile_Timer.obj" \ + "$(INTDIR)/IPC_SAP.obj" \ + "$(INTDIR)/FILE_Addr.obj" \ + "$(INTDIR)/Service_Object.obj" \ + "$(INTDIR)/Obstack.obj" \ + "$(INTDIR)/DEV_Connector.obj" \ + "$(INTDIR)/SOCK_Dgram.obj" \ + "$(INTDIR)/LSOCK_CODgram.obj" \ + "$(INTDIR)/Local_Tokens.obj" \ + "$(INTDIR)/Name_Proxy.obj" \ + "$(INTDIR)/Thread.obj" \ + "$(INTDIR)/Synch.obj" \ + "$(INTDIR)/SOCK_IO.obj" \ + "$(INTDIR)/TLI_Connector.obj" \ + "$(INTDIR)/SPIPE_Addr.obj" \ + "$(INTDIR)/FILE.obj" \ + "$(INTDIR)/FIFO_Send.obj" \ + "$(INTDIR)/Shared_Memory_SV.obj" \ + "$(INTDIR)/Time_Request_Reply.obj" \ + "$(INTDIR)/SPIPE_Stream.obj" \ + "$(INTDIR)/Token.obj" \ + "$(INTDIR)/Reactor.obj" \ + "$(INTDIR)/Memory_Pool.obj" \ + "$(INTDIR)/Log_Record.obj" \ + "$(INTDIR)/Service_Main.obj" \ + "$(INTDIR)/TLI.obj" \ + "$(INTDIR)/ARGV.obj" \ + "$(INTDIR)/Service_Record.obj" \ + "$(INTDIR)/UPIPE_Stream.obj" \ + "$(INTDIR)/DEV_IO.obj" \ + "$(INTDIR)/Name_Request_Reply.obj" \ + "$(INTDIR)/Dump.obj" \ + "$(INTDIR)/Service_Manager.obj" \ + "$(INTDIR)/FIFO_Recv_Msg.obj" \ + "$(INTDIR)/Proactor.obj" \ + "$(INTDIR)/Dynamic.obj" \ + "$(INTDIR)/TLI_Stream.obj" \ + "$(INTDIR)/High_Res_Timer.obj" \ + "$(INTDIR)/Shared_Object.obj" \ + "$(INTDIR)/TTY_IO.obj" + +"$(OUTDIR)\ace.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "ace - Win32 Release" +# Name "ace - Win32 Debug" + +!IF "$(CFG)" == "ace - Win32 Release" + +!ELSEIF "$(CFG)" == "ace - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\UPIPE_Stream.cpp +NODEP_CPP_UPIPE=\ + ".\ace\UPIPE_Stream.h"\ + ".\ace\UPIPE_Stream.i"\ + + +"$(INTDIR)\UPIPE_Stream.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\UPIPE_Connector.cpp +NODEP_CPP_UPIPE_=\ + ".\ace\UPIPE_Connector.h"\ + + +"$(INTDIR)\UPIPE_Connector.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\UPIPE_Acceptor.cpp +NODEP_CPP_UPIPE_A=\ + ".\ace\UPIPE_Acceptor.h"\ + ".\ace\Log_Msg.h"\ + + +"$(INTDIR)\UPIPE_Acceptor.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\UNIX_Addr.cpp +NODEP_CPP_UNIX_=\ + ".\ace\UNIX_Addr.h"\ + ".\ace\UNIX_Addr.i"\ + + +"$(INTDIR)\UNIX_Addr.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Trace.cpp +NODEP_CPP_TRACE=\ + ".\ace\config.h"\ + ".\ace\ACE.h"\ + ".\ace\Log_Msg.h"\ + ".\ace\Trace.h"\ + ".\ace\Trace.i"\ + + +"$(INTDIR)\Trace.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Token_Request_Reply.cpp +NODEP_CPP_TOKEN=\ + ".\ace\Log_Msg.h"\ + ".\ace\Token_Request_Reply.h"\ + ".\ace\Token_Request_Reply.i"\ + + +"$(INTDIR)\Token_Request_Reply.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Token_Manager.cpp +NODEP_CPP_TOKEN_=\ + ".\ace\Log_Msg.h"\ + ".\ace\Token_Manager.h"\ + ".\ace\Token_Manager.i"\ + + +"$(INTDIR)\Token_Manager.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Token_Collection.cpp +NODEP_CPP_TOKEN_C=\ + ".\ace\Token_Collection.h"\ + ".\ace\Log_Msg.h"\ + ".\ace\Token_Collection.i"\ + + +"$(INTDIR)\Token_Collection.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Token.cpp +NODEP_CPP_TOKEN_CP=\ + ".\ace\Thread.h"\ + ".\ace\Time_Value.h"\ + ".\ace\Token.h"\ + ".\ace\Token.i"\ + + +"$(INTDIR)\Token.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\TLI_Stream.cpp +NODEP_CPP_TLI_S=\ + ".\ace\TLI_Stream.h"\ + ".\ace\Log_Msg.h"\ + + +"$(INTDIR)\TLI_Stream.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\TLI_Connector.cpp +NODEP_CPP_TLI_C=\ + ".\ace\Handle_Set.h"\ + ".\ace\TLI_Connector.h"\ + ".\ace\Time_Value.h"\ + + +"$(INTDIR)\TLI_Connector.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\TLI_Acceptor.cpp +NODEP_CPP_TLI_A=\ + ".\ace\TLI_Acceptor.h"\ + ".\ace\Log_Msg.h"\ + + +"$(INTDIR)\TLI_Acceptor.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\TLI.cpp +NODEP_CPP_TLI_CP=\ + ".\ace\TLI.h"\ + ".\ace\Log_Msg.h"\ + + +"$(INTDIR)\TLI.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Timer_Queue.cpp +NODEP_CPP_TIMER=\ + ".\ace\Timer_Queue.h"\ + + +"$(INTDIR)\Timer_Queue.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Time_Value.cpp +NODEP_CPP_TIME_=\ + ".\ace\ACE.h"\ + ".\ace\Time_Value.h"\ + ".\ace\Time_Value.i"\ + + +"$(INTDIR)\Time_Value.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Time_Request_Reply.cpp +NODEP_CPP_TIME_R=\ + ".\ace\Log_Msg.h"\ + ".\ace\Time_Request_Reply.h"\ + + +"$(INTDIR)\Time_Request_Reply.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Thread_Manager.cpp +NODEP_CPP_THREA=\ + ".\ace\Thread_Manager.h"\ + ".\ace\Thread_Manager.i"\ + + +"$(INTDIR)\Thread_Manager.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Thread.cpp +NODEP_CPP_THREAD=\ + ".\ace\Thread.h"\ + ".\ace\Thread.i"\ + + +"$(INTDIR)\Thread.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\System_Time.cpp +NODEP_CPP_SYSTE=\ + ".\ace\Time_Value.h"\ + ".\ace\System_Time.h"\ + + +"$(INTDIR)\System_Time.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Synch_Options.cpp +NODEP_CPP_SYNCH=\ + ".\ace\Synch_Options.h"\ + + +"$(INTDIR)\Synch_Options.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Synch.cpp +NODEP_CPP_SYNCH_=\ + ".\ace\Thread.h"\ + ".\ace\Synch.h"\ + ".\ace\Log_Msg.h"\ + ".\ace\Time_Value.h"\ + ".\ace\Synch.i"\ + + +"$(INTDIR)\Synch.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Svc_Conf_y.cpp +NODEP_CPP_SVC_C=\ + ".\ace\ARGV.h"\ + ".\ace\Svc_Conf.h"\ + ".\ace\Module.h"\ + ".\ace\Stream.h"\ + + +"$(INTDIR)\Svc_Conf_y.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Svc_Conf_l.cpp +NODEP_CPP_SVC_CO=\ + ".\ace\Svc_Conf.h"\ + ".\ace\Svc_Conf_Tokens.h"\ + + +"$(INTDIR)\Svc_Conf_l.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SV_Shared_Memory.cpp +NODEP_CPP_SV_SH=\ + ".\ace\SV_Shared_Memory.h"\ + ".\ace\Log_Msg.h"\ + ".\ace\SV_Shared_Memory.i"\ + + +"$(INTDIR)\SV_Shared_Memory.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SV_Semaphore_Simple.cpp +NODEP_CPP_SV_SE=\ + ".\ace\Log_Msg.h"\ + ".\ace\SV_Semaphore_Simple.h"\ + + +"$(INTDIR)\SV_Semaphore_Simple.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SV_Semaphore_Complex.cpp +NODEP_CPP_SV_SEM=\ + ".\ace\Log_Msg.h"\ + ".\ace\SV_Semaphore_Complex.h"\ + + +"$(INTDIR)\SV_Semaphore_Complex.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SV_Message_Queue.cpp +NODEP_CPP_SV_ME=\ + ".\ace\SV_Message_Queue.h"\ + ".\ace\Log_Msg.h"\ + + +"$(INTDIR)\SV_Message_Queue.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SV_Message.cpp +NODEP_CPP_SV_MES=\ + ".\ace\SV_Message.h"\ + ".\ace\SV_Message.i"\ + + +"$(INTDIR)\SV_Message.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SString.cpp +NODEP_CPP_SSTRI=\ + ".\ace\Malloc.h"\ + ".\ace\Service_Config.h"\ + ".\ace\SString.h"\ + ".\ace\SString.i"\ + + +"$(INTDIR)\SString.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SPIPE_Stream.cpp +NODEP_CPP_SPIPE=\ + ".\ace\SPIPE_Stream.h"\ + + +"$(INTDIR)\SPIPE_Stream.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SPIPE_Connector.cpp +NODEP_CPP_SPIPE_=\ + ".\ace\SPIPE_Connector.h"\ + + +"$(INTDIR)\SPIPE_Connector.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SPIPE_Addr.cpp +NODEP_CPP_SPIPE_A=\ + ".\ace\SPIPE_Addr.h"\ + ".\ace\SPIPE_Addr.i"\ + + +"$(INTDIR)\SPIPE_Addr.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SPIPE_Acceptor.cpp +NODEP_CPP_SPIPE_AC=\ + ".\ace\SPIPE_Acceptor.h"\ + ".\ace\Log_Msg.h"\ + + +"$(INTDIR)\SPIPE_Acceptor.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SPIPE.cpp +NODEP_CPP_SPIPE_C=\ + ".\ace\SPIPE.h"\ + + +"$(INTDIR)\SPIPE.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SOCK_Stream.cpp +NODEP_CPP_SOCK_=\ + ".\ace\SOCK_Stream.h"\ + + +"$(INTDIR)\SOCK_Stream.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SOCK_IO.cpp +NODEP_CPP_SOCK_I=\ + ".\ace\SOCK_IO.h"\ + + +"$(INTDIR)\SOCK_IO.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SOCK_Dgram_Mcast.cpp +NODEP_CPP_SOCK_D=\ + ".\ace\SOCK_Dgram_Mcast.h"\ + ".\ace\INET_Addr.h"\ + + +"$(INTDIR)\SOCK_Dgram_Mcast.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SOCK_Dgram_Bcast.cpp +NODEP_CPP_SOCK_DG=\ + ".\ace\SOCK_Dgram_Bcast.h"\ + ".\ace\Log_Msg.h"\ + + +"$(INTDIR)\SOCK_Dgram_Bcast.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SOCK_Dgram.cpp +NODEP_CPP_SOCK_DGR=\ + ".\ace\SOCK_Dgram.h"\ + ".\ace\Log_Msg.h"\ + + +"$(INTDIR)\SOCK_Dgram.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SOCK_Connector.cpp +NODEP_CPP_SOCK_C=\ + ".\ace\SOCK_Connector.h"\ + ".\ace\Handle_Set.h"\ + ".\ace\INET_Addr.h"\ + + +"$(INTDIR)\SOCK_Connector.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SOCK_CODgram.cpp +NODEP_CPP_SOCK_CO=\ + ".\ace\SOCK_CODgram.h"\ + ".\ace\Log_Msg.h"\ + + +"$(INTDIR)\SOCK_CODgram.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SOCK_Acceptor.cpp +NODEP_CPP_SOCK_A=\ + ".\ace\SOCK_Acceptor.h"\ + ".\ace\Log_Msg.h"\ + ".\ace\SOCK_Acceptor.i"\ + + +"$(INTDIR)\SOCK_Acceptor.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Signal.cpp +NODEP_CPP_SIGNA=\ + ".\ace\Log_Msg.h"\ + ".\ace\Signal.h"\ + ".\ace\Signal.i"\ + + +"$(INTDIR)\Signal.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Shared_Object.cpp +NODEP_CPP_SHARE=\ + ".\ace\Shared_Object.h"\ + ".\ace\Shared_Object.i"\ + + +"$(INTDIR)\Shared_Object.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Shared_Memory_SV.cpp +NODEP_CPP_SHARED=\ + ".\ace\Shared_Memory_SV.h"\ + ".\ace\Shared_Memory_SV.i"\ + + +"$(INTDIR)\Shared_Memory_SV.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Shared_Memory_MM.cpp +NODEP_CPP_SHARED_=\ + ".\ace\Shared_Memory_MM.h"\ + ".\ace\Shared_Memory_MM.i"\ + + +"$(INTDIR)\Shared_Memory_MM.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Service_Repository.cpp +NODEP_CPP_SERVI=\ + ".\ace\Service_Repository.h"\ + ".\ace\Service_Repository.i"\ + + +"$(INTDIR)\Service_Repository.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Service_Record.cpp +NODEP_CPP_SERVIC=\ + ".\ace\Service_Record.h"\ + ".\ace\Service_Record.i"\ + + +"$(INTDIR)\Service_Record.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Service_Object.cpp +NODEP_CPP_SERVICE=\ + ".\ace\Service_Object.h"\ + ".\ace\Service_Object.i"\ + + +"$(INTDIR)\Service_Object.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Service_Manager.cpp +NODEP_CPP_SERVICE_=\ + ".\ace\Get_Opt.h"\ + ".\ace\Service_Repository.h"\ + ".\ace\Service_Config.h"\ + ".\ace\Service_Manager.h"\ + ".\ace\Reactor.h"\ + ".\ace\Service_Manager.i"\ + + +"$(INTDIR)\Service_Manager.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Service_Main.cpp +NODEP_CPP_SERVICE_M=\ + ".\ace\Service_Config.h"\ + + +"$(INTDIR)\Service_Main.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Service_Config.cpp +NODEP_CPP_SERVICE_C=\ + ".\ace\Svc_Conf.h"\ + ".\ace\Get_Opt.h"\ + ".\ace\ARGV.h"\ + ".\ace\Malloc.h"\ + ".\ace\Service_Manager.h"\ + ".\ace\Service_Repository.h"\ + ".\ace\Service_Record.h"\ + ".\ace\Set.h"\ + ".\ace\Auto_Ptr.h"\ + ".\ace\Service_Config.h"\ + ".\ace\Service_Config.i"\ + + +"$(INTDIR)\Service_Config.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Remote_Tokens.cpp +NODEP_CPP_REMOT=\ + ".\ace\Log_Msg.h"\ + ".\ace\Remote_Tokens.h"\ + ".\ace\Singleton.h"\ + ".\ace\Remote_Tokens.i"\ + + +"$(INTDIR)\Remote_Tokens.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Remote_Name_Space.cpp +NODEP_CPP_REMOTE=\ + ".\ace\Log_Msg.h"\ + ".\ace\Remote_Name_Space.h"\ + + +"$(INTDIR)\Remote_Name_Space.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Read_Buffer.cpp +NODEP_CPP_READ_=\ + ".\ace\Read_Buffer.h"\ + ".\ace\Service_Config.h"\ + + +"$(INTDIR)\Read_Buffer.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Reactor.cpp +NODEP_CPP_REACT=\ + ".\ace\Log_Msg.h"\ + ".\ace\Synch_T.h"\ + ".\ace\SOCK_Acceptor.h"\ + ".\ace\SOCK_Connector.h"\ + ".\ace\Reactor.h"\ + + +"$(INTDIR)\Reactor.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Profile_Timer.cpp +NODEP_CPP_PROFI=\ + ".\ace\Profile_Timer.h"\ + ".\ace\Profile_Timer.i"\ + + +"$(INTDIR)\Profile_Timer.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Process_Manager.cpp +NODEP_CPP_PROCE=\ + ".\ace\Process_Manager.h"\ + ".\ace\Process_Manager.i"\ + + +"$(INTDIR)\Process_Manager.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Pipe.cpp +NODEP_CPP_PIPE_=\ + ".\ace\Log_Msg.h"\ + ".\ace\SOCK_Acceptor.h"\ + ".\ace\SOCK_Connector.h"\ + ".\ace\Pipe.h"\ + + +"$(INTDIR)\Pipe.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Parse_Node.cpp +NODEP_CPP_PARSE=\ + ".\ace\Service_Config.h"\ + ".\ace\Service_Repository.h"\ + ".\ace\Task.h"\ + ".\ace\Parse_Node.h"\ + ".\ace\Parse_Node.i"\ + + +"$(INTDIR)\Parse_Node.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\OS.cpp +NODEP_CPP_OS_CP=\ + ".\ace\OS.h"\ + ".\ace\Log_Msg.h"\ + ".\ace\ARGV.h"\ + ".\ace\OS.i"\ + ".\ace\Synch.h"\ + ".\ace\Set.h"\ + + +"$(INTDIR)\OS.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Obstack.cpp +NODEP_CPP_OBSTA=\ + ".\ace\Obstack.h"\ + + +"$(INTDIR)\Obstack.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Naming_Context.cpp +NODEP_CPP_NAMIN=\ + ".\ace\Log_Msg.h"\ + ".\ace\Get_Opt.h"\ + ".\ace\Naming_Context.h"\ + ".\ace\Remote_Name_Space.h"\ + ".\ace\Local_Name_Space.h"\ + + +"$(INTDIR)\Naming_Context.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Name_Space.cpp +NODEP_CPP_NAME_=\ + ".\ace\Name_Space.h"\ + + +"$(INTDIR)\Name_Space.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Name_Request_Reply.cpp +NODEP_CPP_NAME_R=\ + ".\ace\Log_Msg.h"\ + ".\ace\Name_Request_Reply.h"\ + + +"$(INTDIR)\Name_Request_Reply.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Name_Proxy.cpp +NODEP_CPP_NAME_P=\ + ".\ace\Log_Msg.h"\ + ".\ace\Name_Proxy.h"\ + + +"$(INTDIR)\Name_Proxy.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Multiplexor.cpp +NODEP_CPP_MULTI=\ + ".\ace\Multiplexor.h"\ + ".\ace\Multiplexor.i"\ + + +"$(INTDIR)\Multiplexor.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Message_Block.cpp +NODEP_CPP_MESSA=\ + ".\ace\Log_Msg.h"\ + ".\ace\Message_Block.h"\ + ".\ace\Message_Block.i"\ + + +"$(INTDIR)\Message_Block.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Memory_Pool.cpp +NODEP_CPP_MEMOR=\ + ".\ace\Log_Msg.h"\ + ".\ace\Memory_Pool.h"\ + ".\ace\Memory_Pool.i"\ + + +"$(INTDIR)\Memory_Pool.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Mem_Map.cpp +NODEP_CPP_MEM_M=\ + ".\ace\Mem_Map.h"\ + ".\ace\Mem_Map.i"\ + + +"$(INTDIR)\Mem_Map.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Malloc.cpp +NODEP_CPP_MALLO=\ + ".\ace\Malloc.h"\ + ".\ace\Malloc.i"\ + + +"$(INTDIR)\Malloc.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\LSOCK_Stream.cpp +NODEP_CPP_LSOCK=\ + ".\ace\Log_Msg.h"\ + ".\ace\LSOCK_Stream.h"\ + + +"$(INTDIR)\LSOCK_Stream.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\LSOCK_Dgram.cpp +NODEP_CPP_LSOCK_=\ + ".\ace\LSOCK_Dgram.h"\ + ".\ace\Log_Msg.h"\ + + +"$(INTDIR)\LSOCK_Dgram.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\LSOCK_Connector.cpp +NODEP_CPP_LSOCK_C=\ + ".\ace\LSOCK_Connector.h"\ + + +"$(INTDIR)\LSOCK_Connector.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\LSOCK_CODgram.cpp +NODEP_CPP_LSOCK_CO=\ + ".\ace\LSOCK_CODgram.h"\ + ".\ace\Log_Msg.h"\ + + +"$(INTDIR)\LSOCK_CODgram.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\LSOCK_Acceptor.cpp +NODEP_CPP_LSOCK_A=\ + ".\ace\Log_Msg.h"\ + ".\ace\LSOCK_Acceptor.h"\ + ".\ace\LSOCK_Acceptor.i"\ + + +"$(INTDIR)\LSOCK_Acceptor.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\LSOCK.cpp +NODEP_CPP_LSOCK_CP=\ + ".\ace\Log_Msg.h"\ + ".\ace\LSOCK.h"\ + + +"$(INTDIR)\LSOCK.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Log_Record.cpp +NODEP_CPP_LOG_R=\ + ".\ace\Log_Msg.h"\ + ".\ace\Log_Record.h"\ + + +"$(INTDIR)\Log_Record.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Log_Msg.cpp +NODEP_CPP_LOG_M=\ + ".\ace\config.h"\ + ".\ace\ACE.h"\ + ".\ace\Thread.h"\ + ".\ace\Synch.h"\ + ".\ace\Log_Msg.h"\ + ".\ace\SPIPE_Connector.h"\ + ".\ace\FIFO_Send_Msg.h"\ + + +"$(INTDIR)\Log_Msg.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Local_Tokens.cpp +NODEP_CPP_LOCAL=\ + ".\ace\Log_Msg.h"\ + ".\ace\Thread.h"\ + ".\ace\Local_Tokens.h"\ + ".\ace\Token_Manager.h"\ + ".\ace\Local_Tokens.i"\ + + +"$(INTDIR)\Local_Tokens.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Local_Name_Space.cpp +NODEP_CPP_LOCAL_=\ + ".\ace\Log_Msg.h"\ + ".\ace\ACE.h"\ + ".\ace\Local_Name_Space.h"\ + + +"$(INTDIR)\Local_Name_Space.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\IPC_SAP.cpp +NODEP_CPP_IPC_S=\ + ".\ace\Log_Msg.h"\ + ".\ace\IPC_SAP.h"\ + + +"$(INTDIR)\IPC_SAP.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\IO_SAP.cpp +NODEP_CPP_IO_SA=\ + ".\ace\Log_Msg.h"\ + ".\ace\IO_SAP.h"\ + + +"$(INTDIR)\IO_SAP.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\IO_Cntl_Msg.cpp + +"$(INTDIR)\IO_Cntl_Msg.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\INET_Addr.cpp +NODEP_CPP_INET_=\ + ".\ace\INET_Addr.h"\ + ".\ace\INET_Addr.i"\ + + +"$(INTDIR)\INET_Addr.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\High_Res_Timer.cpp +NODEP_CPP_HIGH_=\ + ".\ace\Log_Msg.h"\ + ".\ace\High_Res_Timer.h"\ + ".\ace\High_Res_Timer.i"\ + + +"$(INTDIR)\High_Res_Timer.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Handle_Set.cpp +NODEP_CPP_HANDL=\ + ".\ace\Log_Msg.h"\ + ".\ace\Handle_Set.h"\ + ".\ace\Handle_Set.i"\ + + +"$(INTDIR)\Handle_Set.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Get_Opt.cpp +NODEP_CPP_GET_O=\ + ".\ace\Log_Msg.h"\ + ".\ace\Get_Opt.h"\ + ".\ace\Get_Opt.i"\ + + +"$(INTDIR)\Get_Opt.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\FILE_IO.cpp +NODEP_CPP_FILE_=\ + ".\ace\FILE_IO.h"\ + ".\ace\Log_Msg.h"\ + + +"$(INTDIR)\FILE_IO.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\FILE_Connector.cpp +NODEP_CPP_FILE_C=\ + ".\ace\FILE_Connector.h"\ + + +"$(INTDIR)\FILE_Connector.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\FILE_Addr.cpp +NODEP_CPP_FILE_A=\ + ".\ace\Log_Msg.h"\ + ".\ace\FILE_Addr.h"\ + ".\ace\FILE_Addr.i"\ + + +"$(INTDIR)\FILE_Addr.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\FILE.cpp +NODEP_CPP_FILE_CP=\ + ".\ace\FILE.h"\ + + +"$(INTDIR)\FILE.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\FIFO_Send_Msg.cpp +NODEP_CPP_FIFO_=\ + ".\ace\FIFO_Send_Msg.h"\ + ".\ace\Log_Msg.h"\ + + +"$(INTDIR)\FIFO_Send_Msg.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\FIFO_Send.cpp +NODEP_CPP_FIFO_S=\ + ".\ace\FIFO_Send.h"\ + ".\ace\Log_Msg.h"\ + + +"$(INTDIR)\FIFO_Send.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\FIFO_Recv_Msg.cpp +NODEP_CPP_FIFO_R=\ + ".\ace\FIFO_Recv_Msg.h"\ + ".\ace\Log_Msg.h"\ + + +"$(INTDIR)\FIFO_Recv_Msg.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\FIFO_Recv.cpp +NODEP_CPP_FIFO_RE=\ + ".\ace\FIFO_Recv.h"\ + ".\ace\Log_Msg.h"\ + + +"$(INTDIR)\FIFO_Recv.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Event_Handler.cpp +NODEP_CPP_EVENT=\ + ".\ace\Event_Handler.h"\ + ".\ace\Message_Block.h"\ + ".\ace\Event_Handler.i"\ + + +"$(INTDIR)\Event_Handler.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Dynamic.cpp +NODEP_CPP_DYNAM=\ + ".\ace\Dynamic.h"\ + ".\ace\Dynamic.i"\ + + +"$(INTDIR)\Dynamic.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Dump.cpp +NODEP_CPP_DUMP_=\ + ".\ace\Dump.h"\ + + +"$(INTDIR)\Dump.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\DEV_IO.cpp +NODEP_CPP_DEV_I=\ + ".\ace\DEV_IO.h"\ + ".\ace\Log_Msg.h"\ + + +"$(INTDIR)\DEV_IO.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\DEV_Connector.cpp +NODEP_CPP_DEV_C=\ + ".\ace\DEV_Connector.h"\ + + +"$(INTDIR)\DEV_Connector.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\DEV_Addr.cpp +NODEP_CPP_DEV_A=\ + ".\ace\Log_Msg.h"\ + ".\ace\DEV_Addr.h"\ + ".\ace\DEV_Addr.i"\ + + +"$(INTDIR)\DEV_Addr.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\DEV.cpp +NODEP_CPP_DEV_CP=\ + ".\ace\DEV.h"\ + + +"$(INTDIR)\DEV.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Date_Time.cpp +NODEP_CPP_DATE_=\ + ".\ace\Date_Time.h"\ + + +"$(INTDIR)\Date_Time.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\CORBA_Handler.cpp +NODEP_CPP_CORBA=\ + ".\ace\Log_Msg.h"\ + ".\ace\CORBA_Handler.h"\ + ".\ace\CORBA_Handler.i"\ + + +"$(INTDIR)\CORBA_Handler.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\ARGV.cpp +NODEP_CPP_ARGV_=\ + ".\ace\Log_Msg.h"\ + ".\ace\ARGV.h"\ + ".\ace\ARGV.i"\ + + +"$(INTDIR)\ARGV.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Addr.cpp +NODEP_CPP_ADDR_=\ + ".\ace\Log_Msg.h"\ + ".\ace\Addr.h"\ + ".\ace\Addr.i"\ + + +"$(INTDIR)\Addr.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\ACE.cpp +NODEP_CPP_ACE_C=\ + ".\ace\IPC_SAP.h"\ + ".\ace\Time_Value.h"\ + ".\ace\Handle_Set.h"\ + ".\ace\ACE.h"\ + ".\ace\Thread_Manager.h"\ + ".\ace\Reactor.h"\ + + +"$(INTDIR)\ACE.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\SOCK.cpp +NODEP_CPP_SOCK_CP=\ + ".\ace\SOCK.h"\ + ".\ace\Log_Msg.h"\ + + +"$(INTDIR)\SOCK.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\FIFO.cpp +NODEP_CPP_FIFO_C=\ + ".\ace\FIFO.h"\ + ".\ace\FIFO.i"\ + + +"$(INTDIR)\FIFO.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Proactor.cpp +NODEP_CPP_PROAC=\ + ".\ace\Proactor.h"\ + ".\ace\Proactor.i"\ + + +"$(INTDIR)\Proactor.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\ReactorEx.cpp +NODEP_CPP_REACTO=\ + ".\ace\ReactorEx.h"\ + ".\ace\ReactorEx.i"\ + + +"$(INTDIR)\ReactorEx.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Token_Invariants.cpp +NODEP_CPP_TOKEN_I=\ + ".\ace\Log_Msg.h"\ + ".\ace\Token_Invariants.h"\ + ".\ace\Token_Invariants.i"\ + + +"$(INTDIR)\Token_Invariants.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Process.cpp +NODEP_CPP_PROCES=\ + ".\ace\Process.h"\ + ".\ace\Process.i"\ + + +"$(INTDIR)\Process.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\TTY_IO.cpp +NODEP_CPP_TTY_I=\ + ".\ace\TTY_IO.h"\ + + +"$(INTDIR)\TTY_IO.obj" : $(SOURCE) "$(INTDIR)" + + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/ace/ace.mdp b/ace/ace.mdp new file mode 100644 index 00000000000..ffa58663909 Binary files /dev/null and b/ace/ace.mdp differ diff --git a/ace/config-aix-3.2.5.h b/ace/config-aix-3.2.5.h new file mode 100644 index 00000000000..bdf3593f176 --- /dev/null +++ b/ace/config-aix-3.2.5.h @@ -0,0 +1,47 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for AIX 3.2.5 +// with xlC. Thanks to Bob Olson for this. + +/*#define ACE_HAS_PTHREADS*/ + +#define MAXNAMELEN 1024 + +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +#define ACE_HAS_TEMPLATE_TYPEDEFS + +#define ACE_HAS_STRERROR + +#define ACE_HAS_SIG_ATOMIC_T + +#define ACE_HAS_SSIZE_T + +#define ACE_HAS_CPLUSPLUS_HEADERS + +#define ACE_HAS_POLL + +#define ACE_HAS_POSIX_NONBLOCK + +#define ACE_HAS_AIX_GETTIMEOFDAY + +#define ACE_HAS_NO_SYSCALL_H + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Compiler/platform uses old malloc()/free() prototypes (ugh). +#define ACE_HAS_OLD_MALLOC + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Compiler/platform supports struct strbuf +#define ACE_HAS_STRBUF_T + +// Platform supports STREAMS. +/*#define ACE_HAS_STREAMS*/ diff --git a/ace/config-aix-4.1.x.h b/ace/config-aix-4.1.x.h new file mode 100644 index 00000000000..0f27126b334 --- /dev/null +++ b/ace/config-aix-4.1.x.h @@ -0,0 +1,105 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for HP +// platforms running AIX 4.1.x. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +// Compiling for AIX. +#define AIX +#define _BSD 43 +#define ACE_HAS_UNION_WAIT +#define ACE_HAS_MULTICAST +#define ACE_HAS_TID_T +#define ACE_HAS_SIGWAIT +#define ACE_HAS_H_ERRNO +#define ACE_LACKS_THREAD_PROCESS_SCOPING +#define ACE_LACKS_THREAD_STACK_ADDR +#define ACE_LACKS_CONDATTR_PSHARED +#define ACE_HAS_SIN_LEN +#define ACE_HAS_SYSV_IPC +#define ACE_HAS_STRUCT_NETDB_DATA +#define ACE_HAS_ALLOCA +#define ACE_HAS_REENTRANT_FUNCTIONS +#define ACE_HAS_SYSV_IPC +#define ACE_HAS_TLI +#define ACE_HAS_TLI_PROTOTYPES +#define ACE_HAS_TIUSER_H +#define ACE_TEMPLATES_REQUIRE_PRAGMA +#define ACE_HAS_THREAD_SPECIFIC_STORAGE +#define ACE_HAS_AUTOMATIC_INIT_FINI +#define ACE_HAS_CHARPTR_DL +#define ACE_HAS_SVR4_DYNAMIC_LINKING +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_SVR4_TIME +#define ACE_HAS_THREADS +#define ACE_MT_SAFE +#define ACE_HAS_UTIME +#define ACE_HAS_SELECT_H + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// This environment requires this thing +#define _BSD_INCLUDES +#define COMPAT_43 + +// Compiler supports the getrusage() system call +#define ACE_HAS_GETRUSAGE + +// Prototypes for both signal() and struct sigaction are consistent. +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Compiler/platform supports poll(). +#define ACE_HAS_POLL + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform defines the sig_atomic_t typedef +#define ACE_HAS_SIG_ATOMIC_T + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Compiler supports stropts.h +#define ACE_HAS_STREAMS +// #define ACE_HAS_STREAM_PIPES + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// EYE the include file is there + +// AIX bzero() +#define ACE_HAS_STRINGS + +// ??? has the berkeley stuff +// #define ACE_HAS_SUNOS4_GETTIMEOFDAY +#define ACE_HAS_SVR4_GETTIMEOFDAY + +// Note, this only works if the flag is set above! +#define ACE_HAS_GETRUSAGE + +// EYE assume it does for now. +#define ACE_HAS_DCETHREADS +#define ACE_PTHREADS_MAP + +// include there +#define ACE_HAS_TIMOD_H +#define ACE_HAS_TIUSER_H + +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ +#define ACE_HAS_STRBUF_T + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-hpux-10.x-g++.h b/ace/config-hpux-10.x-g++.h new file mode 100644 index 00000000000..2930a01a058 --- /dev/null +++ b/ace/config-hpux-10.x-g++.h @@ -0,0 +1,99 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for HP +// platforms running HP/UX 10.x using G++. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +// Compiling for HPUX. +#if !defined (HPUX) +#define HPUX +#endif /* HPUX */ + +// Compiler's template mechanism must see source code (i.e., .C files). +#define ACE_TEMPLATES_REQUIRE_SOURCE +// Compiler doesn't support static data member templates. +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES +// Must specialize templates due to G++'s lame parameterized type +// support... I added this Afara +#define ACE_TEMPLATES_REQUIRE_SPECIALIZATION + +#define ACE_LACKS_SYSCALL +#define ACE_LACKS_STRRECVFD +#define ACE_HAS_POSIX_TIME + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Fixes a problem with HP/UX not wrapping the mmap(2) header files +// with extern "C". +#define ACE_HAS_BROKEN_MMAP_H + +// Prototypes for both signal() and struct sigaction are consistent. +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Header files lack t_errno for ACE_TLI. +#define ACE_LACKS_T_ERRNO + +// Compiler/platform supports poll(). +#define ACE_HAS_POLL + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform defines the sig_atomic_t typedef +#define ACE_HAS_SIG_ATOMIC_T + +// ACE supports POSIX Pthreads. +//#define ACE_HAS_DCETHREADS //changed by Afara 09/24/96 + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// ??? +#define ACE_HAS_SUNOS4_GETTIMEOFDAY + +// HP/UX has an undefined syscall for GETRUSAGE... +#define ACE_HAS_SYSCALL_GETRUSAGE + +// Note, this only works if the flag is set above! +#define ACE_HAS_GETRUSAGE + +// Platform uses int for select() rather than fd_set. +#define ACE_SELECT_USES_INT + +// Platform has the XLI version of ACE_TLI. +// #define ACE_HAS_XLI + +// Platform supports ACE_TLI tiuser header. +#define ACE_HAS_TIUSER_H + +// Platform provides ACE_TLI function prototypes. +#define ACE_HAS_TLI_PROTOTYPES + +// Platform supports ACE_TLI. +#define ACE_HAS_TLI + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-hpux-10.x.h b/ace/config-hpux-10.x.h new file mode 100644 index 00000000000..cdfad30891e --- /dev/null +++ b/ace/config-hpux-10.x.h @@ -0,0 +1,110 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for HP +// platforms running HP/UX 10.x. For using HP C++ compiler with +// templates you should have patch PHSS_6246. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +// Compiling for HPUX. +#if !defined (HPUX) +#define HPUX +#endif /* HPUX */ + +#define _HPUX_SOURCE +#include +#include // pthread.h doesn't include this + +#define ACE_LACKS_SYSCALL +#define ACE_HAS_POSIX_TIME + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Fixes a problem with HP/UX not wrapping the mmap(2) header files +// with extern "C". +#define ACE_HAS_BROKEN_MMAP_H + +// Prototypes for both signal() and struct sigaction are consistent. +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Header files lack t_errno for ACE_TLI. +#define ACE_LACKS_T_ERRNO + +// Compiler/platform supports poll(). +#define ACE_HAS_POLL + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform defines the sig_atomic_t typedef +#define ACE_HAS_SIG_ATOMIC_T + +#define ACE_HAS_THREADS +#define ACE_HAS_PTHREADS +#define ACE_MT_SAFE +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_SETKIND_NP +#define ACE_LACKS_CONDATTR_PSHARED +#define ACE_LACKS_SI_ADDR +#define ACE_LACKS_SETDETACH // new +#define ACE_LACKS_KEYDELETE // new +#define ACE_LACKS_THREAD_PROCESS_SCOPING +#define ACE_LACKS_THREAD_STACK_ADDR + +// Compiler/platform has thread-specific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// ??? +#define ACE_HAS_SUNOS4_GETTIMEOFDAY + +// HP/UX has an undefined syscall for GETRUSAGE... +#define ACE_HAS_SYSCALL_GETRUSAGE + +// Note, this only works if the flag is set above! +#define ACE_HAS_GETRUSAGE + +// Platform uses int for select() rather than fd_set. +#define ACE_SELECT_USES_INT + +// Platform has the XLI version of ACE_TLI. +// #define ACE_HAS_XLI + +// Platform supports ACE_TLI tiuser header. +#define ACE_HAS_TIUSER_H + +// Platform provides ACE_TLI function prototypes. +#define ACE_HAS_TLI_PROTOTYPES + +// Platform supports ACE_TLI. +#define ACE_HAS_TLI + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-hpux-9.x-orbix.h b/ace/config-hpux-9.x-orbix.h new file mode 100644 index 00000000000..0cf71f2f3ee --- /dev/null +++ b/ace/config-hpux-9.x-orbix.h @@ -0,0 +1,89 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for HP +// platforms running HP/UX 9.x. Dave added Orbix stuff + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +// Compiling for HPUX. +#if !defined (HPUX) +#define HPUX +#endif /* HPUX */ + +// ************* HERE IS THE ORBIX STUFF - Dave 4/2/96 +#define ACE_HAS_ORBIX + +#define ACE_LACKS_SYSCALL +#define ACE_LACKS_STRRECVFD + +// Compiler doesn't support static data member templates. +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Fixes a problem with HP/UX not wrapping the mmap(2) header files +// with extern "C". +#define ACE_HAS_BROKEN_MMAP_H + +// Prototypes for both signal() and struct sigaction are consistent. +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Header files lack t_errno for ACE_TLI. +#define ACE_LACKS_T_ERRNO + +// Compiler/platform supports poll(). +#define ACE_HAS_POLL + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform defines the sig_atomic_t typedef +#define ACE_HAS_SIG_ATOMIC_T + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// ??? +#define ACE_HAS_SUNOS4_GETTIMEOFDAY + +// HP/UX has an undefined syscall for GETRUSAGE... +#define ACE_HAS_SYSCALL_GETRUSAGE + +// Note, this only works if the flag is set above! +#define ACE_HAS_GETRUSAGE + +// Platform uses int for select() rather than fd_set. +// Dave 4/2/96 took this out. It appears that HP -can- use fd_set for int +// But time.h has a prototype defined so that int must be used ! so it goes +// back in +#define ACE_SELECT_USES_INT + +// Platform has prototypes for ACE_TLI. +//#define ACE_HAS_TLI_PROTOTYPES +// Platform has the XLI version of ACE_TLI. +// #define ACE_HAS_XLI + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-hpux-9.x.h b/ace/config-hpux-9.x.h new file mode 100644 index 00000000000..57a90f3cb59 --- /dev/null +++ b/ace/config-hpux-9.x.h @@ -0,0 +1,83 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work +// for HP platforms running HP/UX 9.x. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +// Compiling for HPUX. +#if !defined (HPUX) +#define HPUX +#endif /* HPUX */ + +#define ACE_LACKS_SYSCALL +#define ACE_LACKS_STRRECVFD + +// Compiler doesn't support static data member templates. +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Fixes a problem with HP/UX not wrapping the mmap(2) header files +// with extern "C". +#define ACE_HAS_BROKEN_MMAP_H + +// Prototypes for both signal() and struct sigaction are consistent. +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Header files lack t_errno for ACE_TLI. +#define ACE_LACKS_T_ERRNO + +// Compiler/platform supports poll(). +#define ACE_HAS_POLL + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform defines the sig_atomic_t typedef +#define ACE_HAS_SIG_ATOMIC_T + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// ??? +#define ACE_HAS_SUNOS4_GETTIMEOFDAY + +// HP/UX has an undefined syscall for GETRUSAGE... +#define ACE_HAS_SYSCALL_GETRUSAGE + +// Note, this only works if the flag is set above! +#define ACE_HAS_GETRUSAGE + +// Platform uses int for select() rather than fd_set. +#define ACE_SELECT_USES_INT + +// Platform has prototypes for ACE_TLI. +//#define ACE_HAS_TLI_PROTOTYPES +// Platform has the XLI version of ACE_TLI. +// #define ACE_HAS_XLI + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-irix5.2.h b/ace/config-irix5.2.h new file mode 100644 index 00000000000..3b729019f05 --- /dev/null +++ b/ace/config-irix5.2.h @@ -0,0 +1,62 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for the SGI +// Indigo2EX running Irix 5.2 platform using the gcc v2.6.x compiler +// and libg++ v2.6.x. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +// Platform supports STREAM pipes (note that this is disabled by +// default, see the manual page on pipe(2) to find out how to enable +// it). +//#define ACE_HAS_STREAM_PIPES + +#define ACE_HAS_SIGWAIT + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Platform requires void * for mmap(). +#define ACE_HAS_VOIDPTR_MMAP + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +#define IRIX5 +#define ACE_HAS_ALLOCA +// Compiler/platform has +#define ACE_HAS_ALLOCA_H +#define ACE_HAS_BSTRING +#define ACE_HAS_GETRUSAGE +#define ACE_HAS_POSIX_NONBLOCK +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_SVR4_TIME +#define ACE_HAS_CPLUSPLUS_HEADERS +#define ACE_HAS_POLL +#define ACE_HAS_PROC_FS +#define ACE_HAS_RTLD_LAZY_V +#define ACE_HAS_SIG_ATOMIC_T +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T +#define ACE_HAS_STREAMS +#define ACE_HAS_SSIZE_T +#define ACE_HAS_STRERROR +#define ACE_HAS_STRBUF_T +#define ACE_HAS_SVR4_DYNAMIC_LINKING +#define ACE_HAS_SVR4_SIGNAL_T +#define ACE_HAS_SYS_SIGLIST +#define ACE_HAS_SYS_FILIO_H +#define ACE_HAS_SEMUN +#define ACE_PAGE_SIZE 4096 + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-irix5.3-g++.h b/ace/config-irix5.3-g++.h new file mode 100644 index 00000000000..7c23f36a848 --- /dev/null +++ b/ace/config-irix5.3-g++.h @@ -0,0 +1,121 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for the SGI +// Indigo2EX running Irix 5.3 platform using the GNU C++ Compiler + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +#define IRIX5 +#define ACE_HAS_SIGWAIT + +#define ACE_TEMPLATES_REQUIRE_SOURCE + +#define ACE_TEMPLATES_REQUIRE_SPECIALIZATION + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Platform requires void * for mmap(). +#define ACE_HAS_VOIDPTR_MMAP + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Compiler/platform supports alloca() +#define ACE_HAS_ALLOCA + +// Compiler/platform has +#define ACE_HAS_ALLOCA_H + +// IRIX5 needs to define bzero() in this odd file +#define ACE_HAS_BSTRING + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Denotes that IRIX 5.3 has second argument to gettimeofday() +// which is variable ... +#define ACE_HAS_IRIX_GETTIMEOFDAY + +// Denotes that GNU has cstring.h as standard +// which redefines memchr() +#define ACE_HAS_GNU_CSTRING_H + +// Compiler doesn't support static data member templates. +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Platform supports POSIX timers via timestruc_t. +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_SVR4_TIME + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Platform contains . +#define ACE_HAS_POLL + +// Platform supports the /proc file system. +#define ACE_HAS_PROC_FS + +// Explicit dynamic linking permits "lazy" symbol resolution. +#define ACE_HAS_RTLD_LAZY_V + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Platform supports SVR4 extended signals. +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Platform supports STREAM pipes (note that this is disabled by +// default, see the manual page on pipe(2) to find out how to enable +// it). +// #define ACE_HAS_STREAM_PIPES + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Compiler/platform supports SVR4 signal typedef. +#define ACE_HAS_IRIX_53_SIGNALS + +// Compiler/platform supports sys_siglist array. +#define ACE_HAS_SYS_SIGLIST + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Compiler/platform defines a union semun for SysV shared memory. +#define ACE_HAS_SEMUN + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-irix5.3-sgic++.h b/ace/config-irix5.3-sgic++.h new file mode 100644 index 00000000000..2a4781e320e --- /dev/null +++ b/ace/config-irix5.3-sgic++.h @@ -0,0 +1,118 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work +// for the SGI Indigo2EX running Irix 5.3 platform using +// the SGI C++ Compiler. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +#define IRIX5 + +#define ACE_NEEDS_SYSTIME_H +#define ACE_HAS_SIGWAIT + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Platform requires void * for mmap(). +#define ACE_HAS_VOIDPTR_MMAP + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Compiler/platform supports alloca() +#define ACE_HAS_ALLOCA + +// Compiler/platform has +#define ACE_HAS_ALLOCA_H + +// IRIX5 needs to define bzero() in this odd file +#define ACE_HAS_BSTRING + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Denotes that IRIX 5.3 has second argument to gettimeofday() +// which is variable ... +#define ACE_HAS_IRIX_GETTIMEOFDAY + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Platform supports POSIX timers via timestruc_t. +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_SVR4_TIME + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Platform contains . +#define ACE_HAS_POLL + +// No multi-threading so use poll() call +// - for easier debugging, if nothing else +// #define ACE_USE_POLL + +// Platform supports the /proc file system. +#define ACE_HAS_PROC_FS + +// Explicit dynamic linking permits "lazy" symbol resolution. +#define ACE_HAS_RTLD_LAZY_V + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Platform supports SVR4 extended signals. +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Platform supports STREAM pipes (note that this is disabled by +// default, see the manual page on pipe(2) to find out how to enable +// it). +// #define ACE_HAS_STREAM_PIPES + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Compiler/platform supports SVR4 signal typedef. +#define ACE_HAS_IRIX_53_SIGNALS + +// Compiler/platform supports sys_siglist array. +#define ACE_HAS_SYS_SIGLIST + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Compiler/platform defines a union semun for SysV shared memory. +#define ACE_HAS_SEMUN + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-irix6.2-sgic++.h b/ace/config-irix6.2-sgic++.h new file mode 100644 index 00000000000..8c065491dd3 --- /dev/null +++ b/ace/config-irix6.2-sgic++.h @@ -0,0 +1,151 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for the SGI +// Indigo2EX running IRIX 6.2 platform using the SGI C++ Compiler. +// Please note that the following system patches MUST be applied to +// Irix 6.2 in order to have MT: +// +// patchSG0001361 +// patchSG0001367 +// patchSG0001389 + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +#define ACE_HAS_IRIX62_THREADS + +// Needed for the threading stuff? +#include +#include +#define PTHREAD_MIN_PRIORITY PX_PRIO_MIN +#define PTHREAD_MAX_PRIORITY PX_PRIO_MAX + +// ACE supports threads. +#define ACE_HAS_THREADS + +//Sockets may be called in multi-threaded programs +#define ACE_HAS_MT_SAFE_SOCKETS + +// Compiler/platform has thread-specific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// Compile using multi-thread libraries +#define ACE_MT_SAFE + +// Platform supports the tid_t type (e.g., AIX and Irix 6.2) +#define ACE_HAS_TID_T + +// Platform has no implementation of pthread_condattr_setpshared(), +// even though it supports pthreads! (like Irix 6.2) +#define ACE_LACKS_CONDATTR_PSHARED + +// IRIX 6.2 supports some variant of POSIX Pthreads, is it stock DCE? +#define ACE_HAS_PTHREADS + +// Platform/compiler has the sigwait(2) prototype +#define ACE_HAS_SIGWAIT + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Platform requires void * for mmap(). +#define ACE_HAS_VOIDPTR_MMAP + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Compiler/platform supports alloca() +#define ACE_HAS_ALLOCA + +// Compiler/platform has +#define ACE_HAS_ALLOCA_H + +// Irix needs to define bzero() in this odd file +#define ACE_HAS_BSTRING + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Denotes that Irix has second argument to gettimeofday() which is +// variable (...) +#define ACE_HAS_IRIX_GETTIMEOFDAY + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Platform supports POSIX timers via timestruc_t. +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_SVR4_TIME + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Platform contains . +#define ACE_HAS_POLL + +// No multi-threading so use poll() call +// - for easier debugging, if nothing else +// #define ACE_USE_POLL + +// Platform supports the /proc file system. +#define ACE_HAS_PROC_FS + +// Explicit dynamic linking permits "lazy" symbol resolution. +#define ACE_HAS_RTLD_LAZY_V + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Platform supports SVR4 extended signals. +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Platform supports STREAM pipes (note that this is disabled by +// default, see the manual page on pipe(2) to find out how to enable +// it). +// #define ACE_HAS_STREAM_PIPES + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Prototypes for both signal() and struct sigaction are consistent. +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Compiler/platform supports sys_siglist array. +#define ACE_HAS_SYS_SIGLIST + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Compiler/platform defines a union semun for SysV shared memory. +#define ACE_HAS_SEMUN + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-linux-pthread.h b/ace/config-linux-pthread.h new file mode 100644 index 00000000000..942510e4a17 --- /dev/null +++ b/ace/config-linux-pthread.h @@ -0,0 +1,99 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for Linux +// platforms using GNU C++ and the MIT threads package. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +// Fixes a problem with new versions of Linux... +#ifndef msg_accrights +#undef msg_control +#define msg_accrights msg_control +#endif + +#ifndef msg_accrightslen +#undef msg_controllen +#define msg_accrightslen msg_controllen +#endif + +#define ACE_HAS_POSIX_TIME +#define ACE_LACKS_STRRECVFD + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Platforms lacks UNIX domain sockets. +//#define ACE_LACKS_UNIX_DOMAIN_SOCKETS + +// Compiler/platform supports alloca(). +#define ACE_HAS_ALLOCA + +//#define ACE_LACKS_SENDMSG +//#define ACE_LACKS_RECVMSG +#define ACE_LACKS_MSYNC +#define ACE_LACKS_MADVISE + +// Compiler/platform has +#define ACE_HAS_ALLOCA_H + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Compiler/platform supports sys_siglist array. +#define ACE_HAS_SYS_SIGLIST + +// Compiler/platform defines a union semun for SysV shared memory. +#define ACE_HAS_SEMUN + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +#define ACE_HAS_SUNOS4_GETTIMEOFDAY +#define LINUX 1.2.10 + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +// Linux defines struct msghdr in /usr/include/socket.h +#define ACE_HAS_MSG + +// TDN - adapted from file for SunOS4 platforms using the GNU g++ compiler +// Compiler's template mechanism must see source code (i.e., .C files). +#define ACE_TEMPLATES_REQUIRE_SOURCE + +#define ACE_TEMPLATES_REQUIRE_SPECIALIZATION + +// Compiler doesn't support static data member templates. +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES + +// Yes, we do have threads. +#define ACE_HAS_THREADS +// And they're even POSIX pthreads (MIT implementation) +#define ACE_HAS_PTHREADS +#define ACE_HAS_SIGWAIT +#define ACE_LACKS_CONDATTR_PSHARED + +// To use pthreads on Linux you'll need to use the MIT version, for +// now... +#define _MIT_POSIX_THREADS 1 +#include + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-linux.h b/ace/config-linux.h new file mode 100644 index 00000000000..fb4d787fc47 --- /dev/null +++ b/ace/config-linux.h @@ -0,0 +1,91 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for Linux +// platforms using GNU C++. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +// Do we really need this #define here? +#define LINUX 1.2.10 + +// Fixes a problem with new versions of Linux... +#ifndef msg_accrights +#undef msg_control +#define msg_accrights msg_control +#endif + +#ifndef msg_accrightslen +#undef msg_controllen +#define msg_accrightslen msg_controllen +#endif + +// You may need to undefine these for older versions of Linux. +//#define ACE_LACKS_SENDMSG +//#define ACE_LACKS_RECVMSG + +#define ACE_HAS_POSIX_TIME +#define ACE_LACKS_STRRECVFD + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Platforms lacks UNIX domain sockets. +//#define ACE_LACKS_UNIX_DOMAIN_SOCKETS + +// Compiler/platform supports alloca(). +#define ACE_HAS_ALLOCA + +#define ACE_LACKS_MSYNC +#define ACE_LACKS_MADVISE + +// Compiler/platform has +#define ACE_HAS_ALLOCA_H + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Compiler/platform supports sys_siglist array. +#define ACE_HAS_SYS_SIGLIST + +// Compiler/platform defines a union semun for SysV shared memory. +#define ACE_HAS_SEMUN + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +#define ACE_HAS_SUNOS4_GETTIMEOFDAY + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +// Linux defines struct msghdr in /usr/include/socket.h +#define ACE_HAS_MSG + +// TDN - adapted from file for SunOS4 platforms using the GNU g++ compiler +// Compiler's template mechanism must see source code (i.e., .C files). +#define ACE_TEMPLATES_REQUIRE_SOURCE + +#define ACE_TEMPLATES_REQUIRE_SPECIALIZATION + +// Compiler doesn't support static data member templates. +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-m88k.h b/ace/config-m88k.h new file mode 100644 index 00000000000..f2c2222a17c --- /dev/null +++ b/ace/config-m88k.h @@ -0,0 +1,223 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for Motorolla 88k SVR4 platforms +// using pthreads from Florida State (ACE_HAS_FSU_PTHREADS) + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +#if !defined (m88k) +#define m88k +#endif + +extern "C" void pthread_init(); + +#define PTHREAD_STACK_MIN 1024 + +#if !defined (IP_ADD_MEMBERSHIP) +#define IP_ADD_MEMBERSHIP 0x13 +#endif // m88k + +#if !defined (IP_DROP_MEMBERSHIP) +#define IP_DROP_MEMBERSHIP 0x14 +#endif // m88k + +struct sched_param +{ + int sched_priority; + int prio; +}; + +// This seems to be necessary for m88k. +struct ip_mreq +{ + struct in_addr imr_multiaddr; // IP multicast address of the group + struct in_addr imr_interface; // local IP address of the interface +}; + +#if !defined (ACE_HAS_FSU_PTHREADS) +#define ACE_HAS_FSU_PTHREADS +#endif + +// Added for compilation on the m88k +#if defined (m88k) +#define ACE_LACKS_T_ERRNO +#define ACE_LACKS_MADVISE +#define ACE_HAS_GNU_CSTRING_H +#define ACE_TEMPLATES_REQUIRE_SOURCE +#define ACE_TEMPLATES_REQUIRE_SPECIALIZATION +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES +#endif // m88k + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Sun has the wrong prototype for sendmsg. +#define ACE_HAS_BROKEN_SENDMSG + +// The SunOS 5.x version of rand_r is inconsistent with the header files... +#define ACE_HAS_BROKEN_RANDR + +// Platform supports system configuration information. +#define ACE_HAS_SYSINFO + +// Platform supports the POSIX regular expression library. +#define ACE_HAS_REGEX + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +#if !defined (ACE_HAS_FSU_PTHREADS) +// Platform supports reentrant functions (i.e., all the POSIX *_r functions). +#define ACE_HAS_REENTRANT_FUNCTIONS +#endif // ACE_HAS_FSU_PTHREADS + +// Platform has terminal ioctl flags like TCGETS and TCSETS. +#define ACE_HAS_TERM_IOCTLS + +// Compiler/platform correctly calls init()/fini() for shared libraries. +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +#if !defined (m88k) +// Compiler/platform supports SunOS high resolution timers. +#define ACE_HAS_HI_RES_TIMER +#endif // m88k + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Compiler/platform supports the "long long" datatype. +#define ACE_HAS_LONGLONG_T + +// Compiler/platform supports alloca() +#define ACE_HAS_ALLOCA + +#if !defined (m88k) +// Compiler/platform has +#define ACE_HAS_ALLOCA_H +#endif // m88k + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Platform contains . +#define ACE_HAS_POLL + +// Platform supports POSIX timers via timestruc_t. +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_SVR4_TIME + +// Platform supports the /proc file system. +#define ACE_HAS_PROC_FS + +#if !defined (m88k) +// Platform supports the prusage_t struct. +#define ACE_HAS_PRUSAGE_T +#endif // m88k + +// Explicit dynamic linking permits "lazy" symbol resolution. +#define ACE_HAS_RTLD_LAZY_V + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Platform supports SVR4 extended signals. +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SOCKIO_H + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Platform supports STREAM pipes. +#define ACE_HAS_STREAM_PIPES + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Compiler/platform supports SVR4 gettimeofday() prototype. +#define ACE_HAS_SVR4_GETTIMEOFDAY + +// Compiler/platform supports SVR4 signal typedef. +#define ACE_HAS_SVR4_SIGNAL_T + +// Compiler/platform supports SVR4 ACE_TLI (in particular, T_GETNAME stuff)... +#define ACE_HAS_SVR4_TLI + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +#if !defined (m88k) +// Compiler/platform supports sys_siglist array. +#define ACE_HAS_SYS_SIGLIST +#endif // m88k + +/* Turn off the following four defines if you want to disable threading. */ +// Compile using multi-thread libraries. +#define ACE_MT_SAFE + +#if !defined (m88k) +// Platform supports Solaris threads. +#define ACE_HAS_STHREADS +#else +#define ACE_HAS_PTHREADS +#endif // m88k + +// Platform supports threads. +#define ACE_HAS_THREADS + +#if defined (ACE_HAS_FSU_PTHREADS) +#define ACE_LACKS_THREAD_STACK_ADDR +#endif // ACE_HAS_FSU_PTHREADS + +// Compiler/platform has thread-specific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// Reactor detects deadlock +// #define ACE_REACTOR_HAS_DEADLOCK_DETECTION + +// Platform supports ACE_TLI timod STREAMS module. +#define ACE_HAS_TIMOD_H + +// Platform supports ACE_TLI tiuser header. +#define ACE_HAS_TIUSER_H + +// Platform provides ACE_TLI function prototypes. +#define ACE_HAS_TLI_PROTOTYPES + +// Platform supports ACE_TLI. +#define ACE_HAS_TLI + +// Use the poll() event demultiplexor rather than select(). +//#define ACE_USE_POLL + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-osf1-3.2.h b/ace/config-osf1-3.2.h new file mode 100644 index 00000000000..2bb2ba7ee0a --- /dev/null +++ b/ace/config-osf1-3.2.h @@ -0,0 +1,165 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for OSF1 3.2 +// platforms with the DEC 5.1 C++ compiler. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +#define ACE_HAS_PTHREAD_MUTEXATTR_CREATE +#define ACE_HAS_PTHREAD_MUTEXATTR_DELETE + +#define ACE_HAS_BROKEN_MSG_H +#define ACE_LACKS_SYSV_MSQ_PROTOS + +// Platform supports +#define ACE_HAS_PROC_FS + +// Platform supports tid_t +#define ACE_HAS_TID_T + +// Platform lacks support for shared condition variables +#define ACE_LACKS_CONDATTR_PSHARED + +// Platform lacks support for stack address information +#define ACE_LACKS_THREAD_STACK_ADDR + +// Platform lacks thread process scoping +#define ACE_LACKS_THREAD_PROCESS_SCOPING + +// Platform has non-POSIX setkind and other functions. +#define ACE_HAS_SETKIND_NP +#define ACE_HAS_PTHREAD_T + +// Platform defines MAP_FAILED as a long constant. +#define ACE_HAS_LONG_MAP_FAILED + +// Platform's implementation of sendmsg() has a non-const msgheader parameter. +#define ACE_HAS_BROKEN_SENDMSG + +// Platform's implementation of writev() has a non-const iovec parameter. +#define ACE_HAS_BROKEN_WRITEV + +// Platform's implementation of setlrmit() has a non-const rlimit parameter. +#define ACE_HAS_BROKEN_SETRLIMIT + +// Compiler has integer overflow problem with bit-shift operations. +#define ACE_HAS_BROKEN_BITSHIFT + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Compiler/platform correctly calls init()/fini(). +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// Prototypes for both signal() and struct sigaction are consistent. +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// ACE has no mktemp(). +#define ACE_LACKS_MKTEMP + +// Compiler/platform has thread-specific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// Platform supports C++ headers +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Platform supports the OSF ACE_TLI timod STREAMS module. +#define ACE_HAS_OSF_TIMOD_H + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Platform contains . +#define ACE_HAS_POLL + +// Platform supports POSIX timers via timestruc_t. +#define ACE_HAS_POSIX_TIME + +// Platform defines struct timespec in +#define ACE_HAS_BROKEN_POSIX_TIME +// #define ACE_HAS_SVR4_TIME + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// ACE supports POSIX Pthreads. +#define ACE_HAS_DCETHREADS + +// Explicit dynamic linking permits "lazy" symbol resolution +#define ACE_HAS_RTLD_LAZY_V + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Added 6/13/95, 1 line +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T + +// Compiler/platform has ssize_t. +#define ACE_HAS_SSIZE_T + +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Platform has 64bit longs and 32bit ints... +#define ACE_HAS_64BIT_LONGS + +// Platform supports STREAM pipes. +// #define ACE_HAS_STREAM_PIPES + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Platform support OSF1 gettimeofday +#define ACE_HAS_OSF1_GETTIMEOFDAY + +// Compiler/platform supports SVR4 signal typedef. +#define ACE_HAS_SVR4_SIGNAL_T + +// Compiler/platform has strerror(). +#define ACE_HAS_STRERROR + +// ACE supports threads. +#define ACE_HAS_THREADS + +// Platform supports ACE_TLI tiuser header. +#define ACE_HAS_TIUSER_H + +// Platform supports ACE_TLI timod STREAMS module. +// #define ACE_HAS_TIMOD_H + +// Platform provides ACE_TLI function prototypes. +#define ACE_HAS_TLI_PROTOTYPES + +// Platform supports ACE_TLI. +#define ACE_HAS_TLI + +// Compile using multi-thread libraries. +#define ACE_MT_SAFE + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-osf1-4.0.h b/ace/config-osf1-4.0.h new file mode 100644 index 00000000000..784a8673e2f --- /dev/null +++ b/ace/config-osf1-4.0.h @@ -0,0 +1,182 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for the +// Digital UNIX V4.0 platforms with the DEC 5.4 C++ compiler. It is +// configured to use the IEEE Std 1003.1c-1995, POSIX System +// Application Program Interface. An early release Digital UNIX V4.0 +// was used for porting so additional minor changes may be required. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +// DJT removed this due to some minor issues related to the +// definitions of timestruc_t and tid_t in procfs.h not sure what +// functionality is lost? Platform supports +//#define ACE_HAS_PROC_FS + +// Platform defines MAP_FAILED as a long constant. +#define ACE_HAS_LONG_MAP_FAILED + +// DJT 6/10/96 All these broken macro's can now be removed with the +// approporiate ordering of the include files. The Platinum release +// now temporarily supports both forms. Platform's implementation of +// sendmsg() has a non-const msgheader parameter. +#define ACE_HAS_BROKEN_SENDMSG + +// Platform's implementation of writev() has a non-const iovec +// parameter. +#define ACE_HAS_BROKEN_WRITEV + +// Platform's implementation of setlrmit() has a non-const rlimit +// parameter. +#define ACE_HAS_BROKEN_SETRLIMIT + +// Platform supports System V IPC (most versions of UNIX, but not +// Win32) +#define ACE_HAS_SYSV_IPC + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Compiler/platform correctly calls init()/fini(). +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// Prototypes for both signal() and struct sigaction are consistent. +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// ACE has no mktemp(). +//#define ACE_LACKS_MKTEMP + +// Compiler/platform has thread-specific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// Platform supports C++ headers +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Platform supports the OSF ACE_TLI timod STREAMS module. +#define ACE_HAS_OSF_TIMOD_H + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Platform contains . +#define ACE_HAS_POLL + +// Platform supports POSIX timers via timestruc_t. +#define ACE_HAS_POSIX_TIME + +// Platform defines struct timespec in +// #define ACE_HAS_BROKEN_POSIX_TIME +// DJT added 6/5/96 +// #define ACE_HAS_SVR4_TIME +//#define ACE_HAS_SVR4_TIME + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// DJT modified 6/5/96 +// ACE supports POSIX Pthreads. +//#define ACE_HAS_DCETHREADS +#define ACE_HAS_PTHREADS +// DJT 6/6/96 added +// IEEE Std 1003.1c-1995, POSIX System Application Program Interface +#define ACE_HAS_PTHREADS_1003_DOT_1C + +// Explicit dynamic linking permits "lazy" symbol resolution +#define ACE_HAS_RTLD_LAZY_V + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Added 6/13/95, 1 line +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T + +// DJT added 6/7/96 +#define ACE_HAS_SIGWAIT + +// Compiler/platform has ssize_t. +#define ACE_HAS_SSIZE_T + +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Platform has 64bit longs and 32bit ints... +#define ACE_HAS_64BIT_LONGS + +// Platform supports STREAM pipes. +// #define ACE_HAS_STREAM_PIPES + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Platform support OSF1 gettimeofday +#define ACE_HAS_OSF1_GETTIMEOFDAY + +// Compiler/platform supports SVR4 signal typedef. +#define ACE_HAS_SVR4_SIGNAL_T + +// Compiler/platform has strerror(). +#define ACE_HAS_STRERROR + +// ACE supports threads. +#define ACE_HAS_THREADS + +// DJT modified 6/5/96 +// Platform defines the tid_t structure. +//#define ACE_HAS_TID_T + +// Platform supports ACE_TLI tiuser header. +#define ACE_HAS_TIUSER_H + +// Platform supports ACE_TLI timod STREAMS module. +// #define ACE_HAS_TIMOD_H + +// Platform provides ACE_TLI function prototypes. +#define ACE_HAS_TLI_PROTOTYPES + +// Platform supports ACE_TLI. +#define ACE_HAS_TLI + +// DJT added 6/6/96 +#define ACE_LACKS_CONDATTR_PSHARED + +// DJT added 6/7/96 +#define ACE_LACKS_THREAD_STACK_ADDR + +// DJT added 7/10/96 +#define ACE_LACKS_THREAD_PROCESS_SCOPING + +// Compile using multi-thread libraries. +#define ACE_MT_SAFE + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +// DJT modified 6/5/96 +// Defines the page size of the system. +//#define ACE_PAGE_SIZE 4096 +#define ACE_PAGE_SIZE 8192 + +// DJT added 6/6/96 +// uses ctime_r & asctime_r with only two parameters vs. three +#define ACE_HAS_ONLY_TWO_PARAMS_FOR_ASCTIME_R_AND_CTIME_R + +#define ACE_HAS_BROKEN_IF_HEADER + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-sco-4.2-nothread.h b/ace/config-sco-4.2-nothread.h new file mode 100644 index 00000000000..428f601493e --- /dev/null +++ b/ace/config-sco-4.2-nothread.h @@ -0,0 +1,105 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work +// for HP platforms running HP/UX 9.x. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +// Compiling for SCO. +#if !defined (SCO) +#define SCO +#endif /* SCO */ + +#if defined (SCO) && !defined (MAXPATHLEN) +#define MAXPATHLEN 1023 +#endif /* SCO */ + +#define ACE_TEMPLATES_REQUIRE_SOURCE +#define ACE_TEMPLATES_REQUIRE_SPECIALIZATION +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES + +#define ACE_LACKS_UNIX_DOMAIN_SOCKETS +#define ACE_LACKS_SYSCALL +#define ACE_LACKS_STRRECVFD +#define ACE_LACKS_MMAP +#define ACE_LACKS_SOCKETPAIR +#define ACE_HAS_SEMUN +#define ACE_LACKS_MSYNC +#define ACE_LACKS_MADVISE +#define ACE_NEEDS_WRITEV +#define ACE_NEEDS_READV +#define ACE_NEEDS_FTRUNCATE +#define ACE_LACKS_RLIMIT +#define ACE_LACKS_RECVMSG +#define ACE_LACKS_SENDMSG + +// Compiler doesn't support static data member templates. +//#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Platform supports recvmsg and sendmsg. +//#define ACE_HAS_MSG + +// Compiler/platform contains the file. +//#define ACE_HAS_SYSCALL_H + +// Fixes a problem with HP/UX not wrapping the mmap(2) header files +// with extern "C". +//#define ACE_HAS_BROKEN_MMAP_H + +// Prototypes for both signal() and struct sigaction are consistent. +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Header files lack t_errno for ACE_TLI. +//#define ACE_LACKS_T_ERRNO + +// Compiler/platform supports poll(). +#define ACE_HAS_POLL + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform defines the sig_atomic_t typedef +#define ACE_HAS_SIG_ATOMIC_T + +// Compiler supports the ssize_t typedef. +//#define ACE_HAS_SSIZE_T + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// ??? +#define ACE_HAS_SUNOS4_GETTIMEOFDAY + +// HP/UX has an undefined syscall for GETRUSAGE... +//#define ACE_HAS_SYSCALL_GETRUSAGE + +// Note, this only works if the flag is set above! +//#define ACE_HAS_GETRUSAGE + +// Platform uses int for select() rather than fd_set. +#define ACE_SELECT_USES_INT + +// Platform has prototypes for ACE_TLI. +//#define ACE_HAS_TLI_PROTOTYPES +// Platform has the XLI version of ACE_TLI. +// #define ACE_HAS_XLI + +#define ACE_HAS_GNU_CSTRING_H + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos4-g++.h b/ace/config-sunos4-g++.h new file mode 100644 index 00000000000..e20835a7b3d --- /dev/null +++ b/ace/config-sunos4-g++.h @@ -0,0 +1,94 @@ +/* -*- C++ -*- */ +// $Id$ + +// for SunOS4 platforms using the GNU g++ compiler + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +#define ACE_NEEDS_SYSTIME_H + +// Must specialize templates due to G++'s lame parameterized type +// support... +#define ACE_TEMPLATES_REQUIRE_SPECIALIZATION + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Compiler's template mechanism must see source code (i.e., .C files). +#define ACE_TEMPLATES_REQUIRE_SOURCE + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Compiler/platform supports strerror (). +// #define ACE_HAS_STRERROR +#define ACE_HAS_SYS_ERRLIST + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Header files lack t_errno for ACE_TLI. +// #define ACE_LACKS_T_ERRNO + +// Compiler doesn't support static data member templates. +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES + +// Compiler/platform uses old malloc()/free() prototypes (ugh). +#define ACE_HAS_OLD_MALLOC + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Compiler/platform supports poll(). +#define ACE_HAS_POLL + +// Compiler/platform defines a union semun for SysV shared memory. +#define ACE_HAS_SEMUN + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SOCKIO_H + +// Compiler has system V signals +#define ACE_HAS_SVR4_SIGNAL_T + +// Compiler/platform supports struct strbuf +#define ACE_HAS_STRBUF_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H +// Platform supports ACE_TLI tiuser header. +// #define ACE_HAS_TIUSER_H + +// Platform has ACE_TLI. +// #define ACE_HAS_TLI + +#define ACE_HAS_SUNOS4_SIGNAL_T +#define ACE_HAS_CPLUSPLUS_HEADERS +#define ACE_HAS_RTLD_LAZY_V +#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 6)) +#define ACE_HAS_SYSENT_H +#endif +#define ACE_HAS_ALLOCA +// Compiler/platform has +#define ACE_HAS_ALLOCA_H +#define ACE_HAS_SVR4_GETTIMEOFDAY +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos4-lucid3.2.h b/ace/config-sunos4-lucid3.2.h new file mode 100644 index 00000000000..92438ea3c7d --- /dev/null +++ b/ace/config-sunos4-lucid3.2.h @@ -0,0 +1,83 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work +// for SunOS4 platforms using the Lucid 3.2 compiler. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +#define ACE_HAS_SYS_ERRLIST + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Compiler/platform supports alloca() +#define ACE_HAS_ALLOCA + +// Compiler/platform has +#define ACE_HAS_ALLOCA_H + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Header files lack t_errno for ACE_TLI. +// #define ACE_LACKS_T_ERRNO + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Compiler/platform supports poll(). +#define ACE_HAS_POLL + +// Compiler/platform defines a union semun for SysV shared memory. +#define ACE_HAS_SEMUN + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SOCKIO_H + +// Compiler/platform supports struct strbuf +#define ACE_HAS_STRBUF_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Compiler/platform supports strerror (). +// #define ACE_HAS_STRERROR + +// SunOS 4 style prototype. +#define ACE_HAS_SUNOS4_GETTIMEOFDAY + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Platform provides header. +#define ACE_HAS_SYSENT_H + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Platform supports ACE_TLI tiuser header. +// #define ACE_HAS_TIUSER_H + +// Platform has ACE_TLI. +// #define ACE_HAS_TLI + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos4-sun3.x.h b/ace/config-sunos4-sun3.x.h new file mode 100644 index 00000000000..62e63a6098e --- /dev/null +++ b/ace/config-sunos4-sun3.x.h @@ -0,0 +1,71 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work +// for SunOS4 platforms using the SunC++ 3.0.x compiler. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +#define ACE_HAS_SYS_ERRLIST + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Header files lack t_errno for ACE_TLI. +// #define ACE_LACKS_T_ERRNO + +// Compiler/platform uses old malloc()/free() prototypes (ugh). +#define ACE_HAS_OLD_MALLOC + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Compiler/platform supports poll(). +#define ACE_HAS_POLL + +// Compiler/platform defines a union semun for SysV shared memory. +#define ACE_HAS_SEMUN + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SOCKIO_H + +// Compiler/platform supports struct strbuf +#define ACE_HAS_STRBUF_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// SunOS 4 style prototype. +#define ACE_HAS_SUNOS4_GETTIMEOFDAY + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Platform supports ACE_TLI tiuser header. +// #define ACE_HAS_TIUSER_H + +// Platform has ACE_TLI. +// #define ACE_HAS_TLI + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos4-sun4.1.4.h b/ace/config-sunos4-sun4.1.4.h new file mode 100644 index 00000000000..8e97561bf41 --- /dev/null +++ b/ace/config-sunos4-sun4.1.4.h @@ -0,0 +1,82 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for SunOS4.1.4 +// platforms using the SunC++ 4.x compiler. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +#define ACE_NEEDS_SYSTIME_H + +// Special addition to handle sunOS 4.1 which is unable to +// handle POSIX Prototypes ! +#define ACE_LACKS_POSIX_PROTO + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Compiler/platform supports strerror (). +// #define ACE_HAS_STRERROR +#define ACE_HAS_SYS_ERRLIST + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Header files lack t_errno for ACE_TLI. +// #define ACE_LACKS_T_ERRNO + +// Compiler/platform uses old malloc()/free() prototypes (ugh). +#define ACE_HAS_OLD_MALLOC + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Compiler/platform supports poll(). +#define ACE_HAS_POLL + +// Compiler/platform defines a union semun for SysV shared memory. +#define ACE_HAS_SEMUN + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SOCKIO_H + +// Compiler has brain-damaged SPARCwork signal prototype... +#define ACE_HAS_SPARCWORKS_401_SIGNALS + +// Compiler/platform supports struct strbuf +#define ACE_HAS_STRBUF_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// SunOS 4 style prototype. +#define ACE_HAS_SUNOS4_GETTIMEOFDAY + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Platform supports ACE_TLI tiuser header. +// #define ACE_HAS_TIUSER_H + +// Platform has ACE_TLI. +// #define ACE_HAS_TLI + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos4-sun4.x-orbix.h b/ace/config-sunos4-sun4.x-orbix.h new file mode 100644 index 00000000000..d3e593eef88 --- /dev/null +++ b/ace/config-sunos4-sun4.x-orbix.h @@ -0,0 +1,82 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work +// for SunOS4 platforms using the SunC++ 4.x compiler. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// ACE sparcworks 4.01 signal handling under SunOS +#define ACE_HAS_SPARCWORKS_401_SIGNALS + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Platform contains Orbix CORBA implementation. +#define ACE_HAS_ORBIX + +// Compiler/platform supports strerror (). +// #define ACE_HAS_STRERROR +#define ACE_HAS_SYS_ERRLIST + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Header files lack t_errno for ACE_TLI. +// #define ACE_LACKS_T_ERRNO + +// Compiler/platform uses old malloc()/free() prototypes (ugh). +#define ACE_HAS_OLD_MALLOC + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Compiler/platform supports poll(). +#define ACE_HAS_POLL + +// Compiler/platform defines a union semun for SysV shared memory. +#define ACE_HAS_SEMUN + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SOCKIO_H + +// Compiler has brain-damaged SPARCwork signal prototype... +#define ACE_HAS_SPARCWORKS_401_SIGNALS + +// Compiler/platform supports struct strbuf +#define ACE_HAS_STRBUF_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// SunOS 4 style prototype. +#define ACE_HAS_SUNOS4_GETTIMEOFDAY + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Platform supports ACE_TLI tiuser header. +// #define ACE_HAS_TIUSER_H + +// Platform has ACE_TLI. +// #define ACE_HAS_TLI + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos4-sun4.x.h b/ace/config-sunos4-sun4.x.h new file mode 100644 index 00000000000..9d1a71aa56b --- /dev/null +++ b/ace/config-sunos4-sun4.x.h @@ -0,0 +1,76 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work +// for SunOS4 platforms using the SunC++ 4.x compiler. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Compiler/platform has the getrusage() system call. +#define ACE_HAS_GETRUSAGE + +// Compiler/platform supports strerror (). +// #define ACE_HAS_STRERROR +#define ACE_HAS_SYS_ERRLIST + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Header files lack t_errno for ACE_TLI. +// #define ACE_LACKS_T_ERRNO + +// Compiler/platform uses old malloc()/free() prototypes (ugh). +#define ACE_HAS_OLD_MALLOC + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Compiler/platform supports poll(). +#define ACE_HAS_POLL + +// Compiler/platform defines a union semun for SysV shared memory. +#define ACE_HAS_SEMUN + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SOCKIO_H + +// Compiler has brain-damaged SPARCwork signal prototype... +#define ACE_HAS_SPARCWORKS_401_SIGNALS + +// Compiler/platform supports struct strbuf +#define ACE_HAS_STRBUF_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// SunOS 4 style prototype. +#define ACE_HAS_SUNOS4_GETTIMEOFDAY + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Platform supports ACE_TLI tiuser header. +// #define ACE_HAS_TIUSER_H + +// Platform has ACE_TLI. +// #define ACE_HAS_TLI + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos5.4-centerline-2.x.h b/ace/config-sunos5.4-centerline-2.x.h new file mode 100644 index 00000000000..9c7aa2debb3 --- /dev/null +++ b/ace/config-sunos5.4-centerline-2.x.h @@ -0,0 +1,152 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for SunOS 5.4 +// platforms using the Centerline 2.x C++ compiler. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +#define ACE_HAS_UNICODE + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Sun has the wrong prototype for sendmsg. +#define ACE_HAS_BROKEN_SENDMSG + +// The SunOS 5.x version of rand_r is inconsistent with the header files... +#define ACE_HAS_BROKEN_RANDR + +// Platform supports system configuration information. +#define ACE_HAS_SYSINFO + +// Platform supports the POSIX regular expression library +#define ACE_HAS_REGEX + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Platform supports reentrant functions (i.e., all the POSIX *_r functions). +#define ACE_HAS_REENTRANT_FUNCTIONS + +// Platform has terminal ioctl flags like TCGETS and TCSETS. +#define ACE_HAS_TERM_IOCTLS + +// Compiler/platform correctly calls init()/fini() for shared libraries. +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Compiler/platform supports SunOS high resolution timers. +#define ACE_HAS_HI_RES_TIMER + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Platform contains . +#define ACE_HAS_POLL + +// Platform supports POSIX timers via timestruc_t. +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_SVR4_TIME + +// Platform supports the /proc file system. +#define ACE_HAS_PROC_FS + +// Platform supports the prusage_t struct. +#define ACE_HAS_PRUSAGE_T + +// Explicit dynamic linking permits "lazy" symbol resolution. +#define ACE_HAS_RTLD_LAZY_V + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Platform supports SVR4 extended signals. +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SOCKIO_H + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Platform supports STREAM pipes. +#define ACE_HAS_STREAM_PIPES + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Andreas Ueltschi tells me this is a good thing... +#define ACE_HAS_SVR5_GETTIMEOFDAY + +// Compiler/platform supports poll(). +#define ACE_HAS_SVR4_POLL + +// Compiler/platform supports SVR4 signal typedef. +#define ACE_HAS_SVR4_SIGNAL_T + +// Compiler/platform supports SVR4 ACE_TLI (in particular, T_GETNAME stuff)... +#define ACE_HAS_SVR4_TLI + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Compiler/platform supports sys_siglist array. +#define ACE_HAS_SYS_SIGLIST + +/* Turn off the following four defines if you want to disable threading. */ +// Compile using multi-thread libraries. +#define ACE_MT_SAFE + +// Platform supports threads. +#define ACE_HAS_THREADS + +// Platform supports Solaris threads. +#define ACE_HAS_STHREADS + +// Compiler/platform has thread-specific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// Platform supports ACE_TLI timod STREAMS module. +#define ACE_HAS_TIMOD_H + +// Platform supports ACE_TLI tiuser header. +#define ACE_HAS_TIUSER_H + +// Platform provides ACE_TLI function prototypes. +#define ACE_HAS_TLI_PROTOTYPES + +// Platform supports ACE_TLI. +#define ACE_HAS_TLI + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos5.4-g++.h b/ace/config-sunos5.4-g++.h new file mode 100644 index 00000000000..0add5d1b80d --- /dev/null +++ b/ace/config-sunos5.4-g++.h @@ -0,0 +1,180 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for SunOS 5.4 +// platforms using the GNU g++ compiler. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +#define ACE_HAS_UNICODE + +// Must specialize templates due to G++'s lame parameterized type +// support... +#define ACE_TEMPLATES_REQUIRE_SPECIALIZATION + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Sun has the wrong prototype for sendmsg. +#define ACE_HAS_BROKEN_SENDMSG + +// The SunOS 5.x version of rand_r is inconsistent with the header files... +// #define ACE_HAS_BROKEN_RANDR + +// Platform supports system configuration information. +#define ACE_HAS_SYSINFO + +// Platform supports the POSIX regular expression library +#define ACE_HAS_REGEX + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Platform supports reentrant functions (i.e., all the POSIX *_r functions). +#define ACE_HAS_REENTRANT_FUNCTIONS + +// Compiler's template mechanism must see source code (i.e., .C files). +#define ACE_TEMPLATES_REQUIRE_SOURCE + +// Denotes that GNU has cstring.h as standard +// which redefines memchr() +#define ACE_HAS_GNU_CSTRING_H + +// Compiler doesn't support static data member templates. +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES + +// Compiler/platform correctly calls init()/fini() for shared libraries. +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Compiler/platform supports SunOS high resolution timers. +#define ACE_HAS_HI_RES_TIMER + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Compiler/platform supports the "long long" datatype. +#define ACE_HAS_LONGLONG_T + +// Compiler/platform supports alloca() +#define ACE_HAS_ALLOCA + +// Compiler/platform has +#define ACE_HAS_ALLOCA_H + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Platform contains . +#define ACE_HAS_POLL + +// Platform supports POSIX timers via timestruc_t. +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_SVR4_TIME + +// Platform supports the /proc file system. +#define ACE_HAS_PROC_FS + +// Platform supports the prusage_t struct. +#define ACE_HAS_PRUSAGE_T + +// Explicit dynamic linking permits "lazy" symbol resolution. +#define ACE_HAS_RTLD_LAZY_V + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Platform supports SVR4 extended signals. +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SOCKIO_H + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Platform supports STREAM pipes. +#define ACE_HAS_STREAM_PIPES + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Compiler has system V signals +// #define ACE_HAS_SVR4_SIGNAL_T + +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Compiler/platform supports SVR4 gettimeofday() prototype. +#define ACE_HAS_SVR4_GETTIMEOFDAY + +// Compiler/platform supports SVR4 signal typedef. +#define ACE_HAS_SVR4_SIGNAL_T + +// Compiler/platform supports SVR4 TLI (in particular, T_GETNAME stuff)... +#define ACE_HAS_SVR4_TLI + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Compiler/platform supports sys_siglist array. +#define ACE_HAS_SYS_SIGLIST + +/* Turn off the following four defines if you want to disable threading. */ +// Compile using multi-thread libraries. +#define ACE_MT_SAFE + +// Platform supports Solaris threads. +#define ACE_HAS_STHREADS + +// Platform supports threads. +#define ACE_HAS_THREADS + +// Compiler/platform has thread-specific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// Platform supports TLI timod STREAMS module. +#define ACE_HAS_TIMOD_H + +// Platform supports TLI tiuser header. +#define ACE_HAS_TIUSER_H + +// Platform provides TLI function prototypes. +#define ACE_HAS_TLI_PROTOTYPES + +// Platform supports TLI. +#define ACE_HAS_TLI + +// Use the poll() event demultiplexor rather than select(). +//#define ACE_USE_POLL + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Define this file to keep /usr/include/memory.h from being included. +#include + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos5.4-sunc++-4.x-orbix.h b/ace/config-sunos5.4-sunc++-4.x-orbix.h new file mode 100644 index 00000000000..83a3cdcbe82 --- /dev/null +++ b/ace/config-sunos5.4-sunc++-4.x-orbix.h @@ -0,0 +1,168 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for SunOS 5.4 +// platforms using the SunC++ 4.0.x compiler. This works with the +// MT-Orbix CORBA IDL compiler. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +#define ACE_HAS_UNICODE + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Sun has the wrong prototype for sendmsg. +#define ACE_HAS_BROKEN_SENDMSG + +// The SunOS 5.x version of rand_r is inconsistent with the header files... +#define ACE_HAS_BROKEN_RANDR + +// Platform supports system configuration information. +#define ACE_HAS_SYSINFO + +// Platform supports the POSIX regular expression library +#define ACE_HAS_REGEX + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Platform supports reentrant functions (i.e., all the POSIX *_r functions). +#define ACE_HAS_REENTRANT_FUNCTIONS + +// Platform has terminal ioctl flags like TCGETS and TCSETS. +#define ACE_HAS_TERM_IOCTLS + +// Compiler/platform correctly calls init()/fini() for shared libraries. +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Compiler/platform supports SunOS high resolution timers. +#define ACE_HAS_HI_RES_TIMER + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Compiler/platform supports the "long long" datatype. +#define ACE_HAS_LONGLONG_T + +// Compiler/platform supports alloca() +#define ACE_HAS_ALLOCA + +// Compiler/platform has +#define ACE_HAS_ALLOCA_H + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Platform contains the Orbix CORBA implementation. +#define ACE_HAS_ORBIX + +// Platform contains the multi-threaded Orbix CORBA implementation. +// #define ACE_HAS_MT_ORBIX + +// Platform contains . +#define ACE_HAS_POLL + +// Platform supports POSIX timers via timestruc_t. +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_SVR4_TIME + +// Platform supports the /proc file system. +#define ACE_HAS_PROC_FS + +// Platform supports the prusage_t struct. +#define ACE_HAS_PRUSAGE_T + +// Explicit dynamic linking permits "lazy" symbol resolution. +#define ACE_HAS_RTLD_LAZY_V + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Platform supports SVR4 extended signals. +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SOCKIO_H + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Platform supports STREAM pipes. +#define ACE_HAS_STREAM_PIPES + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Compiler/platform supports SVR4 gettimeofday() prototype. +#define ACE_HAS_SVR4_GETTIMEOFDAY + +// Compiler/platform supports SVR4 signal typedef. +#define ACE_HAS_SVR4_SIGNAL_T + +// Compiler/platform supports SVR4 ACE_TLI (in particular, T_GETNAME stuff)... +#define ACE_HAS_SVR4_TLI + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Compiler/platform supports sys_siglist array. +#define ACE_HAS_SYS_SIGLIST + +/* Turn off the following four defines if you want to disable threading. */ +// Compile using multi-thread libraries. +#define ACE_MT_SAFE + +// Platform supports Solaris threads. +#define ACE_HAS_STHREADS + +// Platform supports threads. +#define ACE_HAS_THREADS + +// Compiler/platform has thread-specific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// Platform supports ACE_TLI timod STREAMS module. +#define ACE_HAS_TIMOD_H + +// Platform supports ACE_TLI tiuser header. +#define ACE_HAS_TIUSER_H + +// Platform provides ACE_TLI function prototypes. +#define ACE_HAS_TLI_PROTOTYPES + +// Platform supports ACE_TLI. +#define ACE_HAS_TLI + +// Use the poll() event demultiplexor rather than select(). +//#define ACE_USE_POLL + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos5.4-sunc++-4.x.h b/ace/config-sunos5.4-sunc++-4.x.h new file mode 100644 index 00000000000..5d25574ccb0 --- /dev/null +++ b/ace/config-sunos5.4-sunc++-4.x.h @@ -0,0 +1,165 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for SunOS 5.4 +// platforms using the SunC++ 4.0.x compiler. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +#define ACE_HAS_UNICODE + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Sun has the wrong prototype for sendmsg. +#define ACE_HAS_BROKEN_SENDMSG + +// The SunOS 5.x version of rand_r is inconsistent with the header files... +#define ACE_HAS_BROKEN_RANDR + +// Platform supports system configuration information. +#define ACE_HAS_SYSINFO + +// Platform supports the POSIX regular expression library. +#define ACE_HAS_REGEX + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Platform supports reentrant functions (i.e., all the POSIX *_r functions). +#define ACE_HAS_REENTRANT_FUNCTIONS + +// Platform has terminal ioctl flags like TCGETS and TCSETS. +#define ACE_HAS_TERM_IOCTLS + +// Compiler/platform correctly calls init()/fini() for shared libraries. +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Compiler/platform supports SunOS high resolution timers. +#define ACE_HAS_HI_RES_TIMER + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Compiler/platform supports the "long long" datatype. +#define ACE_HAS_LONGLONG_T + +// Compiler/platform supports alloca() +#define ACE_HAS_ALLOCA + +// Compiler/platform has +#define ACE_HAS_ALLOCA_H + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Platform contains . +#define ACE_HAS_POLL + +// Platform supports POSIX timers via timestruc_t. +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_SVR4_TIME + +// Platform supports the /proc file system. +#define ACE_HAS_PROC_FS + +// Platform supports the prusage_t struct. +#define ACE_HAS_PRUSAGE_T + +// Explicit dynamic linking permits "lazy" symbol resolution. +#define ACE_HAS_RTLD_LAZY_V + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Platform supports SVR4 extended signals. +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SOCKIO_H + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Platform supports STREAM pipes. +#define ACE_HAS_STREAM_PIPES + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Compiler/platform supports SVR4 gettimeofday() prototype. +#define ACE_HAS_SVR4_GETTIMEOFDAY + +// Compiler/platform supports SVR4 signal typedef. +#define ACE_HAS_SVR4_SIGNAL_T + +// Compiler/platform supports SVR4 ACE_TLI (in particular, T_GETNAME stuff)... +#define ACE_HAS_SVR4_TLI + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Compiler/platform supports sys_siglist array. +#define ACE_HAS_SYS_SIGLIST + +/* Turn off the following four defines if you want to disable threading. */ +// Compile using multi-thread libraries. +#define ACE_MT_SAFE + +// Platform supports Solaris threads. +#define ACE_HAS_STHREADS + +// Platform supports threads. +#define ACE_HAS_THREADS + +// Compiler/platform has thread-specific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// Reactor detects deadlock +// #define ACE_REACTOR_HAS_DEADLOCK_DETECTION + +// Platform supports ACE_TLI timod STREAMS module. +#define ACE_HAS_TIMOD_H + +// Platform supports ACE_TLI tiuser header. +#define ACE_HAS_TIUSER_H + +// Platform provides ACE_TLI function prototypes. +#define ACE_HAS_TLI_PROTOTYPES + +// Platform supports ACE_TLI. +#define ACE_HAS_TLI + +// Use the poll() event demultiplexor rather than select(). +//#define ACE_USE_POLL + +// Turns off the tracing feature. +// #define ACE_NTRACE 0 +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos5.5-g++.h b/ace/config-sunos5.5-g++.h new file mode 100644 index 00000000000..8917421aebf --- /dev/null +++ b/ace/config-sunos5.5-g++.h @@ -0,0 +1,171 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for SunOS 5.5 +// platforms using the GNU g++ compiler. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +#define ACE_HAS_UNICODE + +// Must specialize templates due to G++'s lame parameterized type +// support... +#define ACE_TEMPLATES_REQUIRE_SPECIALIZATION + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Platform supports system configuration information. +#define ACE_HAS_SYSINFO + +// Platform supports the POSIX regular expression library +#define ACE_HAS_REGEX + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Platform supports reentrant functions (i.e., all the POSIX *_r functions). +#define ACE_HAS_REENTRANT_FUNCTIONS + +// Compiler's template mechanism must see source code (i.e., .C files). +#define ACE_TEMPLATES_REQUIRE_SOURCE + +// Denotes that GNU has cstring.h as standard +// which redefines memchr() +#define ACE_HAS_GNU_CSTRING_H + +// Compiler doesn't support static data member templates. +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES + +// Compiler/platform correctly calls init()/fini() for shared libraries. +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Compiler/platform supports SunOS high resolution timers. +#define ACE_HAS_HI_RES_TIMER + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Compiler/platform supports the "long long" datatype. +#define ACE_HAS_LONGLONG_T + +// Compiler/platform supports alloca() +#define ACE_HAS_ALLOCA + +// Compiler/platform has +#define ACE_HAS_ALLOCA_H + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Platform contains . +#define ACE_HAS_POLL + +// Platform supports POSIX timers via timestruc_t. +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_SVR4_TIME + +// Platform supports the /proc file system. +#define ACE_HAS_PROC_FS + +// Platform supports the prusage_t struct. +#define ACE_HAS_PRUSAGE_T + +// Explicit dynamic linking permits "lazy" symbol resolution. +#define ACE_HAS_RTLD_LAZY_V + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Platform supports SVR4 extended signals. +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SOCKIO_H + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Platform supports STREAM pipes. +#define ACE_HAS_STREAM_PIPES + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Compiler/platform supports SVR4 gettimeofday() prototype. +#define ACE_HAS_SVR4_GETTIMEOFDAY + +// Compiler/platform supports SVR4 TLI (in particular, T_GETNAME stuff)... +#define ACE_HAS_SVR4_TLI + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Compiler/platform supports sys_siglist array. +#define ACE_HAS_SYS_SIGLIST + +/* Turn off the following four defines if you want to disable threading. */ +// Compile using multi-thread libraries. +#define ACE_MT_SAFE + +// Platform supports threads. +#define ACE_HAS_THREADS + +// Platform supports POSIX pthreads *and* Solaris threads! +#define ACE_HAS_STHREADS +#define ACE_HAS_PTHREADS +#define ACE_HAS_SIGWAIT +#define ACE_LACKS_CONDATTR_PSHARED + +// Compiler/platform has thread-specific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// Platform supports TLI timod STREAMS module. +#define ACE_HAS_TIMOD_H + +// Platform supports TLI tiuser header. +#define ACE_HAS_TIUSER_H + +// Platform provides TLI function prototypes. +#define ACE_HAS_TLI_PROTOTYPES + +// Platform supports TLI. +#define ACE_HAS_TLI + +// Use the poll() event demultiplexor rather than select(). +//#define ACE_USE_POLL + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// Define this file to keep /usr/include/memory.h from being included. +#include + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos5.5-sunc++-4.x-orbix.h b/ace/config-sunos5.5-sunc++-4.x-orbix.h new file mode 100644 index 00000000000..3c325dab04e --- /dev/null +++ b/ace/config-sunos5.5-sunc++-4.x-orbix.h @@ -0,0 +1,166 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for SunOS 5.5 +// platforms using the SunC++ 4.0.x compiler. This works with the +// Orbix 2.0 CORBA IDL compiler. + + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +// Platform contains the Orbix CORBA implementation. +#define ACE_HAS_ORBIX + +// Platform contains the multi-threaded Orbix CORBA implementation. +//#define ACE_HAS_MT_ORBIX + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Platform supports system configuration information. +#define ACE_HAS_SYSINFO + +// Platform supports the POSIX regular expression library. +#define ACE_HAS_REGEX + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Platform supports reentrant functions (i.e., all the POSIX *_r functions). +#define ACE_HAS_REENTRANT_FUNCTIONS + +// Platform has terminal ioctl flags like TCGETS and TCSETS. +#define ACE_HAS_TERM_IOCTLS + +// Compiler/platform correctly calls init()/fini() for shared libraries. +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Compiler/platform supports SunOS high resolution timers. +#define ACE_HAS_HI_RES_TIMER + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Compiler/platform supports the "long long" datatype. +#define ACE_HAS_LONGLONG_T + +// Compiler/platform supports alloca() +#define ACE_HAS_ALLOCA + +// Compiler/platform has +#define ACE_HAS_ALLOCA_H + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Platform contains . +#define ACE_HAS_POLL + +// Platform supports POSIX timers via timestruc_t. +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_SVR4_TIME + +// Platform supports the /proc file system. +#define ACE_HAS_PROC_FS + +// Platform supports the prusage_t struct. +#define ACE_HAS_PRUSAGE_T + +// Explicit dynamic linking permits "lazy" symbol resolution. +#define ACE_HAS_RTLD_LAZY_V + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Platform supports SVR4 extended signals. +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SOCKIO_H + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Platform supports STREAM pipes. +#define ACE_HAS_STREAM_PIPES + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Compiler/platform supports SVR4 gettimeofday() prototype. +#define ACE_HAS_SVR4_GETTIMEOFDAY + +// Compiler/platform supports SVR4 ACE_TLI (in particular, T_GETNAME stuff)... +#define ACE_HAS_SVR4_TLI + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Compiler/platform supports sys_siglist array. +#define ACE_HAS_SYS_SIGLIST + +/* Turn off the following four defines if you want to disable threading. */ +// Compile using multi-thread libraries. +#define ACE_MT_SAFE + +// Platform supports threads. +#define ACE_HAS_THREADS + +// Platform supports POSIX pthreads *and* Solaris threads! +#define ACE_HAS_STHREADS +#define ACE_HAS_PTHREADS +#define ACE_HAS_SIGWAIT +#define ACE_LACKS_CONDATTR_PSHARED + +// Compiler/platform has thread-specific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// Reactor detects deadlock +// #define ACE_REACTOR_HAS_DEADLOCK_DETECTION + +// Platform supports ACE_TLI timod STREAMS module. +#define ACE_HAS_TIMOD_H + +// Platform supports ACE_TLI tiuser header. +#define ACE_HAS_TIUSER_H + +// Platform provides ACE_TLI function prototypes. +#define ACE_HAS_TLI_PROTOTYPES + +// Platform supports ACE_TLI. +#define ACE_HAS_TLI + +// Use the poll() event demultiplexor rather than select(). +//#define ACE_USE_POLL + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunos5.5-sunc++-4.x.h b/ace/config-sunos5.5-sunc++-4.x.h new file mode 100644 index 00000000000..63b4aaea320 --- /dev/null +++ b/ace/config-sunos5.5-sunc++-4.x.h @@ -0,0 +1,161 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for SunOS 5.5 +// platforms using the SunC++ 4.0.x compiler. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +#define ACE_HAS_UNICODE + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Platform supports system configuration information. +#define ACE_HAS_SYSINFO + +// Platform supports the POSIX regular expression library. +#define ACE_HAS_REGEX + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Platform supports reentrant functions (i.e., all the POSIX *_r functions). +#define ACE_HAS_REENTRANT_FUNCTIONS + +// Platform has terminal ioctl flags like TCGETS and TCSETS. +#define ACE_HAS_TERM_IOCTLS + +// Compiler/platform correctly calls init()/fini() for shared libraries. +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Compiler/platform supports SunOS high resolution timers. +#define ACE_HAS_HI_RES_TIMER + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Compiler/platform supports the "long long" datatype. +#define ACE_HAS_LONGLONG_T + +// Compiler/platform supports alloca() +#define ACE_HAS_ALLOCA + +// Compiler/platform has +#define ACE_HAS_ALLOCA_H + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Platform contains . +#define ACE_HAS_POLL + +// Platform supports POSIX timers via timestruc_t. +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_SVR4_TIME + +// Platform supports the /proc file system. +#define ACE_HAS_PROC_FS + +// Platform supports the prusage_t struct. +#define ACE_HAS_PRUSAGE_T + +// Explicit dynamic linking permits "lazy" symbol resolution. +#define ACE_HAS_RTLD_LAZY_V + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Platform supports SVR4 extended signals. +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SOCKIO_H + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Platform supports STREAM pipes. +#define ACE_HAS_STREAM_PIPES + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Compiler/platform supports SVR4 gettimeofday() prototype. +#define ACE_HAS_SVR4_GETTIMEOFDAY + +// Compiler/platform supports SVR4 ACE_TLI (in particular, T_GETNAME stuff)... +#define ACE_HAS_SVR4_TLI + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Compiler/platform supports sys_siglist array. +#define ACE_HAS_SYS_SIGLIST + +/* Comment out the following seven defines if you want to disable threading. */ +// Compile using multi-thread libraries. +#define ACE_MT_SAFE + +// Platform supports threads. +#define ACE_HAS_THREADS + +// Platform supports POSIX pthreads *and* Solaris threads! +#define ACE_HAS_STHREADS +#define ACE_HAS_PTHREADS +#define ACE_HAS_SIGWAIT +#define ACE_LACKS_CONDATTR_PSHARED + +// Compiler/platform has thread-specific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE +/* End of threading #defines */ + +// Reactor detects deadlock +// #define ACE_REACTOR_HAS_DEADLOCK_DETECTION + +// Platform supports ACE_TLI timod STREAMS module. +#define ACE_HAS_TIMOD_H + +// Platform supports ACE_TLI tiuser header. +#define ACE_HAS_TIUSER_H + +// Platform provides ACE_TLI function prototypes. +#define ACE_HAS_TLI_PROTOTYPES + +// Platform supports ACE_TLI. +#define ACE_HAS_TLI + +// Use the poll() event demultiplexor rather than select(). +//#define ACE_USE_POLL + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-sunx86-sunc++-4.x.h b/ace/config-sunx86-sunc++-4.x.h new file mode 100644 index 00000000000..c29373b495b --- /dev/null +++ b/ace/config-sunx86-sunc++-4.x.h @@ -0,0 +1,142 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for SunOS5.x86 +// platforms using the SunC++ 4.0.x compiler. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +// Platform supports System V IPC (most versions of UNIX, but not Win32) +#define ACE_HAS_SYSV_IPC + +// Platform supports recvmsg and sendmsg. +#define ACE_HAS_MSG + +// Compiler/platform contains the file. +#define ACE_HAS_SYSCALL_H + +// Compiler/platform correctly calls init()/fini() for shared libraries. +#define ACE_HAS_AUTOMATIC_INIT_FINI + +// Platform supports POSIX O_NONBLOCK semantics. +#define ACE_HAS_POSIX_NONBLOCK + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Compiler/platform supports SunOS high resolution timers. +#define ACE_HAS_HI_RES_TIMER + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Compiler/platform supports the "long long" datatype. +#define ACE_HAS_LONGLONG_T + +// Compiler/platform supports alloca() +#define ACE_HAS_ALLOCA + +// Compiler/platform has +#define ACE_HAS_ALLOCA_H + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Platform contains . +#define ACE_HAS_POLL + +// Platform supports POSIX timers via timestruc_t. +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_SVR4_TIME + +// Platform supports the /proc file system. +#define ACE_HAS_PROC_FS + +// Platform supports the prusage_t struct. +#define ACE_HAS_PRUSAGE_T + +// Explicit dynamic linking permits "lazy" symbol resolution. +#define ACE_HAS_RTLD_LAZY_V + +// Compiler/platform defines the sig_atomic_t typedef. +#define ACE_HAS_SIG_ATOMIC_T + +// Platform supports SVR4 extended signals. +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T + +// Compiler/platform provides the sockio.h file. +#define ACE_HAS_SOCKIO_H + +// Compiler supports the ssize_t typedef. +#define ACE_HAS_SSIZE_T + +// Platform supports STREAMS. +#define ACE_HAS_STREAMS + +// Platform supports STREAM pipes. +#define ACE_HAS_STREAM_PIPES + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Compiler/platform supports struct strbuf. +#define ACE_HAS_STRBUF_T + +// Compiler/platform supports SVR4 dynamic linking semantics. +#define ACE_HAS_SVR4_DYNAMIC_LINKING + +// Compiler/platform supports SVR4 gettimeofday() prototype. +#define ACE_HAS_SVR4_GETTIMEOFDAY + +// Compiler/platform supports SVR4 signal typedef. +#define ACE_HAS_SVR4_SIGNAL_T +//#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES + +// Compiler/platform supports SVR4 ACE_TLI (in particular, T_GETNAME stuff)... +#define ACE_HAS_SVR4_TLI + +// Platform provides header. +#define ACE_HAS_SYS_FILIO_H + +// Compiler/platform supports sys_siglist array. +#define ACE_HAS_SYS_SIGLIST + +/* Turn off the following four defines if you want to disable threading. */ +// Compile using multi-thread libraries. +#define ACE_MT_SAFE + +// Platform supports Solaris threads. +#define ACE_HAS_STHREADS + +// Platform supports threads. +#define ACE_HAS_THREADS + +// Platform has ACE_TLI. +#define ACE_HAS_TLI + +// Platform supports ACE_TLI timod STREAMS module. +#define ACE_HAS_TIMOD_H + +// Platform supports ACE_TLI tiuser header. +#define ACE_HAS_TIUSER_H + +// Platform provides ACE_TLI function prototypes. +#define ACE_HAS_TLI_PROTOTYPES + +// Platform supports ACE_TLI. +#define ACE_HAS_TLI + +// Use the poll() event demultiplexor rather than select(). +//#define ACE_USE_POLL + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-unixware-2.01-g++.h b/ace/config-unixware-2.01-g++.h new file mode 100644 index 00000000000..8e48ada35e2 --- /dev/null +++ b/ace/config-unixware-2.01-g++.h @@ -0,0 +1,95 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work +// for Unixware platforms running UnixWare 2.01. +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +// See README for what the ACE_HAS... and ACE_LACKS... macros mean + +#define ACE_HAS_SIZET_SOCKET_LEN +#define ACE_HAS_AUTOMATIC_INIT_FINI +#define ACE_HAS_CPLUSPLUS_HEADERS +#define ACE_HAS_GNU_CSTRING_H +#define ACE_HAS_INLINED_OSCALLS +#define ACE_HAS_MSG +// Not yet sure about threads +#define ACE_HAS_MT_SAFE_SOCKETS +#define ACE_HAS_NONCONST_GETBY +#define ACE_HAS_OSF1_GETTIMEOFDAY +#define ACE_HAS_POLL +#define ACE_HAS_POSIX_NONBLOCK +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_REENTRANT_FUNCTIONS +#define ACE_HAS_REGEX +#define ACE_HAS_LAZY_V +#define ACE_HAS_SELECT_H +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_UCONTEXT_T +#define ACE_HAS_SIGWAIT +#define ACE_HAS_SIG_ATOMIC_T +#define ACE_HAS_SOCKIO_H +#define ACE_HAS_SSIZE_T +#define ACE_HAS_STHREADS +#define ACE_HAS_STRBUF_T +#define ACE_HAS_STREAMS +#define ACE_HAS_STREAM_PIPES +#define ACE_HAS_STRERROR +#define ACE_HAS_SVR4_DYNAMIC_LINKING +#define ACE_HAS_SVR4_TIME +#define ACE_HAS_SYSCALL_H +#define ACE_HAS_SYSINFO +#define ACE_HAS_SYSV_IPC +#define ACE_HAS_SYS_FILIO_H +#define ACE_HAS_SYS_SIGLIST +#define ACE_HAS_TERM_IOCTLS +#define ACE_HAS_THREADS +#define ACE_HAS_THREAD_SPECIFIC_STORAGE +#define ACE_HAS_THREAD_T +#define ACE_HAS_TIMOD_H +#define ACE_HAS_TIUSER_H +#define ACE_HAS_TLI +#define ACE_HAS_TLI_PROTOTYPES +#define ACE_HAS_UNIXWARE_SVR4_SIGNAL_T +#define ACE_HAS_VOIDPTR_SOCKOPT + +#define ACE_LACKS_MADVISE +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES +#define ACE_LACKS_SYSCALL + +#define ACE_MT_SAFE +#define ACE_PAGE_SIZE 4096 +#define ACE_REDEFINES_XTI_FUNCTIONS +#define ACE_TEMPLATES_REQUIRE_SOURCE +#define ACE_TEMPLATES_REQUIRE_SPECIALIZATION + + +// Compiling for UNIXWARE +#if !defined (UNIXWARE) +#define UNIXWARE +#endif /* UNIXWARE */ + +// These seem to be missing... Process_Manager uses them +// +//typedef int Process_t; +//typedef int hProcess_t; +//typedef int hpid_t; + + +// Compiler/platform supports OSF/1 gettimeofday() prototype. +//#define ACE_HAS_OSF1_GETTIMEOFDAY + +// Compiler/platform supports SVR4 TLI (in particular, T_GETNAME stuff)... +//#define ACE_HAS_SVR4_TLI + + +// Platform doesn't have getby... char *arg defined as const +//#define ACE_GET_BLAH_BY_NO_CONST + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-vxworks-ghs-1.8.h b/ace/config-vxworks-ghs-1.8.h new file mode 100644 index 00000000000..deee0c0209e --- /dev/null +++ b/ace/config-vxworks-ghs-1.8.h @@ -0,0 +1,46 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for VxWorks +// 5.2 platforms using the GreenHills 1.8.7 compiler. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +#define ACE_HAS_BROKEN_SENDMSG +#define ACE_HAS_BROKEN_WRITEV +#define ACE_HAS_CHARPTR_SOCKOPT +#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES +#define ACE_HAS_CPLUSPLUS_HEADERS +#define ACE_HAS_GREENHILLS_SOCKETS +#define ACE_HAS_MSG +#define ACE_HAS_MT_SAFE_SOCKETS +#define ACE_HAS_POSIX_NONBLOCK +#define ACE_HAS_POSIX_TIME +#define ACE_HAS_SIG_ATOMIC_T +#define ACE_HAS_SIGINFO_T +#define ACE_HAS_SIGWAIT +#define ACE_HAS_THREADS +#define ACE_LACKS_MADVISE +#define ACE_LACKS_MALLOC_H +#define ACE_LACKS_MKTEMP +#define ACE_LACKS_MMAP +#define ACE_LACKS_MSYNC +#define ACE_LACKS_PARAM_H +#define ACE_LACKS_RLIMIT +#define ACE_LACKS_SBRK +#define ACE_LACKS_SEMBUF_T +#define ACE_LACKS_SIGINFO_H +#define ACE_LACKS_SI_ADDR +#define ACE_LACKS_SOCKETPAIR +#define ACE_LACKS_STRRECVFD +#define ACE_LACKS_SYSCALL +#define ACE_LACKS_UCONTEXT_H +#define ACE_LACKS_UTSNAME_T +#define ACE_MT_SAFE +#define SIGNAL_SAFE_OS_CALLS + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-win32-msvc2.0.h b/ace/config-win32-msvc2.0.h new file mode 100644 index 00000000000..a438b6ffe41 --- /dev/null +++ b/ace/config-win32-msvc2.0.h @@ -0,0 +1,133 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for Windows NT +// platforms using the Microsoft Visual C++ 2.0 compiler. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +// Needed for timeval. +#include + +#define ACE_HAS_UNICODE + +// Compiler/platform correctly calls init()/fini() for shared +// libraries. - applied for DLLs ? +//define ACE_HAS_AUTOMATIC_INIT_FINI + +// Compiler doesn't support static data member templates. +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES + +// #define ACE_HAS_ORBIX + +// Version 1.1 of WinSock +#define ACE_WSOCK_VERSION 1, 1 +#define ACE_LACKS_RECVMSG +#define ACE_LACKS_SENDMSG +#define ACE_LACKS_MODE_MASKS + +#define ACE_LACKS_SBRK +#define ACE_LACKS_UTSNAME_T +#define ACE_LACKS_SEMBUF_T +#define ACE_LACKS_MSGBUF_T +#define ACE_LACKS_SYSV_SHMEM + +// Platform supports POSIX O_NONBLOCK semantics. +//define ACE_HAS_POSIX_NONBLOCK + +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES + +#define ACE_LACKS_STRRECVFD + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Platform contains . +//define ACE_HAS_POLL + +// Platform supports POSIX timers via timestruc_t. +//define ACE_HAS_POSIX_TIME + +// This needs to be here since MSVC++ 2.0 seems to have forgotten to +// include it. +inline void *operator new (unsigned int, void *p) { return p; } + +// Platform supports the /proc file system. +//define ACE_HAS_PROC_FS + +// Platform supports the rusage struct. +#define ACE_HAS_GETRUSAGE + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Andreas Ueltschi tells me this is a good thing... +#define ACE_HAS_SVR5_GETTIMEOFDAY + +// Compiler/platform supports poll(). +//define ACE_HAS_SVR4_POLL + +// Compiler/platform supports SVR4 signal typedef. +//define ACE_HAS_SVR4_SIGNAL_T + +// Platform provides header. +//define ACE_HAS_SYS_FILIO_H + +// Compiler/platform supports sys_siglist array. +//define ACE_HAS_SYS_SIGLIST + +/* Turn off the following four defines if you want to disable threading. */ +// Compile using multi-thread libraries. +#define ACE_MT_SAFE + +// Platform supports threads. +#define ACE_HAS_THREADS + +// Platform supports Windows32 threads. +#define ACE_HAS_WTHREADS +#define ACE_WIN32 +#define ACE_HAS_TEMPLATE_INSTANTIATION + +//#define ACE_HAS_ALLOC_HOOKS +#define ACE_TEMPLATES_REQUIRE_SOURCE + +// Compiler/platform has thread-specific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// Platform supports ACE_TLI timod STREAMS module. +//define ACE_HAS_TIMOD_H + +// Platform supports ACE_TLI tiuser header. +//define ACE_HAS_TIUSER_H + +// Platform provides ACE_TLI function prototypes. +// For Win32, this is not really true, but saves a lot of hassle! +#define ACE_HAS_TLI_PROTOTYPES +#define ACE_HAS_GNU_CSTRING_H +// Platform supports ACE_TLI. +//define ACE_HAS_TLI + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ +// #define ACE_NLOGGING + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// I'm pretty sure NT lacks these +#define ACE_LACKS_UNIX_DOMAIN_SOCKETS + +// Windows NT needs readv() and writev() +#define ACE_NEEDS_WRITEV +#define ACE_NEEDS_READV + +#endif /* ACE_CONFIG_H */ diff --git a/ace/config-win32-msvc4.0.h b/ace/config-win32-msvc4.0.h new file mode 100644 index 00000000000..aacf85f8d73 --- /dev/null +++ b/ace/config-win32-msvc4.0.h @@ -0,0 +1,167 @@ +/* -*- C++ -*- */ +// $Id$ + +// The following configuration file is designed to work for Windows NT +// platforms using the Microsoft Visual C++ 4.0 compiler. + +#if !defined (ACE_CONFIG_H) +#define ACE_CONFIG_H + +// Needed for timeval. +#include + +#if defined (_MSC_VER) +// "C4355: 'this' : used in base member initializer list" +#pragma warning(disable:4355) // disable C4514 warning +// #pragma warning(default:4355) // use this to reenable, if desired +#endif /* _MSC_VER */ +// While digging the MSVC 4.0 include files, I found how to disable MSVC +// warnings: +// --Amos Shapira + +// and MFC's are mutually +// incompatible. is brain-dead about MFC; it doesn't check +// to see whether MFC stuff is anticipated or already in progress +// before doing its thing. ACE needs (practically always) , +// and winsock in turn needs support either from windows.h or from +// afxwin.h. One or the other, not both. +// +// The MSVC++ V4.0 environment defines preprocessor macros that +// indicate the programmer has chosen something from the +// Build-->Settings-->General-->MFC combo-box. defines a +// macro itself to protect against double inclusion. We'll take +// advantage of all this to select the proper support for winsock. - +// trl 26-July-1996 + +#ifdef _AFXDLL // May be defined by MSVC++ IDE +#include // He is doing MFC +#endif +#ifdef _WINDLL // May be defined by MSVC++ IDE +#include // He is doing MFC +#endif + +#ifndef __AFX_H__ // set in afxwin.h +#include // if he's not doing MFC, snag this +#endif + +#define ACE_HAS_UNICODE + +// Uncomment these if you want to integrate ACE and Orbix in Win32. +// #define ACE_HAS_ORBIX +// #define ACE_HAS_MT_ORBIX + +#define ACE_LACKS_SBRK +#define ACE_LACKS_UTSNAME_T +#define ACE_LACKS_SEMBUF_T +#define ACE_LACKS_MSGBUF_T +#define ACE_LACKS_SYSV_SHMEM + +// Build as as a DLL. Zap this line if you want to build a static +// lib. +#define ACE_HAS_DLL + +// Compiler/platform correctly calls init()/fini() for shared +// libraries. - applied for DLLs ? +//define ACE_HAS_AUTOMATIC_INIT_FINI + +// Compiler doesn't support static data member templates. +#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES + +// Version 1.1 of WinSock +#define ACE_WSOCK_VERSION 1, 1 +#define ACE_LACKS_RECVMSG +#define ACE_LACKS_SENDMSG + +// Platform supports POSIX O_NONBLOCK semantics. +//define ACE_HAS_POSIX_NONBLOCK + +#define ACE_LACKS_MODE_MASKS +#define ACE_LACKS_STRRECVFD + +// Compiler/platform has correctly prototyped header files. +#define ACE_HAS_CPLUSPLUS_HEADERS + +// Platform supports IP multicast +#define ACE_HAS_IP_MULTICAST + +// Sockets may be called in multi-threaded programs. +#define ACE_HAS_MT_SAFE_SOCKETS + +// Platform contains . +//define ACE_HAS_POLL + +// Platform supports POSIX timers via timestruc_t. +//define ACE_HAS_POSIX_TIME + +// Platform supports the /proc file system. +//define ACE_HAS_PROC_FS + +// Platform supports the rusage struct. +#define ACE_HAS_GETRUSAGE + +// Compiler/platform supports strerror (). +#define ACE_HAS_STRERROR + +// Andreas Ueltschi tells me this is a good thing... +#define ACE_HAS_SVR5_GETTIMEOFDAY + +// Compiler/platform supports poll(). +//define ACE_HAS_SVR4_POLL + +// Compiler/platform supports SVR4 signal typedef. +//define ACE_HAS_SVR4_SIGNAL_T + +// Platform provides header. +//define ACE_HAS_SYS_FILIO_H + +// Compiler/platform supports sys_siglist array. +//define ACE_HAS_SYS_SIGLIST + +/* Turn off the following four defines if you want to disable threading. */ +// Compile using multi-thread libraries. +#define ACE_MT_SAFE + +// Platform supports threads. +#define ACE_HAS_THREADS + +// Platform supports Windows32 threads. +#define ACE_HAS_WTHREADS +#define ACE_WIN32 +#define ACE_HAS_TEMPLATE_INSTANTIATION + +//#define ACE_HAS_ALLOC_HOOKS +#define ACE_TEMPLATES_REQUIRE_SOURCE + +// Compiler/platform has thread-specific storage +#define ACE_HAS_THREAD_SPECIFIC_STORAGE + +// Platform supports ACE_TLI timod STREAMS module. +//define ACE_HAS_TIMOD_H + +// Platform supports ACE_TLI tiuser header. +//define ACE_HAS_TIUSER_H + +// Platform provides ACE_TLI function prototypes. +// For Win32, this is not really true, but saves a lot of hassle! +#define ACE_HAS_TLI_PROTOTYPES +#define ACE_HAS_GNU_CSTRING_H +// Platform supports ACE_TLI. +//define ACE_HAS_TLI + +// Turns off the tracing feature. +#if !defined (ACE_NTRACE) +#define ACE_NTRACE 1 +#endif /* ACE_NTRACE */ +// #define ACE_NLOGGING + +// Defines the page size of the system. +#define ACE_PAGE_SIZE 4096 + +// I'm pretty sure NT lacks these +#define ACE_LACKS_UNIX_DOMAIN_SOCKETS + +// Windows NT needs readv() and writev() +#define ACE_NEEDS_WRITEV +#define ACE_NEEDS_READV + +#endif /* ACE_CONFIG_H */ diff --git a/ace/makefile-light b/ace/makefile-light new file mode 100644 index 00000000000..af44520c851 --- /dev/null +++ b/ace/makefile-light @@ -0,0 +1,883 @@ +#---------------------------------------------------------------------------- +# @(#)makefile-light 1.1 10/18/96 +# +# Sun Makefile for a lightweight version of the ACE library +# +# 1. The Reactor class category +# 2. The SOCK_SAP C++ wrappers for sockets +# 3. The threading and synchronization wrappers. +# 4. The Acceptor/Connector classes +#---------------------------------------------------------------------------- + +LIB = libIR_ACE.a +SHLIB = libIR_ACE.so + +SRC = Acceptor.C \ + Addr.C \ + Atomic_Op.C \ + Connector.C \ + Event_Handler.C \ + Event_Handler_T.C \ + Get_Opt.C \ + Handle_Set.C \ + INET_Addr.C \ + IPC_SAP.C \ + LSOCK.C \ + LSOCK_Acceptor.C \ + LSOCK_CODgram.C \ + LSOCK_Connector.C \ + LSOCK_Dgram.C \ + LSOCK_Stream.C \ + Misc.C \ + Reactor.C \ + SOCK.C \ + SOCK_Acceptor.C \ + SOCK_CODgram.C \ + SOCK_Connector.C \ + SOCK_Dgram.C \ + SOCK_Dgram_Bcast.C \ + SOCK_IO.C \ + SOCK_Dgram_Mcast.C \ + SOCK_Stream.C \ + Signal.C \ + Svc_Handler.C \ + Synch.C \ + Thread.C \ + Thread_Manager.C \ + Time_Value.C \ + Timer_Queue.C \ + Token.C \ + UNIX_Addr.C + +OBJ = Acceptor.o \ + Addr.o \ + Atomic_Op.o \ + Connector.o \ + Event_Handler.o \ + Event_Handler_T.o \ + Get_Opt.o \ + Handle_Set.o \ + INET_Addr.o \ + IPC_SAP.o \ + LSOCK.o \ + LSOCK_Acceptor.o \ + LSOCK_CODgram.o \ + LSOCK_Connector.o \ + LSOCK_Dgram.o \ + LSOCK_Stream.o \ + Misc.o \ + Reactor.o \ + SOCK.o \ + SOCK_Acceptor.o \ + SOCK_CODgram.o \ + SOCK_Connector.o \ + SOCK_Dgram.o \ + SOCK_Dgram_Bcast.o \ + SOCK_IO.o \ + SOCK_Dgram_Mcast.o \ + SOCK_Stream.o \ + Signal.o \ + Svc_Handler.o \ + Synch.o \ + Thread.o \ + Thread_Manager.o \ + Time_Value.o \ + Timer_Queue.o \ + Token.o \ + UNIX_Addr.o + +SHOBJ = Acceptor.so \ + Addr.so \ + Atomic_Op.so \ + Connector.so \ + Event_Handler.so \ + Event_Handler_T.so \ + Get_Opt.so \ + Handle_Set.so \ + INET_Addr.so \ + IPC_SAP.so \ + LSOCK.so \ + LSOCK_Acceptor.so \ + LSOCK_CODgram.so \ + LSOCK_Connector.so \ + LSOCK_Dgram.so \ + LSOCK_Stream.so \ + Misc.so \ + Reactor.so \ + SOCK.so \ + SOCK_Acceptor.so \ + SOCK_CODgram.so \ + SOCK_Connector.so \ + SOCK_Dgram.so \ + SOCK_Dgram_Bcast.so \ + SOCK_IO.so \ + SOCK_Dgram_Mcast.so \ + SOCK_Stream.so \ + Signal.so \ + Svc_Handler.so \ + Synch.so \ + Thread.so \ + Thread_Manager.so \ + Time_Value.so \ + Timer_Queue.so \ + Token.so \ + UNIX_Addr.so + +#---------------------------------------------------------------------------- +# Local Macros and Targets +#---------------------------------------------------------------------------- + +# Set up the suffixes for C++ and IDL. +.SUFFIXES: .cc .C $(SUFFIXES) + +%.o: %.C + $(COMPILE.cc) -o $@ $< + +%.o: %.cc + $(COMPILE.cc) -o $@ $< + +%.so: %.C + $(SOBUILD) + +# Turn off logging to remove the dependency on the Log_Msg class. +AR = CC +ARFLAGS = -xar -o +DEFFLAGS += -DACE_NLOGGING +INCLDIRS += -I$(WRAPPER_ROOT)/include +CPPFLAGS += $(DEFFLAGS) $(INCLDIRS) +CCFLAGS += -g +CXX = CC +DLD = $(CXX) +PIC = -pic +SOFLAGS = -G $(CPPFLAGS) +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<; \ + $(SOLINK.cc) -o $@ -h $@ $(LDFLAGS) $(VSHDIR)$*.o + +COMPILE.cc =$(CXX) $(CCFLAGS) $(CPPFLAGS) -c +LINK.cc =$(CXX) $(CCFLAGS) $(CPPFLAGS) +SOLINK.cc =$(DLD) $(SOFLAGS) + +all: build + +build: $(SHLIB) # Replace with $(LIB) if you only want to build static libs. + +$(LIB): $(OBJ) + $(AR) $(ARFLAGS) $@ $? + +$(SHLIB): $(SHOBJ) + $(SOLINK.cc) -o $@ $(LDFLAGS) *.o -lsocket -lnsl + + -$(RM) -rf *.o *.so *~ *.bak makefile-light.old core Templates.DB + + -$(RM) -f *.o *~ *.bak Makefile.old core + -$(RM) -rf ptrepository Templates.DB + +realclean: clean + -$(RM) -f $(LIB) $(SHLIB) + +#---------------------------------------------------------------------------- +# Dependency generation target +#---------------------------------------------------------------------------- + +depend: makefile-light + @$(RM) -f makefile-light.old + @cp makefile-light makefile-light.old + $(WRAPPER_ROOT)/bin/g++dep -f makefile-light $(CPPFLAGS) $(SRC) + @cat makefile-light | \ + sed -e "s;$(WRAPPER_ROOT);$$(WRAPPER_ROOT);g" \ + -e "/:$$/d" \ + > makefile-light.new + @mv makefile-light.new makefile-light + @if cmp -s makefile-light makefile-light.old ;\ + then echo "Makefile dependencies unchanged." ;\ + else \ + echo "Makefile dependencies updated." ;\ + fi ;\ + $(RM) -f makefile-light.old ; + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +Acceptor.o: Acceptor.C \ + $(WRAPPER_ROOT)/include/ace/Acceptor.h \ + $(WRAPPER_ROOT)/include/ace/Service_Config.h \ + $(WRAPPER_ROOT)/include/ace/Reactor.h \ + $(WRAPPER_ROOT)/include/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/Handle_Set.i \ + $(WRAPPER_ROOT)/include/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/include/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/include/ace/Signal.h \ + $(WRAPPER_ROOT)/include/ace/Thread.h \ + $(WRAPPER_ROOT)/include/ace/Token.h \ + $(WRAPPER_ROOT)/include/ace/Reactor.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Specific.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/include/ace/FIFO.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Log_Record.h \ + $(WRAPPER_ROOT)/include/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/include/ace/Log_Record.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Service_Repository.h \ + $(WRAPPER_ROOT)/include/ace/Service_Record.h \ + $(WRAPPER_ROOT)/include/ace/Service_Object.h \ + $(WRAPPER_ROOT)/include/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/include/ace/Stream.h \ + $(WRAPPER_ROOT)/include/ace/Module.h \ + $(WRAPPER_ROOT)/include/ace/Task.h \ + $(WRAPPER_ROOT)/include/ace/Trace.h \ + $(WRAPPER_ROOT)/include/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/include/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/include/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/include/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/include/ace/Acceptor.i \ + $(WRAPPER_ROOT)/include/ace/Get_Opt.h +Addr.o: Addr.C \ + $(WRAPPER_ROOT)/include/ace/Addr.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/Addr.i +Atomic_Op.o: Atomic_Op.C +Connector.o: Connector.C \ + $(WRAPPER_ROOT)/include/ace/Connector.h \ + $(WRAPPER_ROOT)/include/ace/Service_Config.h \ + $(WRAPPER_ROOT)/include/ace/Reactor.h \ + $(WRAPPER_ROOT)/include/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/Handle_Set.i \ + $(WRAPPER_ROOT)/include/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/include/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/include/ace/Signal.h \ + $(WRAPPER_ROOT)/include/ace/Thread.h \ + $(WRAPPER_ROOT)/include/ace/Token.h \ + $(WRAPPER_ROOT)/include/ace/Reactor.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Specific.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/include/ace/FIFO.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Log_Record.h \ + $(WRAPPER_ROOT)/include/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/include/ace/Log_Record.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Service_Repository.h \ + $(WRAPPER_ROOT)/include/ace/Service_Record.h \ + $(WRAPPER_ROOT)/include/ace/Service_Object.h \ + $(WRAPPER_ROOT)/include/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/include/ace/Stream.h \ + $(WRAPPER_ROOT)/include/ace/Module.h \ + $(WRAPPER_ROOT)/include/ace/Task.h \ + $(WRAPPER_ROOT)/include/ace/Trace.h \ + $(WRAPPER_ROOT)/include/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/include/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/include/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/include/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/include/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/include/ace/Connector.i +Event_Handler.o: Event_Handler.C \ + $(WRAPPER_ROOT)/include/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/Event_Handler.i +Event_Handler_T.o: Event_Handler_T.C \ + $(WRAPPER_ROOT)/include/ace/Event_Handler_T.h \ + $(WRAPPER_ROOT)/include/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/Event_Handler_T.i +Get_Opt.o: Get_Opt.C \ + $(WRAPPER_ROOT)/include/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/include/ace/Get_Opt.i \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h +Handle_Set.o: Handle_Set.C \ + $(WRAPPER_ROOT)/include/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/Handle_Set.i +INET_Addr.o: INET_Addr.C \ + $(WRAPPER_ROOT)/include/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/include/ace/Addr.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/INET_Addr.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Specific.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/include/ace/FIFO.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Log_Record.h \ + $(WRAPPER_ROOT)/include/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/include/ace/Log_Record.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.i +IPC_SAP.o: IPC_SAP.C \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i +LSOCK.o: LSOCK.C \ + $(WRAPPER_ROOT)/include/ace/LSOCK.h \ + $(WRAPPER_ROOT)/include/ace/SOCK.h \ + $(WRAPPER_ROOT)/include/ace/Addr.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/SOCK.i \ + $(WRAPPER_ROOT)/include/ace/LSOCK.i +LSOCK_Acceptor.o: LSOCK_Acceptor.C \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Specific.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/include/ace/FIFO.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Log_Record.h \ + $(WRAPPER_ROOT)/include/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/include/ace/Log_Record.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.i \ + $(WRAPPER_ROOT)/include/ace/LSOCK_Acceptor.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/include/ace/SOCK.h \ + $(WRAPPER_ROOT)/include/ace/Addr.h \ + $(WRAPPER_ROOT)/include/ace/SOCK.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_Acceptor.i \ + $(WRAPPER_ROOT)/include/ace/UNIX_Addr.h \ + $(WRAPPER_ROOT)/include/ace/LSOCK_Stream.h \ + $(WRAPPER_ROOT)/include/ace/LSOCK.h \ + $(WRAPPER_ROOT)/include/ace/LSOCK.i \ + $(WRAPPER_ROOT)/include/ace/LSOCK_Stream.i +LSOCK_CODgram.o: LSOCK_CODgram.C \ + $(WRAPPER_ROOT)/include/ace/LSOCK_CODgram.h \ + $(WRAPPER_ROOT)/include/ace/LSOCK.h \ + $(WRAPPER_ROOT)/include/ace/SOCK.h \ + $(WRAPPER_ROOT)/include/ace/Addr.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/SOCK.i \ + $(WRAPPER_ROOT)/include/ace/LSOCK.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_CODgram.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_CODgram.i \ + $(WRAPPER_ROOT)/include/ace/LSOCK_CODgram.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Specific.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/include/ace/FIFO.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Log_Record.h \ + $(WRAPPER_ROOT)/include/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/include/ace/Log_Record.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.i +LSOCK_Connector.o: LSOCK_Connector.C \ + $(WRAPPER_ROOT)/include/ace/LSOCK_Connector.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/include/ace/SOCK.h \ + $(WRAPPER_ROOT)/include/ace/Addr.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/SOCK.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Specific.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/include/ace/FIFO.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Log_Record.h \ + $(WRAPPER_ROOT)/include/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/include/ace/Log_Record.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.i \ + $(WRAPPER_ROOT)/include/ace/LSOCK_Stream.h \ + $(WRAPPER_ROOT)/include/ace/LSOCK.h \ + $(WRAPPER_ROOT)/include/ace/LSOCK.i \ + $(WRAPPER_ROOT)/include/ace/LSOCK_Stream.i \ + $(WRAPPER_ROOT)/include/ace/UNIX_Addr.h \ + $(WRAPPER_ROOT)/include/ace/LSOCK_Connector.i +LSOCK_Dgram.o: LSOCK_Dgram.C \ + $(WRAPPER_ROOT)/include/ace/LSOCK_Dgram.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_Dgram.h \ + $(WRAPPER_ROOT)/include/ace/SOCK.h \ + $(WRAPPER_ROOT)/include/ace/Addr.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/SOCK.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_Dgram.i \ + $(WRAPPER_ROOT)/include/ace/LSOCK.h \ + $(WRAPPER_ROOT)/include/ace/LSOCK.i \ + $(WRAPPER_ROOT)/include/ace/LSOCK_Dgram.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Specific.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/include/ace/FIFO.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Log_Record.h \ + $(WRAPPER_ROOT)/include/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/include/ace/Log_Record.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.i +LSOCK_Stream.o: LSOCK_Stream.C \ + $(WRAPPER_ROOT)/include/ace/LSOCK_Stream.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/include/ace/SOCK.h \ + $(WRAPPER_ROOT)/include/ace/Addr.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/SOCK.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/include/ace/LSOCK.h \ + $(WRAPPER_ROOT)/include/ace/LSOCK.i \ + $(WRAPPER_ROOT)/include/ace/LSOCK_Stream.i +Misc.o: Misc.C \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h +Reactor.o: Reactor.C \ + $(WRAPPER_ROOT)/include/ace/Reactor.h \ + $(WRAPPER_ROOT)/include/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/Handle_Set.i \ + $(WRAPPER_ROOT)/include/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/include/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/include/ace/Signal.h \ + $(WRAPPER_ROOT)/include/ace/Thread.h \ + $(WRAPPER_ROOT)/include/ace/Token.h \ + $(WRAPPER_ROOT)/include/ace/Reactor.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Specific.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/include/ace/FIFO.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Log_Record.h \ + $(WRAPPER_ROOT)/include/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/include/ace/Log_Record.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.i +SOCK.o: SOCK.C \ + $(WRAPPER_ROOT)/include/ace/SOCK.h \ + $(WRAPPER_ROOT)/include/ace/Addr.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/SOCK.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Specific.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/include/ace/FIFO.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Log_Record.h \ + $(WRAPPER_ROOT)/include/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/include/ace/Log_Record.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.i +SOCK_Acceptor.o: SOCK_Acceptor.C \ + $(WRAPPER_ROOT)/include/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/include/ace/SOCK.h \ + $(WRAPPER_ROOT)/include/ace/Addr.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/SOCK.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_Acceptor.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Specific.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/include/ace/FIFO.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Log_Record.h \ + $(WRAPPER_ROOT)/include/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/include/ace/Log_Record.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.i +SOCK_CODgram.o: SOCK_CODgram.C \ + $(WRAPPER_ROOT)/include/ace/SOCK_CODgram.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/include/ace/SOCK.h \ + $(WRAPPER_ROOT)/include/ace/Addr.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/SOCK.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_CODgram.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Specific.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/include/ace/FIFO.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Log_Record.h \ + $(WRAPPER_ROOT)/include/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/include/ace/Log_Record.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.i +SOCK_Connector.o: SOCK_Connector.C \ + $(WRAPPER_ROOT)/include/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/include/ace/SOCK.h \ + $(WRAPPER_ROOT)/include/ace/Addr.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/SOCK.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Specific.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/include/ace/FIFO.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Log_Record.h \ + $(WRAPPER_ROOT)/include/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/include/ace/Log_Record.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/include/ace/Handle_Set.i \ + $(WRAPPER_ROOT)/include/ace/INET_Addr.h +SOCK_Dgram.o: SOCK_Dgram.C \ + $(WRAPPER_ROOT)/include/ace/SOCK_Dgram.h \ + $(WRAPPER_ROOT)/include/ace/SOCK.h \ + $(WRAPPER_ROOT)/include/ace/Addr.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/SOCK.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_Dgram.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Specific.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/include/ace/FIFO.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Log_Record.h \ + $(WRAPPER_ROOT)/include/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/include/ace/Log_Record.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.i +SOCK_Dgram_Bcast.o: SOCK_Dgram_Bcast.C \ + $(WRAPPER_ROOT)/include/ace/SOCK_Dgram_Bcast.h \ + $(WRAPPER_ROOT)/include/ace/SOCK.h \ + $(WRAPPER_ROOT)/include/ace/Addr.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/SOCK.i \ + $(WRAPPER_ROOT)/include/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_Dgram.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_Dgram.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_Dgram_Bcast.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Specific.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/include/ace/FIFO.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Log_Record.h \ + $(WRAPPER_ROOT)/include/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/include/ace/Log_Record.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.i +SOCK_IO.o: SOCK_IO.C \ + $(WRAPPER_ROOT)/include/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/include/ace/SOCK.h \ + $(WRAPPER_ROOT)/include/ace/Addr.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/SOCK.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_IO.i +SOCK_Dgram_Mcast.o: SOCK_Dgram_Mcast.C \ + $(WRAPPER_ROOT)/include/ace/SOCK_Dgram_Mcast.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_Dgram.h \ + $(WRAPPER_ROOT)/include/ace/SOCK.h \ + $(WRAPPER_ROOT)/include/ace/Addr.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/SOCK.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_Dgram.i \ + $(WRAPPER_ROOT)/include/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_Dgram_Mcast.i +SOCK_Stream.o: SOCK_Stream.C \ + $(WRAPPER_ROOT)/include/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/include/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/include/ace/SOCK.h \ + $(WRAPPER_ROOT)/include/ace/Addr.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/SOCK.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/include/ace/SOCK_Stream.i +Signal.o: Signal.C \ + $(WRAPPER_ROOT)/include/ace/Signal.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/include/ace/Signal.i +Svc_Handler.o: Svc_Handler.C \ + $(WRAPPER_ROOT)/include/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/include/ace/Task.h \ + $(WRAPPER_ROOT)/include/ace/Trace.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/Service_Object.h \ + $(WRAPPER_ROOT)/include/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/include/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Specific.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/include/ace/FIFO.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Log_Record.h \ + $(WRAPPER_ROOT)/include/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/include/ace/Log_Record.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/include/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/include/ace/Thread.h \ + $(WRAPPER_ROOT)/include/ace/Service_Config.h \ + $(WRAPPER_ROOT)/include/ace/Reactor.h \ + $(WRAPPER_ROOT)/include/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/include/ace/Handle_Set.i \ + $(WRAPPER_ROOT)/include/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/include/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/include/ace/Signal.h \ + $(WRAPPER_ROOT)/include/ace/Token.h \ + $(WRAPPER_ROOT)/include/ace/Reactor.i \ + $(WRAPPER_ROOT)/include/ace/Service_Repository.h \ + $(WRAPPER_ROOT)/include/ace/Service_Record.h \ + $(WRAPPER_ROOT)/include/ace/Stream.h \ + $(WRAPPER_ROOT)/include/ace/Module.h \ + $(WRAPPER_ROOT)/include/ace/Svc_Handler.i +Synch.o: Synch.C \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/Synch.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Specific.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/include/ace/FIFO.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Log_Record.h \ + $(WRAPPER_ROOT)/include/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/include/ace/Log_Record.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Thread.h +Thread.o: Thread.C \ + $(WRAPPER_ROOT)/include/ace/Thread.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/Thread.i +Thread_Manager.o: Thread_Manager.C \ + $(WRAPPER_ROOT)/include/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/Thread.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Manager.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Specific.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/include/ace/FIFO.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/include/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/include/ace/FIFO_Send_Msg.i \ + $(WRAPPER_ROOT)/include/ace/Log_Record.h \ + $(WRAPPER_ROOT)/include/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/include/ace/Log_Record.i \ + $(WRAPPER_ROOT)/include/ace/Log_Msg.i +Thread_Specific.o: Thread_Specific.C \ + $(WRAPPER_ROOT)/include/ace/Thread_Specific.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/Thread_Specific.i +Time_Value.o: Time_Value.C \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.i +Timer_Queue.o: Timer_Queue.C \ + $(WRAPPER_ROOT)/include/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/include/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/Timer_Queue.i +Token.o: Token.C \ + $(WRAPPER_ROOT)/include/ace/Thread.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/Token.h \ + $(WRAPPER_ROOT)/include/ace/Synch.h \ + $(WRAPPER_ROOT)/include/ace/Time_Value.h +UNIX_Addr.o: UNIX_Addr.C \ + $(WRAPPER_ROOT)/include/ace/UNIX_Addr.h \ + $(WRAPPER_ROOT)/include/ace/Addr.h \ + $(WRAPPER_ROOT)/include/ace/sysincludes.h \ + $(WRAPPER_ROOT)/include/ace/config.h \ + $(WRAPPER_ROOT)/include/ace/Misc.h \ + $(WRAPPER_ROOT)/include/ace/UNIX_Addr.i + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/apps/Gateway/Gateway/Channel.cpp b/apps/Gateway/Gateway/Channel.cpp new file mode 100644 index 00000000000..f07b5a81978 --- /dev/null +++ b/apps/Gateway/Gateway/Channel.cpp @@ -0,0 +1,713 @@ +#include "ace/Log_Msg.h" +// @(#)Channel.cpp 1.1 10/18/96 + +#include "Routing_Entry.h" +#include "Channel_Connector.h" + +// Convenient short-hands. +#define CO CONDITION +#define MU MUTEX + +// = The total number of bytes sent/received on this channel. +size_t +Channel::total_bytes (void) +{ + return this->total_bytes_; +} + +void +Channel::total_bytes (size_t bytes) +{ + this->total_bytes_ += bytes; +} + +Channel::Channel (ROUTING_TABLE *rt, + Channel_Connector *cc, + ACE_Thread_Manager *thr_mgr, + int socket_queue_size) + : id_ (-1), + total_bytes_ (0), + state_ (Channel::IDLE), + routing_table_ (rt), + connector_ (cc), + timeout_ (1), + max_timeout_ (Channel::MAX_RETRY_TIMEOUT), + socket_queue_size_ (socket_queue_size), + ACE_Svc_Handler (thr_mgr) +{ +} + +// Set the associated channel. + +void +Channel::active (int a) +{ + this->state (a == 0 ? Channel::IDLE : Channel::ESTABLISHED); +} + +// Get the associated channel. + +int +Channel::active (void) +{ + return this->state () == Channel::ESTABLISHED; +} + +// Set the direction. + +void +Channel::direction (char d) +{ + this->direction_ = d; +} + +// Get the direction. + +char +Channel::direction (void) +{ + return this->direction_; +} + +// Sets the timeout delay. + +void +Channel::timeout (int to) +{ + if (to > this->max_timeout_) + to = this->max_timeout_; + + this->timeout_ = to; +} + +// Recalculate the current retry timeout delay using exponential +// backoff. Returns the original timeout (i.e., before the +// recalculation). + +int +Channel::timeout (void) +{ + int old_timeout = this->timeout_; + this->timeout_ *= 2; + + if (this->timeout_ > this->max_timeout_) + this->timeout_ = this->max_timeout_; + + return old_timeout; +} + +// Sets the max timeout delay. + +void +Channel::max_timeout (int mto) +{ + this->max_timeout_ = mto; +} + +// Gets the max timeout delay. + +int +Channel::max_timeout (void) +{ + return this->max_timeout_; +} + +// Restart connection asynchronously when timeout occurs. + +int +Channel::handle_timeout (const ACE_Time_Value &, const void *) +{ + ACE_DEBUG ((LM_DEBUG, + "(%t) attempting to reconnect Channel %d with timeout = %d\n", + this->id (), this->timeout_)); + return this->connector_->initiate_connection (this, ACE_Synch_Options::asynch); +} + +// Restart connection (blocking_semantics dicates whether we +// restart synchronously or asynchronously). + +int +Channel::reinitiate_connection (void) +{ + // Skip over deactivated descriptors. + if (this->get_handle () != -1) + { + // Make sure to close down peer to reclaim descriptor. + this->peer ().close (); + +#if 0 +// if (this->state () == FAILED) +// { + // Reinitiate timeout to improve reconnection time. +// this->timeout (1); +#endif + + ACE_DEBUG ((LM_DEBUG, + "(%t) scheduling reinitiation of Channel %d\n", + this->id ())); + + // Reschedule ourselves to try and connect again. + if (ACE_Service_Config::reactor ()->schedule_timer (this, 0, + this->timeout ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", + "schedule_timer"), -1); + } + return 0; +} + +// Handle shutdown of the Channel object. + +int +Channel::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) shutting down Channel %d on handle %d\n", + this->id (), this->get_handle ())); + + return this->reinitiate_connection (); +} + +// Set the state of the channel. + +void +Channel::state (Channel::State s) +{ + this->state_ = s; +} + +// Perform the first-time initiation of a connection to the peer. + +int +Channel::initialize_connection (void) +{ + this->state_ = Channel::ESTABLISHED; + + // Restart the timeout to 1. + this->timeout (1); + +#if defined (ASSIGN_ROUTING_ID) + // Action that sends the route id to the peerd. + + CONN_ID id = htons (this->id ()); + + ssize_t n = this->peer ().send ((const void *) &id, sizeof id); + + if (n != sizeof id) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", + n == 0 ? "gatewayd has closed down unexpectedly" : "send"), -1); +#endif /* ASSIGN_ROUTING_ID */ + return 0; +} + +// Set the size of the socket queue. + +void +Channel::socket_queue_size (void) +{ + if (this->socket_queue_size_ > 0) + { + int option = this->direction_ == 'I' ? SO_RCVBUF : SO_SNDBUF; + + if (this->peer ().set_option (SOL_SOCKET, option, + &this->socket_queue_size_, sizeof (int)) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "set_option")); + } +} + +// Upcall from the ACE_Acceptor::handle_input() that +// delegates control to our application-specific Channel. + +int +Channel::open (void *a) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) Channel's fd = %d\n", this->peer ().get_handle ())); + + // Set the size of the socket queue. + this->socket_queue_size (); + + // Turn on non-blocking I/O. + if (this->peer ().enable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "enable"), -1); + + // Call down to the base class to activate and register this handler. + if (this->ACE_Svc_Handler::open (a) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "activate"), -1); + + return this->initialize_connection (); +} + +// Return the current state of the channel. + +Channel::State +Channel::state (void) +{ + return this->state_; +} + +void +Channel::id (CONN_ID id) +{ + this->id_ = id; +} + +CONN_ID +Channel::id (void) +{ + return this->id_; +} + +// Set the peer's address information. +int +Channel::bind (const ACE_INET_Addr &remote_addr, + const ACE_INET_Addr &local_addr, + CONN_ID id) +{ + this->remote_addr_ = remote_addr; + this->local_addr_ = local_addr; + this->id_ = id; + return 0; +} + +ACE_INET_Addr & +Channel::remote_addr (void) +{ + return this->remote_addr_; +} + +ACE_INET_Addr & +Channel::local_addr (void) +{ + return this->local_addr_; +} + +// Constructor sets the routing table pointer. + +Output_Channel::Output_Channel (ROUTING_TABLE *rt, + Channel_Connector *cc, + ACE_Thread_Manager *thr_mgr, + int socket_queue_size) + : Channel (rt, cc, thr_mgr, socket_queue_size) +{ + this->direction_ = 'O'; + this->msg_queue ()->high_water_mark (Output_Channel::QUEUE_SIZE); +} + +// This method should be called only when the peer shuts down +// unexpectedly. This method simply marks the Channel as +// having failed so that handle_close () can reconnect. + +int +Output_Channel::handle_input (ACE_HANDLE) +{ + char buf[1]; + + this->state (Channel::FAILED); + + switch (this->peer ().recv (buf, sizeof buf)) + { + case -1: + ACE_ERROR_RETURN ((LM_ERROR, + "(%t) Peer has failed unexpectedly for Output Channel %d\n", + this->id ()), -1); + /* NOTREACHED */ + case 0: + ACE_ERROR_RETURN ((LM_ERROR, + "(%t) Peer has shutdown unexpectedly for Output Channel %d\n", + this->id ()), -1); + /* NOTREACHED */ + default: + ACE_ERROR_RETURN ((LM_ERROR, + "(%t) Peer is sending input on Output Channel %d\n", + this->id ()), -1); + /* NOTREACHED */ + } +} + +int +Output_Channel::svc (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "(%t) svc should not be called on Output_Channel!\n"), -1); +} + +// Perform a non-blocking put() of message MB. If we are unable to +// send the entire message the remainder is re-queued at the *front* of +// the Message_List. + +int +Output_Channel::nonblk_put (ACE_Message_Block *mb) +{ + // Try to send the message. If we don't send it all (e.g., due to + // flow control), then re-queue the remainder at the head of the + // Message_List and ask the ACE_Reactor to inform us (via + // handle_output()) when it is possible to try again. + + ssize_t n; + + if ((n = this->send_peer (mb)) == -1) + { + // Things have gone wrong, let's try to close down and set up a new reconnection. + this->state (Channel::FAILED); + this->handle_close (); + return -1; + } + else if (errno == EWOULDBLOCK) // Didn't manage to send everything. + { + ACE_DEBUG ((LM_DEBUG, "(%t) queueing activated on handle %d to routing id %d\n", + this->get_handle (), this->id ())); + + // ACE_Queue in *front* of the list to preserve order. + if (this->msg_queue ()->enqueue_head (mb, (ACE_Time_Value *) &ACE_Time_Value::zero) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "enqueue_head"), -1); + + // Tell ACE_Reactor to call us back when we can send again. + else if (ACE_Service_Config::reactor ()-> + schedule_wakeup (this, ACE_Event_Handler::WRITE_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "schedule_wakeup"), -1); + return 0; + } + else + return n; +} + +int +Output_Channel::send_peer (ACE_Message_Block *mb) +{ + ssize_t n; + size_t len = mb->length (); + + if ((n = this->peer ().send (mb->rd_ptr (), len)) <= 0) + return errno == EWOULDBLOCK ? 0 : n; + else if (n < len) + // Re-adjust pointer to skip over the part we did send. + mb->rd_ptr (n); + else /* if (n == length) */ + { + // The whole message is sent, we can now safely deallocate the buffer. + // Note that this should decrement a reference count... + delete mb; + errno = 0; + } + this->total_bytes (n); + return n; +} + +// Finish sending a message when flow control conditions abate. +// This method is automatically called by the ACE_Reactor. + +int +Output_Channel::handle_output (ACE_HANDLE) +{ + ACE_Message_Block *mb = 0; + int status = 0; + + ACE_DEBUG ((LM_DEBUG, "(%t) in handle_output on handle %d\n", this->get_handle ())); + // The list had better not be empty, otherwise there's a bug! + + if (this->msg_queue ()->dequeue_head (mb, (ACE_Time_Value *) &ACE_Time_Value::zero) != -1) + { + switch (this->nonblk_put (mb)) + { + case 0: // Partial send. + ACE_ASSERT (errno == EWOULDBLOCK); + // Didn't write everything this time, come back later... + break; + + case -1: + // Caller is responsible for freeing a ACE_Message_Block if failures occur. + delete mb; + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "transmission failure")); + + /* FALLTHROUGH */ + default: // Sent the whole thing. + + // If we succeed in writing the entire message (or we did not fail + // due to EWOULDBLOCK) then check if there are more messages on the Message_List. + // If there aren't, tell the ACE_Reactor not to notify us anymore (at least + // until there are new messages queued up). + + if (this->msg_queue ()->is_empty ()) + { + ACE_DEBUG ((LM_DEBUG, "(%t) queueing deactivated on handle %d to routing id %d\n", + this->get_handle (), this->id ())); + + + if (ACE_Service_Config::reactor ()-> + cancel_wakeup (this, ACE_Event_Handler::WRITE_MASK) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "cancel_wakeup")); + } + } + } + else + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "dequeue_head")); + return 0; +} + +// Send a message to a peer (may queue if necessary). + +int +Output_Channel::put (ACE_Message_Block *mb, ACE_Time_Value *) +{ + if (this->msg_queue ()->is_empty ()) + // Try to send the message *without* blocking! + return this->nonblk_put (mb); + else + // If we have queued up messages due to flow control + // then just enqueue and return. + return this->msg_queue ()->enqueue_tail (mb, (ACE_Time_Value *) &ACE_Time_Value::zero); +} + +// Constructor sets the routing table pointer and the connector pointer. + +Input_Channel::Input_Channel (ROUTING_TABLE *rt, + Channel_Connector *cc, + ACE_Thread_Manager *thr_mgr, + int socket_queue_size) + : msg_frag_ (0), + Channel (rt, cc, thr_mgr, socket_queue_size) +{ + this->direction_ = 'I'; + this->msg_queue ()->high_water_mark (0); +} + +int +Input_Channel::put (ACE_Message_Block *, ACE_Time_Value *) +{ + ACE_ERROR_RETURN ((LM_ERROR, "(%t) put should not be called on Input_Channel!\n"), -1); +} + +int +Input_Channel::svc (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "(%t) svc should not be called on Input_Channel!\n"), -1); +} + +// Receive a Peer message from peerd. Handles fragmentation. +// +// The routing message returned from recv_peer consists of two parts: +// 1. The Address part, contains the virtual routing id. +// 2. The Data part, which contains the actual data to be routed. +// +// The reason for having two parts is to shield the higher layers +// of software from knowledge of the message structure. + +int +Input_Channel::recv_peer (ACE_Message_Block *&route_addr) +{ + Peer_Message *peer_msg; + size_t len; + ssize_t n = 0; + ssize_t m = 0; + size_t offset = 0; + + if (this->msg_frag_ == 0) + { + // No existing fragment... + ACE_NEW_RETURN (this->msg_frag_, + ACE_Message_Block (sizeof (Peer_Message)), + -1); + + if (this->msg_frag_ == 0) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) out of memory\n"), -1); + + peer_msg = (Peer_Message *) this->msg_frag_->rd_ptr (); + + switch (n = this->peer ().recv (peer_msg, sizeof (Peer_Header))) + { + case sizeof (Peer_Header): + len = ntohl (peer_msg->header_.len_); + if (len <= sizeof peer_msg->buf_) + { + this->msg_frag_->wr_ptr (sizeof (Peer_Header)); + break; // The message is within the maximum size range. + } + else + ACE_ERROR ((LM_ERROR, "(%t) message too long = %d\n", len)); + /* FALLTHROUGH */ + default: + ACE_ERROR ((LM_ERROR, "(%t) invalid length = %d\n", n)); + n = -1; + /* FALLTHROUGH */ + case -1: + /* FALLTHROUGH */ + case 0: // Premature EOF. + // Make sure to free up memory on error returns. + delete this->msg_frag_; + this->msg_frag_ = 0; + return n; + } + } + else + { + // Figure out where we left off. + peer_msg = (Peer_Message *) this->msg_frag_->rd_ptr (); + offset = this->msg_frag_->length () - sizeof (Peer_Header); + len = peer_msg->header_.len_ - offset; + } + + // Try to receive the remainder of the message. + + switch (m = this->peer ().recv (peer_msg->buf_ + offset, len)) + { + case -1: + if (errno == EWOULDBLOCK) + { + // This shouldn't happen since the ACE_Reactor + // just triggered us to handle pending I/O! + ACE_DEBUG ((LM_DEBUG, "(%t) unexpected recv failure\n")); + errno = EWOULDBLOCK; + return -1; + } + else + /* FALLTHROUGH */; + + case 0: // Premature EOF. + delete this->msg_frag_; + this->msg_frag_ = 0; + return 0; + + default: + if (m != len) + // Re-adjust pointer to skip over the part we've read. + { + this->msg_frag_->wr_ptr (m); + errno = EWOULDBLOCK; + return -1; // Inform caller that we didn't get the whole message. + } + else + { + // Set the write pointer at 1 past the end of the message. + this->msg_frag_->wr_ptr (m); + + // Set the read pointer to the beginning of the message. + this->msg_frag_->rd_ptr (this->msg_frag_->base ()); + + // Allocate a routing message header and chain the data portion + // onto its continuation field. + ACE_NEW_RETURN (route_addr, + ACE_Message_Block (sizeof (Peer_Addr), + ACE_Message_Block::MB_PROTO, + this->msg_frag_), + -1); + + Peer_Addr peer_addr (this->id (), peer_msg->header_.routing_id_, 0); + // Copy the routing address from the Peer_Message into routing_addr. + route_addr->copy ((char *) &peer_addr, sizeof (Peer_Addr)); + + // Reset the pointer to indicate we've got an entire message. + this->msg_frag_ = 0; + } + this->total_bytes (m + n); +#if defined (VERBOSE) + ACE_DEBUG ((LM_DEBUG, "(%t) channel id = %d, route id = %d, len = %d, payload = %*s", + peer_addr.conn_id_, peer_msg->header_.routing_id_, peer_msg->header_.len_, + peer_msg->header_.len_, peer_msg->buf_)); +#else + ACE_DEBUG ((LM_DEBUG, "(%t) route id = %d, cur len = %d, total bytes read = %d\n", + peer_msg->header_.routing_id_, peer_msg->header_.len_, this->total_bytes ())); +#endif + return m + n; + } +} + +// Receive various types of input (e.g., Peer message from the +// gatewayd, as well as stdio). + +int +Input_Channel::handle_input (ACE_HANDLE) +{ + ACE_Message_Block *route_addr = 0; + + switch (this->recv_peer (route_addr)) + { + case 0: + // Note that a peer should never initiate a shutdown. + this->state (Channel::FAILED); + ACE_ERROR_RETURN ((LM_ERROR, + "(%t) Peer has closed down unexpectedly for Input Channel %d\n", + this->id ()), -1); + /* NOTREACHED */ + case -1: + if (errno == EWOULDBLOCK) + // A short-read, we'll come back and finish it up later on! + return 0; + else // A weird problem occurred, shut down and start again. + { + this->state (Channel::FAILED); + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p for Input Channel %d\n", + "Peer has failed unexpectedly", + this->id ()), -1); + } + /* NOTREACHED */ + default: + return this->route_message (route_addr); + } +} + +// Route a message to its appropriate destination. + +int +Input_Channel::route_message (ACE_Message_Block *route_addr) +{ + // We got a valid message, so determine its virtual routing id, + // which is stored in the first of the two message blocks chained together. + + Peer_Addr *routing_key = (Peer_Addr *) route_addr->rd_ptr (); + + // Skip over the address portion. + const ACE_Message_Block *const data = route_addr->cont (); + + // RE points to the routing entry located for this routing id. + Routing_Entry *re = 0; + + if (this->routing_table_->find (*routing_key, re) != -1) + { + // Check to see if there are any destinations. + if (re->destinations ()->size () == 0) + ACE_DEBUG ((LM_WARNING, + "there are no active destinations for this message currently\n")); + + else // There are destinations, so forward the message. + { + Routing_Entry::ENTRY_SET *esp = re->destinations (); + Routing_Entry::ENTRY_ITERATOR si (*esp); + + for (Channel **channel = 0; si.next (channel) != 0; si.advance ()) + { + // Only process active channels. + if ((*channel)->active ()) + { + // Clone the message portion (should be doing reference counting here...) + ACE_Message_Block *newmsg = data->clone (); + + ACE_DEBUG ((LM_DEBUG, "(%t) sending to peer %d\n", (*channel)->id ())); + + if ((*channel)->put (newmsg) == -1) + { + if (errno == EWOULDBLOCK) // The queue has filled up! + ACE_ERROR ((LM_ERROR, "(%t) %p\n", + "gateway is flow controlled, so we're dropping messages")); + else + ACE_ERROR ((LM_ERROR, "(%t) %p transmission error to route %d\n", + "put", (*channel)->id ())); + + // Caller is responsible for freeing a ACE_Message_Block if failures occur. + delete newmsg; + } + } + } + // Will become superfluous once we have reference counting... + delete route_addr; + return 0; + } + } + delete route_addr; + // Failure return. + ACE_ERROR ((LM_DEBUG, "(%t) find failed on conn id = %d, logical id = %d, payload = %d\n", + routing_key->conn_id_, routing_key->logical_id_, routing_key->payload_)); + return 0; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Map_Manager; +template class ACE_Map_Iterator; +template class ACE_Map_Entry; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/apps/Gateway/Gateway/Channel.h b/apps/Gateway/Gateway/Channel.h new file mode 100644 index 00000000000..9410d0121ae --- /dev/null +++ b/apps/Gateway/Gateway/Channel.h @@ -0,0 +1,281 @@ +/* -*- C++ -*- */ +// @(#)Channel.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// apps +// +// = FILENAME +// Channel.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (_CHANNEL) +#define _CHANNEL + +#include "ace/Service_Config.h" +#include "ace/INET_Addr.h" +#include "ace/SOCK_Connector.h" +#include "ace/Svc_Handler.h" +#include "Routing_Table.h" +#include "Routing_Entry.h" +#include "Peer_Message.h" + +// The following typedefs are used in order to parameterize the +// synchronization policies without changing the source code! + +// If we don't have threads then use the single-threaded synchronization. +#if !defined (ACE_HAS_THREADS) +#define SYNCH ACE_NULL_SYNCH +typedef ACE_Null_Mutex MUTEX; +#define CHANNEL_PEER_STREAM ACE_SOCK_STREAM +#define CHANNEL_PEER_CONNECTOR ACE_SOCK_CONNECTOR +#else /* ACE_HAS_THREADS */ + +// Select communication mechanisms. +#if 0 // defined (ACE_HAS_TLI) +// Note that due to inconsistencies between the semantics of sockets +// and TLI with respect to establishing non-blocking connections it's +// not a good idea to use TLI... +#include "ace/TLI_Connector.h" +#define CHANNEL_PEER_STREAM ACE_TLI_STREAM +#define CHANNEL_PEER_CONNECTOR ACE_TLI_CONNECTOR +#else +#define CHANNEL_PEER_STREAM ACE_SOCK_STREAM +#define CHANNEL_PEER_CONNECTOR ACE_SOCK_CONNECTOR +#endif /* 0 */ + +// Note that we only need to make the ACE_Task thread-safe if we +// are using the multi-threaded Thr_Output_Channel... +#if defined (USE_OUTPUT_MT) +#define SYNCH ACE_MT_SYNCH +#else +#define SYNCH ACE_NULL_SYNCH +#endif /* USE_OUTPUT_MT || USE_INPUT_MT */ + +// Note that we only need to make the ACE_Map_Manager thread-safe if +// we are using the multi-threaded Thr_Input_Channel... +#if defined (USE_INPUT_MT) +typedef ACE_RW_Mutex MUTEX; +#else +typedef ACE_Null_Mutex MUTEX; +#endif /* USE_INPUT_MT */ +#endif /* ACE_HAS_THREADS */ + +// Typedef for the routing table. +typedef Routing_Table + ROUTING_TABLE; + +// Forward declaration. +class Channel_Connector; + +class Channel : public ACE_Svc_Handler + // = TITLE + // Channel contains info about connection state and addressing. + // + // = DESCRIPTION + // The Channel classes process messages sent from the peers to the + // gateway. These classes works as follows: + // + // 1. Channel_Connector creates a number of connections with the set of + // peers specified in a configuration file. + // + // 2. For each peer that connects successfully, Channel_Connector + // creates an Channel object. Each object assigns a unique routing + // id to its associated peer. The Channels are used by gatewayd + // that to receive, route, and forward messages from source peer(s) + // to destination peer(s). +{ +public: + Channel (ROUTING_TABLE *, + Channel_Connector *, + ACE_Thread_Manager * = 0, + int socket_queue_size = 0); + + virtual int open (void * = 0); + // Initialize and activate a single-threaded Channel (called by + // ACE_Connector::handle_output()). + + int bind (const ACE_INET_Addr &remote_addr, + const ACE_INET_Addr &local_addr, + CONN_ID); + // Set the peer's addressing and routing information. + + ACE_INET_Addr &remote_addr (void); + // Returns the peer's routing address. + + ACE_INET_Addr &local_addr (void); + // Returns our local address. + + // = Set/get routing id. + CONN_ID id (void); + void id (CONN_ID); + + // = Set/get the current state of the Channel. + enum State + { + IDLE = 1, // Prior to initialization. + CONNECTING, // During connection establishment. + ESTABLISHED, // Channel is established and active. + DISCONNECTING, // Channel is in the process of connecting. + FAILED // Channel has failed. + }; + + // = Set/get the current state. + State state (void); + void state (State); + + // = Set/get the current retry timeout delay. + int timeout (void); + void timeout (int); + + // = Set/get the maximum retry timeout delay. + int max_timeout (void); + void max_timeout (int); + + // = Set/get Channel activity status. + int active (void); + void active (int); + + // = Set/get direction (necessary for error checking). + char direction (void); + void direction (char); + + // = The total number of bytes sent/received on this channel. + size_t total_bytes (void); + void total_bytes (size_t bytes); + // Increment count by . + + virtual int handle_timeout (const ACE_Time_Value &, const void *arg); + // Perform timer-based Channel reconnection. + +protected: + enum + { + MAX_RETRY_TIMEOUT = 300 // 5 minutes is the maximum timeout. + }; + + int initialize_connection (void); + // Perform the first-time initiation of a connection to the peer. + + int reinitiate_connection (void); + // Reinitiate a connection asynchronously when peers fail. + + void socket_queue_size (void); + // Set the socket queue size. + + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::RWE_MASK); + // Perform Channel termination. + + ROUTING_TABLE *routing_table_; + // Pointer to table that maps a Peer_Addr + // to a Set of Channel *'s for output. + + ACE_INET_Addr remote_addr_; + // Address of peer. + + ACE_INET_Addr local_addr_; + // Address of us. + + CONN_ID id_; + // The assigned routing ID of this entry. + + size_t total_bytes_; + // The total number of bytes sent/received on this channel. + + State state_; + // The current state of the channel. + + Channel_Connector *connector_; + // Back pointer to Channel_Connector to reestablish broken + // connections. + + int timeout_; + // Amount of time to wait between reconnection attempts. + + int max_timeout_; + // Maximum amount of time to wait between reconnection attempts. + + char direction_; + // Indicates which direction data flows through the channel ('O' == + // output and 'I' == input). + + int socket_queue_size_; + // Size of the socket queue (0 means "use default"). +}; + +class Input_Channel : public Channel + // = TITLE + // Handle reception of Peer messages arriving as events. +{ +public: + Input_Channel (ROUTING_TABLE *, + Channel_Connector *, + ACE_Thread_Manager * = 0, + int socket_queue_size = 0); + // Constructor sets the routing table pointer. + + virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE); + // Receive and process peer messages. + +protected: + virtual int recv_peer (ACE_Message_Block *&); + // Receive a message from a peer. + + int route_message (ACE_Message_Block *); + // Action that receives messages from peerd. + + ACE_Message_Block *msg_frag_; + // Keep track of message fragment to handle non-blocking recv's from + // peers. + + virtual int svc (void); + // This method is not used since we are single-threaded. + +private: + virtual int put (ACE_Message_Block *, ACE_Time_Value *tv = 0); + // This methods should not be called to handle input. +}; + +class Output_Channel : public Channel + // = TITLE + // Handle transmission of messages to other Peers using a + // single-threaded approach. +{ +public: + Output_Channel (ROUTING_TABLE *, + Channel_Connector *, + ACE_Thread_Manager * = 0, + int socket_queue_size = 0); + + virtual int put (ACE_Message_Block *, ACE_Time_Value * = 0); + // Send a message to a gateway (may be queued if necessary). + +protected: + // = We'll allow up to 16 megabytes to be queued per-output + // channel. + enum {QUEUE_SIZE = 1024 * 1024 * 16}; + + virtual int handle_input (ACE_HANDLE); + // Receive and process shutdowns from peer. + + virtual int handle_output (ACE_HANDLE); + // Finish sending a message when flow control conditions abate. + + int nonblk_put (ACE_Message_Block *mb); + // Perform a non-blocking put(). + + virtual int send_peer (ACE_Message_Block *); + // Send a message to a peer. + + virtual int svc (void); + // This method is not used since we are single-threaded. +}; + +#endif /* _CHANNEL */ diff --git a/apps/Gateway/Gateway/Channel_Connector.cpp b/apps/Gateway/Gateway/Channel_Connector.cpp new file mode 100644 index 00000000000..429fa595df2 --- /dev/null +++ b/apps/Gateway/Gateway/Channel_Connector.cpp @@ -0,0 +1,92 @@ +#include "Channel_Connector.h" +// @(#)Channel_Connector.cpp 1.1 10/18/96 + + +Channel_Connector::Channel_Connector (void) +{ +} + +// Override the connection-failure method to add timer support. +// Note that these timers perform "expoential backoff" to +// avoid rapidly trying to reestablish connections when a link +// goes down. + +int +Channel_Connector::handle_close (ACE_HANDLE sd, ACE_Reactor_Mask) +{ + ACE_Connector::AST *stp = 0; + + // Locate the ACE_Svc_Handler corresponding to the socket descriptor. + if (this->handler_map_.find (sd, stp) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) can't locate channel %d in map, %p\n", + sd, "find"), -1); + + Channel *channel = stp->svc_handler (); + + // Schedule a reconnection request at some point in the future + // (note that channel uses an exponential backoff scheme). + if (ACE_Service_Config::reactor ()->schedule_timer (channel, 0, + channel->timeout ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", + "schedule_timer"), -1); + return 0; +} + +// Initiate (or reinitiate) a connection to the Channel. + +int +Channel_Connector::initiate_connection (Channel *channel, + ACE_Synch_Options &synch_options) +{ + char buf[MAXHOSTNAMELEN]; + + // Mark ourselves as idle so that the various iterators + // will ignore us until we are reconnected. + channel->state (Channel::IDLE); + + if (channel->remote_addr ().addr_to_string (buf, sizeof buf) == -1 + || channel->local_addr ().addr_to_string (buf, sizeof buf) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", + "can't obtain peer's address"), -1); + + // Try to connect to the Peer. + + if (this->connect (channel, channel->remote_addr (), + synch_options, channel->local_addr ()) == -1) + { + if (errno != EWOULDBLOCK) + { + channel->state (Channel::FAILED); + ACE_DEBUG ((LM_DEBUG, "(%t) %p on address %s\n", + "connect", buf)); + + // Reschedule ourselves to try and connect again. + if (synch_options[ACE_Synch_Options::USE_REACTOR]) + { + if (ACE_Service_Config::reactor ()->schedule_timer + (channel, 0, channel->timeout ()) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", + "schedule_timer"), -1); + } + else + // Failures on synchronous connects are reported as errors + // so that the caller can decide how to proceed. + return -1; + } + else + { + channel->state (Channel::CONNECTING); + ACE_DEBUG ((LM_DEBUG, + "(%t) in the process of connecting %s to %s\n", + synch_options[ACE_Synch_Options::USE_REACTOR] + ? "asynchronously" : "synchronously", buf)); + } + } + else + { + channel->state (Channel::ESTABLISHED); + ACE_DEBUG ((LM_DEBUG, "(%t) connected to %s on %d\n", + buf, channel->get_handle ())); + } + return 0; +} diff --git a/apps/Gateway/Gateway/Channel_Connector.h b/apps/Gateway/Gateway/Channel_Connector.h new file mode 100644 index 00000000000..f15ced0e14d --- /dev/null +++ b/apps/Gateway/Gateway/Channel_Connector.h @@ -0,0 +1,41 @@ +/* -*- C++ -*- */ +// @(#)Channel_Connector.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// apps +// +// = FILENAME +// Channel_Connector.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (_CHANNEL_CONNECTOR) +#define _CHANNEL_CONNECTOR + +#include "ace/Connector.h" +#include "Thr_Channel.h" + +class Channel_Connector : public ACE_Connector + // = TITLE + // A concrete factory class that setups connections to peerds + // and produces a new Channel object to do the dirty work... +{ +public: + Channel_Connector (void); + + // Initiate (or reinitiate) a connection on the Channel. + int initiate_connection (Channel *, + ACE_Synch_Options & = ACE_Synch_Options::synch); + +protected: + // Override the connection-failure method to add timer support. + virtual int handle_close (ACE_HANDLE sd, ACE_Reactor_Mask); +}; + +#endif /* _CHANNEL_CONNECTOR */ diff --git a/apps/Gateway/Gateway/Config_Files.cpp b/apps/Gateway/Gateway/Config_Files.cpp new file mode 100644 index 00000000000..5dddbf8cefa --- /dev/null +++ b/apps/Gateway/Gateway/Config_Files.cpp @@ -0,0 +1,170 @@ +#include "ace/OS.h" +// @(#)Config_Files.cpp 1.1 10/18/96 + +#include "Config_Files.h" + +// This fixes a nasty bug with cfront-based compilers (like +// Centerline). +typedef FP::Return_Type FP_RETURN_TYPE; + +FP_RETURN_TYPE +RT_Config_File_Parser::read_entry (RT_Config_File_Entry &entry, + int &line_number) +{ + FP_RETURN_TYPE read_result; + // increment the line count + line_number++; + + // Ignore comments, check for EOF and EOLINE + // if this succeeds, we have our connection id + while ((read_result = this->getint (entry.conn_id_)) != FP::SUCCESS) + { + if (read_result == FP::EOFILE) + return FP::EOFILE; + else if (read_result == FP::EOLINE + || read_result == FP::COMMENT) + { + // increment the line count + line_number++; + } + } + + // Get the logic id. + if ((read_result = this->getint (entry.logical_id_)) != FP::SUCCESS) + return read_result; + + // Get the payload type. + if ((read_result = this->getint (entry.payload_type_)) != FP::SUCCESS) + return read_result; + + // get all the destinations. + entry.total_destinations_ = 0; + + while ((read_result = this->getint (entry.destinations_[entry.total_destinations_])) + == FP::SUCCESS) + ++entry.total_destinations_; // do nothing + + if (read_result == FP::EOLINE || read_result == FP::EOFILE) + return FP::SUCCESS; + else + return read_result; +} + +FP_RETURN_TYPE +CC_Config_File_Parser::read_entry (CC_Config_File_Entry &entry, + int &line_number) +{ + char buf[BUFSIZ]; + FP_RETURN_TYPE read_result; + // increment the line count + line_number++; + + // Ignore comments, check for EOF and EOLINE + // if this succeeds, we have our connection id + while ((read_result = this->getint (entry.conn_id_)) != FP::SUCCESS) + { + if (read_result == FP::EOFILE) + return FP::EOFILE; + else if (read_result == FP::EOLINE || + read_result == FP::COMMENT) + { + // increment the line count + line_number++; + } + } + + // get the hostname + if ((read_result = this->getword (entry.host_)) != FP::SUCCESS) + return read_result; + + int port; + + // Get the port number. + if ((read_result = this->getint (port)) != FP::SUCCESS) + return read_result; + else + entry.remote_port_ = (u_short) port; + + // Get the direction. + if ((read_result = this->getword (buf)) != FP::SUCCESS) + return read_result; + else + entry.direction_ = buf[0]; + + // Get the max retry delay. + if ((read_result = this->getint (entry.max_retry_delay_)) != FP::SUCCESS) + return read_result; + + // Get the local port number. + if ((read_result = this->getint (port)) != FP::SUCCESS) + return read_result; + else + entry.local_port_ = (u_short) port; + + return FP::SUCCESS; +} + +#if defined (DEBUGGING) +int main (int argc, char *argv[]) +{ + if (argc != 4) { +// ACE_ERROR_RETURN ((LM_ERROR, "%s filename\n", argv[0]), -1); + cerr << argv[0] << " CCfilename RTfilename Mapfilename.\n"; + exit (1); + } + FP_RETURN_TYPE result; + CC_Config_File_Entry CCentry; + CC_Config_File_Parser CCfile; + + CCfile.open (argv[1]); + + int line_number = 0; + + printf ("ConnID\tHost\t\tRPort\tDir\tRetry\tLPort\n"); + + // Read config file line at a time. + while ((result = CCfile.read_entry (CCentry, line_number)) != EOF) + { + if (result != FP::SUCCESS) + // ACE_DEBUG ((LM_DEBUG, "Error line %d.\n", line_number)); + cerr << "Error at line " << line_number << endl; + else + printf ("%d\t%s\t%d\t%c\t%d\t%c\t%d\n", + CCentry.conn_id_, CCentry.host_, CCentry.remote_port_, CCentry.direction_, + CCentry.max_retry_delay_, CCentry.transform_, CCentry.local_port_); + } + CCfile.close(); + + RT_Config_File_Entry RTentry; + RT_Config_File_Parser RTfile; + + RTfile.open (argv[2]); + + line_number = 0; + + printf ("\nConnID\tLogic\tPayload\tDestinations\n"); + + // Read config file line at a time. + while ((result = RTfile.read_entry (RTentry, line_number)) != EOF) + { + if (result != FP::SUCCESS) + cerr << "Error at line " << line_number << endl; + else + { + printf ("%d\t%d\t%d\t%d\t", + RTentry.conn_id_, RTentry.logical_id_, RTentry.payload_type_); + while (--RTentry.total_destinations_ >= 0) + printf ("%d,", RTentry.destinations_[RTentry.total_destinations_]); + printf ("\n"); + } + } + RTfile.close(); + + return 0; +} +#endif /* DEBUGGING */ + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class File_Parser; +template class File_Parser; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/apps/Gateway/Gateway/Config_Files.h b/apps/Gateway/Gateway/Config_Files.h new file mode 100644 index 00000000000..67965fbff8b --- /dev/null +++ b/apps/Gateway/Gateway/Config_Files.h @@ -0,0 +1,91 @@ +/* -*- C++ -*- */ +// @(#)Config_Files.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// apps +// +// = FILENAME +// Config_Files.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (_CONFIG_FILES) +#define _CONFIG_FILES + +#include "ace/OS.h" +#include "File_Parser.h" + +class CC_Config_File_Entry + // = TITLE + // Stores the information in a Channel Connection entry. +{ +public: + int conn_id_; + // Connection id for this Channel. + + char host_[BUFSIZ]; + // Host to connect with. + + u_short remote_port_; + // Port to connect with. + + char direction_; + // 'I' (input) or 'O' (output) + + int max_retry_delay_; + // Maximum amount of time to wait for reconnecting. + + u_short local_port_; + // Our local port number. +}; + +class CC_Config_File_Parser : public File_Parser + // = TITLE + // Parser for the Channel Connection file. +{ +public: + virtual FP::Return_Type + read_entry (CC_Config_File_Entry &entry, int &line_number); +}; + +class RT_Config_File_Entry + // = TITLE + // Stores the information in a Routing Table entry. +{ +public: + enum { + MAX_DESTINATIONS = 1000 // Total number of multicast destinations. + }; + + int conn_id_; + // Connection id for this channel. + + int logical_id_; + // Logical routing id for this channel. + + int payload_type_; + // Type of payload in the message. + + int destinations_[MAX_DESTINATIONS]; + // Connection ids for destinations that we're routing to. + + int total_destinations_; + // Total number of these destinations. +}; + +class RT_Config_File_Parser : public File_Parser + // = TITLE + // Parser for the Routing Table file. +{ +public: + virtual FP::Return_Type + read_entry (RT_Config_File_Entry &entry, int &line_number); +}; + +#endif /* _CONFIG_FILES */ diff --git a/apps/Gateway/Gateway/File_Parser.cpp b/apps/Gateway/Gateway/File_Parser.cpp new file mode 100644 index 00000000000..2fc52d7980a --- /dev/null +++ b/apps/Gateway/Gateway/File_Parser.cpp @@ -0,0 +1,142 @@ +#if !defined (FILE_PARSER_C) +// @(#)File_Parser.cpp 1.1 10/18/96 + +#define FILE_PARSER_C + +#include "ace/OS.h" +#include "File_Parser.h" + +// This fixes a nasty bug with cfront-based compilers (like +// Centerline). +typedef FP::Return_Type FP_RETURN_TYPE; + +// File_Parser stuff. + +template int +File_Parser::open (const char filename[]) +{ + return (this->infile_ = ACE_OS::fopen (filename, "r")) == 0 ? -1 : 0; +} + +template int +File_Parser::close (void) +{ + return ACE_OS::fclose (this->infile_); +} + +template FP_RETURN_TYPE +File_Parser::getword (char buf[]) +{ + FP_RETURN_TYPE read_result = this->readword(buf); + if (read_result == FP::SUCCESS) + return FP::SUCCESS; + else + return read_result; +} + +// Get the next string from the file via this->readword() +// Check make sure the string forms a valid number. +template FP_RETURN_TYPE +File_Parser::getint (int &value) +{ + char buf[BUFSIZ]; + FP_RETURN_TYPE read_result = this->readword(buf); + if (read_result == FP::SUCCESS) + { + // ptr is used for error checking with ACE_OS::strtol + char *ptr; + + // try to convert the buf to a decimal number + value = ACE_OS::strtol (buf, &ptr, 10); + + // check if the buf is a decimal or not + if ((value == 0) && (ptr == buf)) + return FP::ERROR; + else + return FP::SUCCESS; + } + else + return read_result; +} + + +template FP_RETURN_TYPE +File_Parser::readword (char buf[]) +{ + int wordlength = 0; + int c; + + // Skip over leading delimiters and get word. + + while ((c = getc (this->infile_)) != EOF && c != '\n') + if (this->delimiter (c)) + { + // We've reached the end of a "word". + if (wordlength > 0) + break; + } + else + buf[wordlength++] = c; + + buf[wordlength] = '\0'; + + if (c == EOF) { + // If the EOF is just a dilimeter, don't return EOF so that the + // word gets processed + if (wordlength > 0) + { + ungetc (c, this->infile_); + return FP::SUCCESS; + } + else + // else return EOF so that read loops stop + return FP::EOFILE; + } + else if (c == '\n') + { + // if the EOLINE is just a dilimeter, don't return EOLINE + // so that the word gets processed + if (wordlength > 0) + ungetc (c, this->infile_); + else + return FP::EOLINE; + } + + // Skip comments. + if (this->comments (buf[0])) + { + if (this->skipline () == EOF) + return FP::EOFILE; + else + return FP::COMMENT; + } + else + return FP::SUCCESS; +} + +template int +File_Parser::delimiter (char ch) +{ + return ch == ' ' || ch == ',' || ch == '\t'; +} + +template int +File_Parser::comments (char ch) +{ + return ch == '#'; +} + +template int +File_Parser::skipline (void) +{ + // Skip the remainder of the line. + + int c; + + while ((c = getc (this->infile_)) != '\n' && c != EOF) + continue; + + return c; +} + +#endif /* _FILE_PARSER_C */ diff --git a/apps/Gateway/Gateway/File_Parser.h b/apps/Gateway/Gateway/File_Parser.h new file mode 100644 index 00000000000..cddf3aa3055 --- /dev/null +++ b/apps/Gateway/Gateway/File_Parser.h @@ -0,0 +1,76 @@ +/* -*- C++ -*- */ +// @(#)File_Parser.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// apps +// +// = FILENAME +// File_Parser.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (_FILE_PARSER) +#define _FILE_PARSER + +#include "ace/OS.h" + +class FP + // = TITLE + // This class serves as a namespace for the Return_Type +{ +public: + enum Return_Type + { + EOLINE, + EOFILE, + SUCCESS, + COMMENT, + ERROR + }; +}; + +template +class File_Parser + // = TITLE + // Class used to parse the configuration file for the routing + // table. +{ +public: + // = Open and Close the file specified + int open (const char filename[]); + int close (void); + + virtual FP::Return_Type read_entry (ENTRY &, int &line_number) = 0; + // Implementations use protected methods to fill in the entry. + +protected: + FP::Return_Type getword (char buf[]); + // Read the next ASCII word. + + FP::Return_Type getint (int &value); + // Read the next integer. + + FP::Return_Type readword (char buf[]); + int delimiter (char ch); + int endofline (char ch); + int comments (char ch); + int skipline (void); + + FILE *infile_; +}; + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "File_Parser.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("File_Parser.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ + +#endif /* _FILE_PARSER */ diff --git a/apps/Gateway/Gateway/Gateway.cpp b/apps/Gateway/Gateway/Gateway.cpp new file mode 100644 index 00000000000..e46bfdd5a86 --- /dev/null +++ b/apps/Gateway/Gateway/Gateway.cpp @@ -0,0 +1,561 @@ +/* -*- C++ -*- */ +// @(#)Gateway.cpp 1.1 10/18/96 + + +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/Service_Config.h" +#include "Config_Files.h" +#include "Gateway.h" +#include "Channel_Connector.h" + +template +class Gateway : public ACE_Service_Object +{ +public: + Gateway (ACE_Thread_Manager * = 0); + + virtual int init (int argc, char *argv[]); + // Perform initialization. + + virtual int fini (void); + // Perform termination. + +protected: + int handle_input (ACE_HANDLE); + + int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); + + typedef ACE_Map_Manager CONFIG_TABLE; + typedef ACE_Map_Iterator CONFIG_ITERATOR; + + CONFIG_TABLE config_table_; + // Table that maps Connection IDs to Channel *'s. + + ROUTING_TABLE routing_table_; + // Table that maps Peer addresses to a set of Channel *'s for output. + + virtual int info (char **, size_t) const; + // Return info about this service. + + int parse_args (int argc, char *argv[]); + // Parse gateway configuration arguments obtained from svc.conf file. + + int parse_cc_config_file (void); + // Parse the channel connection configuration file. + + int parse_rt_config_file (void); + // Parse the routing table configuration file. + + int initiate_connections (void); + // Initiate connections to the peers. + + virtual int handle_timeout (const ACE_Time_Value &, const void *arg); + // Perform timer-based performance profiling. + + const char *cc_config_file_; + // Name of the channel connection configuration file. + + const char *rt_config_file_; + // Name of the routing table configuration file. + + int performance_window_; + // Number of seconds after connection establishment to report throughput. + + int blocking_semantics_; + // 0 == blocking connects, ACE_NONBLOCK == non-blocking connects. + + int debug_; + // Are we debugging? + + Channel_Connector *connector_; + // This is used to establish the connections actively. + + int socket_queue_size_; + // Size of the socket queue (0 means "use default"). + + // = Manage output and input channel threads (if used.) + // if both input and output mt is used, they will share thr_mgr_, + // thr_mgr_ will always reference the thread manager being used + // regardless of whether input, output, or both channels are using mt. + ACE_Thread_Manager *thr_mgr_; + ACE_Thread_Manager *input_thr_mgr_; + ACE_Thread_Manager *output_thr_mgr_; +}; + +// Convenient shorthands. + +#define IC INPUT_CHANNEL +#define OC OUTPUT_CHANNEL + +template int +Gateway::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + if (signum > 0) + ACE_DEBUG ((LM_DEBUG, "(%t) %S\n", signum)); + + if (this->thr_mgr_ != 0) + { +#if defined (ACE_HAS_THREADS) + ACE_DEBUG ((LM_DEBUG, "(%t) suspending all threads\n")); + if (this->thr_mgr_->suspend_all () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "suspend_all"), -1); +#endif /* ACE_HAS_THREADS */ + } + + // Shut down the main event loop. + ACE_Service_Config::end_reactor_event_loop (); + return 0; +} + +template int +Gateway::handle_input (ACE_HANDLE h) +{ + if (ACE_Service_Config::reactor ()->remove_handler (0, + ACE_Event_Handler::READ_MASK + | ACE_Event_Handler::DONT_CALL) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "remove_handler"), -1); + char buf[BUFSIZ]; + // Consume the input... + ACE_OS::read (h, buf, sizeof (buf)); + return this->handle_signal (h); +} + +template int +Gateway::handle_timeout (const ACE_Time_Value &, const void *) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) doing the performance timeout here...\n")); + CONFIG_ITERATOR cti (this->config_table_); + + // If we've got a ACE_Thread Manager then use it to suspend all + // the threads. This will enable us to get an accurate count. + + if (this->thr_mgr_ != 0) + { +#if defined (ACE_HAS_THREADS) + if (this->thr_mgr_->suspend_all () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "suspend_all"), -1); + ACE_DEBUG ((LM_DEBUG, "(%t) suspending all threads...")); +#endif /* ACE_HAS_THREADS */ + } + + size_t total_bytes_in = 0; + size_t total_bytes_out = 0; + + // Iterate through the routing table connecting all the channels. + + for (ACE_Map_Entry *me = 0; + cti.next (me) != 0; + cti.advance ()) + { + Channel *channel = me->int_id_; + if (channel->direction () == 'O') + total_bytes_out += channel->total_bytes (); + else + total_bytes_in += channel->total_bytes (); + } + +#if defined (ACE_NLOGGING) + ACE_OS::fprintf (stderr, "After %d seconds, \ntotal_bytes_in = %d\ntotal_bytes_out = %d\n", + performance_window_, + total_bytes_in, + total_bytes_out); + + ACE_OS::fprintf (stderr, "%f Mbits/sec received.\n", + (float) (total_bytes_in * 8 / (float) (1024*1024*this->performance_window_))); + + ACE_OS::fprintf (stderr, "%f Mbits/sec sent.\n", + (float) (total_bytes_out * 8 / (float) (1024*1024*this->performance_window_))); +#else + ACE_DEBUG ((LM_DEBUG, "(%t) after %d seconds, \ntotal_bytes_in = %d\ntotal_bytes_out = %d\n", + this->performance_window_, + total_bytes_in, + total_bytes_out)); + ACE_DEBUG ((LM_DEBUG, "(%t) %f Mbits/sec received.\n", + (float) (total_bytes_in * 8 / (float) (1024*1024*this->performance_window_)))); + ACE_DEBUG ((LM_DEBUG, "(%t) %f Mbits/sec sent.\n", + (float) (total_bytes_out * 8 / (float) (1024*1024*this->performance_window_)))); +#endif /* ACE_NLOGGING */ + // Resume all the threads again. + if (this->thr_mgr_ != 0) + { +#if defined (ACE_HAS_THREADS) + this->thr_mgr_->resume_all (); + ACE_DEBUG ((LM_DEBUG, "(%t) resuming all threads...")); +#endif /* ACE_HAS_THREADS */ + } + return 0; +} + +// Give default values to data members. + +template +Gateway::Gateway (ACE_Thread_Manager *thr_mgr) + : cc_config_file_ ("cc_config"), + rt_config_file_ ("rt_config"), + performance_window_ (0), + blocking_semantics_ (ACE_NONBLOCK), + debug_ (0), + connector_ (0), + thr_mgr_ (thr_mgr), + input_thr_mgr_ (thr_mgr), + output_thr_mgr_ (thr_mgr), + socket_queue_size_ (0) +{ +} + +// Parse the "command-line" arguments and set the corresponding flags. + +template int +Gateway::parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, "bc:dr:q:w:", 0); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'b': // Use blocking connection establishment. + this->blocking_semantics_ = 0; + break; + case 'c': + this->cc_config_file_ = get_opt.optarg; + break; + case 'd': + this->debug_ = 1; + break; + case 'q': + this->socket_queue_size_ = ACE_OS::atoi (get_opt.optarg); + break; + case 'r': + this->rt_config_file_ = get_opt.optarg; + break; + case 'w': // Time performance for a designated amount of time. + this->performance_window_ = ACE_OS::atoi (get_opt.optarg); + // Use blocking connection semantics so that we get accurate + // timings (since all connections start at once). + this->blocking_semantics_ = 0; + break; + default: + break; + } + } + return 0; +} + +// Initiate connections with the peers. + +template int +Gateway::initiate_connections (void) +{ + CONFIG_ITERATOR cti (this->config_table_); + + // Iterate through the routing table connecting all the channels. + + for (ACE_Map_Entry *me = 0; + cti.next (me) != 0; + cti.advance ()) + { + Channel *channel = me->int_id_; + if (this->connector_->initiate_connection + (channel, this->blocking_semantics_ == ACE_NONBLOCK + ? ACE_Synch_Options::asynch : ACE_Synch_Options::synch) == -1) + continue; + } + + return 0; +} + +// This method is automatically called when the gateway +// is shutdown. It gracefully shuts down all the Channels +// in the Channel connection Config_Table. + +template int +Gateway::fini (void) +{ + // Question: do we need to do anything special about the Routing_Table? + + CONFIG_ITERATOR cti (this->config_table_); + + for (ACE_Map_Entry *me; + cti.next (me) != 0; + cti.advance ()) + { + Channel *channel = me->int_id_; + ACE_DEBUG ((LM_DEBUG, "(%t) closing down route %d\n", + channel->id ())); + if (channel->state () != Channel::IDLE) + // Mark channel as DISCONNECTING so we don't try to reconnect... + channel->state (Channel::DISCONNECTING); + + // Deallocate Channel resources. + channel->destroy (); // Will trigger a delete. + } + + // Free up the resources allocated dynamically by the ACE_Connector. + delete this->connector_; + delete this->thr_mgr_; + + return 0; +} + +template int +Gateway::init (int argc, char *argv[]) +{ + this->parse_args (argc, argv); + + ACE_NEW_RETURN (this->connector_, Channel_Connector (), -1); + + if (this->connector_ == 0) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "out of memory"), -1); + + // Ignore SIPPIPE so each Output_Channel can handle it. + ACE_Sig_Action sig (ACE_SignalHandler (SIG_IGN), SIGPIPE); + + ACE_Sig_Set sig_set; + sig_set.sig_add (SIGINT); + sig_set.sig_add (SIGQUIT); + + // Register ourselves to receive SIGINT and SIGQUIT + // so we can shut down gracefully via signals. + + if (ACE_Service_Config::reactor ()->register_handler (sig_set, + this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "register_handler"), -1); + + if (ACE_Service_Config::reactor ()->register_handler (0, + this, + ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "register_handler"), -1); + + if (this->thr_mgr_ == 0) + // Create a thread manager if using some combination of multi-threaded channels. +#if defined (USE_OUTPUT_MT) && defined (USE_INPUT_MT) + this->thr_mgr_ = this->output_thr_mgr_ = + this->input_thr_mgr_ = ACE_Service_Config::thr_mgr (); +#elif defined (USE_OUTPUT_MT) + this->thr_mgr_ = this->output_thr_mgr_ = ACE_Service_Config::thr_mgr (); +#elif defined (USE_INPUT_MT) + this->thr_mgr_ = this->input_thr_mgr_ = ACE_Service_Config::thr_mgr (); +#endif + + // Parse the connection configuration file. + this->parse_cc_config_file (); + + // Parse the routing table config file and build the routing table. + this->parse_rt_config_file (); + + // Initiate connections with the peers. + this->initiate_connections (); + + // If this->performance_window_ > 0 start a timer. + + if (this->performance_window_ > 0) + { + if (ACE_Service_Config::reactor ()->schedule_timer (this, 0, + this->performance_window_) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "schedule_timer")); + else + ACE_DEBUG ((LM_DEBUG, "starting timer for %d seconds...\n", + this->performance_window_)); + } + + return 0; +} + +// Returns information on the currently active service. + +template int +Gateway::info (char **strp, size_t length) const +{ + char buf[BUFSIZ]; + + ACE_OS::sprintf (buf, "%s\t %s", "Gateway daemon", + "# Application-level gateway\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +// Parse and build the connection table. + +template int +Gateway::parse_cc_config_file (void) +{ + // File that contains the routing table configuration information. + CC_Config_File_Parser cc_file; + CC_Config_File_Entry entry; + int file_empty = 1; + int line_number = 0; + + if (cc_file.open (this->cc_config_file_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", this->cc_config_file_), -1); + + // Read config file line at a time. + while (cc_file.read_entry (entry, line_number) != FP::EOFILE) + { + file_empty = 0; + + if (this->debug_) + ACE_DEBUG ((LM_DEBUG, "(%t) conn id = %d, host = %s, remote port = %d, " + "direction = %c, max retry timeout = %d, local port = %d\n", + entry.conn_id_, entry.host_, entry.remote_port_, entry.direction_, + entry.max_retry_delay_, entry.local_port_)); + + Channel *channel = 0; + + // The next few lines of code are dependent on whether we are making + // an Input_Channel or an Output_Channel. + + if (entry.direction_ == 'O') // Configure an output channel. + ACE_NEW_RETURN (channel, + OUTPUT_CHANNEL (&this->routing_table_, + this->connector_, + this->output_thr_mgr_, + this->socket_queue_size_), + -1); + else /* direction == 'I' */ // Configure an input channel. + ACE_NEW_RETURN (channel, + INPUT_CHANNEL (&this->routing_table_, + this->connector_, + this->input_thr_mgr_, + this->socket_queue_size_), + -1); + if (channel == 0) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) out of memory\n"), -1); + + // The following code is common to both Input_ and Output_Channels. + + // Initialize the routing entry's peer addressing info. + channel->bind (ACE_INET_Addr (entry.remote_port_, entry.host_), + ACE_INET_Addr (entry.local_port_), entry.conn_id_); + + // Initialize max timeout. + channel->max_timeout (entry.max_retry_delay_); + + // Try to bind the new Channel to the connection ID. + switch (this->config_table_.bind (entry.conn_id_, channel)) + { + case -1: + ACE_ERROR_RETURN ((LM_ERROR, "(%t) bind failed for connection %d\n", + entry.conn_id_), -1); + /* NOTREACHED */ + case 1: // Oops, found a duplicate! + ACE_DEBUG ((LM_DEBUG, "(%t) duplicate connection %d, already bound\n", + entry.conn_id_)); + break; + case 0: + // Success. + break; + } + } + + if (file_empty) + ACE_ERROR ((LM_WARNING, + "warning: connection channel configuration file was empty\n")); + + return 0; +} + +template int +Gateway::parse_rt_config_file (void) +{ + // File that contains the routing table configuration information. + RT_Config_File_Parser rt_file; + RT_Config_File_Entry entry; + int file_empty = 1; + int line_number = 0; + + if (rt_file.open (this->rt_config_file_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", this->rt_config_file_), -1); + + // Read config file line at a time. + while (rt_file.read_entry (entry, line_number) != FP::EOFILE) + { + file_empty = 0; + + if (this->debug_) + { + ACE_DEBUG ((LM_DEBUG, "(%t) conn id = %d, logical id = %d, payload = %d, " + "number of destinations = %d\n", + entry.conn_id_, entry.logical_id_, entry.payload_type_, + entry.total_destinations_)); + for (int i = 0; i < entry.total_destinations_; i++) + ACE_DEBUG ((LM_DEBUG, "(%t) destination[%d] = %d\n", + i, entry.destinations_[i])); + } + + Routing_Entry *re; + ACE_NEW_RETURN (re, Routing_Entry, -1); + Routing_Entry::ENTRY_SET *channel_set = new Routing_Entry::ENTRY_SET; + Peer_Addr peer_addr (entry.conn_id_, entry.logical_id_, + entry.payload_type_); + + // Add the destinations to the Routing Entry. + for (int i = 0; i < entry.total_destinations_; i++) + { + Channel *channel = 0; + + // Lookup destination and add to Routing_Entry set if found. + if (this->config_table_.find (entry.destinations_[i], + channel) != -1) + channel_set->insert (channel); + else + ACE_ERROR ((LM_ERROR, "(%t) not found: destination[%d] = %d\n", + i, entry.destinations_[i])); + } + + // Attach set of destination channels to routing entry. + re->destinations (channel_set); + + // Bind with routing table, keyed by peer address. + switch (this->routing_table_.bind (peer_addr, re)) + { + case -1: + ACE_ERROR_RETURN ((LM_ERROR, "(%t) bind failed for connection %d\n", + entry.conn_id_), -1); + /* NOTREACHED */ + case 1: // Oops, found a duplicate! + ACE_DEBUG ((LM_DEBUG, "(%t) duplicate routing table entry %d, " + "already bound\n", entry.conn_id_)); + break; + case 0: + // Success. + break; + } + } + + if (file_empty) + ACE_ERROR ((LM_WARNING, + "warning: routing table configuration file was empty\n")); + + return 0; +} + +#if defined (ACE_HAS_THREADS) && (defined (USE_OUTPUT_MT) || defined (USE_INPUT_MT)) +#if defined (USE_OUTPUT_MT) +typedef Thr_Output_Channel OUTPUT_CHANNEL; +#else +typedef Output_Channel OUTPUT_CHANNEL; +#endif /* USE_OUTPUT_MT */ + +#if defined (USE_INPUT_MT) +typedef Thr_Input_Channel INPUT_CHANNEL; +#else +typedef Input_Channel INPUT_CHANNEL; +#endif /* USE_INPUT_MT */ +#else +// Instantiate a non-multi-threaded Gateway. +typedef Input_Channel INPUT_CHANNEL; +typedef Output_Channel OUTPUT_CHANNEL; +#endif /* ACE_HAS_THREADS */ + +typedef Gateway ACE_Gateway; + +// The following is a "Factory" used by the ACE_Service_Config and +// svc.conf file to dynamically initialize the state of the Gateway. + +ACE_SVC_FACTORY_DEFINE (ACE_Gateway) diff --git a/apps/Gateway/Gateway/Gateway.h b/apps/Gateway/Gateway/Gateway.h new file mode 100644 index 00000000000..b4269aa9d80 --- /dev/null +++ b/apps/Gateway/Gateway/Gateway.h @@ -0,0 +1,30 @@ +/* -*- C++ -*- */ +// @(#)Gateway.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// apps +// +// = FILENAME +// Gateway.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_GATEWAY) +#define ACE_GATEWAY + +#include "ace/OS.h" + +ACE_SVC_FACTORY_DECLARE (ACE_Gateway) + +#endif /* ACE_GATEWAY */ + + + + + diff --git a/apps/Gateway/Gateway/Makefile b/apps/Gateway/Gateway/Makefile new file mode 100644 index 00000000000..768f774d9c4 --- /dev/null +++ b/apps/Gateway/Gateway/Makefile @@ -0,0 +1,505 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Gateway prototype. +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = gatewayd +LIB = libGateway.a +SHLIB = libGateway.so + +FILES = Channel \ + Channel_Connector \ + Config_Files \ + File_Parser \ + Gateway \ + Routing_Entry \ + Routing_Table \ + Thr_Channel + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(addsuffix .o,$(FILES)) +SHOBJ = $(addsuffix .so,$(FILES)) + +LDLIBS = -lGateway +LIBS = -lACE + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VLIB) $(VSHLIB) $(SHLIBA) $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +# Default behavior is to use single-threading. See the README +# file for information on how to configure this with multiple +# strategies for threading the input and output channels. +DEFFLAGS += -DASSIGN_ROUTING_ID # -DUSE_OUTPUT_MT -DUSE_INPUT_MT + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/Channel.o .shobj/Channel.so: Channel.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + Routing_Entry.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + Channel_Connector.h \ + $(WRAPPER_ROOT)/ace/Connector.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Connector.i \ + $(WRAPPER_ROOT)/ace/Connector.cpp \ + Thr_Channel.h Channel.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + Routing_Table.h Routing_Table.cpp Peer_Message.h +.obj/Channel_Connector.o .shobj/Channel_Connector.so: Channel_Connector.cpp Channel_Connector.h \ + $(WRAPPER_ROOT)/ace/Connector.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Connector.i \ + $(WRAPPER_ROOT)/ace/Connector.cpp \ + Thr_Channel.h Channel.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + Routing_Table.h Routing_Table.cpp Routing_Entry.h Peer_Message.h +.obj/Config_Files.o .shobj/Config_Files.so: Config_Files.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + Config_Files.h File_Parser.h File_Parser.cpp +.obj/File_Parser.o .shobj/File_Parser.so: File_Parser.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + File_Parser.h File_Parser.cpp +.obj/Gateway.o .shobj/Gateway.so: Gateway.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + Config_Files.h File_Parser.h File_Parser.cpp Gateway.h \ + Channel_Connector.h \ + $(WRAPPER_ROOT)/ace/Connector.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Connector.i \ + $(WRAPPER_ROOT)/ace/Connector.cpp \ + Thr_Channel.h Channel.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + Routing_Table.h Routing_Table.cpp Routing_Entry.h Peer_Message.h +.obj/Routing_Entry.o .shobj/Routing_Entry.so: Routing_Entry.cpp Routing_Entry.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i +.obj/Routing_Table.o .shobj/Routing_Table.so: Routing_Table.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + Routing_Table.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + Routing_Table.cpp +.obj/Thr_Channel.o .shobj/Thr_Channel.so: Thr_Channel.cpp Thr_Channel.h Channel.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + Routing_Table.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + Routing_Table.cpp Routing_Entry.h Peer_Message.h Channel_Connector.h \ + $(WRAPPER_ROOT)/ace/Connector.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Connector.i \ + $(WRAPPER_ROOT)/ace/Connector.cpp + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/apps/Gateway/Gateway/Peer_Message.h b/apps/Gateway/Gateway/Peer_Message.h new file mode 100644 index 00000000000..d4041098e1b --- /dev/null +++ b/apps/Gateway/Gateway/Peer_Message.h @@ -0,0 +1,89 @@ +/* -*- C++ -*- */ +// @(#)Peer_Message.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// apps +// +// = FILENAME +// Peer_Message.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (PEER_MESSAGE) +#define PEER_MESSAGE + +// This is the unique connection identifier that denotes a particular +// Channel in the Gateway. +typedef short CONN_ID; + +class Peer_Addr + // = TITLE + // Peer address is used to identify the source/destination of a + // routing message. +{ +public: + Peer_Addr (CONN_ID cid = -1, u_char lid = 0, u_char pay = 0) + : conn_id_ (cid), logical_id_ (lid), payload_ (pay) {} + + int operator== (const Peer_Addr &pa) const + { + return this->conn_id_ == pa.conn_id_ + && this->logical_id_ == pa.logical_id_ + && this->payload_ == pa.payload_; + } + + CONN_ID conn_id_; + // Unique connection identifier that denotes a particular Channel. + + u_char logical_id_; + // Logical ID. + + u_char payload_; + // Payload type. +}; + + +class Peer_Header + // = TITLE + // Fixed sized header. +{ +public: + typedef u_short ROUTING_ID; + // Type used to route messages from gatewayd. + + enum + { + INVALID_ID = -1 // No peer can validly use this number. + }; + + ROUTING_ID routing_id_; + // Source ID. + + size_t len_; + // Length of the message in bytes. +}; + +class Peer_Message + // = TITLE + // Variable-sized message (buf_ may be variable-sized between + // 0 and MAX_PAYLOAD_SIZE). +{ +public: + enum { MAX_PAYLOAD_SIZE = 1024 }; + // The maximum size of an Peer message (see Peer protocol specs for + // exact #). + + Peer_Header header_; + // Message header. + + char buf_[MAX_PAYLOAD_SIZE]; + // Message payload. +}; + +#endif /* PEER_MESSAGE */ diff --git a/apps/Gateway/Gateway/README b/apps/Gateway/Gateway/README new file mode 100644 index 00000000000..ceb17528d0d --- /dev/null +++ b/apps/Gateway/Gateway/README @@ -0,0 +1,22 @@ +This application illustrates an application-level Gateway which +routes messages between a set of Peers in a distributed environment. + +The default configuration is single-threaded, i.e., all Input_Channels +and Output_Channels are multiplexed via the Reactor on a single thread +of control. To obtain a version that multi-threads both input and +output simply set the following flag in the Makefile: + +DEFFLAGS += -DUSE_OUTPUT_MT -DUSE_INPUT_MT + +To get a version that uses single-threading for all Input_Channels, +but a separate thread per-Output_Channel set the following flag in the +Makefile: + +DEFFLAGS += -DUSE_OUTPUT_MT + +If you examine the source code, you'll see that very few changes are +required in the source code to switch between single-threading and +multi-threading. The ACE Task class is primarily responsible for +enabling the flexible modification of concurrency strategies with +little modification to the source code, design, and system +architecture. diff --git a/apps/Gateway/Gateway/Routing_Entry.cpp b/apps/Gateway/Gateway/Routing_Entry.cpp new file mode 100644 index 00000000000..a7333b73aea --- /dev/null +++ b/apps/Gateway/Gateway/Routing_Entry.cpp @@ -0,0 +1,47 @@ +// Defines an entry in the Routing Table. +// @(#)Routing_Entry.cpp 1.1 10/18/96 + +#include "Routing_Entry.h" + +Routing_Entry::Routing_Entry (int validity_interval) + : validity_interval_ (validity_interval) +{ + ACE_NEW (this->destinations_, Routing_Entry::ENTRY_SET); +} + +Routing_Entry::~Routing_Entry (void) +{ + delete this->destinations_; +} + +// Get the associated set of destinations. + +Routing_Entry::ENTRY_SET * +Routing_Entry::destinations (void) +{ + return this->destinations_; +} + +// Set the associated set of destinations. + +void +Routing_Entry::destinations (Routing_Entry::ENTRY_SET *s) +{ + this->destinations_ = s; +} + +// Get the current validity interval for this route. + +int +Routing_Entry::validity_interval (void) +{ + return this->validity_interval_; +} + +// Set the current validity interval for this route. + +void +Routing_Entry::validity_interval (int vi) +{ + this->validity_interval_ = vi; +} diff --git a/apps/Gateway/Gateway/Routing_Entry.h b/apps/Gateway/Gateway/Routing_Entry.h new file mode 100644 index 00000000000..3b281dd77e9 --- /dev/null +++ b/apps/Gateway/Gateway/Routing_Entry.h @@ -0,0 +1,53 @@ +/* -*- C++ -*- */ +// @(#)Routing_Entry.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// apps +// +// = FILENAME +// Routing_Entry.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (_ROUTING_ENTRY) +#define _ROUTING_ENTRY + +#include "ace/Set.h" + +// Forward reference. +class Channel; + +class Routing_Entry +{ + // = TITLE + // Defines an entry in the Routing_Table. +public: + Routing_Entry (int validity_interval = 0); + ~Routing_Entry (void); + + typedef ACE_Unbounded_Set ENTRY_SET; + typedef ACE_Unbounded_Set_Iterator ENTRY_ITERATOR; + + // = Set/get the associated set of destinations. + ENTRY_SET *destinations (void); + void destinations (ENTRY_SET *); + + // = Set/get current validity interval for this routing entry. + int validity_interval (void); + void validity_interval (int); + +protected: + ENTRY_SET *destinations_; + // The set of destinations; + + int validity_interval_; + // The current validity interval of this link. +}; + +#endif /* _ROUTING_ENTRY */ diff --git a/apps/Gateway/Gateway/Routing_Table.cpp b/apps/Gateway/Gateway/Routing_Table.cpp new file mode 100644 index 00000000000..284febeafe1 --- /dev/null +++ b/apps/Gateway/Gateway/Routing_Table.cpp @@ -0,0 +1,69 @@ +/* -*- C++ -*- */ +// @(#)Routing_Table.cpp 1.1 10/18/96 + + +#if !defined (_ROUTING_TABLE_C) +#define _ROUTING_TABLE_C + +#include "ace/Log_Msg.h" +#include "Routing_Table.h" + +/* Bind the EXT_ID to the INT_ID. */ + +template ACE_INLINE int +Routing_Table::bind (EXT_ID ext_id, INT_ID *int_id) +{ + return this->map_.bind (ext_id, int_id); +} + +/* Find the INT_ID corresponding to the EXT_ID. */ + +template ACE_INLINE int +Routing_Table::find (EXT_ID ext_id, INT_ID *&int_id) +{ + return this->map_.find (ext_id, int_id); +} + +/* Unbind (remove) the EXT_ID from the map. */ + +template ACE_INLINE int +Routing_Table::unbind (EXT_ID ext_id) +{ + return this->map_.unbind (ext_id); +} + +template ACE_INLINE +Routing_Iterator::Routing_Iterator (Routing_Table &rt, + int ignore_inactive) + : map_iter_ (rt.map_), + ignore_inactive_ (ignore_inactive) +{ +} + +template ACE_INLINE int +Routing_Iterator::next (INT_ID *&ss) +{ + // Loop in order to skip over inactive entries if necessary. + + for (ACE_Map_Entry *temp = 0; + this->map_iter_.next (temp) != 0; + this->advance ()) + { + // Skip over inactive entries if necessary. + if (temp->int_id_->active () == 0 && this->ignore_inactive_) + continue; + + // Otherwise, return the next item. + ss = temp->int_id_; + return 1; + } + return 0; +} + +template ACE_INLINE int +Routing_Iterator::advance (void) +{ + return this->map_iter_.advance (); +} +#endif /* _ROUTING_TABLE_C */ diff --git a/apps/Gateway/Gateway/Routing_Table.h b/apps/Gateway/Gateway/Routing_Table.h new file mode 100644 index 00000000000..884932c6da1 --- /dev/null +++ b/apps/Gateway/Gateway/Routing_Table.h @@ -0,0 +1,67 @@ +/* -*- C++ -*- */ +// @(#)Routing_Table.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// apps +// +// = FILENAME +// Routing_Table.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (_ROUTING_TABLE_H) +#define _ROUTING_TABLE_H + +#include "ace/Map_Manager.h" + +template +class Routing_Table +{ + // = TITLE + // Define a generic routing table based on the ACE Map_Manager. + // + // = DESCRIPTION + // We need to have this table, rather than just using the Map_Manager + // directly in order to ignore "inactive" routing entries... +public: + int bind (EXT_ID ext_id, INT_ID *int_id); + // Associate EXT_ID with the INT_ID. + + int find (EXT_ID ext_id, INT_ID *&int_id); + // Break any association of EXID. + + int unbind (EXT_ID ext_id); + // Locate EXID and pass out parameter via INID. If found, + // return 0, else -1. + +public: + ACE_Map_Manager map_; + // Map external IDs to internal IDs. +}; + +template +class Routing_Iterator +{ + // = TITLE + // Define an iterator for the Routing Table. +public: + Routing_Iterator (Routing_Table &mm, + int ignore_inactive = 1); + int next (INT_ID *&); + int advance (void); + +private: + ACE_Map_Iterator map_iter_; + int ignore_inactive_; +}; + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "Routing_Table.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ +#endif /* _ROUTING_TABLE_H */ diff --git a/apps/Gateway/Gateway/Thr_Channel.cpp b/apps/Gateway/Gateway/Thr_Channel.cpp new file mode 100644 index 00000000000..bcabb66cc2b --- /dev/null +++ b/apps/Gateway/Gateway/Thr_Channel.cpp @@ -0,0 +1,204 @@ +#include "Thr_Channel.h" +// @(#)Thr_Channel.cpp 1.1 10/18/96 + +#include "Channel_Connector.h" + +#if defined (ACE_HAS_THREADS) +Thr_Output_Channel::Thr_Output_Channel (ROUTING_TABLE *rt, + Channel_Connector *cc, + ACE_Thread_Manager *thr_mgr, + int socket_queue_size) + : Output_Channel (rt, cc, thr_mgr, socket_queue_size) +{ +} + +// This method should be called only when the peer shuts down +// unexpectedly. This method marks the Channel as having failed and +// deactivates the ACE_Message_Queue (to wake up the thread blocked on +// in svc()). Thr_Output_Handler::handle_close () will +// eventually try to reconnect... + +int +Thr_Output_Channel::handle_input (ACE_HANDLE h) +{ + this->Output_Channel::handle_input (h); + ACE_Service_Config::reactor ()->remove_handler (h, + ACE_Event_Handler::RWE_MASK + | ACE_Event_Handler::DONT_CALL); + // Deactivate the queue while we try to get reconnected. + this->msg_queue ()->deactivate (); + return 0; +} + +// Initialize the threaded Output_Channel object and spawn a new +// thread. + +int +Thr_Output_Channel::open (void *) +{ + // Set the size of the socket queue. + this->socket_queue_size (); + + // Turn off non-blocking I/O. + if (this->peer ().disable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "enable"), -1); + + // Register ourselves to receive input events (which indicate that + // the Peer has shut down unexpectedly). + if (ACE_Service_Config::reactor ()->register_handler (this, + ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "register_handler"), -1); + + if (this->initialize_connection ()) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", + "initialize_connection"), -1); + + // Reactivate message queue. If it was active then this is the + // first time in and we need to spawn a thread, otherwise the queue + // was inactive due to some problem and we've already got a thread. + if (this->msg_queue ()->activate () == ACE_Message_Queue::WAS_ACTIVE) + { + ACE_DEBUG ((LM_DEBUG, "(%t) spawning new thread\n")); + // Become an active object by spawning a new thread to transmit + // messages to peers. + return this->activate (THR_NEW_LWP | THR_DETACHED); + } + else + { + ACE_DEBUG ((LM_DEBUG, "(%t) reusing existing thread\n")); + return 0; + } +} + +// ACE_Queue up a message for transmission (must not block since all +// Input_Channels are single-threaded). + +int +Thr_Output_Channel::put (ACE_Message_Block *mb, ACE_Time_Value *) +{ + // Perform non-blocking enqueue. + return this->msg_queue ()->enqueue_tail (mb, (ACE_Time_Value *) &ACE_Time_Value::zero); +} + +// Transmit messages to the peer (note simplification resulting from +// threads...) + +int +Thr_Output_Channel::svc (void) +{ + for (;;) + { + ACE_DEBUG ((LM_DEBUG, "(%t) connected! Thr_Output_Channel's fd = %d\n", + this->peer ().get_handle ())); + + // Since this method runs in its own thread it is OK to block on + // output. + + for (ACE_Message_Block *mb = 0; + this->msg_queue ()->dequeue_head (mb) != -1; ) + if (this->send_peer (mb) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "send failed")); + + ACE_ASSERT (errno == ESHUTDOWN); + + ACE_DEBUG ((LM_DEBUG, "(%t) shutting down threaded Output_Channel %d on handle %d\n", + this->id (), this->get_handle ())); + + this->peer ().close (); + + for (this->timeout (1); + // Default is to reconnect synchronously. + this->connector_->initiate_connection (this) == -1; ) + { + ACE_Time_Value tv (this->timeout ()); + ACE_ERROR ((LM_ERROR, + "(%t) reattempting connection, sec = %d\n", + tv.sec ())); + ACE_OS::sleep (tv); + } + } + + return 0; +} + +Thr_Input_Channel::Thr_Input_Channel (ROUTING_TABLE *rt, + Channel_Connector *cc, + ACE_Thread_Manager *thr_mgr, + int socket_queue_size) + : Input_Channel (rt, cc, thr_mgr, socket_queue_size) +{ +} + +int +Thr_Input_Channel::open (void *) +{ + // Set the size of the socket queue. + this->socket_queue_size (); + + // Turn off non-blocking I/O. + if (this->peer ().disable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "enable"), -1); + + if (this->initialize_connection ()) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", + "initialize_connection"), -1); + + // Reactivate message queue. If it was active then this is the + // first time in and we need to spawn a thread, otherwise the queue + // was inactive due to some problem and we've already got a thread. + if (this->msg_queue ()->activate () == ACE_Message_Queue::WAS_ACTIVE) + { + ACE_DEBUG ((LM_DEBUG, "(%t) spawning new thread\n")); + // Become an active object by spawning a new thread to transmit + // messages to peers. + return this->activate (THR_NEW_LWP | THR_DETACHED); + } + else + { + ACE_DEBUG ((LM_DEBUG, "(%t) reusing existing thread\n")); + return 0; + } +} + +// Receive messages from a Peer in a separate thread (note reuse of +// existing code!). + +int +Thr_Input_Channel::svc (void) +{ + for (;;) + { + ACE_DEBUG ((LM_DEBUG, "(%t) connected! Thr_Input_Channel's fd = %d\n", + this->peer ().get_handle ())); + + // Since this method runs in its own thread and processes + // messages for one connection it is OK to block on input and + // output. + + while (this->handle_input () != -1) + continue; + + ACE_DEBUG ((LM_DEBUG, + "(%t) shutting down threaded Input_Channel %d on handle %d\n", + this->id (), + this->get_handle ())); + + this->peer ().close (); + + // Deactivate the queue while we try to get reconnected. + this->msg_queue ()->deactivate (); + + for (this->timeout (1); + // Default is to reconnect synchronously. + this->connector_->initiate_connection (this) == -1; ) + { + ACE_Time_Value tv (this->timeout ()); + ACE_ERROR ((LM_ERROR, + "(%t) reattempting connection, sec = %d\n", tv.sec ())); + ACE_OS::sleep (tv); + } + } + return 0; +} + +#endif /* ACE_HAS_THREADS */ diff --git a/apps/Gateway/Gateway/Thr_Channel.h b/apps/Gateway/Gateway/Thr_Channel.h new file mode 100644 index 00000000000..796a9759d02 --- /dev/null +++ b/apps/Gateway/Gateway/Thr_Channel.h @@ -0,0 +1,65 @@ +/* -*- C++ -*- */ +// @(#)Thr_Channel.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// apps +// +// = FILENAME +// Thr_Channel.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (_THR_CHANNEL) +#define _THR_CHANNEL + +#include "Channel.h" + +#if defined (ACE_HAS_THREADS) +class Thr_Output_Channel : public Output_Channel + // = TITLE + // Runs each Output Channel in a separate thread. +{ +public: + Thr_Output_Channel (ROUTING_TABLE *, + Channel_Connector *, + ACE_Thread_Manager *, + int socket_queue_size); + + virtual int open (void *); + // Initialize the threaded Output_Channel object and spawn a new + // thread. + + virtual int handle_input (ACE_HANDLE); + // Called when Peer shutdown unexpectedly. + + virtual int put (ACE_Message_Block *, ACE_Time_Value * = 0); + // Send a message to a peer. + + virtual int svc (void); + // Transmit peer messages. +}; + +class Thr_Input_Channel : public Input_Channel + // = TITLE + // Runs each Input Channel in a separate thread. +{ +public: + Thr_Input_Channel (ROUTING_TABLE *, + Channel_Connector *, + ACE_Thread_Manager *, + int socket_queue_size); + + virtual int open (void *); + // Initialize the object and spawn a new thread. + + virtual int svc (void); + // Transmit peer messages. +}; +#endif /* ACE_HAS_THREADS */ +#endif /* _THR_CHANNEL */ diff --git a/apps/Gateway/Gateway/cc_config b/apps/Gateway/Gateway/cc_config new file mode 100644 index 00000000000..96f9ebdedd7 --- /dev/null +++ b/apps/Gateway/Gateway/cc_config @@ -0,0 +1,10 @@ +# Conn ID Hostname Remote Port Direction Max Retry Delay Local Port +# ------- -------- ---- --------- --------------- ---------- + 1 tango.cs 10004 I 32 20000 +# 2 tango.cs 10004 O 32 + 3 merengue.cs 10004 O 32 20001 +# 4 mambo.cs 10004 O 32 20000 +# 5 lambada.cs 10004 O 32 20000 +# 6 tango.cs 10004 O 32 20000 +# 7 tango.cs 5001 I 32 +# 8 tango.cs 5002 O 32 diff --git a/apps/Gateway/Gateway/gatewayd.cpp b/apps/Gateway/Gateway/gatewayd.cpp new file mode 100644 index 00000000000..5897c69ca00 --- /dev/null +++ b/apps/Gateway/Gateway/gatewayd.cpp @@ -0,0 +1,34 @@ +// Main driver program for the Gateway. This file is completely +// @(#)gatewayd.cpp 1.1 10/18/96 + +// generic code due to the ACE Service Configurator framework! + +#include "ace/Service_Config.h" +#include "Gateway.h" + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config daemon; + + if (daemon.open (argc, argv) == -1) + { + if (errno != ENOENT) + ACE_ERROR ((LM_ERROR, "%p\n%a", "open", 1)); + else // Use static binding. + { + static char *l_argv[3] = { "-d" }; + ACE_Service_Object *so = ACE_SVC_INVOKE (ACE_Gateway); + + if (so->init (1, l_argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "init", 1)); + } + } + + // Run forever, performing the configured services until we are shut + // down by a signal. + + ACE_Service_Config::run_reactor_event_loop (); + + return 0; +} diff --git a/apps/Gateway/Gateway/rt_config b/apps/Gateway/Gateway/rt_config new file mode 100644 index 00000000000..e951a0f09be --- /dev/null +++ b/apps/Gateway/Gateway/rt_config @@ -0,0 +1,7 @@ +# Conn ID Logical ID Payload Destinations +# ------- ---------- ------- ------------ +# 1 1 0 3,4,5 + 1 1 0 3 + 3 1 0 3 +# 4 1 0 4 +# 5 1 0 5 diff --git a/apps/Gateway/Gateway/svc.conf b/apps/Gateway/Gateway/svc.conf new file mode 100644 index 00000000000..8dfd56585b1 --- /dev/null +++ b/apps/Gateway/Gateway/svc.conf @@ -0,0 +1,3 @@ +#static Svc_Manager "-d -p 2913" +dynamic Gateway Service_Object *./libGateway.so:_make_ACE_Gateway() active "-d -c cc_config -f rt_config" + diff --git a/apps/Gateway/Makefile b/apps/Gateway/Makefile new file mode 100644 index 00000000000..b7abb07bf51 --- /dev/null +++ b/apps/Gateway/Makefile @@ -0,0 +1,26 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Gateway application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +INFO = README + +DIRS = Gateway \ + Peer + + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + diff --git a/apps/Gateway/Peer/Gateway_Handler.cpp b/apps/Gateway/Peer/Gateway_Handler.cpp new file mode 100644 index 00000000000..84e3c796fe5 --- /dev/null +++ b/apps/Gateway/Peer/Gateway_Handler.cpp @@ -0,0 +1,653 @@ +#include "ace/Get_Opt.h" +// @(#)Gateway_Handler.cpp 1.1 10/18/96 + +#include "ace/Log_Msg.h" +#include "Gateway_Handler.h" + +Gateway_Handler::Gateway_Handler (ACE_Thread_Manager *) + : routing_id_ (0), + msg_frag_ (0), + total_bytes_ (0) +{ + this->msg_queue ()->high_water_mark (Gateway_Handler::QUEUE_SIZE); +} + +int +Gateway_Handler::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) %S\n", signum)); + + // Shut down the main event loop. + ACE_Service_Config::end_reactor_event_loop (); + return 0; +} + +// Cache a binding to the HANDLER_MAP. + +void +Gateway_Handler::map (HANDLER_MAP *m) +{ + this->map_ = m; +} + +// Upcall from the ACE_Acceptor::handle_input() that turns control +// over to our application-specific Gateway handler. + +int +Gateway_Handler::open (void *a) +{ + ACE_DEBUG ((LM_DEBUG, "Gateway handler's fd = %d\n", + this->peer ().get_handle ())); + + // Call down to the base class to activate and register this + // handler. + if (this->inherited::open (a) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + + if (this->peer ().enable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "enable"), -1); + + Gateway_Handler *this_ = this; + + // Add ourselves to the map so we can be removed later on. + if (this->map_->bind (this->get_handle (), this_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "bind"), -1); + + char *to = ACE_OS::getenv ("TIMEOUT"); + int timeout = to == 0 ? 100000 : ACE_OS::atoi (to); + + // Schedule the time between disconnects. This should really be a + // "tunable" parameter. + if (ACE_Service_Config::reactor ()->schedule_timer (this, 0, timeout) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "schedule_timer")); + + // If there are messages left in the queue, make sure we + // enable the ACE_Reactor appropriately to get them sent out. + if (this->msg_queue ()->is_empty () == 0 + && ACE_Service_Config::reactor ()->schedule_wakeup (this, + ACE_Event_Handler::WRITE_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "schedule_wakeup"), -1); + + // First action is to wait to be notified of our routing id. + this->do_action_ = &Gateway_Handler::await_route_id; + return 0; +} + +// Read messages from stdin and send them to the gatewayd. + +int +Gateway_Handler::xmit_stdin (void) +{ + if (this->routing_id_ != -1) + { + ssize_t n; + ACE_Message_Block *mb; + + ACE_NEW_RETURN (mb, + ACE_Message_Block (sizeof (Peer_Message)), + -1); + + Peer_Message *peer_msg = (Peer_Message *) mb->rd_ptr (); + peer_msg->header_.routing_id_ = this->routing_id_; + + n = ACE_OS::read (ACE_STDIN, peer_msg->buf_, sizeof peer_msg->buf_); + + switch (n) + { + case 0: + ACE_DEBUG ((LM_DEBUG, "stdin closing down\n")); + + // Take stdin out of the ACE_Reactor so we stop trying to + // send messages. + if (ACE_Service_Config::reactor ()->remove_handler + (0, ACE_Event_Handler::DONT_CALL | ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "remove_handler")); + delete mb; + break; + case -1: + delete mb; + ACE_ERROR ((LM_ERROR, "%p\n", "read")); + break; + default: + peer_msg->header_.len_ = htonl (n); + mb->wr_ptr (sizeof (Peer_Header) + n); + + if (this->put (mb) == -1) + { + if (errno == EWOULDBLOCK) // The queue has filled up! + ACE_ERROR ((LM_ERROR, "%p\n", + "gateway is flow controlled, so we're dropping messages")); + else + ACE_ERROR ((LM_ERROR, "%p\n", "transmission failure in xmit_stdin")); + + // Caller is responsible for freeing a ACE_Message_Block + // if failures occur. + delete mb; + } + } + } + return 0; +} + +// Perform a non-blocking put() of message MB. If we are unable to +// send the entire message the remainder is re-Taskd at the *front* of +// the Message_List. + +int +Gateway_Handler::nonblk_put (ACE_Message_Block *mb) +{ + // Try to send the message. If we don't send it all (e.g., due to + // flow control), then re-ACE_Task the remainder at the head of the + // Message_List and ask the ACE_Reactor to inform us (via + // handle_output()) when it is possible to try again. + + ssize_t n; + + if ((n = this->send_peer (mb)) == -1) + return -1; + else if (errno == EWOULDBLOCK) // Didn't manage to send everything. + { + ACE_DEBUG ((LM_DEBUG, + "queueing activated on handle %d to routing id %d\n", + this->get_handle (), this->routing_id_)); + + // ACE_Queue in *front* of the list to preserve order. + if (this->msg_queue ()->enqueue_head + (mb, (ACE_Time_Value *) &ACE_Time_Value::zero) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "enqueue_head"), -1); + + // Tell ACE_Reactor to call us back when we can send again. + if (ACE_Service_Config::reactor ()->schedule_wakeup + (this, ACE_Event_Handler::WRITE_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "schedule_wakeup"), -1); + return 0; + } + else + return n; +} + +// Finish sending a message when flow control conditions abate. This +// method is automatically called by the ACE_Reactor. + +int +Gateway_Handler::handle_output (ACE_HANDLE) +{ + ACE_Message_Block *mb = 0; + int status = 0; + + ACE_DEBUG ((LM_DEBUG, "in handle_output\n")); + // The list had better not be empty, otherwise there's a bug! + + if (this->msg_queue ()->dequeue_head + (mb, (ACE_Time_Value *) &ACE_Time_Value::zero) != -1) + { + switch (this->nonblk_put (mb)) + { + case 0: // Partial send. + ACE_ASSERT (errno == EWOULDBLOCK); + // Didn't write everything this time, come back later... + break; + + case -1: + // Caller is responsible for freeing a ACE_Message_Block if + // failures occur. + delete mb; + ACE_ERROR ((LM_ERROR, "%p\n", + "transmission failure in handle_output")); + + /* FALLTHROUGH */ + default: // Sent the whole thing. + + // If we succeed in writing the entire message (or we did + // not fail due to EWOULDBLOCK) then check if there are more + // messages on the Message_List. If there aren't, tell the + // ACE_Reactor not to notify us anymore (at least until + // there are new messages queued up). + + if (this->msg_queue ()->is_empty ()) + { + ACE_DEBUG ((LM_DEBUG, + "queue now empty on handle %d to routing id %d\n", + this->get_handle (), + this->routing_id_)); + + if (ACE_Service_Config::reactor ()->cancel_wakeup + (this, ACE_Event_Handler::WRITE_MASK) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "cancel_wakeup")); + } + } + } + else + ACE_ERROR ((LM_ERROR, "%p\n", "dequeue_head")); + return 0; +} + +// Send a message to a peer (may ACE_Task if necessary). + +int +Gateway_Handler::put (ACE_Message_Block *mb, ACE_Time_Value *) +{ + if (this->msg_queue ()->is_empty ()) + // Try to send the message *without* blocking! + return this->nonblk_put (mb); + else + // If we have queued up messages due to flow control then just + // enqueue and return. + return this->msg_queue ()->enqueue_tail + (mb, (ACE_Time_Value *) &ACE_Time_Value::zero); +} + +// Send an Peer message to gatewayd. + +int +Gateway_Handler::send_peer (ACE_Message_Block *mb) +{ + ssize_t n; + size_t len = mb->length (); + + if ((n = this->peer ().send (mb->rd_ptr (), len)) <= 0) + return errno == EWOULDBLOCK ? 0 : n; + else if (n < len) + { + // Re-adjust pointer to skip over the part we did send. + mb->rd_ptr (n); + this->total_bytes_ += n; + } + else /* if (n == length) */ + { + // The whole message is sent, we can now safely deallocate the + // buffer. Note that this should decrement a reference count... + this->total_bytes_ += n; + delete mb; + errno = 0; + } + ACE_DEBUG ((LM_DEBUG, "sent %d bytes, total bytes sent = %d\n", + n, this->total_bytes_)); + return n; +} + +// Receive an Peer message from gatewayd. Handles fragmentation. + +int +Gateway_Handler::recv_peer (ACE_Message_Block *&mb) +{ + Peer_Message *peer_msg; + size_t len; + ssize_t n; + size_t offset = 0; + + if (this->msg_frag_ == 0) + { + ACE_NEW_RETURN (this->msg_frag_, + ACE_Message_Block (sizeof (Peer_Message)), + -1); + + // No existing fragment... + if (this->msg_frag_ == 0) + ACE_ERROR_RETURN ((LM_ERROR, "out of memory\n"), -1); + + peer_msg = (Peer_Message *) this->msg_frag_->rd_ptr (); + + switch (n = this->peer ().recv (peer_msg, sizeof (Peer_Header))) + { + case sizeof (Peer_Header): + len = ntohl (peer_msg->header_.len_); + if (len <= sizeof peer_msg->buf_) + { + this->msg_frag_->wr_ptr (sizeof (Peer_Header)); + break; // The message is within the maximum size range. + } + else + ACE_ERROR ((LM_ERROR, "message too long = %d\n", len)); + /* FALLTHROUGH */ + default: + ACE_ERROR ((LM_ERROR, "invalid length = %d\n", n)); + n = -1; + /* FALLTHROUGH */ + case -1: + /* FALLTHROUGH */ + case 0: + // Make sure to free up memory on error returns. + delete this->msg_frag_; + this->msg_frag_ = 0; + return n; + } + } + else + { + offset = this->msg_frag_->length () - sizeof (Peer_Header); + len = peer_msg->header_.len_ - offset; + } + + switch (n = this->peer ().recv (peer_msg->buf_ + offset, len)) + { + case -1: + if (errno == EWOULDBLOCK) + { + // This shouldn't happen since the ACE_Reactor + // just triggered us to handle pending I/O! + ACE_DEBUG ((LM_DEBUG, "unexpected recv failure\n")); + // Since ACE_DEBUG might change errno, we need to reset it + // here. + errno = EWOULDBLOCK; + return -1; + } + else + /* FALLTHROUGH */; + + case 0: // EOF. + delete this->msg_frag_; + this->msg_frag_ = 0; + return n; + + default: + if (n != len) + // Re-adjust pointer to skip over the part we've read. + { + this->msg_frag_->wr_ptr (n); + errno = EWOULDBLOCK; + // Inform caller that we didn't get the whole message. + return -1; + } + else + { + // Set the write pointer at 1 past the end of the message. + this->msg_frag_->wr_ptr (n); + + // Set the read pointer to the beginning of the message. + this->msg_frag_->rd_ptr (this->msg_frag_->base ()); + + mb = this->msg_frag_; + + // Reset the pointer to indicate we've got an entire + // message. + this->msg_frag_ = 0; + } + return n; + } +} + +// Receive various types of input (e.g., Peer message from the +// gatewayd, as well as stdio). + +int +Gateway_Handler::handle_input (ACE_HANDLE sd) +{ + ACE_DEBUG ((LM_DEBUG, "in handle_input, sd = %d\n", sd)); + if (sd == ACE_STDIN) // Handle message from stdin. + return this->xmit_stdin (); + else + // Perform the appropriate action depending on the state we are + // in. + return (this->*do_action_) (); +} + +// Action that receives the route id. + +int +Gateway_Handler::await_route_id (void) +{ + ssize_t n = this->peer ().recv (&this->routing_id_, + sizeof this->routing_id_); + + if (n != sizeof this->routing_id_) + { + if (n == 0) + ACE_ERROR_RETURN ((LM_ERROR, + "gatewayd has closed down unexpectedly\n"), -1); + else + ACE_ERROR_RETURN ((LM_ERROR, + "%p, bytes received on handle %d = %d\n", + "recv", this->get_handle (), n), -1); + } + else + ACE_DEBUG ((LM_DEBUG, "assigned routing id %d\n", + this->routing_id_)); + + // Transition to the action that waits for Peer messages. + this->do_action_ = &Gateway_Handler::await_messages; + + // Reset standard input. + ACE_OS::rewind (stdin); + + // Register this handler to receive test messages on stdin. + if (ACE_Service_Config::reactor ()->register_handler + (ACE_STDIN, this, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "register_handler"), -1); + return 0; +} + +// Action that receives messages. + +int +Gateway_Handler::await_messages (void) +{ + ACE_Message_Block *mb = 0; + ssize_t n = this->recv_peer (mb); + + switch (n) + { + case 0: + ACE_ERROR_RETURN ((LM_ERROR, "gatewayd has closed down\n"), -1); + /* NOTREACHED */ + case -1: + if (errno == EWOULDBLOCK) + // A short-read, we'll come back and finish it up later on! + return 0; + else + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv_peer"), -1); + /* NOTREACHED */ + default: + { + // We got a valid message, so let's process it now! At the + // moment, we just print out the message contents... + + Peer_Message *peer_msg = (Peer_Message *) mb->rd_ptr (); + this->total_bytes_ += mb->length (); + +#if defined (VERBOSE) + ACE_DEBUG ((LM_DEBUG, + "route id = %d, len = %d, payload = %*s", + peer_msg->header_.routing_id_, peer_msg->header_.len_, + peer_msg->header_.len_, peer_msg->buf_)); +#else + ACE_DEBUG ((LM_DEBUG, + "route id = %d, cur len = %d, total len = %d\n", + peer_msg->header_.routing_id_, + peer_msg->header_.len_, + this->total_bytes_)); +#endif + delete mb; + return 0; + } + } +} + +// Periodically send messages via ACE_Reactor timer mechanism. + +int +Gateway_Handler::handle_timeout (const ACE_Time_Value &, const void *) +{ + // Skip over deactivated descriptors. + if (this->get_handle () != -1) + { + // Unbind ourselves from the map. + if (this->map_->unbind (this->get_handle ()) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "unbind")); + + // Shut down the handler. + this->handle_close (); + } + return 0; +} + +// Handle shutdown of the Gateway_Handler object. + +int +Gateway_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + if (this->get_handle () != ACE_INVALID_HANDLE) + { + ACE_DEBUG ((LM_DEBUG, "shutting down Gateway_Handler on handle %d\n", + this->get_handle ())); + + // Explicitly remove ourselves for handle 0 (the ACE_Reactor + // removes this->handle (), note that + // ACE_Event_Handler::DONT_CALL instructs the ACE_Reactor *not* + // to call this->handle_close(), which would otherwise lead to + // recursion!). + if (ACE_Service_Config::reactor ()->remove_handler + (0, ACE_Event_Handler::DONT_CALL | ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR ((LM_ERROR, "handle = %d: %p\n", + 0, "remove_handler")); + + // Deregister this handler with the ACE_Reactor. + if (ACE_Service_Config::reactor ()->remove_handler + (this, ACE_Event_Handler::DONT_CALL | ACE_Event_Handler::RWE_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "handle = %d: %p\n", + this->get_handle (), "remove_handler"), -1); + + // Close down the peer. + this->peer ().close (); + return 0; + } +} + +Gateway_Acceptor::Gateway_Acceptor (Gateway_Handler *handler) + : gateway_handler_ (handler) +{ + this->gateway_handler_->map (&this->map_); +} + +// Note how this method just passes back the pre-allocated +// Gateway_Handler instead of having the ACE_Acceptor allocate a new +// one each time! + +Gateway_Handler * +Gateway_Acceptor::make_svc_handler (void) +{ + return this->gateway_handler_; +} + +int +Gateway_Acceptor::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + ACE_DEBUG ((LM_DEBUG, "signal %S occurred\n", signum)); + return 0; +} + +/* Returns information on the currently active service. */ + +int +Gateway_Acceptor::info (char **strp, size_t length) const +{ + char buf[BUFSIZ]; + char addr_str[BUFSIZ]; + + ACE_INET_Addr addr; + + if (this->acceptor ().get_local_addr (addr) == -1) + return -1; + else if (addr.addr_to_string (addr_str, sizeof addr) == -1) + return -1; + + ACE_OS::sprintf (buf, "%s\t %s/%s %s", + "Gateway peer daemon", addr_str, "tcp", + "# IRIDIUM SRP traffic generator and data sink\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +// Hook called by the explicit dynamic linking facility to terminate +// the peer. + +int +Gateway_Acceptor::fini (void) +{ + HANDLER_ITERATOR mi (this->map_); + + for (MAP_ENTRY *me = 0; + mi.next (me) != 0; + mi.advance ()) + { + if (me->int_id_->get_handle () != -1) + { + ACE_DEBUG ((LM_DEBUG, "closing down handle %d\n", + me->int_id_->get_handle ())); + me->int_id_->handle_close (); + } + else + ACE_DEBUG ((LM_DEBUG, "already closed %d\n")); + me->int_id_->destroy (); // Will trigger a delete. + } + + this->gateway_handler_->destroy (); // Will trigger a delete. + return inherited::fini (); +} + +// Hook called by the explicit dynamic linking facility to initialize +// the peer. + +int +Gateway_Acceptor::init (int argc, char *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, "dp:", 0); + ACE_INET_Addr addr; + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'p': + addr.set (ACE_OS::atoi (get_opt.optarg)); + break; + case 'd': + break; + default: + break; + } + } + + if (ACE_Service_Config::reactor ()->register_handler (SIGPIPE, this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "register_handler"), -1); + + if (this->open (addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + else if (ACE_Service_Config::reactor ()->register_handler + (this, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "registering service with ACE_Reactor\n"), -1); + + ACE_Sig_Set sig_set; + sig_set.sig_add (SIGINT); + sig_set.sig_add (SIGQUIT); + + // Register ourselves to receive SIGINT and SIGQUIT so we can shut + // down gracefully via signals. + + if (ACE_Service_Config::reactor ()->register_handler (sig_set, + this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "register_handler"), -1); + return 0; +} + +// Dynamically linked factory function that dynamically allocates a +// new Gateway_Acceptor object. + +ACE_Service_Object * +_alloc_peerd (void) +{ + // This function illustrates how we can associate a ACE_Svc_Handler + // with the ACE_Acceptor at initialization time. + Gateway_Handler *handler; + + ACE_NEW_RETURN (handler, Gateway_Handler, 0); + ACE_Service_Object *temp; + + ACE_NEW_RETURN (temp, Gateway_Acceptor (handler), 0); + return temp; +} diff --git a/apps/Gateway/Peer/Gateway_Handler.h b/apps/Gateway/Peer/Gateway_Handler.h new file mode 100644 index 00000000000..d3156c47ce1 --- /dev/null +++ b/apps/Gateway/Peer/Gateway_Handler.h @@ -0,0 +1,154 @@ +/* -*- C++ -*- */ +// @(#)Gateway_Handler.h 1.1 10/18/96 + + +/* These Gateway handler classes process Peer messages sent from the + communication gateway daemon (gatewayd) to its various peers, e.g., + CF and ETS, (represented collectively in this prototype as peerd). + . These classes works as follows: + + 1. Gateway_Acceptor creates a listener endpoint and waits passively + for gatewayd to connect with it. + + 2. When gatewayd connects, Gateway_Acceptor creates an + Gateway_Handler object that sends/receives messages from + gatewayd. + + 3. Gateway_Handler waits for gatewayd to inform it of its routing + ID, which is prepended to all outgoing messages send from peerd. + + 4. Once the routing ID is set, peerd periodically sends messages to + gatewayd. Peerd also receives and "processes" messages + forwarded to it from gatewayd. In this program, peerd + "processes" messages by writing them to stdout. */ + +#if !defined (GATEWAY_HANDLER) +#define GATEWAY_HANDLER + +#include "ace/Service_Config.h" +#include "ace/Svc_Handler.h" +#include "ace/Acceptor.h" +#include "ace/SOCK_Stream.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/INET_Addr.h" +#include "ace/Map_Manager.h" +#include "Peer_Message.h" + +// Forward declaration. +class Gateway_Handler; + +// Maps a ACE_HANDLE onto a Gateway_Handler *. +typedef ACE_Map_Manager HANDLER_MAP; +typedef ACE_Map_Iterator HANDLER_ITERATOR; +typedef ACE_Map_Entry MAP_ENTRY; + +// Handle Peer messages arriving as events. + +class Gateway_Handler : public ACE_Svc_Handler +{ +public: + Gateway_Handler (ACE_Thread_Manager * = 0); + + virtual int open (void * = 0); + // Initialize the handler (called by ACE_Acceptor::handle_input()) + + virtual int handle_input (ACE_HANDLE); + // Receive and process peer messages. + + virtual int put (ACE_Message_Block *, ACE_Time_Value *tv = 0); + // Send a message to a gateway (may be queued if necessary). + + virtual int handle_output (ACE_HANDLE); + // Finish sending a message when flow control conditions abate. + + virtual int handle_timeout (const ACE_Time_Value &, + const void *arg); + // Periodically send messages via ACE_Reactor timer mechanism. + + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::RWE_MASK); + // Perform object termination. + + void map (HANDLER_MAP *); + // Cache a binding to the HANDLER_MAP. + +protected: + typedef ACE_Svc_Handler inherited; + + // We'll allow up to 16 megabytes to be queued per-output + // channel!!!! This is clearly a policy in search of refinement... + enum { QUEUE_SIZE = 1024 * 1024 * 16 }; + + int handle_signal (int signum, siginfo_t *, ucontext_t *); + + Peer_Header::ROUTING_ID routing_id_; + // Routing ID of the peer (obtained from gatewayd). + + virtual int nonblk_put (ACE_Message_Block *mb); + // Perform a non-blocking put(). + + virtual int recv_peer (ACE_Message_Block *&); + // Receive an Peer message from gatewayd. + + virtual int send_peer (ACE_Message_Block *); + // Send an Peer message to gatewayd. + + int xmit_stdin (void); + // Receive a message from stdin and send it to the gateway. + + int (Gateway_Handler::*do_action_) (void); + // Pointer-to-member-function for the current action to run in this state. + + int await_route_id (void); + // Action that receives the route id. + + int await_messages (void); + // Action that receives messages. + + ACE_Message_Block *msg_frag_; + // Keep track of message fragment to handle non-blocking recv's from gateway. + + size_t total_bytes_; + // The total number of bytes sent/received to the gateway. + + HANDLER_MAP *map_; + // Maps the ACE_HANDLE onto the Gateway_Handler *. +}; + +// A factory class that accept connections from gatewayd and +// dynamically creates a new Gateway_Handler object to do the dirty work. + +class Gateway_Acceptor : public ACE_Acceptor +{ +public: + // = Initialization methods, called when dynamically linked. + Gateway_Acceptor (Gateway_Handler *handler); + virtual int init (int argc, char *argv[]); + // Initialize the acceptor. + + virtual int info (char **, size_t) const; + // Return info about this service. + + virtual int fini (void); + // Perform termination. + + virtual Gateway_Handler *make_svc_handler (void); + // Factory method that creates the Gateway_Handler once. + + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + // Handle various signals (e.g., SIGPIPE) + + HANDLER_MAP map_; + // Maps the ACE_HANDLE onto the Gateway_Handler *. + + Gateway_Handler *gateway_handler_; + // Pointer to memory allocated exactly once. + + typedef ACE_Acceptor inherited; +}; + +// Factory function that allocates a new Peer daemon. +extern "C" ACE_Service_Object *_alloc_peerd (void); + +#endif /* GATEWAY_HANDLER */ + diff --git a/apps/Gateway/Peer/Makefile b/apps/Gateway/Peer/Makefile new file mode 100644 index 00000000000..38362c514a5 --- /dev/null +++ b/apps/Gateway/Peer/Makefile @@ -0,0 +1,137 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the peer portion of the communication gateway +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = peerd + +FILES = Gateway_Handler + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(addsuffix .o,$(FILES)) +VSHOBJS = $(LSRC:%.cpp=$(VSHDIR)%.so) + +LDLIBS = $(VSHOBJS) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/Gateway_Handler.o .shobj/Gateway_Handler.so: Gateway_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + Gateway_Handler.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/Acceptor.cpp \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + Peer_Message.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/apps/Gateway/Peer/Peer_Message.h b/apps/Gateway/Peer/Peer_Message.h new file mode 100644 index 00000000000..f6d636911c2 --- /dev/null +++ b/apps/Gateway/Peer/Peer_Message.h @@ -0,0 +1,44 @@ +/* -*- C++ -*- */ +// @(#)Peer_Message.h 1.1 10/18/96 + +// Define the Peer message schema (this may change). + +#if !defined (PEER_MESSAGE) +#define PEER_MESSAGE + +// Fixed sized header. + +class Peer_Header +{ +public: +// Type used to route messages from gatewayd. + typedef short ROUTING_ID; + + enum + { + INVALID_ID = -1 // No peer may use this number. + }; + + // Source ID. + ROUTING_ID routing_id_; + + // Length of the message in bytes. + size_t len_; +}; + +// Variable-sized message (buf_ may be variable-sized between +// 0 and MAX_PAYLOAD_SIZE). + +class Peer_Message +{ +public: + // The maximum size of an Peer message (see Peer protocol specs for exact #). + enum { MAX_PAYLOAD_SIZE = 1024 }; + + Peer_Header header_; + + // Message payload + char buf_[MAX_PAYLOAD_SIZE]; +}; + +#endif /* PEER_MESSAGE */ diff --git a/apps/Gateway/Peer/peerd.cpp b/apps/Gateway/Peer/peerd.cpp new file mode 100644 index 00000000000..a4c1b65a406 --- /dev/null +++ b/apps/Gateway/Peer/peerd.cpp @@ -0,0 +1,36 @@ +/* Driver for the peer daemon (peerd). Note that this +// @(#)peerd.cpp 1.1 10/18/96 + + is completely generic code due to the Service Configurator + framework! */ + +#include "ace/Service_Config.h" +#include "Gateway_Handler.h" + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config daemon; + + if (daemon.open (argc, argv) == -1) + { + if (errno != ENOENT) + ACE_ERROR ((LM_ERROR, "%p\n%a", "open", 1)); + else // Use static binding. + { + static char *l_argv[3] = { "-d", "-p", "10002" }; + + ACE_Service_Object *so = _alloc_peerd (); + + + if (so->init (3, l_argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "init", 1)); + } + } + + /* Run forever, performing the configured services (until SIGINT/SIGQUIT occurs) */ + + daemon.run_reactor_event_loop (); + + return 0; +} diff --git a/apps/Gateway/Peer/svc.conf b/apps/Gateway/Peer/svc.conf new file mode 100644 index 00000000000..0f663260445 --- /dev/null +++ b/apps/Gateway/Peer/svc.conf @@ -0,0 +1,3 @@ +#static Svc_Manager "-d -p 291" +dynamic Peer1 Service_Object *.shobj/Gateway_Handler.so:_alloc_peerd() active "-p 10004" +#dynamic Peer2 Service_Object *.shobj/Gateway_Handler.so:_alloc_peerd() active "-p 10003" diff --git a/apps/Gateway/README b/apps/Gateway/README new file mode 100644 index 00000000000..7a198d9d07b --- /dev/null +++ b/apps/Gateway/README @@ -0,0 +1,80 @@ +OVERVIEW + +This directory contains source code for a prototype application-level +gateway implemented with ACE. This prototype was developed in my +cs422 grad OS class at Washington University. + +DIRECTORY STRUCTURE + +There are 2 directories: + +Gateway + + -- The application Gateway, which must be started *after* all + the Peers described below). This process reads the + cc_config and rt_config files. The cc_config file tells + the Gateway what connections to establish with which hosts + on which ports, etc. The rt_config file tells the Gateway + how to route data coming from "sources" to the appropriate + "destinations." + +Peer + + -- The test driver programs that must be started *before* the + Gateway. To do anything interesting you'll need at + least two Peers: one for supplying events and one for consuming + them. In the configuration files, these two types of Peers + are designated as follows: + + (1) Input Peers (designated by an "I" in the Gateway's + cc_config configuration file). These Peers are "sources" + of messages to the Gateway. + + (2) Output Peers (designated by an "O" in the Gateway's + cc_config file). These Peers are "destinations" of + messages routed by the Gateway (routing is based on + the settings in the rt_config configuration file). + +RUNNING THE TESTS + +To run the tests do the following: + +1. Compile everything (i.e., first compile the ACE libraries, then + compile the the Gateway directories). + +2. Edit the rt_config and cc_config files as discussed above. + +3. Start up the Peers (peerd). You can start up as many as you + like, as per the cc_config file, but you'll need at least + two (one for supplying input and one for consuming output). I + typically start up each peer in a different window on a different + machine. The peers should print out some diagnostic info and then + block awaiting connections from the Gateway. + +4. Start up the Gateway (gatewayd). This will print out + a bunch of messages as it reads the config files and connects + to all the Peers. Assuming everything works, then all the + Peers will be connected. If some of the Peers aren't set up + correctly then the Gateway will use an exponential backoff + algorithm to attempt to reestablish those connections. + +5. Once the Gateway has connected with all the Peers you can send + messages from Input Peers by typing commands in the Peer window. + This input will be sent to the Gateway, which will forward + the message to all Output Peers that have "subscribed" to receive + these messages. + + Note that if you type ^C in a Peer window the Peer will shutdown + its handlers and exit. The Gateway will detect this and will + start trying to reestablish the connection using the same + exponential backoff algorithm it used for the initial connection + establishment. + +7. When you want to terminate a Gateway, just type ^C + and the process will shut down gracefully. + +Please let me know if there are any questions. + + Doug + +schmidt@cs.wustl.edu diff --git a/apps/Makefile b/apps/Makefile new file mode 100644 index 00000000000..30fddeb5b26 --- /dev/null +++ b/apps/Makefile @@ -0,0 +1,30 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the apps directory +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +INFO = README + +DIRS = Synch-Benchmarks \ + Gateway + +# The following directory isn't compiled by default since haven't +# finished integrating it into ACE... +# +# Orbix-Examples + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + diff --git a/apps/Orbix-Examples/Event_Comm/Consumer/Input_Handler.cpp b/apps/Orbix-Examples/Event_Comm/Consumer/Input_Handler.cpp new file mode 100644 index 00000000000..29d8b1218b2 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/Consumer/Input_Handler.cpp @@ -0,0 +1,130 @@ +#include "Input_Handler.h" +// @(#)Input_Handler.cpp 1.1 10/18/96 + +#include "Notification_Receiver_Handler.h" + +#if defined (ACE_HAS_ORBIX) + +Input_Handler::~Input_Handler (void) +{ + ACE_DEBUG ((LM_DEBUG, "closing down Input_Handler::~Input_Handler\n")); + this->handle_close (); +} + +int +Input_Handler::consumer_initiated_shutdown (void) +{ + return this->consumer_initiated_shutdown_; +} + +void +Input_Handler::consumer_initiated_shutdown (int c) +{ + this->consumer_initiated_shutdown_ = c; +} + +ACE_HANDLE +Input_Handler::get_handle (void) const +{ + return this->handle_; +} + +int +Input_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + ACE_DEBUG ((LM_DEBUG, "closing down Consumer::Input_Handler\n")); + + Event_Comm::Notification_Receiver *receiver = this->receiver_handler_->receiver (); + Event_Comm::Notifier *notifier = this->receiver_handler_->notifier (); + + if (this->consumer_initiated_shutdown ()) + { + // Only try to unsubscribe if the Consumer initiated the + // shutdown. Otherwise, the Supplier initiated it and + // it has probably gone away by now! + TRY { + // Gracefully shutdown the Receiver by removing it + // from the Notifier's internal map. + + notifier->unsubscribe (receiver, "", IT_X); + } CATCHANY { + cerr << IT_X << endl; + } ENDTRY; + } + // Don't execute a callback here otherwise we'll recurse indefinitely! + if (ACE_Service_Config::reactor ()->remove_handler (this, ACE_Event_Handler::READ_MASK + | ACE_Event_Handler::DONT_CALL) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "remove_handler")); + + // *Must* be allocated dyanmically! + delete (void *) this; + return 0; +} + +Input_Handler::Input_Handler (Notification_Receiver_Handler *ch, + ACE_HANDLE handle) + : receiver_handler_ (ch), + handle_ (handle), + consumer_initiated_shutdown_ (0) +{ + if (ACE_Service_Config::reactor ()->register_handler (this, + ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR ((LM_ERROR, "Input_Handler::Input_Handler\n")); +} + +int +Input_Handler::handle_input (ACE_HANDLE h) +{ + char buf[BUFSIZ]; + ssize_t n; + + // Read up to BUFSIZ worth of data from ACE_HANDLE h. + + n = ACE_OS::read (h, buf, sizeof buf - 1); + + if (n > 0) + { + // Null terminate the buffer, replacing the '\n' with '\0'. + if (buf[n - 1] == '\n' || buf[n - 1] == EOF) + buf[n - 1] = '\0'; + else + buf[n] = '\0'; + ACE_DEBUG ((LM_DEBUG, "notifying for event %s\n", buf)); + + } + else + { + ACE_OS::strcpy (buf, "quit"); + ACE_DEBUG ((LM_DEBUG, "shutting down Input_Handler\n")); + } + + Event_Comm::Notifier *notifier = this->receiver_handler_->notifier (); + + ACE_ASSERT (notifier != 0); + + if (ACE_OS::strcmp (buf, "quit") == 0) + { + // Consumer wants to shutdown. + this->consumer_initiated_shutdown (1); + + // Tell the main event loop to shutdown. + ACE_Service_Config::end_reactor_event_loop (); + } + else + { + TRY { + Event_Comm::Notification notification; + + notification.tag_ = ACE_OS::strdup (buf); + + notifier->send_notification (notification, IT_X); + } + CATCHANY { + cerr << "Unexpected exception " << IT_X << endl; + } ENDTRY; + } + + /* NOTREACHED */ + return 0; +} +#endif /* ACE_HAS_ORBIX */ diff --git a/apps/Orbix-Examples/Event_Comm/Consumer/Input_Handler.h b/apps/Orbix-Examples/Event_Comm/Consumer/Input_Handler.h new file mode 100644 index 00000000000..d2b87d90f57 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/Consumer/Input_Handler.h @@ -0,0 +1,71 @@ +/* -*- C++ -*- */ +// @(#)Input_Handler.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// EventComm +// +// = FILENAME +// Input_Handler.h +// +// = DESCRIPTION +// Subclass of ACE ACE_Service_Object that receives unsubscribes from +// the Notifier when input is received from the keyboard. +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) +// +// ============================================================================ + +#if !defined (_INPUT_HANDLER_H) +#define _INPUT_HANDLER_ + +#include "ace/Service_Config.h" + +#if defined (ACE_HAS_ORBIX) +// Forward declaration. +class Notification_Receiver_Handler; + +class Input_Handler : public ACE_Service_Object + // = TITLE + // Handles input events generated from a keyboard. + // + // = DESCRIPTION +{ +public: + Input_Handler (Notification_Receiver_Handler *, ACE_HANDLE h = 0); + + virtual int handle_input (ACE_HANDLE); + // Dispatch the callback when events occur. + + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::NULL_MASK); + // Close down the handler. + + int consumer_initiated_shutdown (void); + // Report whether the Consumer initiated the shutdown. + + void consumer_initiated_shutdown (int); + // Indicate that the Consumer initiated the shutdown. + +private: + ~Input_Handler (void); + // Ensure dynamic allocation. + + virtual ACE_HANDLE get_handle (void) const; + + ACE_HANDLE handle_; + // ACE_HANDLE where the input comes from. + + Notification_Receiver_Handler *receiver_handler_; + // Pointer to the that + // receives notifications from the . + + int consumer_initiated_shutdown_; + // Keep track of whether the Consumer initiated the shutdown. +}; + +#endif /* ACE_HAS_ORBIX */ +#endif /* _INPUT_HANDLER_H */ diff --git a/apps/Orbix-Examples/Event_Comm/Consumer/Makefile b/apps/Orbix-Examples/Event_Comm/Consumer/Makefile new file mode 100644 index 00000000000..872b72a1880 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/Consumer/Makefile @@ -0,0 +1,165 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Consumer. +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = consumer + +FILES = Notification_Receiver_Handler \ + Input_Handler + +LSRC = $(addsuffix .cpp,$(FILES)) consumer.cpp +LOBJ = $(addsuffix .o,$(FILES)) +SHOBJ = $(addsuffix .so,$(FILES)) + +SRX = ../src/.obj + +LDLIBS = $(addprefix .shobj/,$(LOBJ)) ../src/libEvent_Comm.a +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +CPPFLAGS += -I../include +VLDLIBS += -lgen + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +Notification_Receiver_Handler.o: Notification_Receiver_Handler.cpp \ + Notification_Receiver_Handler.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/CORBA_Handler.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Config.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Reactor.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Handle_Set.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/sysincludes.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/config.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Handle_Set.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Timer_Queue.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Event_Handler.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Time_Value.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Synch.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Synch_T.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Timer_Queue.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Signal.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Set.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Token.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Reactor.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Msg.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Record.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Priority.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Record.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Msg.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Specific.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Specific.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Object.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Shared_Object.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Record.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Manager.h \ + ../include/Event_Comm_i.h ../include/Notification_Receiver_i.h \ + ../include/Notifier_i.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Map_Manager.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/SString.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/SString.i \ + ../include/Event_Comm.hh +Input_Handler.o: Input_Handler.cpp Input_Handler.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Config.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Reactor.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Handle_Set.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/sysincludes.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/config.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Handle_Set.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Timer_Queue.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Event_Handler.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Time_Value.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Synch.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Synch_T.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Timer_Queue.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Signal.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Set.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Token.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Reactor.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Msg.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Record.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Priority.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Record.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Msg.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Specific.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Specific.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Object.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Shared_Object.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Record.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Manager.h \ + Notification_Receiver_Handler.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/CORBA_Handler.h \ + ../include/Event_Comm_i.h ../include/Notification_Receiver_i.h \ + ../include/Notifier_i.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Map_Manager.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/SString.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/SString.i \ + ../include/Event_Comm.hh +consumer.o: consumer.cpp \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Msg.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Record.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/sysincludes.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/config.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Priority.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Record.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Msg.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Specific.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Synch.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Time_Value.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Synch_T.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Specific.i \ + Notification_Receiver_Handler.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/CORBA_Handler.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Config.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Reactor.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Handle_Set.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Handle_Set.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Timer_Queue.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Event_Handler.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Timer_Queue.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Signal.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Set.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Token.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Reactor.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Object.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Shared_Object.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Record.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Manager.h \ + ../include/Event_Comm_i.h ../include/Notification_Receiver_i.h \ + ../include/Notifier_i.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Map_Manager.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/SString.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/SString.i \ + ../include/Event_Comm.hh Input_Handler.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/apps/Orbix-Examples/Event_Comm/Consumer/Notification_Receiver_Handler.cpp b/apps/Orbix-Examples/Event_Comm/Consumer/Notification_Receiver_Handler.cpp new file mode 100644 index 00000000000..eccf499f6c0 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/Consumer/Notification_Receiver_Handler.cpp @@ -0,0 +1,114 @@ +#include "Notification_Receiver_Handler.h" +// @(#)Notification_Receiver_Handler.cpp 1.1 10/18/96 + + +#if defined (ACE_HAS_ORBIX) + +#if defined (ACE_HAS_MT_ORBIX) +typedef ACE_MT_CORBA_Handler CORBA_HANDLER; +#else +typedef ACE_ST_CORBA_Handler CORBA_HANDLER; +#endif /* ACE_HAS_MT_ORBIX */ + +int +Notification_Receiver_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ +// ACE_ST_CORBA_Handler::remove_service (Event_Comm_Notification_Receiver_IMPL); + + if (this->receiver_ != 0) + { + ACE_DEBUG ((LM_DEBUG, "closing down Notification_Receiver_Handler\n")); + CORBA_HANDLER::instance ()->deactivate_service (Event_Comm_Notification_Receiver_IMPL, + this->receiver_->_marker ()); + CORBA::release (this->receiver_); + this->receiver_ = 0; + CORBA::release (this->notifier_); + this->notifier_ = 0; + // *Must* be allocated dynamically in order to delete this! + delete this; + } + return 0; +} + +Notification_Receiver_Handler::Notification_Receiver_Handler (int argc, char *argv[]) + : notifier_ (0), + receiver_ (0) +{ + const char *server_name = Event_Comm_Notification_Receiver_IMPL; + char buf[BUFSIZ]; + char *receiver_marker = buf; + char *filtering_criteria; + char *host; + char *notifier_marker; + char *service_location = argv[0]; + + // First see if we have any environment variables. + filtering_criteria = ACE_OS::getenv ("FILTERING_CRITERIA"); + host = ACE_OS::getenv ("HOST"); + notifier_marker = ACE_OS::getenv ("NOTIFIER_MARKER"); + + // Then override these variables with command-line arguments. + filtering_criteria = argc > 1 ? argv[1] : ""; + host = argc > 2 ? argv[2] : "tango.cs"; + notifier_marker = argc > 3 ? argv[3] : "notifier:" Event_Comm_Notifier_IR; + + CORBA::Orbix.setDiagnostics (0); + + struct utsname name; + + // Make the marker name be the "/hostname/processid" + ACE_OS::uname (&name); + sprintf (buf, "/%s/%d", name.nodename, ACE_OS::getpid ()); + + CORBA_HANDLER::instance ()->activate_service (Event_Comm_Notification_Receiver_IMPL, + receiver_marker, service_location); + + // Create the receiver object. + this->receiver_ = new TIE_Event_Comm_Notification_Receiver (Notification_Receiver_i) + (new Notification_Receiver_i); + + this->receiver_->_marker (receiver_marker); + + ACE_ASSERT (this->receiver_); + + TRY { + // Get a binding to the notifier. + this->notifier_ = Event_Comm::Notifier::_bind (notifier_marker, host, IT_X); + + if (this->notifier_ != CORBA::OBJECT_NIL) + // Subscribe ourselves with the notifier's broker. + this->notifier_->subscribe (this->receiver_, + filtering_criteria, IT_X); + } CATCHANY { + cerr << "Unexpected exception " << IT_X << endl; + ACE_OS::exit (1); + } ENDTRY; + // Print out context. + + receiver_marker = (char *) this->receiver_->_marker (); + CORBA::BOA::activationMode mode = CORBA::Orbix.myActivationMode (); + ACE_DEBUG ((LM_DEBUG, "starting up a %spersistent server in mode %d with marker name %s\n", + mode == CORBA::BOA::persistentActivationMode ? "" : "non-", + mode, receiver_marker)); +} + +Event_Comm::Notification_Receiver * +Notification_Receiver_Handler::receiver (void) +{ + return this->receiver_; +} + +Event_Comm::Notifier * +Notification_Receiver_Handler::notifier (void) +{ + return this->notifier_; +} + +// Destroy a Receiver target object. + +Notification_Receiver_Handler::~Notification_Receiver_Handler (void) +{ + this->handle_close (-1, ACE_Event_Handler::RWE_MASK); +} + +#endif /* ACE_HAS_ORBIX */ diff --git a/apps/Orbix-Examples/Event_Comm/Consumer/Notification_Receiver_Handler.h b/apps/Orbix-Examples/Event_Comm/Consumer/Notification_Receiver_Handler.h new file mode 100644 index 00000000000..9ccd472ef1b --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/Consumer/Notification_Receiver_Handler.h @@ -0,0 +1,62 @@ +/* -*- C++ -*- */ +// @(#)Notification_Receiver_Handler.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// EventComm +// +// = FILENAME +// Notifier_Receiver_Handler.h +// +// = DESCRIPTION +// Subclass of Corba_Handler that sets up the Notification_Receiver handler +// for use with the ACE ACE_Reactor. +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) +// +// ============================================================================ + +#if !defined (_NOTIFICATION_RECEIVER_HANDLER_H) +#define _NOTIFICATION_RECEIVER_HANDLER_H + +#include "ace/CORBA_Handler.h" +#include "Event_Comm_i.h" + +#if defined (ACE_HAS_ORBIX) + +class Notification_Receiver_Handler + // = TITLE + // Subclass of Corba_Handler that sets up the Notification Receiver handler + // for use with the ACE ACE_Reactor. + // + // = DESCRIPTION + // Note that this class doesn't inherit from ACE_ST_CORBA_Handler (unlike + // the Supplier's Notifier_Handler class). Instead, it uses an + // alternative interface that can be called directly. +{ +public: + Notification_Receiver_Handler (int argc, char *argv[]); + + Event_Comm::Notification_Receiver *receiver (void); + Event_Comm::Notifier *notifier (void); + + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::NULL_MASK); + // Close down the handler. + +private: + ~Notification_Receiver_Handler (void); + // Ensure dynamic allocation. + + Event_Comm::Notification_Receiver *receiver_; + // Pointer to an IDL proxy object. + + Event_Comm::Notifier *notifier_; + // Pointer to an IDL proxy object. +}; + +#endif /* ACE_HAS_ORBIX */ +#endif /* _NOTIFICATION_RECEIVER_HANDLER_H */ diff --git a/apps/Orbix-Examples/Event_Comm/Consumer/consumer.cpp b/apps/Orbix-Examples/Event_Comm/Consumer/consumer.cpp new file mode 100644 index 00000000000..7133a8c8749 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/Consumer/consumer.cpp @@ -0,0 +1,114 @@ +/* -*- C++ -*- */ +// @(#)consumer.cpp 1.1 10/18/96 + +// Consumer driver for the Orbix Notification example. + +#include "ace/Log_Msg.h" +#include "Notification_Receiver_Handler.h" +#include "Input_Handler.h" + +#if defined (ACE_HAS_ORBIX) + +class Consumer : public ACE_Event_Handler +{ +public: + Consumer (int argc, char *argv[]); + ~Consumer (void); + + void run (void); + // Execute the consumer; + +private: + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + + virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask); + + Input_Handler *ih_; + // Handler for keyboard input. + + Notification_Receiver_Handler *nrh_; + // Handler for CORBA Consumer. + + ACE_Service_Config daemon_; + // ACE server event-loop mechanism. +}; + +int +Consumer::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + ACE_DEBUG ((LM_DEBUG, "closing down Consumer\n")); + return 0; +} + +int +Consumer::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + ACE_DEBUG ((LM_DEBUG, "%S\n", signum)); + + // Indicate that the consumer initiated the shutdown. + this->ih_->consumer_initiated_shutdown (1); + + // Shut down the event loop. + ACE_Service_Config::end_reactor_event_loop (); + return 0; +} + +// Run the event loop until someone calls +// calls ACE_Service_Config::end_reactor_event_loop(). + +void +Consumer::run (void) +{ + if (ACE_Service_Config::run_reactor_event_loop () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "run_reactor_event_loop")); +} + +Consumer::Consumer (int argc, char *argv[]) + : ih_ (0), + nrh_ (0) +{ + // Initialize the server. + if (this->daemon_.open (argc, argv) == -1) + { + if (errno == ENOENT) // There's no svc.conf file, so use static linking... + { + ACE_DEBUG ((LM_DEBUG, "no config file, using static binding\n")); + // The constructor registers the handlers... + this->nrh_ = new Notification_Receiver_Handler (argc, argv); + ACE_ASSERT (this->nrh_ != 0); + this->ih_ = new Input_Handler (this->nrh_); + ACE_ASSERT (this->ih_ != 0); + } + else + ACE_ERROR ((LM_ERROR, "%p\n%a", "open", 1)); + } + + if (ACE_Service_Config::reactor ()->register_handler (SIGINT, this) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "register_handler")); +} + +Consumer::~Consumer (void) +{ + // Free up the handlers if they were statically bound. + this->ih_->handle_close (); + this->nrh_->handle_close (); +} + +int +main (int argc, char *argv[]) +{ + // Initialize the supplier and consumer object references. + Consumer consumer (argc, argv); + + // Loop forever handling events. + consumer.run (); + + return 0; +} +#else /* !defined ACE_HAS_ORBIX */ +int +main (int argc, char *argv[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, "you must have Orbix to run application %s\n", argv[0]), 1); +} +#endif /* ACE_HAS_ORBIX */ diff --git a/apps/Orbix-Examples/Event_Comm/Makefile b/apps/Orbix-Examples/Event_Comm/Makefile new file mode 100644 index 00000000000..3e0c8ae2dd8 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/Makefile @@ -0,0 +1,26 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the consumer/supplier notification application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +INFO = README + +DIRS = libsrc \ + Consumer \ + Supplier + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + diff --git a/apps/Orbix-Examples/Event_Comm/README b/apps/Orbix-Examples/Event_Comm/README new file mode 100644 index 00000000000..1bd7b5d8c45 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/README @@ -0,0 +1,109 @@ +OVERVIEW + +This directory contains source code for a prototype CORBA-based +distributed notification mechanism. This mechanism implements a +"publish/subscribe" communication protocol. It allows Suppliers to +pass messages containing object references to a dynamically managed +group of Consumers. This is similar to the OMG COSS Event Service, +though not as sophisticated. + +This example also illustrates how to integrate Orbix with the ACE +libraries. + +DIRECTORY STRUCTURE + +There are 4 directories: + +Supplier + + -- The supplier test driver, which must be started + first. It has an instance of an IDL Notifier + object. This object accepts subscriptions from Consumers + and forwards events sent to it either via Consumers or + via its standard input. + + The Supplier must be registered with the ORB using the + following command: + + % putit Event_Comm_Notifier /supplier + +Consumer + + -- The consumer test driver, which must be started + after the Supplier. It has an instance of an + IDL Notification_Receiver object. This object is + used to receive notifications from the Notifier object + residing in the Supplier. When the Consumer starts up it + gets an object reference to the Supplier's Notifier. + It then subscribes its Notification_Receiver object with + the Supplier's Notifier by passing an object reference. + + In addition to passing an object reference to a + Notification_Receiver, the Consumer also may specify a + filtering criteria, which is a regular expression. If + the filtering criteria is the string "" then the Notifier + will send all Notifications to the Consumer (i.e., "" is + treated as a "wildcard"). Otherwise, the filtering + criteria is considered to be a regular expression, + and only those Notification tags that match the regular + expression will be forwarded to the Consumer. The regular + expressions are those used by ed(1) (see the regexp(5) + manual page for more info). + + The Consumer must be registered with the ORB + using the following command: + + % putit Event_Comm_Notification_Receiver /consumer + +include + + -- This contains links to the appropriate header + files. + +libsrc + + -- This contains the IDL files and IDL implementation + classes that support the distributed notification scheme. + These are shared by the Consumer and Supplier. + +RUNNING THE TESTS + +To run the tests do the following: + +1. Compile everything. + +2. Start up the Orbix daemon (orbixd) if it's not already + running. + +3. Register the Consumer (i.e., Notification_Receiver) and Supplier + (i.e., Notifier) with the Orbix daemon (orbixd), as described + above. + +4. Start the Supplier/supplier executable. + +5. Start up as many copies of the Consumer/consumer as you'd like. + Typically, I run each one in its own window. If you'd like to use + different machines make sure that you start up the Orbix daemon on + each one and register the Consumer. + +6. Once the Consumers have subscribed you can send them info by typing + commands in the Supplier window. These will be sent to all the + Consumers who have subscribed. Likewise, you can send messages + from a Consumer to all other Consumers by typing messages in a + Consumer window. + + Note that if you type "quit", ^D, or ^C in a Consumer window the + Consumer will unsubscribe and shutdown its handlers and exit. + Likewise, if you type "quit", ^D, or ^C in the Supplier window + the Supplier will disconnect all of its Consumers and exit. + When a Consumer is disconnected from its Supplier it automatically + shuts itself down. + +7. When you want to terminate a Consumer or a Supplier, just type ^C + and the process will shut down gracefully. + +Please let me know if there are any questions. + + Doug + +schmidt@cs.wustl.edu diff --git a/apps/Orbix-Examples/Event_Comm/Supplier/Input_Handler.cpp b/apps/Orbix-Examples/Event_Comm/Supplier/Input_Handler.cpp new file mode 100644 index 00000000000..96a89f0ac6b --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/Supplier/Input_Handler.cpp @@ -0,0 +1,120 @@ +#include "Event_Comm.hh" +// @(#)Input_Handler.cpp 1.1 10/18/96 + +#include "Notifier_Handler.h" +#include "Input_Handler.h" + +#if defined (ACE_HAS_ORBIX) + +int +Input_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + ACE_DEBUG ((LM_DEBUG, "closing down Supplier::Input_Handler\n")); + + Event_Comm::Notifier *notifier = this->notifier_->notifier (); + ACE_ASSERT (notifier != 0); + + ACE_OS::fclose (this->fp_); + + TRY { + // Disconnect all the consumers gracefully. + notifier->send_disconnect ("quit", IT_X); + } CATCHANY { + cerr << IT_X << endl; + } ENDTRY; + + // Don't execute a callback here otherwise we'll recurse indefinitely! + if (ACE_Service_Config::reactor ()->remove_handler (this, ACE_Event_Handler::READ_MASK + | ACE_Event_Handler::DONT_CALL) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "remove_handler")); + + // *Must* be allocated dyanmically! + delete (void *) this; + return 0; +} + +Input_Handler::Input_Handler (Notifier_Handler *notifier, + ACE_HANDLE handle) // Use stdin by default. + : notifier_ (notifier), + handle_ (handle) +{ + // Register ourselves with the ACE_Reactor so that input events + // cause our handle_input() method to be dispatched automatically. + + if (ACE_Service_Config::reactor ()->register_handler (this, + ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "register_handler")); + + this->fp_ = ACE_OS::fdopen (handle, "r"); + + if (this->fp_ == 0) + ACE_ERROR ((LM_ERROR, "%p\n", "fdopen")); +} + +Input_Handler::~Input_Handler (void) +{ + ACE_DEBUG ((LM_DEBUG, "closing down Input_Handler::~Input_Handler\n")); + this->handle_close (); +} + +ACE_HANDLE +Input_Handler::get_handle (void) const +{ + return this->handle_; +} + +// Frame input events and notify . + +int +Input_Handler::handle_input (ACE_HANDLE h) +{ + char buf[BUFSIZ]; + + // Read up to BUFSIZ worth of data from ACE_HANDLE h. + + if (ACE_OS::fgets (buf, sizeof buf - 1, this->fp_) == 0) + { + ACE_OS::strcpy (buf, "quit"); + ACE_DEBUG ((LM_DEBUG, "shutting down Input_Handler\n")); + } + else + { + size_t n = ACE_OS::strlen (buf); + + // Null terminate the buffer, replacing the '\n' with '\0'. + if (buf[n - 1] == '\n' || buf[n - 1] == EOF) + buf[n - 1] = '\0'; + else + buf[n] = '\0'; + ACE_DEBUG ((LM_DEBUG, "notifying for event %s\n", buf)); + } + + Event_Comm::Notifier *notifier = this->notifier_->notifier (); + ACE_ASSERT (notifier != 0); + + if (ACE_OS::strcmp (buf, "quit") == 0) + // Tell the main event loop to shutdown. + ACE_Service_Config::end_reactor_event_loop (); + else + { + // Use the notifier to notify Consumers. + TRY { + Event_Comm::Notification notification; + + // Pass the buf over in the tag field. + notification.tag_ = ACE_OS::strdup (buf); + + // This is where the "any" value goes or the object reference... + // notification.value_ = ... + + // Forward to all . + notifier->send_notification (notification, IT_X); + } + CATCHANY { + cerr << "unexpected exception " << IT_X << endl; + } ENDTRY; + } + return 0; +} + +#endif /* ACE_HAS_ORBIX */ diff --git a/apps/Orbix-Examples/Event_Comm/Supplier/Input_Handler.h b/apps/Orbix-Examples/Event_Comm/Supplier/Input_Handler.h new file mode 100644 index 00000000000..7bd05bbb5db --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/Supplier/Input_Handler.h @@ -0,0 +1,70 @@ +/* -*- C++ -*- */ +// @(#)Input_Handler.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// EventComm +// +// = FILENAME +// Input_Handler.h +// +// = DESCRIPTION +// Handle input from the keyboard. +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) +// +// ============================================================================ + +#if !defined (_INPUT_HANDLER_H) +#define _INPUT_HANDLER_H + +#include "ace/Service_Config.h" + +#if defined (ACE_HAS_ORBIX) + +// Forward declaration. +class Notifier_Handler; + +class Input_Handler : public ACE_Service_Object + // = TITLE + // Handles input events generated from a keyboard. + // + // = DESCRIPTION + // The events are currently framed and forwarded to + // all Consumers. In the future, we will need to + // be more selective and only send to those Consumers + // whose filtering criteria matches! +{ +public: + Input_Handler (Notifier_Handler *, ACE_HANDLE = 0); // Use stdin by default. + + virtual int handle_input (ACE_HANDLE); + // Frame input events and notify . + + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::NULL_MASK); + // Close down the handler. + +protected: + virtual ACE_HANDLE get_handle (void) const; + + ACE_HANDLE handle_; + // ACE_HANDLE where the input comes from. + + Notifier_Handler *notifier_; + // Pointer to a that's used to inform + // Consumers that events of interest have occurred. + + FILE *fp_; + // Pointer to an input ACE_FILE. + +private: + ~Input_Handler (void); + // Ensure dynamic allocation. +}; + +#endif /* ACE_HAS_ORBIX */ +#endif /* _INPUT_HANDLER_H */ diff --git a/apps/Orbix-Examples/Event_Comm/Supplier/Makefile b/apps/Orbix-Examples/Event_Comm/Supplier/Makefile new file mode 100644 index 00000000000..4ded1a20e24 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/Supplier/Makefile @@ -0,0 +1,164 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Notifier. +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = supplier + +FILES = Input_Handler \ + Notifier_Handler + +LSRC = $(addsuffix .cpp,$(FILES)) supplier.cpp +LOBJ = $(addsuffix .o,$(FILES)) +SHOBJ = $(addsuffix .so,$(FILES)) + +SRX = ../src/.obj + +LDLIBS = $(addprefix .shobj/,$(LOBJ)) ../src/libEvent_Comm.a + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +CPPFLAGS += -I../include +VLDLIBS += -lgen + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +Input_Handler.o: Input_Handler.cpp ../include/Event_Comm.hh Notifier_Handler.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/CORBA_Handler.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Config.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Reactor.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Handle_Set.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/sysincludes.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/config.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Handle_Set.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Timer_Queue.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Event_Handler.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Time_Value.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Synch.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Synch_T.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Timer_Queue.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Signal.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Set.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Token.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Reactor.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Msg.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Record.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Priority.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Record.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Msg.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Specific.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Specific.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Object.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Shared_Object.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Record.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Manager.h \ + ../include/Event_Comm_i.h ../include/Notification_Receiver_i.h \ + ../include/Notifier_i.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Map_Manager.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/SString.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/SString.i \ + Input_Handler.h +Notifier_Handler.o: Notifier_Handler.cpp Notifier_Handler.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/CORBA_Handler.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Config.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Reactor.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Handle_Set.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/sysincludes.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/config.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Handle_Set.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Timer_Queue.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Event_Handler.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Time_Value.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Synch.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Synch_T.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Timer_Queue.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Signal.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Set.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Token.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Reactor.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Msg.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Record.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Priority.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Record.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Msg.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Specific.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Specific.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Object.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Shared_Object.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Record.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Manager.h \ + ../include/Event_Comm_i.h ../include/Notification_Receiver_i.h \ + ../include/Notifier_i.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Map_Manager.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/SString.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/SString.i \ + ../include/Event_Comm.hh +supplier.o: supplier.cpp \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Config.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Reactor.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Handle_Set.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/sysincludes.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/config.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Handle_Set.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Timer_Queue.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Event_Handler.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Time_Value.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Synch.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Synch_T.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Timer_Queue.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Signal.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Set.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Token.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Reactor.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Msg.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Record.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Priority.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Record.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Msg.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Specific.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Specific.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Object.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Shared_Object.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Record.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Manager.h \ + Notifier_Handler.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/CORBA_Handler.h \ + ../include/Event_Comm_i.h ../include/Notification_Receiver_i.h \ + ../include/Notifier_i.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Map_Manager.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/SString.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/SString.i \ + ../include/Event_Comm.hh Input_Handler.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/apps/Orbix-Examples/Event_Comm/Supplier/Notifier_Handler.cpp b/apps/Orbix-Examples/Event_Comm/Supplier/Notifier_Handler.cpp new file mode 100644 index 00000000000..84e9b3380bf --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/Supplier/Notifier_Handler.cpp @@ -0,0 +1,66 @@ +#include "Notifier_Handler.h" +// @(#)Notifier_Handler.cpp 1.1 10/18/96 + + +#if defined (ACE_HAS_ORBIX) + +#if defined (ACE_HAS_MT_ORBIX) +typedef ACE_MT_CORBA_Handler CORBA_HANDLER; +#else +typedef ACE_ST_CORBA_Handler CORBA_HANDLER; +#endif /* ACE_HAS_MT_ORBIX */ + +int +Notifier_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + if (this->notifier_ != 0) + { + ACE_DEBUG ((LM_DEBUG, "closing down Notifier_Handler\n")); + CORBA_HANDLER::instance ()->deactivate_service (Event_Comm_Notifier_IMPL, + this->notifier_->_marker ()); + CORBA::release (this->notifier_); + this->notifier_ = 0; + // *Must* be allocated dyanmically! + delete this; + } + return 0; +} + +Event_Comm::Notifier * +Notifier_Handler::notifier (void) +{ + return this->notifier_; +} + +void +Notifier_Handler::notifier (Event_Comm::Notifier *notifier) +{ + if (this->notifier_ != notifier) + { + CORBA::release (this->notifier_); + this->notifier_ = notifier; + } +} + +// Create and initialize a Notifier target object. + +Notifier_Handler::Notifier_Handler (const char *service_location, + const char *marker, + int putit) +{ + CORBA_HANDLER::instance ()->activate_service (Event_Comm_Notifier_IMPL, + putit ? marker : 0, service_location); + + // Create a notifier object using the implementation class Notifier_i. + this->notifier_ = + new TIE_Event_Comm_Notifier (Notifier_i) (new Notifier_i, marker); +} + +// Destroy a Notifier target object. + +Notifier_Handler::~Notifier_Handler (void) +{ + this->handle_close (); +} + +#endif /* ACE_HAS_ORBIX */ diff --git a/apps/Orbix-Examples/Event_Comm/Supplier/Notifier_Handler.h b/apps/Orbix-Examples/Event_Comm/Supplier/Notifier_Handler.h new file mode 100644 index 00000000000..5d0be45924c --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/Supplier/Notifier_Handler.h @@ -0,0 +1,57 @@ +/* -*- C++ -*- */ +// @(#)Notifier_Handler.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// EventComm +// +// = FILENAME +// Notifier_Handler.h +// +// = DESCRIPTION +// Integrate CORBA with the ACE ACE_Reactor. +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) +// +// ============================================================================ + +#if !defined (_NOTIFIER_HANDLER_H) +#define _NOTIFIER_HANDLER_H + +#include "ace/CORBA_Handler.h" +#include "Event_Comm_i.h" + +#if defined (ACE_HAS_ORBIX) + +class Notifier_Handler + // = TITLE + // Integrate CORBA with the ACE ACE_Reactor. + // + // = DESCRIPTION + // +{ +public: + Notifier_Handler (const char *service_location, + const char *marker = "notifier", + int putit = 1); // Default marker name. + + Event_Comm::Notifier *notifier (void); + void notifier (Event_Comm::Notifier *); + + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::NULL_MASK); + // Close down the handler. + +private: + ~Notifier_Handler (void); + // Ensure dynamic allocation. + + Event_Comm::Notifier *notifier_; + // Pointer to an a object. +}; + +#endif /* ACE_HAS_ORBIX */ +#endif /* _NOTIFIER_HANDLER_H */ diff --git a/apps/Orbix-Examples/Event_Comm/Supplier/supplier.cpp b/apps/Orbix-Examples/Event_Comm/Supplier/supplier.cpp new file mode 100644 index 00000000000..927ab73a022 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/Supplier/supplier.cpp @@ -0,0 +1,116 @@ +/* -*- C++ -*- */ +// @(#)supplier.cpp 1.1 10/18/96 + +// Supplier driver for the Orbix Publish/Subscribe example. + +// The executable file generated from this code should be registered +// (under the name 'logger') using the 'putit' command. + +#include "ace/Service_Config.h" +#include "ace/Log_Msg.h" +#include "Notifier_Handler.h" +#include "Input_Handler.h" + +#if defined (ACE_HAS_ORBIX) + +class Supplier : public ACE_Event_Handler +{ +public: + Supplier (int argc, char *argv[]); + ~Supplier (void); + + void run (void); + // Execute the supplier. + +private: + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + + virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask); + + Input_Handler *ih_; + // Handler for keyboard input. + + Notifier_Handler *nh_; + // Handler for CORBA Notifier. + + ACE_Service_Config daemon_; + // ACE server event-loop mechanism. +}; + +int +Supplier::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + ACE_DEBUG ((LM_DEBUG, "closing down Supplier\n")); + return 0; +} + +int +Supplier::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + ACE_DEBUG ((LM_DEBUG, "%S\n", signum)); + ACE_Service_Config::end_reactor_event_loop (); + return 0; +} + +void +Supplier::run (void) +{ + if (ACE_Service_Config::run_reactor_event_loop () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "run_reactor_event_loop")); +} + +Supplier::Supplier (int argc, char *argv[]) + : ih_ (0), + nh_ (0) +{ + // Initialize the server. + if (this->daemon_.open (argc, argv) == -1) + { + if (errno == ENOENT) // There's no svc.conf file, so use static linking... + { + ACE_DEBUG ((LM_DEBUG, "no config file, using static binding\n")); + // The constructor registers the handlers... + int putit = argc > 1 ? 1 : 0; + + // Pass in program exec name to use a service_location! + this->nh_ = new Notifier_Handler (argv[0], "notifier", putit); + ACE_ASSERT (this->nh_ != 0); + this->ih_ = new Input_Handler (this->nh_); + ACE_ASSERT (this->ih_ != 0); + } + else + ACE_ERROR ((LM_ERROR, "%p\n%a", "open", 1)); + } + + ACE_DEBUG ((LM_DEBUG, "starting up server %s\n", + CORBA::Orbix.myImplementationName ())); + + if (ACE_Service_Config::reactor ()->register_handler (SIGINT, this) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "register_handler")); +} + +Supplier::~Supplier (void) +{ + // Free up the handlers if they were statically bound. + this->ih_->handle_close (); + this->nh_->handle_close (); +} + +int +main (int argc, char *argv[]) +{ + // Initialize server daemon. + Supplier supplier (argc, argv); + + // Loop forever handling events. + supplier.run (); + + return 0; +} +#else /* !defined ACE_HAS_ORBIX */ +int +main (int argc, char *argv[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, "you must have Orbix to run application %s\n", argv[0]), 1); +} +#endif /* ACE_HAS_ORBIX */ diff --git a/apps/Orbix-Examples/Event_Comm/include/Event_Comm.hh b/apps/Orbix-Examples/Event_Comm/include/Event_Comm.hh new file mode 100644 index 00000000000..85ad256da2a --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/include/Event_Comm.hh @@ -0,0 +1,887 @@ + +#ifndef Event_Comm_hh +#define Event_Comm_hh + +#include + +#include + +class Event_Comm { +public: + +#ifndef Event_Comm_Notification_defined +#define Event_Comm_Notification_defined + + struct Notification { + CORBA::String_mgr tag_; + + void encodeOp (CORBA::Request &IT_r) const; + void decodeOp (CORBA::Request &IT_r); + void decodeInOutOp (CORBA::Request &IT_r); + static void* IT_anySupport (CORBA::Request &IT_r, + void *&, void*, const CORBA::Flags&); + static const void *IT_fn; + }; + + static const CORBA::TypeCode_ptr _tc_Notification; + +#ifndef Event_Comm_NotificationVarH +#define Event_Comm_NotificationVarH + +#ifndef Event_Comm_NotificationvPtr +#define Event_Comm_NotificationvPtr +typedef Notification* Notification_vPtr; +#endif + +class Notification_var : public CORBA::_var +{ + public: + + Notification_var () { + _ptr = NULL; + } + + Notification_var (Notification *IT_p) { + _ptr = IT_p; + } + + Notification_var (const Notification_var &IT_s) { + if (!IT_s._ptr) { + _ptr = IT_s._ptr; + return; + } + _ptr = new Notification (*(IT_s._ptr)); + } + + Notification_var &operator= (Notification *IT_p) { + if (_ptr != IT_p) { + delete _ptr; + } + _ptr = IT_p; + return (*this); + } + + Notification_var &operator= (const Notification_var &IT_s) { + if (_ptr != IT_s._ptr) { + delete _ptr; + } + _ptr = new Notification (*(IT_s._ptr)); + return (*this); + } + + ~Notification_var () { + delete _ptr; + } + + Notification* operator-> () { + return _ptr; + } + + operator const Notification_vPtr () const { return _ptr;} + operator Notification_vPtr& () { return _ptr;} + operator Notification& () const { return * _ptr;} + + protected: + Notification *_ptr; + private: + Notification_var &operator= (const CORBA::_var &IT_s); + Notification_var (const CORBA::_var &IT_s); +}; + +#endif + + +#endif + + +#ifndef _Event_Comm_Notification_Receiver_defined +#define _Event_Comm_Notification_Receiver_defined +class Notification_Receiver_dispatch : public virtual CORBA::PPTR { +public: + + Notification_Receiver_dispatch (void *IT_p, CORBA::Object* IT_o, const char *IT_m, + CORBA::LoaderClass *IT_l, char *IT_i, void* IT_im) + : CORBA::PPTR (IT_p,IT_o,IT_m,IT_l,IT_i,IT_im) {} + + + Notification_Receiver_dispatch (char *IT_OR, void *IT_p, CORBA::Object *IT_o) + : CORBA::PPTR (IT_OR,IT_p,IT_o) {} + + + Notification_Receiver_dispatch () {} + + Notification_Receiver_dispatch (ObjectReference *IT_OR, void *IT_p, CORBA::Object *IT_o) + : CORBA::PPTR (IT_OR,IT_p,IT_o) {} + + + Notification_Receiver_dispatch (void *IT_p, CORBA::Object *IT_o, const char *IT_m, + char *IT_i, CORBA::Object* IT_ob, void* IT_im) + : CORBA::PPTR (IT_p,IT_o,IT_m,IT_i,IT_ob,IT_im) {} + + + virtual unsigned char dispatch (CORBA::Request &IT_r, + unsigned char IT_isTarget, void* IT_pp=NULL); + + +}; + +class Notification_Receiver; + +#ifndef Event_Comm_Notification_ReceiverPtr +#define Event_Comm_Notification_ReceiverPtr + + typedef Notification_Receiver* Notification_Receiver_ptr; + + typedef Notification_Receiver* Notification_ReceiverRef; + +#endif + + +#ifndef Event_Comm_Notification_ReceiverForwH +#define Event_Comm_Notification_ReceiverForwH +static CORBA::ObjectRef Notification_Receiver_getBase (void *); +static void Notification_Receiver_release (Notification_Receiver *, CORBA::Environment &IT_env); +static void Notification_Receiver_release (Notification_Receiver_ptr); +static Notification_Receiver* Notification_Receiver_duplicate (Notification_Receiver_ptr, CORBA::Environment &IT_env); +static Notification_Receiver* Notification_Receiver_duplicate (Notification_Receiver_ptr ); +static Notification_Receiver_ptr Notification_Receiver_nil (CORBA::Environment &IT_env); +static Notification_Receiver_ptr Notification_Receiver_nil (); +#endif +#define Event_Comm_Notification_Receiver_IMPL "Event_Comm_Notification_Receiver" + + +class Notification_Receiver; + + typedef Notification_Receiver Notification_ReceiverProxy; +#define Event_Comm_Notification_Receiver_IR "Event_Comm_Notification_Receiver" +#define Event_Comm_Notification_Receiver_IMPL "Event_Comm_Notification_Receiver" + +#ifndef Event_Comm_Notification_ReceiverPtr +#define Event_Comm_Notification_ReceiverPtr + + typedef Notification_Receiver* Notification_Receiver_ptr; + + typedef Notification_Receiver* Notification_ReceiverRef; + +#endif + +class Notification_Receiver: public virtual CORBA::Object { +public: + Notification_Receiver (char *IT_OR); + Notification_Receiver (ObjectReference *IT_OR); + Notification_Receiver () : CORBA::Object (1) {} +protected: + Notification_Receiver_ptr __duplicate( + CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) { + CORBA::Object::__duplicate (IT_env); + return this; + } +public: + static Notification_Receiver_ptr _duplicate( + Notification_Receiver_ptr obj, + CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) { + CORBA::EnvExcRaiser IT_raise (&IT_env); + if (CORBA::is_nil(obj, IT_env)) { + IT_raise.maybeRaise (); + return (obj); + } + Notification_Receiver_ptr IT_obj = obj->__duplicate (IT_env); + IT_raise.maybeRaise(); + return IT_obj; + } +public: + static Notification_Receiver* _bind (const char* IT_markerServer, const char* host, + const CORBA::Context &IT_c, + CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()); + static Notification_Receiver* _bind (CORBA::Environment &IT_env); + static Notification_Receiver* _bind (const char* IT_markerServer=NULL, const char* host=NULL, + CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()); + static Notification_Receiver* _narrow (CORBA::Object* , CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()); + static Notification_Receiver_ptr _nil (CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) { + CORBA::EnvExcRaiser IT_raise (&IT_env); + IT_raise.maybeRaise(); + return (Notification_Receiver_ptr) CORBA::OBJECT_NIL;} + virtual void receive_notification (const Event_Comm::Notification& notification, CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) throw (CORBA::SystemException); + virtual void disconnect (const char * reason, CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) throw (CORBA::SystemException); +}; + + static const CORBA::TypeCode_ptr _tc_Notification_Receiver; + + static const CORBA::TypeCode_ptr _tc_Notification_ReceiverRef; + +#ifndef Event_Comm_Notification_ReceiverVarH +#define Event_Comm_Notification_ReceiverVarH + +#ifndef Event_Comm_Notification_ReceivervPtr +#define Event_Comm_Notification_ReceivervPtr +typedef Notification_Receiver* Notification_Receiver_vPtr; +#endif + +class Notification_Receiver_var : public CORBA::_var +{ + public: + + Notification_Receiver_var () { + _ptr = Notification_Receiver_nil (); + } + + Notification_Receiver_var (Notification_Receiver *IT_p) { + _ptr = IT_p; + } + + Notification_Receiver_var (const Notification_Receiver_var &IT_s) { + _ptr = Notification_Receiver_duplicate (IT_s._ptr); + } + + Notification_Receiver_var &operator= (Notification_Receiver *IT_p) { + Notification_Receiver_release (_ptr); + _ptr = IT_p; + return (*this); + } + + Notification_Receiver_var &operator= (const Notification_Receiver_var &IT_s) { + Notification_Receiver_release (_ptr); + _ptr = Notification_Receiver_duplicate (IT_s._ptr); + return (*this); + } + + ~Notification_Receiver_var () { + Notification_Receiver_release (_ptr); + } + + Notification_Receiver* operator-> () { + return _ptr; + } + + operator const Notification_Receiver_vPtr () const { return _ptr;} + operator Notification_Receiver_vPtr& () { return _ptr;} + + protected: + Notification_Receiver *_ptr; + private: + Notification_Receiver_var &operator= (const CORBA::_var &IT_s); + Notification_Receiver_var (const CORBA::_var &IT_s); + Notification_Receiver_var &operator= (const CORBA::_mgr &IT_s); + Notification_Receiver_var &operator= (const CORBA::_SeqElem &IT_s); + Notification_Receiver_var (const CORBA::_mgr &IT_s); + Notification_Receiver_var (const CORBA::_SeqElem &IT_s); +}; + +#endif + + +#ifndef Event_Comm_Notification_ReceiverMgrH +#define Event_Comm_Notification_ReceiverMgrH + +class Notification_Receiver_mgr : public CORBA::_mgr +{ + public: + + Notification_Receiver_mgr () { + _ptr = Notification_Receiver_nil (); + _release = 1; + } + + Notification_Receiver_mgr (const Notification_Receiver_mgr &IT_s) { + _ptr = Notification_Receiver_duplicate (IT_s._ptr); + _release = 1; + } + + Notification_Receiver_mgr &operator= (Notification_Receiver *IT_p) { + if (_ptr && _release) + Notification_Receiver_release (_ptr); + _ptr = IT_p; + _release = 1; + return (*this); + } + + Notification_Receiver_mgr &operator= (const Notification_Receiver_mgr &IT_s) { + if (_ptr && _release) + Notification_Receiver_release (_ptr); + _ptr = Notification_Receiver_duplicate(IT_s._ptr); + _release = 1; + return (*this); + } + + Notification_Receiver_mgr &operator= (const Notification_Receiver_var &IT_s) { + if (_ptr && _release) + Notification_Receiver_release (_ptr); + _ptr = Notification_Receiver_duplicate(IT_s); + _release = 1; + return (*this); + } + + ~Notification_Receiver_mgr () { + if (_release) + Notification_Receiver_release (_ptr); + } + + unsigned char release () { + return _release; + } + + void release (unsigned char rel) { + _release = rel; + } + + operator int () const { + CORBA::Environment env; + CORBA::EnvExcRaiser IT_raise (&env); + return (!(CORBA::is_nil((CORBA::Object*) _ptr, env))); + } + + operator void* () const { + return _ptr; + } + + operator CORBA::Object * () const { + return (CORBA::Object *) _ptr; + } + + operator Notification_Receiver* () const { + return (Notification_Receiver*) _ptr; + } + + Notification_Receiver *_ptr; + + protected: + + unsigned char _release; +}; + +#endif + +#ifndef Event_Comm_Notification_ReceiverSeqElemH +#define Event_Comm_Notification_ReceiverSeqElemH + +class Notification_Receiver_SeqElem : public CORBA::_SeqElem +{ + public: + + Notification_Receiver_SeqElem (Event_Comm::Notification_Receiver_ptr* IT_p, unsigned char rel) { + _ptr = IT_p; + _release = rel; + } + + Notification_Receiver_SeqElem &operator= (Event_Comm::Notification_Receiver_ptr IT_p) { + if (!_ptr) + return (*this); + if (*(_ptr) && _release) + Notification_Receiver_release (*(_ptr)); + *(_ptr) = IT_p; + return (*this); + } + + Notification_Receiver_SeqElem &operator= (const Notification_Receiver_SeqElem &IT_s) { + if (!_ptr|| !IT_s._ptr) + return (*this); + if (*(_ptr) && _release) + Notification_Receiver_release (*(_ptr)); + *(_ptr) = Notification_Receiver_duplicate(*(IT_s._ptr)); + return (*this); + } + + operator Event_Comm::Notification_Receiver_ptr () const +{ + if (!_ptr) + return (Notification_Receiver_nil()); + return (Event_Comm::Notification_Receiver_ptr) (*_ptr); + } + + Notification_Receiver_ptr operator->() const { return *_ptr;} + + protected: + Event_Comm::Notification_Receiver_ptr *_ptr; + unsigned char _release; +}; + +#endif + + +#define TIE_Event_Comm_Notification_Receiver(X) Event_Comm_Notification_Receiver##X + +#define DEF_TIE_Event_Comm_Notification_Receiver(X) \ + class Event_Comm_Notification_Receiver##X : public virtual Event_Comm::Notification_Receiver { \ + X* m_obj; \ + public: \ + \ + Event_Comm_Notification_Receiver##X (X *objp, const char* m="", CORBA::LoaderClass *l=0)\ + : Event_Comm::Notification_Receiver(), CORBA::Object (), m_obj(objp) { \ + m_pptr = new Event_Comm::Notification_Receiver_dispatch \ + (( Event_Comm::Notification_Receiver*)this,(CORBA::Object*)this,m,l,Event_Comm_Notification_Receiver_IR,m_obj); \ + } \ + Event_Comm_Notification_Receiver##X (CORBA::Object *IT_p, const char* IT_m="", void *IT_q=0)\ + : Event_Comm::Notification_Receiver(), CORBA::Object () { \ + m_pptr = new Event_Comm::Notification_Receiver_dispatch \ + (( Event_Comm::Notification_Receiver*)this,(CORBA::Object*)this,IT_m,Event_Comm_Notification_Receiver_IR,IT_p,IT_q); \ + m_obj = (X*)(m_pptr->getImplObj ()); \ + } \ + \ + virtual ~Event_Comm_Notification_Receiver##X () { \ + if (_okToDeleteImpl ()) delete m_obj; } \ + \ + virtual void* _deref () { \ + return m_obj; } \ + \ + virtual void receive_notification (const Event_Comm::Notification& notification, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->receive_notification ( notification,IT_env);\ +}\ + \ + virtual void disconnect (const char * reason, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->disconnect ( reason,IT_env);\ +}\ + \ + }; + + +#define QUALS_Event_Comm_Notification_Receiver \ + virtual void receive_notification (const Event_Comm::Notification& notification, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->receive_notification ( notification,IT_env);\ +}\ + \ + virtual void disconnect (const char * reason, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->disconnect ( reason,IT_env);\ +}\ + + + + +class Notification_ReceiverProxyFactoryClass : public virtual CORBA::ObjectFactoryClass { +public: + Notification_ReceiverProxyFactoryClass (unsigned char IT_p=0) + : CORBA::ProxyFactory (Event_Comm_Notification_Receiver_IR, IT_p) {} + + virtual void* New (char *IT_OR, CORBA::Environment&); + + virtual void* New (ObjectReference *IT_OR, CORBA::Environment&); + + virtual void* New2 (); + + virtual void* IT_castUp (void *IT_p, char* IT_s); + + virtual CORBA::PPTR* pptr (void *IT_p); + + virtual void baseInterfaces (_IDL_SEQUENCE_string&); + + +}; + +static Notification_ReceiverProxyFactoryClass Notification_ReceiverProxyFactory; + + + +#endif + + +#ifndef _Event_Comm_Notifier_defined +#define _Event_Comm_Notifier_defined +class Notifier_dispatch : public virtual CORBA::PPTR { +public: + + Notifier_dispatch (void *IT_p, CORBA::Object* IT_o, const char *IT_m, + CORBA::LoaderClass *IT_l, char *IT_i, void* IT_im) + : CORBA::PPTR (IT_p,IT_o,IT_m,IT_l,IT_i,IT_im) {} + + + Notifier_dispatch (char *IT_OR, void *IT_p, CORBA::Object *IT_o) + : CORBA::PPTR (IT_OR,IT_p,IT_o) {} + + + Notifier_dispatch () {} + + Notifier_dispatch (ObjectReference *IT_OR, void *IT_p, CORBA::Object *IT_o) + : CORBA::PPTR (IT_OR,IT_p,IT_o) {} + + + Notifier_dispatch (void *IT_p, CORBA::Object *IT_o, const char *IT_m, + char *IT_i, CORBA::Object* IT_ob, void* IT_im) + : CORBA::PPTR (IT_p,IT_o,IT_m,IT_i,IT_ob,IT_im) {} + + + virtual unsigned char dispatch (CORBA::Request &IT_r, + unsigned char IT_isTarget, void* IT_pp=NULL); + + +}; + +class Notifier; + +#ifndef Event_Comm_NotifierPtr +#define Event_Comm_NotifierPtr + + typedef Notifier* Notifier_ptr; + + typedef Notifier* NotifierRef; + +#endif + + +#ifndef Event_Comm_NotifierForwH +#define Event_Comm_NotifierForwH +static CORBA::ObjectRef Notifier_getBase (void *); +static void Notifier_release (Notifier *, CORBA::Environment &IT_env); +static void Notifier_release (Notifier_ptr); +static Notifier* Notifier_duplicate (Notifier_ptr, CORBA::Environment &IT_env); +static Notifier* Notifier_duplicate (Notifier_ptr ); +static Notifier_ptr Notifier_nil (CORBA::Environment &IT_env); +static Notifier_ptr Notifier_nil (); +#endif +#define Event_Comm_Notifier_IMPL "Event_Comm_Notifier" + + +class Notifier; + + typedef Notifier NotifierProxy; +#define Event_Comm_Notifier_IR "Event_Comm_Notifier" +#define Event_Comm_Notifier_IMPL "Event_Comm_Notifier" + +#ifndef Event_Comm_NotifierPtr +#define Event_Comm_NotifierPtr + + typedef Notifier* Notifier_ptr; + + typedef Notifier* NotifierRef; + +#endif + +class Notifier: public virtual CORBA::Object { +public: + Notifier (char *IT_OR); + Notifier (ObjectReference *IT_OR); + Notifier () : CORBA::Object (1) {} +protected: + Notifier_ptr __duplicate( + CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) { + CORBA::Object::__duplicate (IT_env); + return this; + } +public: + static Notifier_ptr _duplicate( + Notifier_ptr obj, + CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) { + CORBA::EnvExcRaiser IT_raise (&IT_env); + if (CORBA::is_nil(obj, IT_env)) { + IT_raise.maybeRaise (); + return (obj); + } + Notifier_ptr IT_obj = obj->__duplicate (IT_env); + IT_raise.maybeRaise(); + return IT_obj; + } +public: + static Notifier* _bind (const char* IT_markerServer, const char* host, + const CORBA::Context &IT_c, + CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()); + static Notifier* _bind (CORBA::Environment &IT_env); + static Notifier* _bind (const char* IT_markerServer=NULL, const char* host=NULL, + CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()); + static Notifier* _narrow (CORBA::Object* , CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()); + static Notifier_ptr _nil (CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) { + CORBA::EnvExcRaiser IT_raise (&IT_env); + IT_raise.maybeRaise(); + return (Notifier_ptr) CORBA::OBJECT_NIL;} + virtual void send_disconnect (const char * reason, CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) throw (CORBA::SystemException); + virtual void send_notification (const Event_Comm::Notification& notification, CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) throw (CORBA::SystemException); + virtual void subscribe (Event_Comm::Notification_Receiver_ptr notification_receiver, const char * filtering_criteria, CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) throw (CORBA::SystemException); + virtual void unsubscribe (Event_Comm::Notification_Receiver_ptr notification_receiver, const char * filtering_criteria, CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) throw (CORBA::SystemException); +}; + + static const CORBA::TypeCode_ptr _tc_Notifier; + + static const CORBA::TypeCode_ptr _tc_NotifierRef; + +#ifndef Event_Comm_NotifierVarH +#define Event_Comm_NotifierVarH + +#ifndef Event_Comm_NotifiervPtr +#define Event_Comm_NotifiervPtr +typedef Notifier* Notifier_vPtr; +#endif + +class Notifier_var : public CORBA::_var +{ + public: + + Notifier_var () { + _ptr = Notifier_nil (); + } + + Notifier_var (Notifier *IT_p) { + _ptr = IT_p; + } + + Notifier_var (const Notifier_var &IT_s) { + _ptr = Notifier_duplicate (IT_s._ptr); + } + + Notifier_var &operator= (Notifier *IT_p) { + Notifier_release (_ptr); + _ptr = IT_p; + return (*this); + } + + Notifier_var &operator= (const Notifier_var &IT_s) { + Notifier_release (_ptr); + _ptr = Notifier_duplicate (IT_s._ptr); + return (*this); + } + + ~Notifier_var () { + Notifier_release (_ptr); + } + + Notifier* operator-> () { + return _ptr; + } + + operator const Notifier_vPtr () const { return _ptr;} + operator Notifier_vPtr& () { return _ptr;} + + protected: + Notifier *_ptr; + private: + Notifier_var &operator= (const CORBA::_var &IT_s); + Notifier_var (const CORBA::_var &IT_s); + Notifier_var &operator= (const CORBA::_mgr &IT_s); + Notifier_var &operator= (const CORBA::_SeqElem &IT_s); + Notifier_var (const CORBA::_mgr &IT_s); + Notifier_var (const CORBA::_SeqElem &IT_s); +}; + +#endif + + +#ifndef Event_Comm_NotifierMgrH +#define Event_Comm_NotifierMgrH + +class Notifier_mgr : public CORBA::_mgr +{ + public: + + Notifier_mgr () { + _ptr = Notifier_nil (); + _release = 1; + } + + Notifier_mgr (const Notifier_mgr &IT_s) { + _ptr = Notifier_duplicate (IT_s._ptr); + _release = 1; + } + + Notifier_mgr &operator= (Notifier *IT_p) { + if (_ptr && _release) + Notifier_release (_ptr); + _ptr = IT_p; + _release = 1; + return (*this); + } + + Notifier_mgr &operator= (const Notifier_mgr &IT_s) { + if (_ptr && _release) + Notifier_release (_ptr); + _ptr = Notifier_duplicate(IT_s._ptr); + _release = 1; + return (*this); + } + + Notifier_mgr &operator= (const Notifier_var &IT_s) { + if (_ptr && _release) + Notifier_release (_ptr); + _ptr = Notifier_duplicate(IT_s); + _release = 1; + return (*this); + } + + ~Notifier_mgr () { + if (_release) + Notifier_release (_ptr); + } + + unsigned char release () { + return _release; + } + + void release (unsigned char rel) { + _release = rel; + } + + operator int () const { + CORBA::Environment env; + CORBA::EnvExcRaiser IT_raise (&env); + return (!(CORBA::is_nil((CORBA::Object*) _ptr, env))); + } + + operator void* () const { + return _ptr; + } + + operator CORBA::Object * () const { + return (CORBA::Object *) _ptr; + } + + operator Notifier* () const { + return (Notifier*) _ptr; + } + + Notifier *_ptr; + + protected: + + unsigned char _release; +}; + +#endif + +#ifndef Event_Comm_NotifierSeqElemH +#define Event_Comm_NotifierSeqElemH + +class Notifier_SeqElem : public CORBA::_SeqElem +{ + public: + + Notifier_SeqElem (Event_Comm::Notifier_ptr* IT_p, unsigned char rel) { + _ptr = IT_p; + _release = rel; + } + + Notifier_SeqElem &operator= (Event_Comm::Notifier_ptr IT_p) { + if (!_ptr) + return (*this); + if (*(_ptr) && _release) + Notifier_release (*(_ptr)); + *(_ptr) = IT_p; + return (*this); + } + + Notifier_SeqElem &operator= (const Notifier_SeqElem &IT_s) { + if (!_ptr|| !IT_s._ptr) + return (*this); + if (*(_ptr) && _release) + Notifier_release (*(_ptr)); + *(_ptr) = Notifier_duplicate(*(IT_s._ptr)); + return (*this); + } + + operator Event_Comm::Notifier_ptr () const +{ + if (!_ptr) + return (Notifier_nil()); + return (Event_Comm::Notifier_ptr) (*_ptr); + } + + Notifier_ptr operator->() const { return *_ptr;} + + protected: + Event_Comm::Notifier_ptr *_ptr; + unsigned char _release; +}; + +#endif + + +#define TIE_Event_Comm_Notifier(X) Event_Comm_Notifier##X + +#define DEF_TIE_Event_Comm_Notifier(X) \ + class Event_Comm_Notifier##X : public virtual Event_Comm::Notifier { \ + X* m_obj; \ + public: \ + \ + Event_Comm_Notifier##X (X *objp, const char* m="", CORBA::LoaderClass *l=0)\ + : Event_Comm::Notifier(), CORBA::Object (), m_obj(objp) { \ + m_pptr = new Event_Comm::Notifier_dispatch \ + (( Event_Comm::Notifier*)this,(CORBA::Object*)this,m,l,Event_Comm_Notifier_IR,m_obj); \ + } \ + Event_Comm_Notifier##X (CORBA::Object *IT_p, const char* IT_m="", void *IT_q=0)\ + : Event_Comm::Notifier(), CORBA::Object () { \ + m_pptr = new Event_Comm::Notifier_dispatch \ + (( Event_Comm::Notifier*)this,(CORBA::Object*)this,IT_m,Event_Comm_Notifier_IR,IT_p,IT_q); \ + m_obj = (X*)(m_pptr->getImplObj ()); \ + } \ + \ + virtual ~Event_Comm_Notifier##X () { \ + if (_okToDeleteImpl ()) delete m_obj; } \ + \ + virtual void* _deref () { \ + return m_obj; } \ + \ + virtual void send_disconnect (const char * reason, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->send_disconnect ( reason,IT_env);\ +}\ + \ + virtual void send_notification (const Event_Comm::Notification& notification, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->send_notification ( notification,IT_env);\ +}\ + \ + virtual void subscribe (Event_Comm::Notification_Receiver_ptr notification_receiver, const char * filtering_criteria, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->subscribe ( notification_receiver, filtering_criteria,IT_env);\ +}\ + \ + virtual void unsubscribe (Event_Comm::Notification_Receiver_ptr notification_receiver, const char * filtering_criteria, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->unsubscribe ( notification_receiver, filtering_criteria,IT_env);\ +}\ + \ + }; + + +#define QUALS_Event_Comm_Notifier \ + virtual void send_disconnect (const char * reason, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->send_disconnect ( reason,IT_env);\ +}\ + \ + virtual void send_notification (const Event_Comm::Notification& notification, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->send_notification ( notification,IT_env);\ +}\ + \ + virtual void subscribe (Event_Comm::Notification_Receiver_ptr notification_receiver, const char * filtering_criteria, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->subscribe ( notification_receiver, filtering_criteria,IT_env);\ +}\ + \ + virtual void unsubscribe (Event_Comm::Notification_Receiver_ptr notification_receiver, const char * filtering_criteria, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->unsubscribe ( notification_receiver, filtering_criteria,IT_env);\ +}\ + + + + +class NotifierProxyFactoryClass : public virtual CORBA::ObjectFactoryClass { +public: + NotifierProxyFactoryClass (unsigned char IT_p=0) + : CORBA::ProxyFactory (Event_Comm_Notifier_IR, IT_p) {} + + virtual void* New (char *IT_OR, CORBA::Environment&); + + virtual void* New (ObjectReference *IT_OR, CORBA::Environment&); + + virtual void* New2 (); + + virtual void* IT_castUp (void *IT_p, char* IT_s); + + virtual CORBA::PPTR* pptr (void *IT_p); + + virtual void baseInterfaces (_IDL_SEQUENCE_string&); + + +}; + +static NotifierProxyFactoryClass NotifierProxyFactory; + + + +#endif + +}; + + +void operator<<= (CORBA::any &IT_a, Event_Comm::Notification_Receiver_ptr IT_t); +CORBA::Boolean operator>>= (const CORBA::any &IT_a, Event_Comm::Notification_Receiver_ptr& IT_t); + + +void operator<<= (CORBA::any &IT_a, Event_Comm::Notifier_ptr IT_t); +CORBA::Boolean operator>>= (const CORBA::any &IT_a, Event_Comm::Notifier_ptr& IT_t); + + +void operator<<= (CORBA::any &IT_a, const Event_Comm::Notification& IT_t); +CORBA::Boolean operator>>= (const CORBA::any &IT_a, Event_Comm::Notification*& IT_t); + + +#endif diff --git a/apps/Orbix-Examples/Event_Comm/include/Event_Comm_i.h b/apps/Orbix-Examples/Event_Comm/include/Event_Comm_i.h new file mode 100644 index 00000000000..49673abec84 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/include/Event_Comm_i.h @@ -0,0 +1,37 @@ +/* -*- C++ -*- */ +// @(#)Event_Comm_i.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// EventComm +// +// = FILENAME +// Event_Comm_i.h +// +// = DESCRIPTION +// Class interface for the implementation of the distributed +// event notification mechanism. +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) +// +// ============================================================================ + +#if !defined (_EVENT_COMM_I_H) +#define _EVENT_COMM_I_H + +#include "Notification_Receiver_i.h" +#include "Notifier_i.h" + +#if defined (ACE_HAS_ORBIX) + +// Tie the Notification_Receiver and Notifier implementation classes +// together with the IDL interface. + +DEF_TIE_Event_Comm_Notification_Receiver (Notification_Receiver_i) +DEF_TIE_Event_Comm_Notifier (Notifier_i) + +#endif /* ACE_HAS_ORBIX */ +#endif /* _EVENT_COMM_I_H */ diff --git a/apps/Orbix-Examples/Event_Comm/include/Notification_Receiver_i.h b/apps/Orbix-Examples/Event_Comm/include/Notification_Receiver_i.h new file mode 100644 index 00000000000..4f0bcc980e4 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/include/Notification_Receiver_i.h @@ -0,0 +1,48 @@ +/* -*- C++ -*- */ +// @(#)Notification_Receiver_i.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// EventComm +// +// = FILENAME +// Notification_Receiver__i.h +// +// = DESCRIPTION +// Class interface for the implementation of the +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) +// +// ============================================================================ + +#if !defined (_Notification_Receiver_i_H) +#define _Notification_Receiver_i_H + +#if defined (ACE_HAS_ORBIX) +#include "Event_Comm.hh" + +class Notification_Receiver_i + // = TITLE + // Defines the implementation class for event . + // + // = DESCRIPTION +{ +public: + Notification_Receiver_i (void); + ~Notification_Receiver_i (void); + + virtual void receive_notification (const Event_Comm::Notification ¬ification, + CORBA::Environment &IT_env); + // Pass the to the . + + virtual void disconnect (const char *reason, + CORBA::Environment &IT_env); + // Disconnect the from the , + // giving it the . +}; + +#endif /* ACE_HAS_ORBIX */ +#endif /* _Notification_Receiver_i_H */ diff --git a/apps/Orbix-Examples/Event_Comm/include/Notifier_i.h b/apps/Orbix-Examples/Event_Comm/include/Notifier_i.h new file mode 100644 index 00000000000..379f96b8097 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/include/Notifier_i.h @@ -0,0 +1,82 @@ +/* -*- C++ -*- */ +// @(#)Notifier_i.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// EventComm +// +// = FILENAME +// Notifier_i.h +// +// = DESCRIPTION +// Class interface for the implementation of the +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) +// +// ============================================================================ + +#if !defined (_Notifier_i_H) +#define _Notifier_i_H + +#include "ace/Map_Manager.h" +#include "ace/Synch.h" +#include "ace/SString.h" +#include "Event_Comm.hh" + +#if defined (ACE_HAS_ORBIX) + +// Forward reference. +class Notification_Receiver_Entry; + +class Notifier_i + // = TITLE + // Defines the implementation class for event . + // + // = DESCRIPTION +{ +public: + enum + { + DEFAULT_SIZE = 1024 // Default max number of Event_Comm::Notification_Receivers. + }; + + Notifier_i (size_t size_hint = Notifier_i::DEFAULT_SIZE); + // Initialize a Notifier_i object with the specified size hint. + + void send_disconnect (const char *reason, + CORBA::Environment &IT_env); + // Disconnect all the receivers, giving them the . + + void send_notification (const Event_Comm::Notification ¬ification, + CORBA::Environment &IT_env); + // Send the to all the consumers who + // have subscribed and who match the filtering criteria. + + void subscribe (Event_Comm::Notification_Receiver *notification_receiver, + const char *filtering_criteria, + CORBA::Environment &IT_env); + // Subscribe the to receive events that + // match applied by the . + + void unsubscribe (Event_Comm::Notification_Receiver *notification_receiver, + const char *filtering_criteria, + CORBA::Environment &IT_env); + // Unsubscribe the . + +private: + // The following implementation should be replaced + // by a standard container class from STL... + + typedef ACE_Map_Manager MAP_MANAGER; + typedef ACE_Map_Iterator MAP_ITERATOR; + typedef ACE_Map_Entry MAP_ENTRY; + + MAP_MANAGER map_; + // Table that maps a to a . +}; + +#endif /* ACE_HAS_ORBIX */ +#endif /* _Notifier_i_H */ diff --git a/apps/Orbix-Examples/Event_Comm/libsrc/Event_Comm.hh b/apps/Orbix-Examples/Event_Comm/libsrc/Event_Comm.hh new file mode 100644 index 00000000000..85ad256da2a --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/libsrc/Event_Comm.hh @@ -0,0 +1,887 @@ + +#ifndef Event_Comm_hh +#define Event_Comm_hh + +#include + +#include + +class Event_Comm { +public: + +#ifndef Event_Comm_Notification_defined +#define Event_Comm_Notification_defined + + struct Notification { + CORBA::String_mgr tag_; + + void encodeOp (CORBA::Request &IT_r) const; + void decodeOp (CORBA::Request &IT_r); + void decodeInOutOp (CORBA::Request &IT_r); + static void* IT_anySupport (CORBA::Request &IT_r, + void *&, void*, const CORBA::Flags&); + static const void *IT_fn; + }; + + static const CORBA::TypeCode_ptr _tc_Notification; + +#ifndef Event_Comm_NotificationVarH +#define Event_Comm_NotificationVarH + +#ifndef Event_Comm_NotificationvPtr +#define Event_Comm_NotificationvPtr +typedef Notification* Notification_vPtr; +#endif + +class Notification_var : public CORBA::_var +{ + public: + + Notification_var () { + _ptr = NULL; + } + + Notification_var (Notification *IT_p) { + _ptr = IT_p; + } + + Notification_var (const Notification_var &IT_s) { + if (!IT_s._ptr) { + _ptr = IT_s._ptr; + return; + } + _ptr = new Notification (*(IT_s._ptr)); + } + + Notification_var &operator= (Notification *IT_p) { + if (_ptr != IT_p) { + delete _ptr; + } + _ptr = IT_p; + return (*this); + } + + Notification_var &operator= (const Notification_var &IT_s) { + if (_ptr != IT_s._ptr) { + delete _ptr; + } + _ptr = new Notification (*(IT_s._ptr)); + return (*this); + } + + ~Notification_var () { + delete _ptr; + } + + Notification* operator-> () { + return _ptr; + } + + operator const Notification_vPtr () const { return _ptr;} + operator Notification_vPtr& () { return _ptr;} + operator Notification& () const { return * _ptr;} + + protected: + Notification *_ptr; + private: + Notification_var &operator= (const CORBA::_var &IT_s); + Notification_var (const CORBA::_var &IT_s); +}; + +#endif + + +#endif + + +#ifndef _Event_Comm_Notification_Receiver_defined +#define _Event_Comm_Notification_Receiver_defined +class Notification_Receiver_dispatch : public virtual CORBA::PPTR { +public: + + Notification_Receiver_dispatch (void *IT_p, CORBA::Object* IT_o, const char *IT_m, + CORBA::LoaderClass *IT_l, char *IT_i, void* IT_im) + : CORBA::PPTR (IT_p,IT_o,IT_m,IT_l,IT_i,IT_im) {} + + + Notification_Receiver_dispatch (char *IT_OR, void *IT_p, CORBA::Object *IT_o) + : CORBA::PPTR (IT_OR,IT_p,IT_o) {} + + + Notification_Receiver_dispatch () {} + + Notification_Receiver_dispatch (ObjectReference *IT_OR, void *IT_p, CORBA::Object *IT_o) + : CORBA::PPTR (IT_OR,IT_p,IT_o) {} + + + Notification_Receiver_dispatch (void *IT_p, CORBA::Object *IT_o, const char *IT_m, + char *IT_i, CORBA::Object* IT_ob, void* IT_im) + : CORBA::PPTR (IT_p,IT_o,IT_m,IT_i,IT_ob,IT_im) {} + + + virtual unsigned char dispatch (CORBA::Request &IT_r, + unsigned char IT_isTarget, void* IT_pp=NULL); + + +}; + +class Notification_Receiver; + +#ifndef Event_Comm_Notification_ReceiverPtr +#define Event_Comm_Notification_ReceiverPtr + + typedef Notification_Receiver* Notification_Receiver_ptr; + + typedef Notification_Receiver* Notification_ReceiverRef; + +#endif + + +#ifndef Event_Comm_Notification_ReceiverForwH +#define Event_Comm_Notification_ReceiverForwH +static CORBA::ObjectRef Notification_Receiver_getBase (void *); +static void Notification_Receiver_release (Notification_Receiver *, CORBA::Environment &IT_env); +static void Notification_Receiver_release (Notification_Receiver_ptr); +static Notification_Receiver* Notification_Receiver_duplicate (Notification_Receiver_ptr, CORBA::Environment &IT_env); +static Notification_Receiver* Notification_Receiver_duplicate (Notification_Receiver_ptr ); +static Notification_Receiver_ptr Notification_Receiver_nil (CORBA::Environment &IT_env); +static Notification_Receiver_ptr Notification_Receiver_nil (); +#endif +#define Event_Comm_Notification_Receiver_IMPL "Event_Comm_Notification_Receiver" + + +class Notification_Receiver; + + typedef Notification_Receiver Notification_ReceiverProxy; +#define Event_Comm_Notification_Receiver_IR "Event_Comm_Notification_Receiver" +#define Event_Comm_Notification_Receiver_IMPL "Event_Comm_Notification_Receiver" + +#ifndef Event_Comm_Notification_ReceiverPtr +#define Event_Comm_Notification_ReceiverPtr + + typedef Notification_Receiver* Notification_Receiver_ptr; + + typedef Notification_Receiver* Notification_ReceiverRef; + +#endif + +class Notification_Receiver: public virtual CORBA::Object { +public: + Notification_Receiver (char *IT_OR); + Notification_Receiver (ObjectReference *IT_OR); + Notification_Receiver () : CORBA::Object (1) {} +protected: + Notification_Receiver_ptr __duplicate( + CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) { + CORBA::Object::__duplicate (IT_env); + return this; + } +public: + static Notification_Receiver_ptr _duplicate( + Notification_Receiver_ptr obj, + CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) { + CORBA::EnvExcRaiser IT_raise (&IT_env); + if (CORBA::is_nil(obj, IT_env)) { + IT_raise.maybeRaise (); + return (obj); + } + Notification_Receiver_ptr IT_obj = obj->__duplicate (IT_env); + IT_raise.maybeRaise(); + return IT_obj; + } +public: + static Notification_Receiver* _bind (const char* IT_markerServer, const char* host, + const CORBA::Context &IT_c, + CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()); + static Notification_Receiver* _bind (CORBA::Environment &IT_env); + static Notification_Receiver* _bind (const char* IT_markerServer=NULL, const char* host=NULL, + CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()); + static Notification_Receiver* _narrow (CORBA::Object* , CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()); + static Notification_Receiver_ptr _nil (CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) { + CORBA::EnvExcRaiser IT_raise (&IT_env); + IT_raise.maybeRaise(); + return (Notification_Receiver_ptr) CORBA::OBJECT_NIL;} + virtual void receive_notification (const Event_Comm::Notification& notification, CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) throw (CORBA::SystemException); + virtual void disconnect (const char * reason, CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) throw (CORBA::SystemException); +}; + + static const CORBA::TypeCode_ptr _tc_Notification_Receiver; + + static const CORBA::TypeCode_ptr _tc_Notification_ReceiverRef; + +#ifndef Event_Comm_Notification_ReceiverVarH +#define Event_Comm_Notification_ReceiverVarH + +#ifndef Event_Comm_Notification_ReceivervPtr +#define Event_Comm_Notification_ReceivervPtr +typedef Notification_Receiver* Notification_Receiver_vPtr; +#endif + +class Notification_Receiver_var : public CORBA::_var +{ + public: + + Notification_Receiver_var () { + _ptr = Notification_Receiver_nil (); + } + + Notification_Receiver_var (Notification_Receiver *IT_p) { + _ptr = IT_p; + } + + Notification_Receiver_var (const Notification_Receiver_var &IT_s) { + _ptr = Notification_Receiver_duplicate (IT_s._ptr); + } + + Notification_Receiver_var &operator= (Notification_Receiver *IT_p) { + Notification_Receiver_release (_ptr); + _ptr = IT_p; + return (*this); + } + + Notification_Receiver_var &operator= (const Notification_Receiver_var &IT_s) { + Notification_Receiver_release (_ptr); + _ptr = Notification_Receiver_duplicate (IT_s._ptr); + return (*this); + } + + ~Notification_Receiver_var () { + Notification_Receiver_release (_ptr); + } + + Notification_Receiver* operator-> () { + return _ptr; + } + + operator const Notification_Receiver_vPtr () const { return _ptr;} + operator Notification_Receiver_vPtr& () { return _ptr;} + + protected: + Notification_Receiver *_ptr; + private: + Notification_Receiver_var &operator= (const CORBA::_var &IT_s); + Notification_Receiver_var (const CORBA::_var &IT_s); + Notification_Receiver_var &operator= (const CORBA::_mgr &IT_s); + Notification_Receiver_var &operator= (const CORBA::_SeqElem &IT_s); + Notification_Receiver_var (const CORBA::_mgr &IT_s); + Notification_Receiver_var (const CORBA::_SeqElem &IT_s); +}; + +#endif + + +#ifndef Event_Comm_Notification_ReceiverMgrH +#define Event_Comm_Notification_ReceiverMgrH + +class Notification_Receiver_mgr : public CORBA::_mgr +{ + public: + + Notification_Receiver_mgr () { + _ptr = Notification_Receiver_nil (); + _release = 1; + } + + Notification_Receiver_mgr (const Notification_Receiver_mgr &IT_s) { + _ptr = Notification_Receiver_duplicate (IT_s._ptr); + _release = 1; + } + + Notification_Receiver_mgr &operator= (Notification_Receiver *IT_p) { + if (_ptr && _release) + Notification_Receiver_release (_ptr); + _ptr = IT_p; + _release = 1; + return (*this); + } + + Notification_Receiver_mgr &operator= (const Notification_Receiver_mgr &IT_s) { + if (_ptr && _release) + Notification_Receiver_release (_ptr); + _ptr = Notification_Receiver_duplicate(IT_s._ptr); + _release = 1; + return (*this); + } + + Notification_Receiver_mgr &operator= (const Notification_Receiver_var &IT_s) { + if (_ptr && _release) + Notification_Receiver_release (_ptr); + _ptr = Notification_Receiver_duplicate(IT_s); + _release = 1; + return (*this); + } + + ~Notification_Receiver_mgr () { + if (_release) + Notification_Receiver_release (_ptr); + } + + unsigned char release () { + return _release; + } + + void release (unsigned char rel) { + _release = rel; + } + + operator int () const { + CORBA::Environment env; + CORBA::EnvExcRaiser IT_raise (&env); + return (!(CORBA::is_nil((CORBA::Object*) _ptr, env))); + } + + operator void* () const { + return _ptr; + } + + operator CORBA::Object * () const { + return (CORBA::Object *) _ptr; + } + + operator Notification_Receiver* () const { + return (Notification_Receiver*) _ptr; + } + + Notification_Receiver *_ptr; + + protected: + + unsigned char _release; +}; + +#endif + +#ifndef Event_Comm_Notification_ReceiverSeqElemH +#define Event_Comm_Notification_ReceiverSeqElemH + +class Notification_Receiver_SeqElem : public CORBA::_SeqElem +{ + public: + + Notification_Receiver_SeqElem (Event_Comm::Notification_Receiver_ptr* IT_p, unsigned char rel) { + _ptr = IT_p; + _release = rel; + } + + Notification_Receiver_SeqElem &operator= (Event_Comm::Notification_Receiver_ptr IT_p) { + if (!_ptr) + return (*this); + if (*(_ptr) && _release) + Notification_Receiver_release (*(_ptr)); + *(_ptr) = IT_p; + return (*this); + } + + Notification_Receiver_SeqElem &operator= (const Notification_Receiver_SeqElem &IT_s) { + if (!_ptr|| !IT_s._ptr) + return (*this); + if (*(_ptr) && _release) + Notification_Receiver_release (*(_ptr)); + *(_ptr) = Notification_Receiver_duplicate(*(IT_s._ptr)); + return (*this); + } + + operator Event_Comm::Notification_Receiver_ptr () const +{ + if (!_ptr) + return (Notification_Receiver_nil()); + return (Event_Comm::Notification_Receiver_ptr) (*_ptr); + } + + Notification_Receiver_ptr operator->() const { return *_ptr;} + + protected: + Event_Comm::Notification_Receiver_ptr *_ptr; + unsigned char _release; +}; + +#endif + + +#define TIE_Event_Comm_Notification_Receiver(X) Event_Comm_Notification_Receiver##X + +#define DEF_TIE_Event_Comm_Notification_Receiver(X) \ + class Event_Comm_Notification_Receiver##X : public virtual Event_Comm::Notification_Receiver { \ + X* m_obj; \ + public: \ + \ + Event_Comm_Notification_Receiver##X (X *objp, const char* m="", CORBA::LoaderClass *l=0)\ + : Event_Comm::Notification_Receiver(), CORBA::Object (), m_obj(objp) { \ + m_pptr = new Event_Comm::Notification_Receiver_dispatch \ + (( Event_Comm::Notification_Receiver*)this,(CORBA::Object*)this,m,l,Event_Comm_Notification_Receiver_IR,m_obj); \ + } \ + Event_Comm_Notification_Receiver##X (CORBA::Object *IT_p, const char* IT_m="", void *IT_q=0)\ + : Event_Comm::Notification_Receiver(), CORBA::Object () { \ + m_pptr = new Event_Comm::Notification_Receiver_dispatch \ + (( Event_Comm::Notification_Receiver*)this,(CORBA::Object*)this,IT_m,Event_Comm_Notification_Receiver_IR,IT_p,IT_q); \ + m_obj = (X*)(m_pptr->getImplObj ()); \ + } \ + \ + virtual ~Event_Comm_Notification_Receiver##X () { \ + if (_okToDeleteImpl ()) delete m_obj; } \ + \ + virtual void* _deref () { \ + return m_obj; } \ + \ + virtual void receive_notification (const Event_Comm::Notification& notification, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->receive_notification ( notification,IT_env);\ +}\ + \ + virtual void disconnect (const char * reason, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->disconnect ( reason,IT_env);\ +}\ + \ + }; + + +#define QUALS_Event_Comm_Notification_Receiver \ + virtual void receive_notification (const Event_Comm::Notification& notification, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->receive_notification ( notification,IT_env);\ +}\ + \ + virtual void disconnect (const char * reason, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->disconnect ( reason,IT_env);\ +}\ + + + + +class Notification_ReceiverProxyFactoryClass : public virtual CORBA::ObjectFactoryClass { +public: + Notification_ReceiverProxyFactoryClass (unsigned char IT_p=0) + : CORBA::ProxyFactory (Event_Comm_Notification_Receiver_IR, IT_p) {} + + virtual void* New (char *IT_OR, CORBA::Environment&); + + virtual void* New (ObjectReference *IT_OR, CORBA::Environment&); + + virtual void* New2 (); + + virtual void* IT_castUp (void *IT_p, char* IT_s); + + virtual CORBA::PPTR* pptr (void *IT_p); + + virtual void baseInterfaces (_IDL_SEQUENCE_string&); + + +}; + +static Notification_ReceiverProxyFactoryClass Notification_ReceiverProxyFactory; + + + +#endif + + +#ifndef _Event_Comm_Notifier_defined +#define _Event_Comm_Notifier_defined +class Notifier_dispatch : public virtual CORBA::PPTR { +public: + + Notifier_dispatch (void *IT_p, CORBA::Object* IT_o, const char *IT_m, + CORBA::LoaderClass *IT_l, char *IT_i, void* IT_im) + : CORBA::PPTR (IT_p,IT_o,IT_m,IT_l,IT_i,IT_im) {} + + + Notifier_dispatch (char *IT_OR, void *IT_p, CORBA::Object *IT_o) + : CORBA::PPTR (IT_OR,IT_p,IT_o) {} + + + Notifier_dispatch () {} + + Notifier_dispatch (ObjectReference *IT_OR, void *IT_p, CORBA::Object *IT_o) + : CORBA::PPTR (IT_OR,IT_p,IT_o) {} + + + Notifier_dispatch (void *IT_p, CORBA::Object *IT_o, const char *IT_m, + char *IT_i, CORBA::Object* IT_ob, void* IT_im) + : CORBA::PPTR (IT_p,IT_o,IT_m,IT_i,IT_ob,IT_im) {} + + + virtual unsigned char dispatch (CORBA::Request &IT_r, + unsigned char IT_isTarget, void* IT_pp=NULL); + + +}; + +class Notifier; + +#ifndef Event_Comm_NotifierPtr +#define Event_Comm_NotifierPtr + + typedef Notifier* Notifier_ptr; + + typedef Notifier* NotifierRef; + +#endif + + +#ifndef Event_Comm_NotifierForwH +#define Event_Comm_NotifierForwH +static CORBA::ObjectRef Notifier_getBase (void *); +static void Notifier_release (Notifier *, CORBA::Environment &IT_env); +static void Notifier_release (Notifier_ptr); +static Notifier* Notifier_duplicate (Notifier_ptr, CORBA::Environment &IT_env); +static Notifier* Notifier_duplicate (Notifier_ptr ); +static Notifier_ptr Notifier_nil (CORBA::Environment &IT_env); +static Notifier_ptr Notifier_nil (); +#endif +#define Event_Comm_Notifier_IMPL "Event_Comm_Notifier" + + +class Notifier; + + typedef Notifier NotifierProxy; +#define Event_Comm_Notifier_IR "Event_Comm_Notifier" +#define Event_Comm_Notifier_IMPL "Event_Comm_Notifier" + +#ifndef Event_Comm_NotifierPtr +#define Event_Comm_NotifierPtr + + typedef Notifier* Notifier_ptr; + + typedef Notifier* NotifierRef; + +#endif + +class Notifier: public virtual CORBA::Object { +public: + Notifier (char *IT_OR); + Notifier (ObjectReference *IT_OR); + Notifier () : CORBA::Object (1) {} +protected: + Notifier_ptr __duplicate( + CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) { + CORBA::Object::__duplicate (IT_env); + return this; + } +public: + static Notifier_ptr _duplicate( + Notifier_ptr obj, + CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) { + CORBA::EnvExcRaiser IT_raise (&IT_env); + if (CORBA::is_nil(obj, IT_env)) { + IT_raise.maybeRaise (); + return (obj); + } + Notifier_ptr IT_obj = obj->__duplicate (IT_env); + IT_raise.maybeRaise(); + return IT_obj; + } +public: + static Notifier* _bind (const char* IT_markerServer, const char* host, + const CORBA::Context &IT_c, + CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()); + static Notifier* _bind (CORBA::Environment &IT_env); + static Notifier* _bind (const char* IT_markerServer=NULL, const char* host=NULL, + CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()); + static Notifier* _narrow (CORBA::Object* , CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()); + static Notifier_ptr _nil (CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) { + CORBA::EnvExcRaiser IT_raise (&IT_env); + IT_raise.maybeRaise(); + return (Notifier_ptr) CORBA::OBJECT_NIL;} + virtual void send_disconnect (const char * reason, CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) throw (CORBA::SystemException); + virtual void send_notification (const Event_Comm::Notification& notification, CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) throw (CORBA::SystemException); + virtual void subscribe (Event_Comm::Notification_Receiver_ptr notification_receiver, const char * filtering_criteria, CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) throw (CORBA::SystemException); + virtual void unsubscribe (Event_Comm::Notification_Receiver_ptr notification_receiver, const char * filtering_criteria, CORBA::Environment &IT_env=CORBA::IT_chooseDefaultEnv ()) throw (CORBA::SystemException); +}; + + static const CORBA::TypeCode_ptr _tc_Notifier; + + static const CORBA::TypeCode_ptr _tc_NotifierRef; + +#ifndef Event_Comm_NotifierVarH +#define Event_Comm_NotifierVarH + +#ifndef Event_Comm_NotifiervPtr +#define Event_Comm_NotifiervPtr +typedef Notifier* Notifier_vPtr; +#endif + +class Notifier_var : public CORBA::_var +{ + public: + + Notifier_var () { + _ptr = Notifier_nil (); + } + + Notifier_var (Notifier *IT_p) { + _ptr = IT_p; + } + + Notifier_var (const Notifier_var &IT_s) { + _ptr = Notifier_duplicate (IT_s._ptr); + } + + Notifier_var &operator= (Notifier *IT_p) { + Notifier_release (_ptr); + _ptr = IT_p; + return (*this); + } + + Notifier_var &operator= (const Notifier_var &IT_s) { + Notifier_release (_ptr); + _ptr = Notifier_duplicate (IT_s._ptr); + return (*this); + } + + ~Notifier_var () { + Notifier_release (_ptr); + } + + Notifier* operator-> () { + return _ptr; + } + + operator const Notifier_vPtr () const { return _ptr;} + operator Notifier_vPtr& () { return _ptr;} + + protected: + Notifier *_ptr; + private: + Notifier_var &operator= (const CORBA::_var &IT_s); + Notifier_var (const CORBA::_var &IT_s); + Notifier_var &operator= (const CORBA::_mgr &IT_s); + Notifier_var &operator= (const CORBA::_SeqElem &IT_s); + Notifier_var (const CORBA::_mgr &IT_s); + Notifier_var (const CORBA::_SeqElem &IT_s); +}; + +#endif + + +#ifndef Event_Comm_NotifierMgrH +#define Event_Comm_NotifierMgrH + +class Notifier_mgr : public CORBA::_mgr +{ + public: + + Notifier_mgr () { + _ptr = Notifier_nil (); + _release = 1; + } + + Notifier_mgr (const Notifier_mgr &IT_s) { + _ptr = Notifier_duplicate (IT_s._ptr); + _release = 1; + } + + Notifier_mgr &operator= (Notifier *IT_p) { + if (_ptr && _release) + Notifier_release (_ptr); + _ptr = IT_p; + _release = 1; + return (*this); + } + + Notifier_mgr &operator= (const Notifier_mgr &IT_s) { + if (_ptr && _release) + Notifier_release (_ptr); + _ptr = Notifier_duplicate(IT_s._ptr); + _release = 1; + return (*this); + } + + Notifier_mgr &operator= (const Notifier_var &IT_s) { + if (_ptr && _release) + Notifier_release (_ptr); + _ptr = Notifier_duplicate(IT_s); + _release = 1; + return (*this); + } + + ~Notifier_mgr () { + if (_release) + Notifier_release (_ptr); + } + + unsigned char release () { + return _release; + } + + void release (unsigned char rel) { + _release = rel; + } + + operator int () const { + CORBA::Environment env; + CORBA::EnvExcRaiser IT_raise (&env); + return (!(CORBA::is_nil((CORBA::Object*) _ptr, env))); + } + + operator void* () const { + return _ptr; + } + + operator CORBA::Object * () const { + return (CORBA::Object *) _ptr; + } + + operator Notifier* () const { + return (Notifier*) _ptr; + } + + Notifier *_ptr; + + protected: + + unsigned char _release; +}; + +#endif + +#ifndef Event_Comm_NotifierSeqElemH +#define Event_Comm_NotifierSeqElemH + +class Notifier_SeqElem : public CORBA::_SeqElem +{ + public: + + Notifier_SeqElem (Event_Comm::Notifier_ptr* IT_p, unsigned char rel) { + _ptr = IT_p; + _release = rel; + } + + Notifier_SeqElem &operator= (Event_Comm::Notifier_ptr IT_p) { + if (!_ptr) + return (*this); + if (*(_ptr) && _release) + Notifier_release (*(_ptr)); + *(_ptr) = IT_p; + return (*this); + } + + Notifier_SeqElem &operator= (const Notifier_SeqElem &IT_s) { + if (!_ptr|| !IT_s._ptr) + return (*this); + if (*(_ptr) && _release) + Notifier_release (*(_ptr)); + *(_ptr) = Notifier_duplicate(*(IT_s._ptr)); + return (*this); + } + + operator Event_Comm::Notifier_ptr () const +{ + if (!_ptr) + return (Notifier_nil()); + return (Event_Comm::Notifier_ptr) (*_ptr); + } + + Notifier_ptr operator->() const { return *_ptr;} + + protected: + Event_Comm::Notifier_ptr *_ptr; + unsigned char _release; +}; + +#endif + + +#define TIE_Event_Comm_Notifier(X) Event_Comm_Notifier##X + +#define DEF_TIE_Event_Comm_Notifier(X) \ + class Event_Comm_Notifier##X : public virtual Event_Comm::Notifier { \ + X* m_obj; \ + public: \ + \ + Event_Comm_Notifier##X (X *objp, const char* m="", CORBA::LoaderClass *l=0)\ + : Event_Comm::Notifier(), CORBA::Object (), m_obj(objp) { \ + m_pptr = new Event_Comm::Notifier_dispatch \ + (( Event_Comm::Notifier*)this,(CORBA::Object*)this,m,l,Event_Comm_Notifier_IR,m_obj); \ + } \ + Event_Comm_Notifier##X (CORBA::Object *IT_p, const char* IT_m="", void *IT_q=0)\ + : Event_Comm::Notifier(), CORBA::Object () { \ + m_pptr = new Event_Comm::Notifier_dispatch \ + (( Event_Comm::Notifier*)this,(CORBA::Object*)this,IT_m,Event_Comm_Notifier_IR,IT_p,IT_q); \ + m_obj = (X*)(m_pptr->getImplObj ()); \ + } \ + \ + virtual ~Event_Comm_Notifier##X () { \ + if (_okToDeleteImpl ()) delete m_obj; } \ + \ + virtual void* _deref () { \ + return m_obj; } \ + \ + virtual void send_disconnect (const char * reason, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->send_disconnect ( reason,IT_env);\ +}\ + \ + virtual void send_notification (const Event_Comm::Notification& notification, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->send_notification ( notification,IT_env);\ +}\ + \ + virtual void subscribe (Event_Comm::Notification_Receiver_ptr notification_receiver, const char * filtering_criteria, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->subscribe ( notification_receiver, filtering_criteria,IT_env);\ +}\ + \ + virtual void unsubscribe (Event_Comm::Notification_Receiver_ptr notification_receiver, const char * filtering_criteria, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->unsubscribe ( notification_receiver, filtering_criteria,IT_env);\ +}\ + \ + }; + + +#define QUALS_Event_Comm_Notifier \ + virtual void send_disconnect (const char * reason, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->send_disconnect ( reason,IT_env);\ +}\ + \ + virtual void send_notification (const Event_Comm::Notification& notification, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->send_notification ( notification,IT_env);\ +}\ + \ + virtual void subscribe (Event_Comm::Notification_Receiver_ptr notification_receiver, const char * filtering_criteria, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->subscribe ( notification_receiver, filtering_criteria,IT_env);\ +}\ + \ + virtual void unsubscribe (Event_Comm::Notification_Receiver_ptr notification_receiver, const char * filtering_criteria, CORBA::Environment &IT_env) throw (CORBA::SystemException){\ + m_obj->unsubscribe ( notification_receiver, filtering_criteria,IT_env);\ +}\ + + + + +class NotifierProxyFactoryClass : public virtual CORBA::ObjectFactoryClass { +public: + NotifierProxyFactoryClass (unsigned char IT_p=0) + : CORBA::ProxyFactory (Event_Comm_Notifier_IR, IT_p) {} + + virtual void* New (char *IT_OR, CORBA::Environment&); + + virtual void* New (ObjectReference *IT_OR, CORBA::Environment&); + + virtual void* New2 (); + + virtual void* IT_castUp (void *IT_p, char* IT_s); + + virtual CORBA::PPTR* pptr (void *IT_p); + + virtual void baseInterfaces (_IDL_SEQUENCE_string&); + + +}; + +static NotifierProxyFactoryClass NotifierProxyFactory; + + + +#endif + +}; + + +void operator<<= (CORBA::any &IT_a, Event_Comm::Notification_Receiver_ptr IT_t); +CORBA::Boolean operator>>= (const CORBA::any &IT_a, Event_Comm::Notification_Receiver_ptr& IT_t); + + +void operator<<= (CORBA::any &IT_a, Event_Comm::Notifier_ptr IT_t); +CORBA::Boolean operator>>= (const CORBA::any &IT_a, Event_Comm::Notifier_ptr& IT_t); + + +void operator<<= (CORBA::any &IT_a, const Event_Comm::Notification& IT_t); +CORBA::Boolean operator>>= (const CORBA::any &IT_a, Event_Comm::Notification*& IT_t); + + +#endif diff --git a/apps/Orbix-Examples/Event_Comm/libsrc/Event_Comm.idl b/apps/Orbix-Examples/Event_Comm/libsrc/Event_Comm.idl new file mode 100644 index 00000000000..26890129d70 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/libsrc/Event_Comm.idl @@ -0,0 +1,92 @@ +/* -*- C++ -*- */ +// @(#)Event_Comm.idl 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// EventComm +// +// = FILENAME +// Event_Comm.idl +// +// = DESCRIPTION +// The CORBA IDL module for distributed event notification. +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) +// +// ============================================================================ + +#ifndef _EVENT_COMM_IDL +#define _EVENT_COMM_IDL + +module Event_Comm + // = TITLE + // The CORBA IDL module for distributed event notification. + // + // = DESCRIPTION +{ + struct Notification + // = TITLE + // Defines the interface for an event . + // + // = This is the type passed by the Notifier to the Notification_Receiver. + // Since it contains an , it can hold any values. Naturally, + // the consumer must understand how to interpret this! + { + string tag_; + // Tag for the notification. + + // any value_; + // A notification can contain anything. + +// Object object_ref_; + // Object reference for callbacks. + }; + + interface Notification_Receiver + // = TITLE + // Defines the interface for a of events. + // Note that all operations are to avoid blocking. + // + // = DESCRIPTION + { + oneway void receive_notification (in Notification notification); + // Inform the that has occurred. + + oneway void disconnect (in string reason); + // Disconnect the from the , + // giving it the . + }; + + interface Notifier + // = TITLE + // Defines the interface for a of events. + // + // = DESCRIPTION + { + oneway void send_disconnect (in string reason); + // Disconnect all the receivers, giving them the . + + oneway void send_notification (in Notification notification); + // Send the to all the consumers who + // have subscribed and who match the filtering criteria. + + oneway void subscribe (in Notification_Receiver notification_receiver, + in string filtering_criteria); + // Subscribe the to receive events that + // match the regular expresssion applied by + // the . If is "" then all events + // are matched. + + oneway void unsubscribe (in Notification_Receiver notification_receiver, + in string filtering_criteria); + // Unsubscribe the that matches the + // filtering criteria. If is "" then + // all with the matching object reference + // are removed. + }; +}; + +#endif /* _EVENT_COMM_IDL */ diff --git a/apps/Orbix-Examples/Event_Comm/libsrc/Event_CommC.cpp b/apps/Orbix-Examples/Event_Comm/libsrc/Event_CommC.cpp new file mode 100644 index 00000000000..eee25b11a72 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/libsrc/Event_CommC.cpp @@ -0,0 +1,351 @@ + +// @(#)Event_CommC.cpp 1.1 10/18/96 + +#include "Event_Comm.hh" + + +#ifndef Event_Comm_Notification_Ops +#define Event_Comm_Notification_Ops + +void Event_Comm::Notification:: encodeOp (CORBA::Request &IT_r) const { + IT_r.encodeStringOp (tag_); +} + +void Event_Comm::Notification:: decodeOp (CORBA::Request &IT_r) { + IT_r.decodeStringOp(tag_); +} + +void Event_Comm::Notification:: decodeInOutOp (CORBA::Request &IT_r) { + IT_r.decodeInOutStrOp(tag_, 0); +} + +void* Event_Comm::Notification:: IT_anySupport (CORBA::Request &IT_r, + void *& IT_v, void *IT_to, const CORBA::Flags& IT_f) { + Event_Comm::Notification* IT_l = (Event_Comm::Notification*)IT_v; + + if (IT_f.isSetAll (CORBA::ARG_INOUT)) { + if (!IT_l) + IT_l = new Event_Comm::Notification(); + IT_l -> decodeInOutOp (IT_r); + IT_v = IT_l; + } + else if (IT_f.isSet (CORBA::ARG_IN)) { + IT_l -> encodeOp (IT_r); + } + else if (IT_f.isSet (CORBA::ARG_OUT)) { + if (!IT_l) + IT_l = new Event_Comm::Notification(); + IT_l -> decodeOp (IT_r); + IT_v = IT_l; + } + else if (IT_f.isSet (CORBA::_ANY_ASSIGN)) { + Event_Comm::Notification*IT_s = IT_to ? (Event_Comm::Notification*)IT_to : new Event_Comm::Notification; + *IT_s = *IT_l; return IT_s; + } + else if (IT_f.isSet (CORBA::_ANY_DELETE)) { + if (IT_to) IT_l->Event_Comm::Notification::~Notification(); + else delete IT_l; + return NULL; + } + else if (IT_f.isSet (CORBA::_ANY_SIZEOF)) { + return (void*) (sizeof (Event_Comm::Notification)); + } + else if (IT_f.isNil ()) { + if (!IT_l) + IT_l = new Event_Comm::Notification(); + IT_l -> decodeOp (IT_r); + IT_v = IT_l; + } + return NULL; +} + +const void *Event_Comm::Notification:: IT_fn = +CORBA::anyTable.record ("Event_Comm::Notification", &Event_Comm::Notification:: IT_anySupport); + +Event_Comm::Notification &Event_Comm::Notification:: operator= (const Event_Comm::IONANC_Notification& IT_p) { + this->operator= (*(Event_Comm::Notification*) &IT_p); + return (*this); +} + +Event_Comm::Notification:: operator Event_Comm::IONANC_Notification () { + Event_Comm::IONANC_Notification tmp; + memset (&tmp, 0, sizeof(tmp)); + ((Event_Comm::Notification *) &tmp)->operator= (*this); + return tmp; +} + +Event_Comm::Notification:: operator const Event_Comm::IONANC_Notification () const { + Event_Comm::IONANC_Notification tmp; + memset (&tmp, 0, sizeof(tmp)); + ((Event_Comm::Notification *) &tmp)->operator= (*this); + return tmp; +} + +Event_Comm::Notification::~Notification () { + if (tag_) delete [] tag_; +} + +Event_Comm::Notification:: Notification (const Event_Comm::Notification &IT_s) + { + if (IT_s.tag_) { + tag_=new char [strlen(IT_s.tag_)+1]; + strcpy (tag_, IT_s.tag_); + } + else { + tag_ = NULL; + } +} + +Event_Comm::Notification:: Notification () { + tag_ = NULL; +} + +Event_Comm::Notification &Event_Comm::Notification:: operator= (const Event_Comm::Notification& IT_s) { + if (this == &IT_s) return *this; + if (tag_) delete [] tag_; + if (IT_s.tag_) { + tag_=new char [strlen(IT_s.tag_)+1]; + strcpy (tag_, IT_s.tag_); + } + else { + tag_ = NULL; + } + return *this; +} + +Event_Comm::IONANC_Notification:: operator Event_Comm::Notification () { + return (*((Event_Comm::Notification *) this)); +} + +Event_Comm::IONANC_Notification:: operator const Event_Comm::Notification () const { + return (*((const Event_Comm::Notification *) this)); +} + + +#endif +Event_Comm::Notification_Receiver::Notification_Receiver (char *IT_OR) { + m_pptr = new Notification_Receiver_dispatch (IT_OR, this,(CORBA::Object*)this); +} + +#ifndef Event_Comm_Notification_ReceiverForwC +#define Event_Comm_Notification_ReceiverForwC +CORBA::ObjectRef Event_Comm::Notification_Receiver_getBase(void *IT_p){ + return (Event_Comm::Notification_Receiver*)IT_p;} + +void Event_Comm::Notification_Receiver_release (void *IT_p, CORBA::Environment &IT_env) { + ((Event_Comm::Notification_Receiver*)IT_p)->_release(IT_env);} + +Event_Comm::Notification_Receiver* Event_Comm::Notification_Receiver_duplicate (void *IT_p, CORBA::Environment &IT_env) { + return ((Event_Comm::Notification_Receiver*)IT_p)->_duplicate(IT_env); } +#endif + + + +Event_Comm::Notification_Receiver* Event_Comm::Notification_Receiver:: _bind (const char* IT_markerServer, const char* host, + const CORBA::Context &IT_c, + CORBA::Environment &IT_env) { + Notification_Receiver*IT_p = + (Notification_Receiver*)CORBA::Factory.New (IT_markerServer, IT_env, IT_c, host, + Event_Comm_Notification_Receiver_IMPL, Event_Comm_Notification_Receiver_IR); + return IT_p ? IT_p->_duplicate () : NULL; } + + + +Event_Comm::Notification_Receiver* Event_Comm::Notification_Receiver:: _bind (CORBA::Environment &IT_env) { + return _bind (NULL,NULL,CORBA::Context(), IT_env); } + + +Event_Comm::Notification_Receiver* Event_Comm::Notification_Receiver:: _bind (const char* IT_markerServer, const char* host, + CORBA::Environment &IT_env) { + return _bind (IT_markerServer, host, CORBA::Context (), IT_env); } +Event_Comm::Notification_Receiver* Event_Comm::Notification_Receiver::_narrow (CORBA::Object* IT_obj, CORBA::Environment &IT_env) { + Event_Comm::Notification_Receiver* IT_p = (Event_Comm::Notification_Receiver*)CORBA::Object::_castDown (IT_obj, Event_Comm_Notification_Receiver_IR, IT_env); + return IT_p ? IT_p->_duplicate(IT_env) : NULL; + } + +void* Event_Comm::Notification_ReceiverProxyFactoryClass::New (char *IT_OR, CORBA::Environment&) { + return new Notification_Receiver(IT_OR);} + +void* Event_Comm::Notification_ReceiverProxyFactoryClass::New2 () { + return new Notification_Receiver();} + +void* Event_Comm::Notification_ReceiverProxyFactoryClass::IT_castUp (void *IT_p, char* IT_s) { + void *IT_l; + if (!CORBA::_interfaceCmp (IT_s,Event_Comm_Notification_Receiver_IR)) + return IT_p; + else if (IT_l=CORBA::ObjectFactoryClass::IT_castUp((CORBA::Object*)((Event_Comm::Notification_Receiver*)IT_p),IT_s)) + return IT_l; + else return NULL; + } + + +CORBA::PPTR* Event_Comm::Notification_ReceiverProxyFactoryClass::pptr (void *IT_p) { + return ((Event_Comm::Notification_Receiver*)IT_p)->_pptr ();} + +void Event_Comm::Notification_ReceiverProxyFactoryClass::baseInterfaces (_IDL_SEQUENCE_string& seq) { + add (seq, Event_Comm_Notification_Receiver_IR); + CORBA::ObjectFactoryClass::baseInterfaces (seq); +} + + void Event_Comm::Notification_Receiver:: receive_notification(const Event_Comm::Notification& notification, CORBA::Environment &IT_env) { + + if (IT_env || m_isNull) return ; + CORBA::Request IT_r (this, "receive_notification",IT_env,1,1); + if (!IT_r.isException (IT_env)) { + notification.encodeOp (IT_r); + } + + IT_r.invoke (CORBA::Flags(CORBA::INV_NO_RESPONSE), IT_env); + } + + void Event_Comm::Notification_Receiver:: disconnect(const char * reason, CORBA::Environment &IT_env) { + + if (IT_env || m_isNull) return ; + CORBA::Request IT_r (this, "disconnect",IT_env,1,1); + if (!IT_r.isException (IT_env)) { + IT_r.encodeStringOp (reason); + } + + IT_r.invoke (CORBA::Flags(CORBA::INV_NO_RESPONSE), IT_env); + } + + +Event_Comm::Notification_ReceiverProxyFactoryClass Event_Comm::Notification_ReceiverProxyFactory(1); + + +#ifndef Event_Comm_Notification_Receiver_dispatch_impl + +unsigned char Event_Comm::Notification_Receiver_dispatch::dispatch (CORBA::Request &IT_r, + unsigned char, void *) { + IT_r.makeRuntimeException1 ("Event_Comm::Notification_Receiver"); + return 0; +} + +#endif + +Event_Comm::Notifier::Notifier (char *IT_OR) { + m_pptr = new Notifier_dispatch (IT_OR, this,(CORBA::Object*)this); +} + +#ifndef Event_Comm_NotifierForwC +#define Event_Comm_NotifierForwC +CORBA::ObjectRef Event_Comm::Notifier_getBase(void *IT_p){ + return (Event_Comm::Notifier*)IT_p;} + +void Event_Comm::Notifier_release (void *IT_p, CORBA::Environment &IT_env) { + ((Event_Comm::Notifier*)IT_p)->_release(IT_env);} + +Event_Comm::Notifier* Event_Comm::Notifier_duplicate (void *IT_p, CORBA::Environment &IT_env) { + return ((Event_Comm::Notifier*)IT_p)->_duplicate(IT_env); } +#endif + + + +Event_Comm::Notifier* Event_Comm::Notifier:: _bind (const char* IT_markerServer, const char* host, + const CORBA::Context &IT_c, + CORBA::Environment &IT_env) { + Notifier*IT_p = + (Notifier*)CORBA::Factory.New (IT_markerServer, IT_env, IT_c, host, + Event_Comm_Notifier_IMPL, Event_Comm_Notifier_IR); + return IT_p ? IT_p->_duplicate () : NULL; } + + + +Event_Comm::Notifier* Event_Comm::Notifier:: _bind (CORBA::Environment &IT_env) { + return _bind (NULL,NULL,CORBA::Context(), IT_env); } + + +Event_Comm::Notifier* Event_Comm::Notifier:: _bind (const char* IT_markerServer, const char* host, + CORBA::Environment &IT_env) { + return _bind (IT_markerServer, host, CORBA::Context (), IT_env); } +Event_Comm::Notifier* Event_Comm::Notifier::_narrow (CORBA::Object* IT_obj, CORBA::Environment &IT_env) { + Event_Comm::Notifier* IT_p = (Event_Comm::Notifier*)CORBA::Object::_castDown (IT_obj, Event_Comm_Notifier_IR, IT_env); + return IT_p ? IT_p->_duplicate(IT_env) : NULL; + } + +void* Event_Comm::NotifierProxyFactoryClass::New (char *IT_OR, CORBA::Environment&) { + return new Notifier(IT_OR);} + +void* Event_Comm::NotifierProxyFactoryClass::New2 () { + return new Notifier();} + +void* Event_Comm::NotifierProxyFactoryClass::IT_castUp (void *IT_p, char* IT_s) { + void *IT_l; + if (!CORBA::_interfaceCmp (IT_s,Event_Comm_Notifier_IR)) + return IT_p; + else if (IT_l=CORBA::ObjectFactoryClass::IT_castUp((CORBA::Object*)((Event_Comm::Notifier*)IT_p),IT_s)) + return IT_l; + else return NULL; + } + + +CORBA::PPTR* Event_Comm::NotifierProxyFactoryClass::pptr (void *IT_p) { + return ((Event_Comm::Notifier*)IT_p)->_pptr ();} + +void Event_Comm::NotifierProxyFactoryClass::baseInterfaces (_IDL_SEQUENCE_string& seq) { + add (seq, Event_Comm_Notifier_IR); + CORBA::ObjectFactoryClass::baseInterfaces (seq); +} + + void Event_Comm::Notifier:: send_disconnect(const char * reason, CORBA::Environment &IT_env) { + + if (IT_env || m_isNull) return ; + CORBA::Request IT_r (this, "send_disconnect",IT_env,1,1); + if (!IT_r.isException (IT_env)) { + IT_r.encodeStringOp (reason); + } + + IT_r.invoke (CORBA::Flags(CORBA::INV_NO_RESPONSE), IT_env); + } + + void Event_Comm::Notifier:: send_notification(const Event_Comm::Notification& notification, CORBA::Environment &IT_env) { + + if (IT_env || m_isNull) return ; + CORBA::Request IT_r (this, "send_notification",IT_env,1,1); + if (!IT_r.isException (IT_env)) { + notification.encodeOp (IT_r); + } + + IT_r.invoke (CORBA::Flags(CORBA::INV_NO_RESPONSE), IT_env); + } + + void Event_Comm::Notifier:: subscribe(Event_Comm::Notification_Receiver* notification_receiver, const char * filtering_criteria, CORBA::Environment &IT_env) { + + if (IT_env || m_isNull) return ; + CORBA::Request IT_r (this, "subscribe",IT_env,1,1); + if (!IT_r.isException (IT_env)) { + IT_r << (CORBA::Object*)notification_receiver; + + IT_r.encodeStringOp (filtering_criteria); + } + + IT_r.invoke (CORBA::Flags(CORBA::INV_NO_RESPONSE), IT_env); + } + + void Event_Comm::Notifier:: unsubscribe(Event_Comm::Notification_Receiver* notification_receiver, const char * filtering_criteria, CORBA::Environment &IT_env) { + + if (IT_env || m_isNull) return ; + CORBA::Request IT_r (this, "unsubscribe",IT_env,1,1); + if (!IT_r.isException (IT_env)) { + IT_r << (CORBA::Object*)notification_receiver; + + IT_r.encodeStringOp (filtering_criteria); + } + + IT_r.invoke (CORBA::Flags(CORBA::INV_NO_RESPONSE), IT_env); + } + + +Event_Comm::NotifierProxyFactoryClass Event_Comm::NotifierProxyFactory(1); + + +#ifndef Event_Comm_Notifier_dispatch_impl + +unsigned char Event_Comm::Notifier_dispatch::dispatch (CORBA::Request &IT_r, + unsigned char, void *) { + IT_r.makeRuntimeException1 ("Event_Comm::Notifier"); + return 0; +} + +#endif + diff --git a/apps/Orbix-Examples/Event_Comm/libsrc/Event_CommS.cpp b/apps/Orbix-Examples/Event_Comm/libsrc/Event_CommS.cpp new file mode 100644 index 00000000000..9adc4cb26d4 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/libsrc/Event_CommS.cpp @@ -0,0 +1,166 @@ + +// @(#)Event_CommS.cpp 1.1 10/18/96 + +#include "Event_Comm.hh" + + +#define Event_Comm_Notification_Receiver_dispatch_impl + +unsigned char Event_Comm::Notification_Receiver_dispatch::dispatch (CORBA::Request &IT_r, + unsigned char IT_isTarget, void *IT_pp) { + if (!IT_pp) + IT_pp = m_obj; + const char *IT_s = IT_r.getOperation (); + if (!strcmp(IT_s,"receive_notification")) { + CORBA::Environment IT_env (IT_r); + CORBA::Filter* IT_f = CORBA::Orbix.getFilter (); + if (!IT_r.tcAssert ("\ +Ro~receive_notification~+notification{R~Event_Comm::Notification~tag_{0}},>{v},O{}\ +")) + return 1; + Event_Comm::Notification notification; + notification.decodeOp (IT_r); + + if (IT_f && !IT_r.isException (IT_env)) + IT_f->inRequestPostM (IT_r, IT_env); + if (!IT_r.isException (IT_env)) + ((Event_Comm::Notification_Receiver*)IT_pp)->receive_notification ( notification, IT_env); + + IT_r.replyNoResults (CORBA::Flags(CORBA::INV_NO_RESPONSE),IT_env); + return 1; + } + + else if (!strcmp(IT_s,"disconnect")) { + CORBA::Environment IT_env (IT_r); + CORBA::Filter* IT_f = CORBA::Orbix.getFilter (); + if (!IT_r.tcAssert ("\ +Ro~disconnect~+reason{0},>{v},O{}\ +")) + return 1; + char * reason; + IT_r.decodeStringOp(reason); + + if (IT_f && !IT_r.isException (IT_env)) + IT_f->inRequestPostM (IT_r, IT_env); + if (!IT_r.isException (IT_env)) + ((Event_Comm::Notification_Receiver*)IT_pp)->disconnect ( reason, IT_env); + + delete [] reason; + IT_r.replyNoResults (CORBA::Flags(CORBA::INV_NO_RESPONSE),IT_env); + return 1; + } + + else if (IT_isTarget) + IT_r.makeRuntimeException2 (); + + return 0; +} + +#define Event_Comm_Notifier_dispatch_impl + +unsigned char Event_Comm::Notifier_dispatch::dispatch (CORBA::Request &IT_r, + unsigned char IT_isTarget, void *IT_pp) { + if (!IT_pp) + IT_pp = m_obj; + const char *IT_s = IT_r.getOperation (); + if (!strcmp(IT_s,"send_disconnect")) { + CORBA::Environment IT_env (IT_r); + CORBA::Filter* IT_f = CORBA::Orbix.getFilter (); + if (!IT_r.tcAssert ("\ +Ro~send_disconnect~+reason{0},>{v},O{}\ +")) + return 1; + char * reason; + IT_r.decodeStringOp(reason); + + if (IT_f && !IT_r.isException (IT_env)) + IT_f->inRequestPostM (IT_r, IT_env); + if (!IT_r.isException (IT_env)) + ((Event_Comm::Notifier*)IT_pp)->send_disconnect ( reason, IT_env); + + delete [] reason; + IT_r.replyNoResults (CORBA::Flags(CORBA::INV_NO_RESPONSE),IT_env); + return 1; + } + + else if (!strcmp(IT_s,"send_notification")) { + CORBA::Environment IT_env (IT_r); + CORBA::Filter* IT_f = CORBA::Orbix.getFilter (); + if (!IT_r.tcAssert ("\ +Ro~send_notification~+notification{R~Event_Comm::Notification~tag_{0}},>{v},O{}\ +")) + return 1; + Event_Comm::Notification notification; + notification.decodeOp (IT_r); + + if (IT_f && !IT_r.isException (IT_env)) + IT_f->inRequestPostM (IT_r, IT_env); + if (!IT_r.isException (IT_env)) + ((Event_Comm::Notifier*)IT_pp)->send_notification ( notification, IT_env); + + IT_r.replyNoResults (CORBA::Flags(CORBA::INV_NO_RESPONSE),IT_env); + return 1; + } + + else if (!strcmp(IT_s,"subscribe")) { + CORBA::Environment IT_env (IT_r); + CORBA::Filter* IT_f = CORBA::Orbix.getFilter (); + if (!IT_r.tcAssert ("\ +Ro~subscribe~+notification_receiver{O~Event_Comm::Notification_Receiver},+filtering_criteria{0},>{v},O{}\ +")) + return 1; + Event_Comm::Notification_Receiver* notification_receiver; + notification_receiver = (Event_Comm::Notification_Receiver*) IT_r.decodeObjRef (Event_Comm_Notification_Receiver_IR); + if (notification_receiver) notification_receiver->_duplicate (); + + char * filtering_criteria; + IT_r.decodeStringOp(filtering_criteria); + + if (IT_f && !IT_r.isException (IT_env)) + IT_f->inRequestPostM (IT_r, IT_env); + if (!IT_r.isException (IT_env)) + ((Event_Comm::Notifier*)IT_pp)->subscribe ( notification_receiver, filtering_criteria, IT_env); + + if (notification_receiver) notification_receiver->_release (); + + delete [] filtering_criteria; + IT_r.replyNoResults (CORBA::Flags(CORBA::INV_NO_RESPONSE),IT_env); + + return 1; + } + + else if (!strcmp(IT_s,"unsubscribe")) { + CORBA::Environment IT_env (IT_r); + CORBA::Filter* IT_f = CORBA::Orbix.getFilter (); + if (!IT_r.tcAssert ("\ +Ro~unsubscribe~+notification_receiver{O~Event_Comm::Notification_Receiver},+filtering_criteria{0},>{v},O{}\ +")) + return 1; + Event_Comm::Notification_Receiver* notification_receiver; + notification_receiver = (Event_Comm::Notification_Receiver*) IT_r.decodeObjRef (Event_Comm_Notification_Receiver_IR); + if (notification_receiver) notification_receiver->_duplicate (); + + char * filtering_criteria; + IT_r.decodeStringOp(filtering_criteria); + + if (IT_f && !IT_r.isException (IT_env)) + IT_f->inRequestPostM (IT_r, IT_env); + if (!IT_r.isException (IT_env)) + ((Event_Comm::Notifier*)IT_pp)->unsubscribe ( notification_receiver, filtering_criteria, IT_env); + + if (notification_receiver) notification_receiver->_release (); + + delete [] filtering_criteria; + IT_r.replyNoResults (CORBA::Flags(CORBA::INV_NO_RESPONSE),IT_env); + + return 1; + } + + else if (IT_isTarget) + IT_r.makeRuntimeException2 (); + + return 0; +} + +#include "Event_CommC.cpp" + diff --git a/apps/Orbix-Examples/Event_Comm/libsrc/Event_Comm_i.h b/apps/Orbix-Examples/Event_Comm/libsrc/Event_Comm_i.h new file mode 100644 index 00000000000..2db73e2f616 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/libsrc/Event_Comm_i.h @@ -0,0 +1,38 @@ +/* -*- C++ -*- */ +// @(#)Event_Comm_i.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// EventComm +// +// = FILENAME +// Event_Comm_i.h +// +// = DESCRIPTION +// Class interface for the implementation of the distributed +// event notification mechanism. +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) +// +// ============================================================================ + +#if !defined (_EVENT_COMM_I_H) +#define _EVENT_COMM_I_H + +#include "Notification_Receiver_i.h" +#include "Notifier_i.h" + +#if defined (ACE_HAS_ORBIX) +#define nil 0 + +// Tie the Notification_Receiver and Notifier implementation classes +// together with the IDL interface. + +DEF_TIE_Event_Comm_Notification_Receiver (Notification_Receiver_i) +DEF_TIE_Event_Comm_Notifier (Notifier_i) + +#endif /* ACE_HAS_ORBIX */ +#endif /* _EVENT_COMM_I_H */ diff --git a/apps/Orbix-Examples/Event_Comm/libsrc/Makefile b/apps/Orbix-Examples/Event_Comm/libsrc/Makefile new file mode 100644 index 00000000000..add9fd31151 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/libsrc/Makefile @@ -0,0 +1,113 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Event Communications library +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +LIB = libEvent_Comm.a +SHLIB = libEvent_Comm.so + +FILES = Event_CommS \ + Event_CommC \ + Notifier_i \ + Notification_Receiver_i + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(addsuffix .o,$(FILES)) +SHOBJ = $(addsuffix .so,$(FILES)) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VLIB) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Orbix related macros and target settings. +#---------------------------------------------------------------------------- + +ORBIX_BINDIR = $(ORBIX_ROOT)/bin +ORBIX_LIBDIR = $(ORBIX_ROOT)/lib +ORBIX_INCDIR = $(ORBIX_ROOT)/include + +CPPFLAGS += -DEXCEPTIONS -I$(ORBIX_INCDIR) -DWANT_ORBIX_FDS +LDFLAGS += -L$(ORBIX_LIBDIR) -R $(ORBIX_LIBDIR) + +IDLFLAGS = -A -s S.cpp -c C.cpp + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +Event_CommS.o: Event_CommS.cpp Event_Comm.hh Event_CommC.cpp +Event_CommC.o: Event_CommC.cpp Event_Comm.hh +Notifier_i.o: Notifier_i.cpp \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Msg.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Record.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/sysincludes.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/config.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Priority.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Record.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Msg.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Specific.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Synch.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Time_Value.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Synch_T.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Specific.i \ + Notification_Receiver_i.h Notifier_i.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Map_Manager.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/SString.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/SString.i \ + Event_Comm.hh +Notification_Receiver_i.o: Notification_Receiver_i.cpp \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Msg.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Record.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/sysincludes.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/config.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Priority.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Record.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Log_Msg.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Specific.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Synch.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Time_Value.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Synch_T.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Specific.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Config.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Reactor.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Handle_Set.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Handle_Set.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Timer_Queue.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Event_Handler.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Timer_Queue.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Signal.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Set.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Token.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Reactor.i \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Object.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Shared_Object.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Service_Record.h \ + /project/adaptive/ACE_wrappers/build/SunOS5.4/include/ace/Thread_Manager.h \ + Notification_Receiver_i.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/apps/Orbix-Examples/Event_Comm/libsrc/Notification.idl b/apps/Orbix-Examples/Event_Comm/libsrc/Notification.idl new file mode 100644 index 00000000000..ecfd5adb8e0 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/libsrc/Notification.idl @@ -0,0 +1,42 @@ +/* -*- C++ -*- */ +// @(#)Notification.idl 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// EventComm +// +// = FILENAME +// Notification.idl +// +// = DESCRIPTION +// This is the CORBA IDL interface for the Event Communication . +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) +// +// ============================================================================ + +#ifndef _NOTIFICATION_IDL +#define _NOTIFICATION_IDL + +struct Notification + // = TITLE + // Defines the interface for an event . + // + // = This is the type passed by the Notifier to the Notification_Receiver. + // Since it contains an , it can hold any values. Naturally, + // the consumer must understand how to interpret this! +{ + string tag_; + // Tag for the notification. + +// any value_; + // A notification can contain anything. + + Object object_ref_; + // Object reference for callbacks. +}; + +#endif /* _NOTIFICATION_IDL */ diff --git a/apps/Orbix-Examples/Event_Comm/libsrc/Notification_Receiver.idl b/apps/Orbix-Examples/Event_Comm/libsrc/Notification_Receiver.idl new file mode 100644 index 00000000000..222f18782f7 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/libsrc/Notification_Receiver.idl @@ -0,0 +1,42 @@ +/* -*- C++ -*- */ +// @(#)Notification_Receiver.idl 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// EventComm +// +// = FILENAME +// Notification_Receiver.idl +// +// = DESCRIPTION +// The CORBA IDL interface for the Event Communication +// component. +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) +// +// ============================================================================ + +#include "Notification.idl" + +#ifndef _Notification_Receiver_iDL +#define _Notification_Receiver_iDL + +interface Notification_Receiver + // = TITLE + // Defines the interface for a of events. + // Note that all operations are to avoid blocking. + // + // = DESCRIPTION +{ + oneway void receive_notification (in Notification notification); + // Inform the that has occurred. + + oneway void disconnect (in string reason); + // Disconnect the from the , + // giving it the . +}; + +#endif /* _Notification_Receiver_iDL */ diff --git a/apps/Orbix-Examples/Event_Comm/libsrc/Notification_Receiver_i.cpp b/apps/Orbix-Examples/Event_Comm/libsrc/Notification_Receiver_i.cpp new file mode 100644 index 00000000000..337cf91e31e --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/libsrc/Notification_Receiver_i.cpp @@ -0,0 +1,39 @@ +#include "ace/Log_Msg.h" +// @(#)Notification_Receiver_i.cpp 1.1 10/18/96 + +#include "ace/Service_Config.h" +#include "Notification_Receiver_i.h" + +#if defined (ACE_HAS_ORBIX) + +Notification_Receiver_i::Notification_Receiver_i (void) +{ +} + +Notification_Receiver_i::~Notification_Receiver_i (void) +{ +} + +// Inform the that has occurred. + +void +Notification_Receiver_i::receive_notification + (const Event_Comm::Notification ¬ification, + CORBA::Environment &IT_env) +{ + const char *tmpstr = notification.tag_; + + ACE_DEBUG ((LM_DEBUG, "**** got notification = %s\n", tmpstr)); +} + +// Disconnect the from the . + +void +Notification_Receiver_i::disconnect (const char *reason, + CORBA::Environment &IT_env) +{ + ACE_DEBUG ((LM_DEBUG, "**** got disconnected due to %s\n", reason)); + ACE_Service_Config::end_reactor_event_loop (); +} + +#endif /* ACE_HAS_ORBIX */ diff --git a/apps/Orbix-Examples/Event_Comm/libsrc/Notification_Receiver_i.h b/apps/Orbix-Examples/Event_Comm/libsrc/Notification_Receiver_i.h new file mode 100644 index 00000000000..4f0bcc980e4 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/libsrc/Notification_Receiver_i.h @@ -0,0 +1,48 @@ +/* -*- C++ -*- */ +// @(#)Notification_Receiver_i.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// EventComm +// +// = FILENAME +// Notification_Receiver__i.h +// +// = DESCRIPTION +// Class interface for the implementation of the +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) +// +// ============================================================================ + +#if !defined (_Notification_Receiver_i_H) +#define _Notification_Receiver_i_H + +#if defined (ACE_HAS_ORBIX) +#include "Event_Comm.hh" + +class Notification_Receiver_i + // = TITLE + // Defines the implementation class for event . + // + // = DESCRIPTION +{ +public: + Notification_Receiver_i (void); + ~Notification_Receiver_i (void); + + virtual void receive_notification (const Event_Comm::Notification ¬ification, + CORBA::Environment &IT_env); + // Pass the to the . + + virtual void disconnect (const char *reason, + CORBA::Environment &IT_env); + // Disconnect the from the , + // giving it the . +}; + +#endif /* ACE_HAS_ORBIX */ +#endif /* _Notification_Receiver_i_H */ diff --git a/apps/Orbix-Examples/Event_Comm/libsrc/Notifier.idl b/apps/Orbix-Examples/Event_Comm/libsrc/Notifier.idl new file mode 100644 index 00000000000..75e738e0627 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/libsrc/Notifier.idl @@ -0,0 +1,49 @@ +/* -*- C++ -*- */ +// @(#)Notifier.idl 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// EventComm +// +// = FILENAME +// Notifier.idl +// +// = DESCRIPTION +// This is the CORBA IDL interface for the Event Communication . +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) +// +// ============================================================================ + +#ifndef _Notifier_iDL +#define _Notifier_iDL + +#include "Notification.idl" +#include "Notification_Receiver.idl" + +interface Notifier + // = TITLE + // Defines the interface for a of events. + // + // = DESCRIPTION +{ + oneway void send_disconnect (in string reason); + // Disconnect all the receivers, giving them the . + + oneway void send_notification (in Notification notification); + // Send the to all the consumers who + // have subscribed and who match the filtering criteria. + + oneway void subscribe (in Notification_Receiver notification_receiver, + in string filtering_criteria); + // Subscribe the to receive events that + // match applied by the . + + oneway void unsubscribe (in Notification_Receiver notification_receiver); + // Unsubscribe the . +}; + +#endif /* _Notifier_iDL */ diff --git a/apps/Orbix-Examples/Event_Comm/libsrc/Notifier_i.cpp b/apps/Orbix-Examples/Event_Comm/libsrc/Notifier_i.cpp new file mode 100644 index 00000000000..1edefc82a29 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/libsrc/Notifier_i.cpp @@ -0,0 +1,324 @@ +#include "ace/Log_Msg.h" +// @(#)Notifier_i.cpp 1.1 10/18/96 + +#include "Notification_Receiver_i.h" +#include "Notifier_i.h" + +#if defined (ACE_HAS_ORBIX) + +class Notification_Receiver_Entry + // = TITLE + // Keeps track of context information associated with + // a entry. + // + // = DESCRIPTION + // +{ +public: + Notification_Receiver_Entry (Event_Comm::Notification_Receiver *notification_receiver, + const char *filtering_criteria); + ~Notification_Receiver_Entry (void); + + // = Set/get filtering criteria. + void criteria (const char *criteria); + const char *criteria (void); + + // = Set/get Event_Comm::Notification_Receiver object reference. + Event_Comm::Notification_Receiver *receiver (void); + void receiver (Event_Comm::Notification_Receiver *); + + // = Set/get the compiled regular expression buffer. + const char *regexp (void); + void regexp (char *); + +private: + const char *filtering_criteria_; + // String containing the filtering criteria. + + char *compiled_regexp_; + // Compiled representation of the regular expression (see + // regexpr(3g)). + + Event_Comm::Notification_Receiver *receiver_; + // Object reference for the Event_Comm::Notification_Receiver. +}; + +// = Set/get filtering criteria. + +void +Notification_Receiver_Entry::criteria (const char *criteria) +{ + ACE_OS::free (ACE_MALLOC_T (this->filtering_criteria_)); + this->filtering_criteria_ = ACE_OS::strdup (criteria); +} + +const char * +Notification_Receiver_Entry::criteria (void) +{ + return this->filtering_criteria_; +} + +// = Set/get Event_Comm::Notification_Receiver object reference. + +Event_Comm::Notification_Receiver * +Notification_Receiver_Entry::receiver (void) +{ + return this->receiver_; +} + +void +Notification_Receiver_Entry::receiver (Event_Comm::Notification_Receiver *receiver) +{ + this->receiver_ = receiver; +} + +const char * +Notification_Receiver_Entry::regexp (void) +{ + return this->compiled_regexp_; +} + +void +Notification_Receiver_Entry::regexp (char *regexp) +{ + ACE_OS::free (ACE_MALLOC_T (this->compiled_regexp_)); + this->compiled_regexp_ = regexp; +} + +Notification_Receiver_Entry::Notification_Receiver_Entry (Event_Comm::Notification_Receiver *receiver, + const char *filtering_criteria) + : receiver_ (receiver), + filtering_criteria_ (0), + compiled_regexp_ (0) +{ + char *compile_buffer = 0; + + this->criteria (filtering_criteria); + ACE_ASSERT (this->criteria ()); + + // Check for wildcard case first. + if (ACE_OS::strcmp (filtering_criteria, "") == 0) + compile_buffer = ACE_OS::strdup (""); + else // Compile the regular expression (the 0's cause ACE_OS::compile to allocate space). + compile_buffer = ACE_OS::compile (filtering_criteria, 0, 0); + + // Should throw an exception here! + ACE_ASSERT (compile_buffer != 0); + + this->regexp (compile_buffer); + ACE_ASSERT (this->regexp ()); + + // Increment the reference count since we are keeping a copy of + // this... + this->receiver_->_duplicate (this->receiver_); +} + +Notification_Receiver_Entry::~Notification_Receiver_Entry (void) +{ + ACE_OS::free (this->filtering_criteria_); + ACE_OS::free (this->compiled_regexp_); + // Decrement the object reference count. + CORBA::release (this->receiver_); +} + +Notifier_i::Notifier_i (size_t size) + : map_ (size) +{ +} + +// Add a new receiver to the table, being careful to check for +// duplicate entries. A receiver is considered a duplicate under +// the following circumstances: +// 1. It has the same marker name and the same filtering criteria +// 2. It has the same marker name and its filtering criteria is "" (the wild card). + +void +Notifier_i::subscribe (Event_Comm::Notification_Receiver *receiver_ref, + const char *filtering_criteria, + CORBA::Environment &IT_env) +{ + ACE_DEBUG ((LM_DEBUG, + "in Notifier_i::subscribe for %s with filtering criteria \"%s\"\n", + receiver_ref->_marker (), filtering_criteria)); + ACE_SString key (receiver_ref->_marker ()); + MAP_ITERATOR mi (this->map_); + + // Try to locate an entry using its marker name (which should be + // unique across the system). If we don't find the entry, or if the + // filtering criteria is different that is good news since we + // currently don't allow duplicates... In particular, if @@ Should + // duplicates be allowed? + + for (MAP_ENTRY *me = 0; mi.next (me) != 0; mi.advance ()) + { + Notification_Receiver_Entry *nr_entry = me->int_id_; + + // Check for a duplicate entry. + if (key == me->ext_id_ + && (ACE_OS::strcmp (filtering_criteria, "") == 0 + || ACE_OS::strcmp (filtering_criteria, nr_entry->criteria ()) == 0)) + { + // Inform the caller that the + // Event_Comm::Notification_Receiver * is already being + // used. + + errno = EADDRINUSE; + ACE_ERROR ((LM_ERROR, + "duplicate entry for receiver %s with criteria \"%s\"", + receiver_ref->_marker (), filtering_criteria)); + // Raise exception here??? + return; + } + } + + // If we get this far then we didn't find a duplicate, so add the + // new entry! + Notification_Receiver_Entry *nr_entry = + new Notification_Receiver_Entry (receiver_ref, filtering_criteria); + + if (nr_entry == 0) + { + errno = ENOMEM; + ACE_ERROR ((LM_ERROR, "%p\n", "new failed")); + // Raise exception here... + } + // Try to add new to the map. + else if (this->map_.bind (key, nr_entry) == -1) + { + // Prevent memory leaks. + delete nr_entry; + // Raise exception here... + ACE_ERROR ((LM_ERROR, "%p\n", "bind failed")); + } +} + +// Remove a receiver from the table. + +void +Notifier_i::unsubscribe (Event_Comm::Notification_Receiver *receiver_ref, + const char *filtering_criteria, + CORBA::Environment &IT_env) +{ + ACE_DEBUG ((LM_DEBUG, "in Notifier_i::unsubscribe for %s\n", + receiver_ref->_marker ())); + Notification_Receiver_Entry *nr_entry = 0; + ACE_SString key; + MAP_ITERATOR mi (this->map_); + int found = 0; + + // Don't make a copy since we are deleting... + key.rep ((char *) receiver_ref->_marker ()); + + // Locate and free up resources. @@ + // Note, we don't properly handle deallocation of KEYS! + + for (MAP_ENTRY *me = 0; mi.next (me) != 0; mi.advance ()) + { + if (key == me->ext_id_ + && (ACE_OS::strcmp (filtering_criteria, "") == 0 + || ACE_OS::strcmp (filtering_criteria, nr_entry->criteria ()) == 0)) + { + ACE_DEBUG ((LM_DEBUG, "removed entry %s with criteria \"%s\"\n", + receiver_ref->_marker (), filtering_criteria)); + found = 1; + // @@ This is a hack, we need a better approach! + if (this->map_.unbind (key, nr_entry) == -1) + ACE_ERROR ((LM_ERROR, "unbind failed for %s\n", + receiver_ref->_marker ())); + else + delete nr_entry; + } + } + + if (found == 0) + ACE_ERROR ((LM_ERROR, "entry %s with criteria \"%s\" not found\n", + receiver_ref->_marker (), filtering_criteria)); +} + +// Disconnect all the receivers, giving them the . + +void +Notifier_i::send_disconnect (const char *reason, + CORBA::Environment &IT_env) +{ + ACE_DEBUG ((LM_DEBUG, "in Notifier_i::send_disconnect = %s\n", reason)); + + MAP_ITERATOR mi (this->map_); + int count = 0; + + // Notify all the receivers, taking into account the filtering criteria. + + for (MAP_ENTRY *me = 0; mi.next (me) != 0; mi.advance ()) + { + Event_Comm::Notification_Receiver *receiver_ref = me->int_id_->receiver (); + ACE_ASSERT (receiver_ref->_marker () != 0); + ACE_DEBUG ((LM_DEBUG, "disconnecting client %s\n", receiver_ref->_marker ())); + TRY { + receiver_ref->disconnect (reason, IT_X); + } + CATCHANY { + cerr << "Unexpected exception " << IT_X << endl; + } + ENDTRY; + delete me->int_id_; + delete me->ext_id_.rep (); + count++; + } + + this->map_.close (); + if (count == 1) + ACE_DEBUG ((LM_DEBUG, "there was 1 receiver\n")); + else + ACE_DEBUG ((LM_DEBUG, "there were %d receivers\n", count)); +} + +// Notify all receivers whose filtering criteria match the event. + +void +Notifier_i::send_notification (const Event_Comm::Notification ¬ification, + CORBA::Environment &IT_env) +{ + ACE_DEBUG ((LM_DEBUG, "in Notifier_i::send_notification = %s\n", + notification.tag_)); + MAP_ITERATOR mi (this->map_); + int count = 0; + + // Notify all the receivers. + // @@ Later on we need to consider the filtering_criteria! + + for (MAP_ENTRY *me = 0; mi.next (me) != 0; mi.advance ()) + { + Event_Comm::Notification_Receiver *receiver_ref = me->int_id_->receiver (); + ACE_ASSERT (receiver_ref->_marker () != 0); + const char *regexp = me->int_id_->regexp (); + const char *criteria = me->int_id_->criteria (); + ACE_ASSERT (regexp); + ACE_ASSERT (criteria); + + // Do a regular expression comparison to determine matching. + if (ACE_OS::strcmp ("", criteria) == 0 // Everything matches the wildcard. +// || ACE_OS::strcmp (notification.tag_, regexp) == 0) + || ACE_OS::step (notification.tag_, regexp) != 0) + { + ACE_DEBUG ((LM_DEBUG, "string %s matched regexp \"%s\" for client %s\n", + notification.tag_, me->int_id_->criteria (), + receiver_ref->_marker ())); + TRY { + receiver_ref->receive_notification (notification, IT_X); + } + CATCHANY { + cerr << "Unexpected exception " << IT_X << endl; + continue; + } + ENDTRY; + count++; + } + } + + if (count == 1) + ACE_DEBUG ((LM_DEBUG, "there was 1 receiver\n")); + else + ACE_DEBUG ((LM_DEBUG, "there were %d receivers\n", count)); +} + +#endif /* ACE_HAS_ORBIX */ diff --git a/apps/Orbix-Examples/Event_Comm/libsrc/Notifier_i.h b/apps/Orbix-Examples/Event_Comm/libsrc/Notifier_i.h new file mode 100644 index 00000000000..379f96b8097 --- /dev/null +++ b/apps/Orbix-Examples/Event_Comm/libsrc/Notifier_i.h @@ -0,0 +1,82 @@ +/* -*- C++ -*- */ +// @(#)Notifier_i.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// EventComm +// +// = FILENAME +// Notifier_i.h +// +// = DESCRIPTION +// Class interface for the implementation of the +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) +// +// ============================================================================ + +#if !defined (_Notifier_i_H) +#define _Notifier_i_H + +#include "ace/Map_Manager.h" +#include "ace/Synch.h" +#include "ace/SString.h" +#include "Event_Comm.hh" + +#if defined (ACE_HAS_ORBIX) + +// Forward reference. +class Notification_Receiver_Entry; + +class Notifier_i + // = TITLE + // Defines the implementation class for event . + // + // = DESCRIPTION +{ +public: + enum + { + DEFAULT_SIZE = 1024 // Default max number of Event_Comm::Notification_Receivers. + }; + + Notifier_i (size_t size_hint = Notifier_i::DEFAULT_SIZE); + // Initialize a Notifier_i object with the specified size hint. + + void send_disconnect (const char *reason, + CORBA::Environment &IT_env); + // Disconnect all the receivers, giving them the . + + void send_notification (const Event_Comm::Notification ¬ification, + CORBA::Environment &IT_env); + // Send the to all the consumers who + // have subscribed and who match the filtering criteria. + + void subscribe (Event_Comm::Notification_Receiver *notification_receiver, + const char *filtering_criteria, + CORBA::Environment &IT_env); + // Subscribe the to receive events that + // match applied by the . + + void unsubscribe (Event_Comm::Notification_Receiver *notification_receiver, + const char *filtering_criteria, + CORBA::Environment &IT_env); + // Unsubscribe the . + +private: + // The following implementation should be replaced + // by a standard container class from STL... + + typedef ACE_Map_Manager MAP_MANAGER; + typedef ACE_Map_Iterator MAP_ITERATOR; + typedef ACE_Map_Entry MAP_ENTRY; + + MAP_MANAGER map_; + // Table that maps a to a . +}; + +#endif /* ACE_HAS_ORBIX */ +#endif /* _Notifier_i_H */ diff --git a/apps/Orbix-Examples/Logger/Logger.cpp b/apps/Orbix-Examples/Logger/Logger.cpp new file mode 100644 index 00000000000..de05360f606 --- /dev/null +++ b/apps/Orbix-Examples/Logger/Logger.cpp @@ -0,0 +1,131 @@ +#include +// @(#)Logger.cpp 1.1 10/18/96 + +#include "Logger.h" + +Logger::~Logger (void) +{ + // Release and free up the object reference. + this->logref_->_release (); + + // Must use free since we used strdup(3C). + ACE_OS::free (ACE_MALLOC_T (this->server_)); +} + +// Constructor takes the name of the host where the server +// is located. If server == 0, then use the locator service. + +Logger::Logger (char *server, size_t max_message_size) + : server_ (server == 0 ? 0 : ACE_OS::strdup (server)), + ip_ (0), + pid_ (ACE_OS::getpid ()) +{ + struct utsname name; + +#if 0 + // Could also use sysinfo(2)... + + ACE_OS::sysinfo (SI_HOSTNAME, clienthost, MAXHOSTNAMELEN); +#endif + + ACE_OS::uname (&name); + hostent *hp = ACE_OS::gethostbyname (name.nodename); + + if (hp != 0) + memcpy ((void *) &this->ip_, (void *) hp->h_addr, hp->h_length); + + TRY { + // First bind to the logger object. + // argv[1] has the hostname (if any) of the target logger object; + // The default is the local host: + this->logref_ = profile_logger::_bind ("", this->server_, IT_X); + } CATCHANY { + // an error occurred while trying to bind to the logger object. + cerr << "Bind to object failed" << endl; + cerr << "Unexpected exception " << IT_X << endl; + } ENDTRY; + // Pre-assign certain values that don't change. + this->log_msg_.app_id = this->pid_; + this->log_msg_.host_addr = this->ip_; + this->log_msg_.msg_data._maximum = max_message_size; +} + +// Transmit the message to the logging server. + +int +Logger::log (logger::Log_Priority priority, char message[], int length) +{ + // The following values change with every logging operation. + this->log_msg_.type = priority; + this->log_msg_.time = ACE_OS::time (0); + this->log_msg_.msg_data._length = length; + this->log_msg_.msg_data._buffer = message; + + TRY { + // Try to log a message. + this->logref_->log (this->log_msg_, IT_X); + } CATCHANY { + // an error occurred while trying to read the height and width: + cerr << "call to log failed" << endl; + cerr << "Unexpected exception " << IT_X << endl; + return -1; + } ENDTRY; + // success. + return 0; +} + +// Get the value of verbose. + +int +Logger::verbose (void) +{ + int verbosity = 0; + + TRY { + verbosity = this->logref_->verbose (); + } CATCHANY { + return -1; + } ENDTRY; + return verbosity; +} + +// Set the value of verbose. + +int +Logger::verbose (int value) +{ + int verbosity = 0; + + TRY { + this->logref_->verbose (value); + } CATCHANY { + return -1; + } ENDTRY; + return 0; +} + +// Activate the timer. + +int +Logger::start_timer (void) +{ + TRY { + this->logref_->start_timer (); + } CATCHANY { + return -1; + } ENDTRY; + return 0; +} + +// Deactivate the timer and return the elapsed time. + +int +Logger::stop_timer (profile_logger::Elapsed_Time &et) +{ + TRY { + this->logref_->stop_timer (et); + } CATCHANY { + return -1; + } ENDTRY; + return 0; +} diff --git a/apps/Orbix-Examples/Logger/Logger.h b/apps/Orbix-Examples/Logger/Logger.h new file mode 100644 index 00000000000..fecae83cbf6 --- /dev/null +++ b/apps/Orbix-Examples/Logger/Logger.h @@ -0,0 +1,56 @@ +/* -*- C++ -*- */ +// @(#)Logger.h 1.1 10/18/96 + + +#if !defined (_LOGGER_H) +#define _LOGGER_H + +#include "ace/OS.h" +#include "logger.hh" + +class Logger + // = TITLE + // Wrapper class that uses CORBA object reference + // as the transport mechanism to simplify implementation. +{ +public: + Logger (char *server, size_t max_message_size); + // Constructor takes the name of the host where the server + // is located. If server == 0, then use the locator service. + + ~Logger (void); + // Destructor releases the object reference. + + int log (logger::Log_Priority prio, char msg[], int len); + // Log a of length with priority . + + int verbose (void); + // Report current level of verbosity. + + int verbose (int verbosity); + // Set the level of verbosity (0 == no verbose, > 0 == verbose). + + int start_timer (void); + // Activate the timer. + + int stop_timer (profile_logger::Elapsed_Time &et); + // Deactivate the timer and return the elapsed time. + +private: + profile_logger *logref_; + // CORBA object reference proxy. + + int pid_; + // Process ID. + + u_long ip_; + // IP address of self. + + logger::Log_Record log_msg_; + // Cache certain non-changing values to avoid recomputing them. + + char *server_; + // Name of server that we are bound to. +}; + +#endif /* _LOGGER_H */ diff --git a/apps/Orbix-Examples/Logger/Makefile b/apps/Orbix-Examples/Logger/Makefile new file mode 100644 index 00000000000..7193cee9945 --- /dev/null +++ b/apps/Orbix-Examples/Logger/Makefile @@ -0,0 +1,63 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Logger. +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +SVR_OBJS = loggerS.o logger_i.o server.o +CLT_OBJS = loggerC.o client.o Logger.o + +LDLIBS = + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Orbix related macros and target settings. +#---------------------------------------------------------------------------- + +ORBIX_BINDIR = $(ORBIX_ROOT)/bin +ORBIX_LIBDIR = $(ORBIX_ROOT)/lib +ORBIX_INCDIR = $(ORBIX_ROOT)/include + +CPPFLAGS += -DEXCEPTIONS -I$(ORBIX_INCDIR) -DWANT_ORBIX_FDS +LDFLAGS += -L$(ORBIX_LIBDIR) -R $(ORBIX_LIBDIR) + +IDLFLAGS = -s S.cpp -c C.cpp -B + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +all: client server + +client: $(addprefix $(VDIR),$(CLT_OBJS)) + $(LINK.cc) -o client $(addprefix $(VDIR),$(CLT_OBJS)) $(LDFLAGS) -lITsrvmt $(VLDLIBS) + +server: $(addprefix $(VDIR),$(SVR_OBJS)) + $(LINK.cc) -o server $(addprefix $(VDIR),$(SVR_OBJS)) $(LDFLAGS) -lITsrvmt $(VLDLIBS) + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + + + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/apps/Orbix-Examples/Logger/Orbix.hostgroups b/apps/Orbix-Examples/Logger/Orbix.hostgroups new file mode 100644 index 00000000000..013636e79c4 --- /dev/null +++ b/apps/Orbix-Examples/Logger/Orbix.hostgroups @@ -0,0 +1 @@ +all:tango diff --git a/apps/Orbix-Examples/Logger/Orbix.hosts b/apps/Orbix-Examples/Logger/Orbix.hosts new file mode 100644 index 00000000000..2e11d889bed --- /dev/null +++ b/apps/Orbix-Examples/Logger/Orbix.hosts @@ -0,0 +1,3 @@ +profile_logger:tango: +logger:tango: +IT_daemon:tango: diff --git a/apps/Orbix-Examples/Logger/README b/apps/Orbix-Examples/Logger/README new file mode 100644 index 00000000000..19b1db681f2 --- /dev/null +++ b/apps/Orbix-Examples/Logger/README @@ -0,0 +1,35 @@ +The directory contains the source code that implements an Orbix +version of the distributed Logger. Other ACE versions of this code +appear in the ./apps/Logger directory. It is interesting to compare +and contrast the alternative implementations. + +RUNNING: + +The client is run as follows: + +client -h host -m max_message_size + +The -h host is optional if the locator service is properly configured. +The -m specifies the maximum number of kilobytes to be sent per log. This +is useful when redirecting messages to stdin. + +TIMING: + +I recommend timing the log's by specifying a max_message_size and +redirecting /usr/dict/words. This will give you several trials from +which to take an average. + +CLIENT: + +While using the client and typing in messages manually, capital Q and V +must be used to quit and toggle verbose respectively. This allows you +to redirect /usr/dict/words without quiting at the q's!! + +SERVER: + +To turn off message reporting on the server side, do a + +setenv NO_MESSAGES + +in the enviroment where the server will be run. If this is done, the server +will only report that a message was received, but not display the messages. diff --git a/apps/Orbix-Examples/Logger/a1.tex b/apps/Orbix-Examples/Logger/a1.tex new file mode 100644 index 00000000000..5d10042e26e --- /dev/null +++ b/apps/Orbix-Examples/Logger/a1.tex @@ -0,0 +1,232 @@ +\documentstyle[times,11pt,moretext] {article} +\input macros +\input widen +\input psfig + +\begin{document} +\centerline{\Large Washington University} +\centerline{\Large Department of Computer Science} +\bigskip +\centerline{\large CS523: Distributed Operating Systems} +%\smallskip +%\centerline{\large Spring 1995} +\bigskip +\centerline{\large Programming Project} +% \centerline{\large Due Tuesday, January $31^{st}$, 1995} + +\section{Overview} + +In this assignment, you will implement a distributed logging service +shown in Figure~\ref{logenv}. Applications use this service to log +information (such as error notifications, debugging traces, and status +updates) in a distributed environment. In this service, CORBA remote +operations are used to send logging records to a central logging +server. The logging server outputs the logging records to a console, +a printer, a file, or a network management database, etc. + +\section{Design and Implementation Issues} + +The distributed logging service will be designed as a client/server +pair, containing the objects shown in Figure~\ref{simplog}. + +\subsection{CORBA IDL Specification} +The following CORBA IDL specification defines the logging interface: + +{ +\small +\ls{0.9} +\begin{verbatim} +// IDL schema definition +interface Logger +{ + // Types of logging messages. + enum Log_Priority { + LM_DEBUG, // Debugging messages + LM_WARNING, // Warning messages + LM_ERROR, // Errors + LM_EMERG // A panic condition + }; + + // Format of the logging record. + struct Log_Record { + Log_Priority type; // Type of logging message. + long time; // Time stamp at sender. + long app_id; // Process ID of sender. + long host_addr; // IP address of the sender. + sequence msg_data; // Sender-specific logging message. + }; + + // Transmit a Log_Record to the logging server. + oneway void log (in Log_Record log_rec); + + // Toggle verbose formatting + attribute char verbose; +}; +\end{verbatim}} + +\begin{figure} +\center{\ \psfig{figure=graphics/logsimp.eps,width=13cm}\ } +\vspace{-0.12in} +\caption{Distributed Logging Service} +\label{logenv} +\end{figure} + +You will use a CORBA IDL compiler to translate this specification into +client-side {\em stubs} and server-side {\em skeletons}. The client +application (which you must write) will use the stubs as a {\em proxy} +to access the logging services provided by the server. You must also +write the implementation of the server, which provides the logging +service. + +\subsection{Client and Server Functionality} +For the purposes of the assignment, you can make the client driver +program very simple. The client can read a line from its standard +input and send it to the logging server. The server can then format +and print the line on its standard output. For example, if you type +this line to the client: + +\begin{verbatim} +To boldly go where no one has gone before +\end{verbatim} + +\noindent Then the server should output something like this: + +\begin{verbatim} +Jan 24 14:50:28 1995@tango.cs.wustl.edu@18352@LM_DEBUG +::To boldly go where no one has gone before +\end{verbatim} + +\noindent Note that the server has printed out the logging message +timestamp, sender's hostname and process id, and the message priority, +followed by the logging message data. + +\begin{figure} +\center{\ \psfig{figure=graphics/simplog.eps,width=13cm}\ } +\vspace{-0.12in} +\caption{CORBA-based Logger Design} +\label{simplog} +\end{figure} + +Note that in order to pass the client's IP address (which is +represented as a 4-byte {\tt long}) in the logging message, you'll +need to learn about several other UNIX routines. On the client-side +you'll need to use {\tt uname(2)} and {\tt gethostbyname(2)} to +determine the IP address of the client host. On the server-side, +you'll need to use the {\tt gethostbyaddr(2)} function to convert the +4-byte IP host address into an ASCII version of the host name. I +recommend that you check the manual pages and read Richard Steven's +book ``UNIX Network Programming'' for more details on using these +functions. + +\subsection{Invoking the Client and Server} +Once the client and server components are written, compiled, and +linked together you will use the {\tt putit} command to register the +server with the Orbix daemon. You'll then need to start up a copy of +{\tt orbixd} (if there isn't already one running). {\tt orbixd} +serves as the Object Request Broker for the local endpoint. + +A client will bind to the {\tt Logger} interface via the generated +{\tt Logger::\_bind} method. There are two general ways to use this +method. The first is to explicitly pass in the name of the server +where {\tt orbixd} is running (your client should accept a +command-line argument that is the name of the server, {\em e.g.,} +``tango.cs.wustl.edu''). + +The second method is to use the CORBA locator service to get an object +reference for the logging service. You'll need to read the Orbix +documentation to learn how to set up a location file. This file will +enable you to omit the name of the server in the call to {\tt +Logger::\_bind}. By using the locator server, your clients can bind +to object's implicitly. Make sure that your solution will work for +either implicit or explicit service location. + +Once the client application has bound (either explicitly or +implicitly) to an object reference for the {\tt Logger}, it can log +messages by calling the {\tt log} method via the object reference +proxy. + +\subsection{Performance Measurement} + +An important part of developing distributed systems is understanding +the performance implications of different design approaches. In order +to measure the performance overhead of using CORBA to build the +Logger, you will write a simple extension to the original {\tt Logger} +interface, as follows: + +{ +\small +\ls{0.9} +\begin{verbatim} +// IDL schema definition +interface Profile_Logger + : Logger // Profile_Logger IS-A Logger +{ + // Stores the amount of time that has elapsed. + struct Elapsed_Time + { + double real_time; + double user_time; + double system_time; + }; + + // Activate the timer. + void start_timer (void); + + // Deactivate the timer and return the elapsed time. + void stop_timer (out Elapsed_Time et); +}; +\end{verbatim}} + +\noindent You will need to modify your client program so that it can +time a series of {\tt Logger::log} operations for various sizes of +logging messages. This will help us understand the performance +overhead of CORBA. + +The main benchmarking should take place within a loop in your client +program. Basically, your client call {\tt +Profile\_Logger::start\_timer} just before sending the first of the +logging messages. After a suitable number of iterations (defined on +the command-line), you client will call {\tt +Profile\_Logger::stop\_timer} to determine and report the elapsed time +to the user. You should print out the ``real'' time, as well as the +``system $+$ user'' times. Make sure that you print out the +throughput in terms of megabits/sec (rather than bytes/sec or +kbytes/sec). Be sure to include the fixed-sized {\tt Log\_Record} +object, as well as the variable-sized {\tt msg\_data} portion in your +computations. + +The number of iterations and the size of the messages sent by the +client should be parameterizable on the command-line. Make sure that +your timing tests are run between processes on two different machines +(rather than processes on the same machine). If possible, try to run +the client and server processes on two machines on the same subnet. + +When you are finished with your timing test, you should explain the +timing results and indicate trends that you observed. + +\section{Learning and Using CORBA} + +To help you learn how CORBA works, I will be making copies of the +Orbix programmer's manual available for a small reproduction fee. +This manual explains how to program in CORBA. I will announce in +class where this will be available. + +We will be using IONA's Orbix CORBA Object Request Broker (ORB) +implementation. The libraries, executables, CORBA IDL compiler, and +example demo applications are located in {\tt +/project/adaptive/Orbix}. Please note that this is an automounted +directory, so you will need to {\tt cd} directly to it in order to see +the contents. To configure Orbix for your environment, copy the {\tt +/project/adaptive/Orbix/Orbix.cfg} file to your account. You'll need +to set the environment variable {\tt IT\_CONFIG\_PATH} to the complete +path where this file is located. + +\section{Concluding Remarks} +In office hours and in class, we will discuss how to use C++ and CORBA +in order to develop your solutions. Note that this assignment will +teach you many skills required to become adept at network programming. +However, it also will require a great deal of thought and planning. +Please make sure you start early, come to office hours, and ask lots +of questions. + +\end{document} diff --git a/apps/Orbix-Examples/Logger/client.cpp b/apps/Orbix-Examples/Logger/client.cpp new file mode 100644 index 00000000000..aea23379488 --- /dev/null +++ b/apps/Orbix-Examples/Logger/client.cpp @@ -0,0 +1,142 @@ +// A client for the distributed logger example. This program reads +// @(#)client.cpp 1.1 10/18/96 + +// from either stdin or from a redirected file and sends all the +// contents to the logging server. It also computes how long it takes +// to send this stuff. + +#include "ace/Log_Msg.h" +#include "Logger.h" + +// maximum message size +static size_t max_message_size = BUFSIZ; + +// Default behavior is to use the locator service. +static char *hostname = 0; + +// Should we prompt the user? +static int user_prompt; + +static void +parse_args (int argc, char *argv[]) +{ + extern char *optarg; + extern int optind; + int c; + + ACE_LOG_MSG->open (argv[0]); + + // If a file has been redirected, don't activate user prompts + if (ACE_OS::isatty (0)) + user_prompt = 1; + else + user_prompt = 0; + + while ((c = ACE_OS::getopt (argc, argv, "m:h:")) != -1) + switch (c) + { + case 'm': + max_message_size = ACE_OS::atoi (optarg) * BUFSIZ; + break; + case 'h': + hostname = optarg; + break; + default: + ACE_ERROR ((LM_ERROR, "%n: -h host -m max_message_size (in kbytes)\n%a", 1)); + /* NOTREACHED */ + } +} + +// Enable/disable verbose logging. + +static int +toggle_verbose (Logger &logger) +{ + int verbose_value; + + verbose_value = logger.verbose (); + logger.verbose (!verbose_value); + return 0; +} + +// Transmit messages to the server. + +int +transmit (Logger &logger, char buf[], ACE_HANDLE handle = 0) +{ + if (user_prompt) + cout << "\nEnter message ('Q':quit,'V':toggle verbose):\n" << flush; + + ssize_t nbytes = ACE_OS::read (handle, buf, max_message_size); + + if (nbytes <= 0) + return nbytes; // End of file or error. + buf[nbytes] = '\0'; + + if (user_prompt) + { + if (buf[0] == 'Q' || buf[0] == 'q') + return 0; + // toggle verbose? + else if (buf[0] == 'V' || buf[0] == 'v') + toggle_verbose (logger); + } + + // send the message to the logger + if (logger.log (logger::LM_DEBUG, buf, nbytes) == -1) + return -1; + else + return nbytes; +} + +// Print the results of the tests. + +void +report_results (profile_logger::Elapsed_Time &et, size_t total_bytes) +{ + ACE_DEBUG ((LM_DEBUG, + "real time = %8.2f\n" + "user time = %8.2f\n" + "sys time = %8.2f\n" + "mbits sec = %8.2f\n", + et.real_time, et.user_time, et.system_time, + (total_bytes / et.real_time) * 8.0 / 1024.0 / 1024.0)); +} + +int +main (int argc, char **argv) +{ + parse_args (argc,argv); + + // Pointer to the logger object that will be used. + Logger logger (hostname, max_message_size); + char *buf = new char [max_message_size]; + size_t total_bytes = 0; + size_t nbytes = 0; + + logger.start_timer (); + + // Transmit logging records until user quits. + + for (int done = 0; done == 0;) + switch (nbytes = transmit (logger, buf)) + { + case -1: + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "transmit"), -1); + /* NOTREACHED */ + case 0: + done = 1; + break; + default: + total_bytes += nbytes; + break; + } + + profile_logger::Elapsed_Time et; + + if (logger.stop_timer (et) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "stop timer"), -1); + + report_results (et, total_bytes); + return 0; +} diff --git a/apps/Orbix-Examples/Logger/logger.hh b/apps/Orbix-Examples/Logger/logger.hh new file mode 100644 index 00000000000..0d0eeeca2f0 --- /dev/null +++ b/apps/Orbix-Examples/Logger/logger.hh @@ -0,0 +1,434 @@ + +#ifndef logger_hh +#define logger_hh + +#include + +#include + + +#ifndef _IDL_SEQUENCE_char_defined +#define _IDL_SEQUENCE_char_defined + +struct IONANC__IDL_SEQUENCE_char; +struct _IDL_SEQUENCE_char { + unsigned long _maximum; + unsigned long _length; + char *_buffer; + + operator IONANC__IDL_SEQUENCE_char(); + operator const IONANC__IDL_SEQUENCE_char() const; + _IDL_SEQUENCE_char& operator= (const IONANC__IDL_SEQUENCE_char&); + + _IDL_SEQUENCE_char& operator= (const _IDL_SEQUENCE_char&); + _IDL_SEQUENCE_char (const _IDL_SEQUENCE_char&); + + _IDL_SEQUENCE_char (unsigned long IT_size = 0); + + ~_IDL_SEQUENCE_char () { if (_buffer) delete [] _buffer; } + + char& operator [] (unsigned long IT_i) const {return _buffer[IT_i]; } + + void encodeOp (CORBA::Request &IT_r) const; + void decodeOp (CORBA::Request &IT_r); + void decodeInOutOp (CORBA::Request &IT_r); +}; + +struct IONANC__IDL_SEQUENCE_char { + unsigned long _maximum; + unsigned long _length; + char *_buffer; + + char& operator [] (unsigned long IT_i) const; + + operator _IDL_SEQUENCE_char (); + + operator const _IDL_SEQUENCE_char () const; + +}; + + + +#endif + + +#ifndef _logger_defined +#define _logger_defined +class logger_dispatch : public virtual CORBA::PPTR { +public: + + logger_dispatch (void *IT_p, CORBA::Object* IT_o, const char *IT_m, + CORBA::LoaderClass *IT_l, char *IT_i, void* IT_im) + : CORBA::PPTR (IT_p,IT_o,IT_m,IT_l,IT_i,IT_im) {} + + + logger_dispatch (char *IT_OR, void *IT_p, CORBA::Object *IT_o) + : CORBA::PPTR (IT_OR,IT_p,IT_o) {} + + + logger_dispatch () {} + + logger_dispatch (void *IT_p, CORBA::Object *IT_o, const char *IT_m, + char *IT_i, CORBA::Object* IT_ob, void* IT_im) + : CORBA::PPTR (IT_p,IT_o,IT_m,IT_i,IT_ob,IT_im) {} + + + virtual unsigned char dispatch (CORBA::Request &IT_r, + unsigned char IT_isTarget, void* IT_pp=NULL); + + +}; + +class logger; + + +#ifndef loggerForwH +#define loggerForwH +CORBA::ObjectRef logger_getBase (void *); +void logger_release (void *, CORBA::Environment &IT_env=CORBA::default_environment); +logger* logger_duplicate (void *, CORBA::Environment &IT_env=CORBA::default_environment); +#endif +#define logger_IMPL "logger" + + +class logger; +#define logger_IR "logger" +#define logger_IMPL "logger" + +typedef logger* loggerRef; +typedef logger* logger_ptr; +class logger: public virtual CORBA::Object { +public: + logger (char *IT_OR); + logger () : CORBA::Object (1) {} + logger* _duplicate( + CORBA::Environment &IT_env=CORBA::default_environment) { + CORBA::Object::_duplicate (IT_env); return this; } + static logger* _bind (const char* IT_markerServer, const char* host, + const CORBA::Context &IT_c, + CORBA::Environment &IT_env=CORBA::default_environment); + static logger* _bind (CORBA::Environment &IT_env); + static logger* _bind (const char* IT_markerServer=NULL, const char* host=NULL, + CORBA::Environment &IT_env=CORBA::default_environment); + static logger* _narrow (CORBA::Object* , CORBA::Environment &IT_env=CORBA::default_environment); +enum Log_Priority {LM_MESSAGE,LM_DEBUG,LM_WARNING,LM_ERROR,LM_EMERG}; + +#ifndef logger_Log_Record_defined +#define logger_Log_Record_defined + +struct IONANC_Log_Record; +struct Log_Record { + logger::Log_Priority type; + long time; + long app_id; + long host_addr; + _IDL_SEQUENCE_char msg_data; + + void encodeOp (CORBA::Request &IT_r) const; + void decodeOp (CORBA::Request &IT_r); + void decodeInOutOp (CORBA::Request &IT_r); + Log_Record(const Log_Record &); + Log_Record(); + operator logger::IONANC_Log_Record(); + operator const logger::IONANC_Log_Record() const; + Log_Record& operator= (const IONANC_Log_Record&); + ~Log_Record(); + Log_Record& operator= (const Log_Record&); +}; + +struct IONANC_Log_Record { + logger::Log_Priority type; + long time; + long app_id; + long host_addr; + IONANC__IDL_SEQUENCE_char msg_data; + operator logger::Log_Record (); + operator const logger::Log_Record () const; + }; + + +#endif + + virtual void log (const logger::Log_Record& log_rec, CORBA::Environment &IT_env=CORBA::default_environment); + virtual void verbose (char verbose, CORBA::Environment &IT_env=CORBA::default_environment); + virtual char verbose (CORBA::Environment &IT_env=CORBA::default_environment); +}; + + +#define TIE_logger(X) logger##X + +#define DEF_TIE_logger(X) \ + class logger##X : public virtual logger { \ + X* m_obj; \ + public: \ + \ + logger##X (X *objp, const char* m="", CORBA::LoaderClass *l=nil)\ + : logger(), CORBA::Object (), m_obj(objp) { \ + m_pptr = new logger_dispatch \ + (( logger*)this,(CORBA::Object*)this,m,l,logger_IR,m_obj); \ + } \ + logger##X (CORBA::Object *IT_p, const char* IT_m="", void *IT_q=nil)\ + : logger(), CORBA::Object () { \ + m_pptr = new logger_dispatch \ + (( logger*)this,(CORBA::Object*)this,IT_m,logger_IR,IT_p,IT_q); \ + m_obj = (X*)(m_pptr->getImplObj ()); \ + } \ + \ + virtual ~logger##X () { \ + if (_okToDeleteImpl ()) delete m_obj; } \ + \ + virtual void* _deref () { \ + return m_obj; } \ + \ + virtual void log (const logger::Log_Record& log_rec, CORBA::Environment &IT_env) {\ +m_obj->log ( log_rec,IT_env);\ +}\ + \ +virtual void verbose (char verbose, CORBA::Environment &IT_env) {\ + m_obj->verbose(verbose,IT_env); }\ + \ +virtual char verbose (CORBA::Environment &IT_env) {\ +return m_obj->verbose(IT_env); }\ + \ + }; + + +#define QUALS_logger \ + virtual void log (const logger::Log_Record& log_rec, CORBA::Environment &IT_env) {\ +m_obj->log ( log_rec,IT_env);\ +}\ + \ +virtual void verbose (char verbose, CORBA::Environment &IT_env) {\ + m_obj->verbose(verbose,IT_env); }\ + \ +virtual char verbose (CORBA::Environment &IT_env) {\ +return m_obj->verbose(IT_env); }\ + + + + +class loggerProxyFactoryClass : public virtual CORBA::ObjectFactoryClass { +public: + loggerProxyFactoryClass (unsigned char IT_p=0) + : CORBA::ProxyFactory (logger_IR, IT_p) {} + + virtual void* New (char *IT_OR, CORBA::Environment&); + + virtual void* New2 (); + + virtual void* IT_castUp (void *IT_p, char* IT_s); + + virtual CORBA::PPTR* pptr (void *IT_p); + + virtual void baseInterfaces (_IDL_SEQUENCE_string&); + + +}; + +extern loggerProxyFactoryClass loggerProxyFactory; + + + +class loggerBOAImpl : public virtual logger { +public: + loggerBOAImpl (const char *m="", CORBA::LoaderClass *l=NULL) { + if (CORBA::PPTR::isOK (m_pptr, logger_IR)) + m_pptr = new logger_dispatch ( (logger*)this, + (CORBA::Object*)this, m, l, logger_IR, this); +} + + virtual void log (const logger::Log_Record& log_rec, CORBA::Environment &IT_env=CORBA::default_environment) =0; + virtual void verbose (char verbose, CORBA::Environment &IT_env=CORBA::default_environment)=0; + virtual char verbose (CORBA::Environment &IT_env=CORBA::default_environment)=0; +}; + + +#endif + + +#ifndef _profile_logger_defined +#define _profile_logger_defined +class profile_logger_dispatch : public virtual logger_dispatch { +public: + + profile_logger_dispatch (void *IT_p, CORBA::Object* IT_o, const char *IT_m, + CORBA::LoaderClass *IT_l, char *IT_i, void* IT_im) + : CORBA::PPTR (IT_p,IT_o,IT_m,IT_l,IT_i,IT_im) {} + + + profile_logger_dispatch (char *IT_OR, void *IT_p, CORBA::Object *IT_o) + : CORBA::PPTR (IT_OR,IT_p,IT_o) {} + + + profile_logger_dispatch () {} + + profile_logger_dispatch (void *IT_p, CORBA::Object *IT_o, const char *IT_m, + char *IT_i, CORBA::Object* IT_ob, void* IT_im) + : CORBA::PPTR (IT_p,IT_o,IT_m,IT_i,IT_ob,IT_im) {} + + + virtual unsigned char dispatch (CORBA::Request &IT_r, + unsigned char IT_isTarget, void* IT_pp=NULL); + + +}; + +class profile_logger; + + +#ifndef profile_loggerForwH +#define profile_loggerForwH +CORBA::ObjectRef profile_logger_getBase (void *); +void profile_logger_release (void *, CORBA::Environment &IT_env=CORBA::default_environment); +profile_logger* profile_logger_duplicate (void *, CORBA::Environment &IT_env=CORBA::default_environment); +#endif +#define profile_logger_IMPL "profile_logger" + + +class profile_logger; +#define profile_logger_IR "profile_logger" +#define profile_logger_IMPL "profile_logger" + +typedef profile_logger* profile_loggerRef; +typedef profile_logger* profile_logger_ptr; +class profile_logger: public virtual logger { +public: + profile_logger (char *IT_OR); + profile_logger () : CORBA::Object (1) {} + profile_logger* _duplicate( + CORBA::Environment &IT_env=CORBA::default_environment) { + CORBA::Object::_duplicate (IT_env); return this; } + static profile_logger* _bind (const char* IT_markerServer, const char* host, + const CORBA::Context &IT_c, + CORBA::Environment &IT_env=CORBA::default_environment); + static profile_logger* _bind (CORBA::Environment &IT_env); + static profile_logger* _bind (const char* IT_markerServer=NULL, const char* host=NULL, + CORBA::Environment &IT_env=CORBA::default_environment); + static profile_logger* _narrow (CORBA::Object* , CORBA::Environment &IT_env=CORBA::default_environment); + +#ifndef profile_logger_Elapsed_Time_defined +#define profile_logger_Elapsed_Time_defined + +struct Elapsed_Time { + double real_time; + double user_time; + double system_time; + + void encodeOp (CORBA::Request &IT_r) const; + void decodeOp (CORBA::Request &IT_r); + void decodeInOutOp (CORBA::Request &IT_r); +}; + + +#endif + + virtual void start_timer (CORBA::Environment &IT_env=CORBA::default_environment); + virtual void stop_timer (profile_logger::Elapsed_Time& et, CORBA::Environment &IT_env=CORBA::default_environment); +}; + + +#define TIE_profile_logger(X) profile_logger##X + +#define DEF_TIE_profile_logger(X) \ + class profile_logger##X : public virtual profile_logger { \ + X* m_obj; \ + public: \ + \ + profile_logger##X (X *objp, const char* m="", CORBA::LoaderClass *l=nil)\ + : profile_logger(), CORBA::Object (), m_obj(objp) { \ + m_pptr = new profile_logger_dispatch \ + (( profile_logger*)this,(CORBA::Object*)this,m,l,profile_logger_IR,m_obj); \ + } \ + profile_logger##X (CORBA::Object *IT_p, const char* IT_m="", void *IT_q=nil)\ + : profile_logger(), CORBA::Object () { \ + m_pptr = new profile_logger_dispatch \ + (( profile_logger*)this,(CORBA::Object*)this,IT_m,profile_logger_IR,IT_p,IT_q); \ + m_obj = (X*)(m_pptr->getImplObj ()); \ + } \ + \ + virtual ~profile_logger##X () { \ + if (_okToDeleteImpl ()) delete m_obj; } \ + \ + virtual void* _deref () { \ + return m_obj; } \ + \ + virtual void log (const logger::Log_Record& log_rec, CORBA::Environment &IT_env) {\ +m_obj->log ( log_rec,IT_env);\ +}\ + \ +virtual void verbose (char verbose, CORBA::Environment &IT_env) {\ + m_obj->verbose(verbose,IT_env); }\ + \ +virtual char verbose (CORBA::Environment &IT_env) {\ +return m_obj->verbose(IT_env); }\ + virtual void start_timer (CORBA::Environment &IT_env) {\ +m_obj->start_timer (IT_env);\ +}\ + \ + virtual void stop_timer (profile_logger::Elapsed_Time& et, CORBA::Environment &IT_env) {\ +m_obj->stop_timer ( et,IT_env);\ +}\ + \ + }; + + +#define QUALS_profile_logger \ + virtual void log (const logger::Log_Record& log_rec, CORBA::Environment &IT_env) {\ +m_obj->log ( log_rec,IT_env);\ +}\ + \ +virtual void verbose (char verbose, CORBA::Environment &IT_env) {\ + m_obj->verbose(verbose,IT_env); }\ + \ +virtual char verbose (CORBA::Environment &IT_env) {\ +return m_obj->verbose(IT_env); }\ + virtual void start_timer (CORBA::Environment &IT_env) {\ +m_obj->start_timer (IT_env);\ +}\ + \ + virtual void stop_timer (profile_logger::Elapsed_Time& et, CORBA::Environment &IT_env) {\ +m_obj->stop_timer ( et,IT_env);\ +}\ + + + + +class profile_loggerProxyFactoryClass : public virtual loggerProxyFactoryClass { +public: + profile_loggerProxyFactoryClass (unsigned char IT_p=0) + : CORBA::ProxyFactory (profile_logger_IR, IT_p) {} + + virtual void* New (char *IT_OR, CORBA::Environment&); + + virtual void* New2 (); + + virtual void* IT_castUp (void *IT_p, char* IT_s); + + virtual CORBA::PPTR* pptr (void *IT_p); + + virtual void baseInterfaces (_IDL_SEQUENCE_string&); + + +}; + +extern profile_loggerProxyFactoryClass profile_loggerProxyFactory; + + + +class profile_loggerBOAImpl : public virtual profile_logger { +public: + profile_loggerBOAImpl (const char *m="", CORBA::LoaderClass *l=NULL) { + if (CORBA::PPTR::isOK (m_pptr, profile_logger_IR)) + m_pptr = new profile_logger_dispatch ( (profile_logger*)this, + (CORBA::Object*)this, m, l, profile_logger_IR, this); +} + + virtual void start_timer (CORBA::Environment &IT_env=CORBA::default_environment) =0; + virtual void stop_timer (profile_logger::Elapsed_Time& et, CORBA::Environment &IT_env=CORBA::default_environment) =0; +}; + + +#endif + + +#endif diff --git a/apps/Orbix-Examples/Logger/logger.idl b/apps/Orbix-Examples/Logger/logger.idl new file mode 100644 index 00000000000..0fe673a84b9 --- /dev/null +++ b/apps/Orbix-Examples/Logger/logger.idl @@ -0,0 +1,56 @@ +/* -*- C++ -*- */ +// @(#)logger.idl 1.1 10/18/96 + +// logger.idl + +interface logger +// = TITLE +// This is the CORBA interface for the logger class. +{ + // = Types of logging messages. + enum Log_Priority + { + LM_MESSAGE, + LM_DEBUG, + LM_WARNING, + LM_ERROR, + LM_EMERG + }; + + // = Format of the logging record. + struct Log_Record + { + Log_Priority type; // Type of logging message. + long time; // Time stamp at sender. + long app_id; // Process ID of sender. + long host_addr; // IP address of the sender. + sequence msg_data; // Sender-specific logging message. + }; + + oneway void log (in Log_Record log_rec); + // Transmit a Log_Record to the logging server. + + attribute char verbose; + // Toggle verbose formatting +}; + +interface profile_logger + : logger // Profile_Logger IS-A Logger +// = TITLE +// IDL Profile Logger definition that is used +// to compute statistics about the logging. +{ + // = Stores the amount of time that has elapsed. + struct Elapsed_Time + { + double real_time; + double user_time; + double system_time; + }; + + void start_timer (); + // Activate the timer. + + void stop_timer (out Elapsed_Time et); + // Deactivate the timer and return the elapsed time. +}; diff --git a/apps/Orbix-Examples/Logger/loggerS.cpp b/apps/Orbix-Examples/Logger/loggerS.cpp new file mode 100644 index 00000000000..b1210683886 --- /dev/null +++ b/apps/Orbix-Examples/Logger/loggerS.cpp @@ -0,0 +1,141 @@ + +// @(#)loggerS.cpp 1.1 10/18/96 + +#include "logger.hh" + + +#define logger_dispatch_impl + +unsigned char logger_dispatch::dispatch (CORBA::Request &IT_r, + unsigned char IT_isTarget, void *IT_pp) { + if (!IT_pp) + IT_pp = m_obj; + const char *IT_s = IT_r.getOperation (); + if (!strcmp(IT_s,"log")) { + CORBA::Environment IT_env (IT_r); + CORBA::Filter* IT_f = CORBA::Orbix.getFilter (); + if (!IT_r.tcAssert ("\ +Ro~log~+log_rec{R~logger::Log_Record~type{E~logger::Log_Priority~LM_MESSAGE,LM_DEBUG,LM_WARNING,LM_ERROR,LM_EMERG},time{l},app_id{l},host_addr{l},msg_data{S{c},0}},>{v},O{}\ +")) + return 1; + logger::Log_Record log_rec; + log_rec.decodeOp (IT_r); + + if (IT_f && !IT_r.isException (IT_env)) + IT_f->inRequestPostM (IT_r, IT_env); + if (!IT_r.isException (IT_env)) + ((logger*)IT_pp)->log ( log_rec, IT_env); + + IT_r.replyNoResults (CORBA::Flags(CORBA::INV_NO_RESPONSE),IT_env); + return 1; + } + + else if (!strcmp (IT_s,"_get_verbose")) { + char verbose; + CORBA::Environment IT_env (IT_r); + CORBA::Filter* IT_f = CORBA::Orbix.getFilter (); + if (!IT_r.tcAssert ("\ +Ro~_get_verbose~>{c},N{}\ +")) + return 1; + if (IT_f) + IT_f->inRequestPostM (IT_r, IT_env); + if (!IT_r.isException (IT_env)) + verbose = ((logger*)IT_pp)->verbose(IT_env); + + if (!IT_r.isException (IT_env)) { + if (!IT_r.convertToReply ("\ +c\ +", IT_env)) return 1; + IT_r << verbose; + } + else IT_r.makeSystemException (IT_env); + + return 1; + } + else if (!strcmp (IT_s,"_set_verbose")) { + CORBA::Environment IT_env (IT_r); + CORBA::Filter* IT_f = CORBA::Orbix.getFilter (); + if (IT_r.tcAssert ("\ +Ro~_set_verbose~+{c},>{v},N{}\ +")) { + char verbose; + IT_r >> verbose; + if (IT_f && !IT_r.isException (IT_env)) + IT_f->inRequestPostM (IT_r, IT_env); + if (!IT_r.isException (IT_env)) + ((logger*)IT_pp)->verbose(verbose, IT_env); + } + IT_r.replyNoResults (IT_env); + return 1; + } + + else if (IT_isTarget) + IT_r.makeRuntimeException2 (); + + return 0; +} + +#define profile_logger_dispatch_impl + +unsigned char profile_logger_dispatch::dispatch (CORBA::Request &IT_r, + unsigned char IT_isTarget, void *IT_pp) { + if (!IT_pp) + IT_pp = m_obj; + const char *IT_s = IT_r.getOperation (); + if (!strcmp(IT_s,"start_timer")) { + CORBA::Environment IT_env (IT_r); + CORBA::Filter* IT_f = CORBA::Orbix.getFilter (); + if (!IT_r.tcAssert ("\ +Ro~start_timer~>{v},N{}\ +")) + return 1; + + if (IT_f && !IT_r.isException (IT_env)) + IT_f->inRequestPostM (IT_r, IT_env); + if (!IT_r.isException (IT_env)) + ((profile_logger*)IT_pp)->start_timer (IT_env); + + IT_r.replyNoResults (IT_env); + return 1; + } + + else if (!strcmp(IT_s,"stop_timer")) { + CORBA::Environment IT_env (IT_r); + CORBA::Filter* IT_f = CORBA::Orbix.getFilter (); + if (!IT_r.tcAssert ("\ +Ro~stop_timer~-et{R~profile_logger::Elapsed_Time~real_time{d},user_time{d},system_time{d}},>{v},N{}\ +")) + return 1; + profile_logger::Elapsed_Time et; + + if (IT_f && !IT_r.isException (IT_env)) + IT_f->inRequestPostM (IT_r, IT_env); + if (!IT_r.isException (IT_env)) + ((profile_logger*)IT_pp)->stop_timer ( et, IT_env); + + + if (!IT_r.isException (IT_env)) { + if (!IT_r.convertToReply ("\ +v\ +", IT_env)) return 1; + et.encodeOp (IT_r); + } + + else IT_r.makeSystemException (IT_env); + return 1; + } + + else if (logger_dispatch::dispatch (IT_r, 0, + (logger*)((profile_logger*)IT_pp))) { + return 1; + } + + else if (IT_isTarget) + IT_r.makeRuntimeException2 (); + + return 0; +} + +#include "loggerC.cpp" + diff --git a/apps/Orbix-Examples/Logger/logger_i.cpp b/apps/Orbix-Examples/Logger/logger_i.cpp new file mode 100644 index 00000000000..cfd5a5b0d8b --- /dev/null +++ b/apps/Orbix-Examples/Logger/logger_i.cpp @@ -0,0 +1,120 @@ +// Implementation of the logger object. +// @(#)logger_i.cpp 1.1 10/18/96 + + +#include "ace/OS.h" +#include +#include "logger_i.h" + +// Select non-verbose logging by default. + +logger_i::logger_i (int verbose) + : verbose_value_ (verbose) +{ + if (ACE_OS::getenv ("NO_MESSAGES") == 0) + this->verbose_message_ = 1; + else + this->verbose_message_ = 0; +} + +// Implement the log method. + +void +logger_i::log (const logger::Log_Record &log_rec, CORBA::Environment &IT_env) +{ + if (this->verbose_value_) // If verbose mode is on + { + char *tm; + + // Convert time + if ((tm = ACE_OS::ctime (&log_rec.time)) == 0) + cerr << "ctime failed" << endl; + else + { + hostent *hp; + + /* 01234567890123456789012345 */ + /* Wed Oct 18 14:25:36 1989n0 */ + tm[24] = '@'; + cout << tm; + + // Get host name of client + + if ((hp = gethostbyaddr((char *) &log_rec.host_addr, + sizeof log_rec.host_addr, AF_INET)) == NULL) + { + cerr << "server: error in calling gethostbyaddr" << endl; + cerr << "h_errno = " << h_errno << endl; + return; + } + else // Output client hostname. + cout << hp->h_name << "@"; + + // Output PID of client + cout << log_rec.app_id << "@"; + + // Output priority + + switch (log_rec.type) + { + case logger::LM_DEBUG: + cout << "LM_DEBUG"; + break; + case logger::LM_WARNING: + cout << "LM_WARNING"; + break; + case logger::LM_ERROR: + cout << "LM_ERROR"; + break; + case logger::LM_EMERG: + cout << "LM_EMERG"; + break; + } + } + } + if (this->verbose_message_) + { + cout << "::"; + // Output message + cout.write (log_rec.msg_data._buffer, log_rec.msg_data._length) << flush; + } +} + +// Enable/disable verbosity. + +void +logger_i::verbose (char verbose, CORBA::Environment &IT_env) +{ + this->verbose_value_ = verbose; +} + +// Report current verbosity level. + +char +logger_i::verbose (CORBA::Environment &IT_env) +{ + return this->verbose_value_; +} + +// Profile_Logger_i + +void +profile_logger_i::start_timer (CORBA::Environment &IT_env) +{ + this->pt_.start (); +} + +void +profile_logger_i::stop_timer (profile_logger::Elapsed_Time& et, + CORBA::Environment &IT_env) +{ + this->pt_.stop (); + + ACE_Profile_Timer::ACE_Elapsed_Time e; + + this->pt_.elapsed_time (e); + + et.real_time = e.real_time; + et.user_time = e.user_time; + et.system_time = e.system_time; +} diff --git a/apps/Orbix-Examples/Logger/logger_i.h b/apps/Orbix-Examples/Logger/logger_i.h new file mode 100644 index 00000000000..65253527370 --- /dev/null +++ b/apps/Orbix-Examples/Logger/logger_i.h @@ -0,0 +1,75 @@ +/* -*- C++ -*- */ +// @(#)logger_i.h 1.1 10/18/96 + + +#include "ace/Profile_Timer.h" +#define EXCEPTIONS +#include "logger.hh" + +class logger_i +#if defined (USE_BOA_IMPL) + : virtual public loggerBOAImpl +#endif /* USE_BOA_IMPL */ + // = TITLE + // Implementation of the logger interface. + // + // = DESCRIPTION + // Uses either the BOAImpl or the DEF_TIE approach, + // depending on the #ifdef +{ +public: + logger_i (int verbose = 0); + // Select non-verbose logging by default. + + virtual void log (const logger::Log_Record &log_rec, CORBA::Environment &IT_env); + // Implement the log method. + + virtual void verbose (char verbose, CORBA::Environment &IT_env); + // Enable/disable verbosity. + + virtual char verbose (CORBA::Environment &IT_env); + // Report current verbosity level. + +private: + unsigned char verbose_value_; + // Indicate if we are using verbose logging or not. + + unsigned char verbose_message_; + // Indicate if we outputting the messages (turn off if you + // want to conduct timing tests that just measure throughput). +}; + +class profile_logger_i : +#if defined (USE_BOA_IMPL) + public virtual profile_loggerBOAImpl, + public virtual Logger_i +#else /* USE_TIE */ + public logger_i +#endif /* USE_BOA_IMPL */ + // = TITLE + // Implementation of the profiler logger interface. + // + // = DESCRIPTION + // Uses the BOAImpl approach. +{ +public: + virtual void start_timer (CORBA::Environment &env); + // Activate the timer. + + virtual void stop_timer (profile_logger::Elapsed_Time &et, + CORBA::Environment &env); + // Deactivate the timer and return the elapsed time. + +private: + ACE_Profile_Timer pt_; + // Object that keeps track of the user and system execution time. +}; + +#if !defined (USE_BOA_IMPL) +// Indicate that the C++ classes logger_i and profile_logger_i implement +// the IDL interface logger and profile_logger, respectively: + +DEF_TIE_logger (logger_i) +DEF_TIE_profile_logger (profile_logger_i) + +#endif /* USE_BOA_IMPL */ diff --git a/apps/Orbix-Examples/Logger/server.cpp b/apps/Orbix-Examples/Logger/server.cpp new file mode 100644 index 00000000000..c41aa474dcf --- /dev/null +++ b/apps/Orbix-Examples/Logger/server.cpp @@ -0,0 +1,40 @@ +// server.C +// @(#)server.cpp 1.1 10/18/96 + + +// The server for the logger example. +// This uses the TRY,CATCHANY,ENDTRY macros for error testing. + +// The executable file generated from this code should be registered +// (under the name 'logger') using the 'putit' command. + +#include +#include "logger_i.h" + +int +main (int, char *[]) +{ + // Tell the server not to hang up while clients are connected. + CORBA::Orbix.setNoHangup (1); + + // create a logger object - using the implementation class logger_i +#if defined (USE_BOA_IMPL) + profile_logger_i profile_logger; +#else + TIE_profile_logger (profile_logger_i) profile_logger (new profile_logger_i); +#endif /* USE_BOA_IMPL */ + + TRY { + // tell Orbix that we have completed the server's initialisation: + CORBA::Orbix.impl_is_ready (profile_logger_IMPL, IT_X); + } CATCHANY { + // an error occured calling impl_is_ready () - output the error. + cout << IT_X << endl; + } ENDTRY; + + // impl_is_ready() returns only when Orbix times-out an idle server + // (or an error occurs). + cerr << "server exiting" << endl; + + return 0; +} diff --git a/apps/Orbix-Examples/Makefile b/apps/Orbix-Examples/Makefile new file mode 100644 index 00000000000..723a4dce7c3 --- /dev/null +++ b/apps/Orbix-Examples/Makefile @@ -0,0 +1,25 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Orbix applications +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +INFO = README + +DIRS = Event_Comm \ + Logger + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + diff --git a/apps/README b/apps/README new file mode 100644 index 00000000000..348bf472216 --- /dev/null +++ b/apps/README @@ -0,0 +1,19 @@ +The subdirectories in this directory provide a number of complete +applications that utilize the ACE features. + + . Gateway -- Implements a connection-oriented application-level + gateway that uses source-based and destination-based routing + of messages between peers connected via TCP/IP networks. + + . Orbix-Examples -- Implements several applications that + integrate ACE and Orbix (which is IONA's implementation of + CORBA). + + . Synch-Benchmarks -- Implements a number of benchmarks + that test the performance of various synchronization + mechanisms. + + . TTCP -- Implements several variants of the TTCP benchmarking + test for TCP and UCP using C sockets, ACE C++ wrappers, and + several versions of CORBA (Orbix and ORBeline). + diff --git a/apps/gperf/COPYING b/apps/gperf/COPYING new file mode 100644 index 00000000000..9a170375811 --- /dev/null +++ b/apps/gperf/COPYING @@ -0,0 +1,249 @@ + + GNU GENERAL PUBLIC LICENSE + Version 1, February 1989 + + Copyright (C) 1989 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The license agreements of most software companies try to keep users +at the mercy of those companies. By contrast, our General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. The +General Public License applies to the Free Software Foundation's +software and to any other program whose authors commit to using it. +You can use it for your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Specifically, the General Public License is designed to make +sure that you have the freedom to give away or sell copies of free +software, that you receive source code or can get it if you want it, +that you can change the software or use pieces of it in new free +programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of a such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must tell them their rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any program or other work which +contains a notice placed by the copyright holder saying it may be +distributed under the terms of this General Public License. The +"Program", below, refers to any such program or work, and a "work based +on the Program" means either the Program or any work containing the +Program or a portion of it, either verbatim or with modifications. Each +licensee is addressed as "you". + + 1. You may copy and distribute verbatim copies of the Program's source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this +General Public License and to the absence of any warranty; and give any +other recipients of the Program a copy of this General Public License +along with the Program. You may charge a fee for the physical act of +transferring a copy. + + 2. You may modify your copy or copies of the Program or any portion of +it, and copy and distribute such modifications under the terms of Paragraph +1 above, provided that you also do the following: + + a) cause the modified files to carry prominent notices stating that + you changed the files and the date of any change; and + + b) cause the whole of any work that you distribute or publish, that + in whole or in part contains the Program or any part thereof, either + with or without modifications, to be licensed at no charge to all + third parties under the terms of this General Public License (except + that you may choose to grant warranty protection to some or all + third parties, at your option). + + c) If the modified program normally reads commands interactively when + run, you must cause it, when started running for such interactive use + in the simplest and most usual way, to print or display an + announcement including an appropriate copyright notice and a notice + that there is no warranty (or else, saying that you provide a + warranty) and that users may redistribute the program under these + conditions, and telling the user how to view a copy of this General + Public License. + + d) You may charge a fee for the physical act of transferring a + copy, and you may at your option offer warranty protection in + exchange for a fee. + +Mere aggregation of another independent work with the Program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other work under the scope of these terms. + + 3. You may copy and distribute the Program (or a portion or derivative of +it, under Paragraph 2) in object code or executable form under the terms of +Paragraphs 1 and 2 above provided that you also do one of the following: + + a) accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Paragraphs 1 and 2 above; or, + + b) accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal charge + for the cost of distribution) a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of + Paragraphs 1 and 2 above; or, + + c) accompany it with the information you received as to where the + corresponding source code may be obtained. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form alone.) + +Source code for a work means the preferred form of the work for making +modifications to it. For an executable file, complete source code means +all the source code for all modules it contains; but, as a special +exception, it need not include source code for modules which are standard +libraries that accompany the operating system on which the executable +file runs, or for standard header files or definitions files that +accompany that operating system. + + 4. You may not copy, modify, sublicense, distribute or transfer the +Program except as expressly provided under this General Public License. +Any attempt otherwise to copy, modify, sublicense, distribute or transfer +the Program is void, and will automatically terminate your rights to use +the Program under this License. However, parties who have received +copies, or rights to use copies, from you under this General Public +License will not have their licenses terminated so long as such parties +remain in full compliance. + + 5. By copying, distributing or modifying the Program (or any work based +on the Program) you indicate your acceptance of this license to do so, +and all its terms and conditions. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the original +licensor to copy, distribute or modify the Program subject to these +terms and conditions. You may not impose any further restrictions on the +recipients' exercise of the rights granted herein. + + 7. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of the license which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +the license, you may choose any version ever published by the Free Software +Foundation. + + 8. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to humanity, the best way to achieve this is to make it +free software which everyone can redistribute and change under these +terms. + + To do so, attach the following notices to the program. It is safest to +attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19xx name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the +appropriate parts of the General Public License. Of course, the +commands you use may be called something other than `show w' and `show +c'; they could even be mouse-clicks or menu items--whatever suits your +program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + program `Gnomovision' (a program to direct compilers to make passes + at assemblers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/apps/gperf/ChangeLog b/apps/gperf/ChangeLog new file mode 100644 index 00000000000..d0e86c82103 --- /dev/null +++ b/apps/gperf/ChangeLog @@ -0,0 +1,1335 @@ +Sun Apr 14 14:31:10 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu) + + * src: Changed things so that there's no longer any use of the + Read_Line and Std_Err code. All of this has been pushed into + the ACE components, which is where it belongs... + + * src: Changed things so that there's no longer any use of the + pointless inheritance in the code. This was a result of my not + understanding inheritance back in 1989... ;-) + + * Began to integrate GNU gperf into the ACE release. Started off + by bringing the standard GNU version up to date wrt to the + changes I made back in 1991! + +Tue Oct 10 16:37:28 1995 Mike Stump + + * src/new.cc: Since malloc/delete are not paired, we cannot call + free. + +Wed Jan 4 12:40:14 1995 Per Bothner + + * src/Makefile.in ($(TARGETPROG)): Link with $(LDFLAGS). + Patch from John Interrante . + +Sat Nov 5 19:12:48 1994 Jason Merrill (jason@phydeaux.cygnus.com) + + * src/Makefile.in (LIBS): Remove. + +Tue Oct 18 17:51:14 1994 Per Bothner + + * src/std-err.cc: Use stderror, instead of the non-standard + sys_nerr and sys_errlist. + +Sat Sep 17 22:02:13 1994 Per Bothner (bothner@kalessin.cygnus.com) + + * src/key-list.cc (output_hash_function): + Patch from William Bader . + +Fri Jul 15 09:38:11 1994 Per Bothner (bothner@cygnus.com) + + * src/std-err.cc: #include , and only declare + extern int errno if errno is not a macro. + +Mon May 30 17:29:34 1994 Per Bothner (bothner@kalessin.cygnus.com) + + * Makefile.in (src_all, install): Make sure to add '/' after + `pwd` in $rootme, as expected by FLAGS_TO_PASS. + +Wed May 11 00:47:22 1994 Jason Merrill (jason@deneb.cygnus.com) + + Make libg++ build with gcc -ansi -pedantic-errors + * src/options.h: Lose commas at end of enumerator lists. + +Sun Dec 5 19:16:40 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * src/hash-table.cc (Hash_Table::~Hash_Table): Don't pass an + argument to fprintf, since it's not expecting one. + +Fri Nov 26 19:03:18 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * src/list-node.cc: #undef index, for the sake of broken NeXT, + +Thu Nov 4 11:16:03 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * Makefile.in (install): Use INSTALL_DATA for gperf.1. + +Mon Oct 25 18:40:51 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * src/key-list.cc (Key_List::read_keys): Use POW macro + to increase hash table size to power of 2. + + * options.h (LARGE_STACK_ARRAYS): New flag. Defaults to zero. + * gen-perf.cc, key-list.cc, read-line.cc: + Only stack-allocate large arrays if LARGE_STACK_ARRAYS is set. + * main.cc (main): Only call setrlimit (RLIMIT_STACK, ...) + if LARGE_STACK_ARRAYS. + +Mon Oct 4 17:45:08 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * src/gen-perf.cc: Always use ANSI rand/srand instead of BSDisms. + +Wed Aug 18 12:19:53 1993 Per Bothner (bothner@kalessin.cygnus.com) + + * Makefile.in (src_all): Make less verbose output. + +Fri May 28 14:01:18 1993 Per Bothner (bothner@rtl.cygnus.com) + + * src/gen-perf.cc (Gen_Perf::change): Don't use gcc-specific + 2-operand conditional expression. + * src/key-list.cc (Key_List::output_lookup_array): + Don't use variable-size stack arrays, unless compiled by g++. + +Tue May 4 14:08:44 1993 Per Bothner (bothner@cygnus.com) + + Changes (mostly from Peter Schauer) to permit compilation + using cfront 3.0 and otherwise be ARM-conforming. + * src/key-list.h: class Key_List must use public derivation + of base class Std_Err (because Gen_Perf::operator() in gen-perf.cc + calls Std_Err::report_error). + * src/gen-perf.cc (Gen_Perf::affects_prev), src/hash-table.cc + (Hash_Table::operator()): Don't use gcc-specific 2-operand + conditional expression. + * src/iterator.cc (Iterator::operator()): Don't use gcc-specific + range construct in case label. + * key-list.cc (Key_List::output_lookup_array, Key_List::read_keys), + src/gen-perf.cc (Gen_Perf::operator(), src/read-line.cc + (Read_Line::readln_aux): If not gcc, don't allocate + variable-sized arrays on stack. + * src/new.cc (operator new): Argument type should be size_t. + * key-list.cc (Key_List::output_lookup_array, Key_List::read_keys), + new/cc (::operator new): Don't use non-standard >?= operator. + +Tue Apr 27 20:11:30 1993 Per Bothner (bothner@cygnus.com) + + * src/Makefile.in: Define TARGETPROG, and use it. + +Mon Apr 19 00:29:18 1993 Per Bothner (bothner@cygnus.com) + + * Makefile.in, configure.in: Re-vamped configure scheme. + * gperf.texinfo: Renamed to gperf.texi. + * src/bool-array.{h,cc}: ANSIfy bzero->memset. + +Sat Jan 30 20:21:28 1993 Brendan Kehoe (brendan@lisa.cygnus.com) + + * tests/Makefile.in (mostlyclean): Also delete aout, cout, m3out, + pout, and preout. + +Tue Dec 29 08:58:17 1992 Ian Lance Taylor (ian@cygnus.com) + + * Makefile.in: pass $(FLAGS_TO_PASS) to all calls to make. + (FLAGS_TO_PASS): added INSTALL, INSTALL_DATA, INSTALL_PROGRAM. + +Mon Dec 21 18:46:46 1992 Per Bothner (bothner@rtl.cygnus.com) + + * tests/expected.* renamed to *.exp to fit in 14 chars. + * tests/Makefile.in: Update accordingly. + Also rename output.* to *.out. + * src/Makefile.in (clean): Remove gperf program. + +Wed Dec 9 14:33:34 1992 Per Bothner (bothner@cygnus.com) + + * src/hash-table.cc, src/bool-array.h: ANSIfy bzero->memset. + +Thu Dec 3 19:34:12 1992 Per Bothner (bothner@cygnus.com) + + * Makefile.in (distclean, realclean): Don't delete + Makefile before recursing. + +Fri Nov 6 13:41:49 1992 Per Bothner (bothner@rtl.cygnus.com) + + * key-list.{h,cc}: Remove MAX_INT (and similar) constant + fields from Key_List class, and use INT_MAX (etc) from limits.h. + * key-list.{h,cc}, options.{h,cc}, vectors.h: Removed all + uses of initialized const fields, as they are non-standard + - and their use was easy to do away with. Mostly, just + made the constants static non-fields in the .cc file. + +Mon Nov 2 13:10:11 1992 Per Bothner (bothner@cygnus.com) + + * tests/Makefile.in: When generating cinset.c, don't pass -C, + since -C assumes an ANSI compiler. Add the -C flag (with -a) + when generating test.out.3 instead. + * tests/expected.out.3: Update accordingly. + +Wed Aug 12 11:47:54 1992 Per Bothner (bothner@cygnus.com) + + * Makefile.in: Factor out common flags into $(FLAGS_TO_PASS). + * Makefile.in: 'install-info' depends on gperf.info. + +Mon Aug 10 11:39:52 1992 Ian Lance Taylor (ian@dumbest.cygnus.com) + + * Makefile.in, src/Makefile.in: always create installation + directories. + +Mon Jul 20 15:33:21 1992 Mike Stump (mrs@cygnus.com) + + * src/new.cc (operator new): Add cast from void * to char *, + since it is not a standard conversion. + +Wed Jun 17 16:25:30 1992 Per Bothner (bothner@rtl.cygnus.com) + + * src/gen-perf.cc: #include <_G_config.h> for _G_SYSV. + * src/key-list.cc: alloca() hair. + * src/main.cc (main): Only call getrlimit if _G_HAVE_SYS_RESOURCE. + * Makefile,in, {src,test}/Makefile.in: Fix *clean rules. + +Fri May 29 13:21:13 1992 Per Bothner (bothner@rtl.cygnus.com) + + * src/gen-perf.cc: Replace USG -> _G_SYSV. + +Thu May 14 13:58:36 1992 Per Bothner (bothner@rtl.cygnus.com) + + * src/Makefile.in: Don't pass obsolete flag -DUNLIMIT_STACK. + * tests/Makefile.in (clean): Fix. + +Sat Mar 7 00:03:56 1992 K. Richard Pixley (rich@rtl.cygnus.com) + + * gperf.texinfo: added menu item hook. + +Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com) + + * Makefile.in, configure.in: removed traces of namesubdir, + -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced + copyrights to '92, changed some from Cygnus to FSF. + +Sun Jan 26 19:21:58 1992 Per Bothner (bothner at cygnus.com) + + * tests/Makefile.in: Use re-directed stdin instead of file + name in argv. This allows us to remove the filename + from the output, the expected output, and hence the diffs. + (Note that the input file is in $(srcdir), which we cannot + place in the expected out files.) + * tests/expected.out.[1235]: Edit out input filename, + to match new output. + +Mon Nov 4 15:04:41 1991 Douglas C. Schmidt (schmidt at bastille.ics.uci.edu) + + * Need to do something about the end-of-line marker being + hard-coded to '\n'... + + * Need to do something about the comment character being + hard-coded to '#'... + +Fri Sep 27 09:30:15 1991 Douglas C. Schmidt (schmidt at net4.ics.uci.edu) + + * Fixed a stupid problem with printout out a local enum with the + -E option (I forgot to check for the case of 0 duplicates, so it + was saying 1 duplicate instead!). + +Mon Aug 19 00:39:40 1991 Douglas C. Schmidt (schmidt at javel.ics.uci.edu) + + * Yow, all finished making gperf run with cfront/Saber C++. Not + really all that hard, actually, though did need to remove some + GNU specific hacks, like dynamically sized arrays and + initializing class data members in their declarations, etc. + + * Bumped up the version # to reflect the recent changes. + +Sun Aug 18 22:25:32 1991 Douglas C. Schmidt (schmidt at javel.ics.uci.edu) + + * Changed passage of Options::usage function in Options.C to have + a leading `&' so that Saber C++ wouldn't complain... + + * Added a new header file called gperf.h that includes system-wide + info. + + * Hacked up the release to work with Saber C++! Changed all *.cc + files to *.C. + +Mon Aug 5 21:18:47 1991 Douglas C. Schmidt (schmidt at net1.ics.uci.edu) + + * Yow, hacked in the nifty changes to the Std_Err error handling + abstraction. This now adds format string support for printing + out signals and the name of the function when things go wrong. + Make changes throughout the source to make use of the new + facilities and also to make sure all previous uses of + Std_Err::report_error are now prefixed by the name of the class. + +Tue Jul 30 00:02:39 1991 Douglas C. Schmidt (schmidt at net4.ics.uci.edu) + + * Make sure to add 1 to the Key_List::total_duplicates value when + printing it out since any time we have more than zero duplicates + we really have two or more duplicates! + + * Added support for the -O (optimize option). This option + optimizes the generated lookup function by assuming that all + input keywords are members of the keyset from the keyfile. + + * Added #define DUPLICATES and #define HASH_VALUE_RANGE (and of + course the enum equivalent) to the generated output. Don't know + how useful this will be, but it allows us to determine at a + glance whether we've got a minimal perfect hash function (in + which case TOTAL_KEYWORDS = HASH_VALUE_RANGE, and DUPLICATES = + 0). + + * Fixed a small bug in the Key_List::output_keyword_table routine + that caused an extra newline to be printed if there where no + leading blank entries... (who cares, right?!) + +Mon Jul 29 22:05:40 1991 Douglas C. Schmidt (schmidt at net4.ics.uci.edu) + + * Modified the handling of the -E (emit enums rather than + #defines) option in conjunction with the -G option. Now, if -G + and -E are given the enums are generated outside the lookup + function, rather than within it! + + * Yow, as part of my Software Practice and Experience submission + writeup I realized I needed to make the # comment character work + correctly. Now if you put a backslash character ('\') in front + of the # it treats the first character as a #. Naturally, to + put a '\' character on the front of the line you need to escape + it also, i.e., + \\I'm a line that starts with only one \ + # I'm a comment line + \#define I'm walking a fine line... ;-) + +Wed Jun 26 11:21:02 1991 Douglas C. Schmidt (schmidt at bastille.ics.uci.edu) + + * Changed all uses of the identifier `iteration_number' to + `generation_number' (also updated the paper!). + +Tue Apr 9 07:59:42 1991 Doug Schmidt (schmidt at net4.ics.uci.edu) + + * Had to change a whole bunch of little thangs in key-list.cc and + list-node.cc to make the -I option work. + + * Changed an alloca statement in key-list.cc to reflect the + strncasecmp modification (i.e., we now need to be able to + allocate a longer buffer if the -I option is used). + +Mon Apr 8 18:17:04 1991 Doug Schmidt (schmidt at net4.ics.uci.edu) + + * Yucko, there was a bug in the handling of -c (and of course the + new -I command in key-list.cc). Apparently when I added the + super-duper hack that provided support for duplicate keys I + forgot to update the strcmp output... + + * Boy, it has been a *long* time since I hacked this puppy. Let's + see, I'm about to add long-overdue support for case-insensitive + string comparisons to gperf's generated output code. We are + going to employ the hitherto unused option -I to indicte this! + +Thu Jun 28 16:17:27 1990 Doug Schmidt (schmidt at brilliant) + + * Wow, first fix on the new job! There was a dumb error + in Key_List::output_lookup_function, where I printed the + string "&wordlist[key]" instead of the correct "&wordlist[index]". + + * Added a couple of #ifdefs for USG support. + +Sun Jun 3 17:16:36 1990 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Updated the version number to 2.5 and sent to Doug Lea for release + with the latest GNU libg++. + + * Changed the error handling when a keyword file cannot be opened + (now calls perror). + +Wed May 30 14:49:40 1990 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Instrumented the source code with trace statements automagically + inserted using my new automated trace instrumentation tool! + +Wed May 9 11:47:41 1990 Doug Schmidt (schmidt at siam.ics.uci.edu) + + * Really fixed the previous bug. Turns out that a small amount + of logic had to be duplicated to handle static links that occur + as part of dynamic link chains. What a pain!!! + +Tue May 8 23:11:44 1990 Doug Schmidt (schmidt at siam.ics.uci.edu) + + * Fixed a stupid bug in Key_List::output_lookup_array that was + causing incorrect counts to be generated when there were both + static and dynamic links occurring for the same hash value. + Also simplified the code that performs the logic in this routine. + +Mon Apr 30 17:37:24 1990 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Fixed stupid bug in Key_List::output_lookup_array that was + making the generated lookup[] array contain `chars' even + when the values stored in the chars are greater than 127! + + * Changed the behavior of the -G (global table) option so that it + will output the `length[]' array in the global scope along with + the `word_list[]' array. + + * Fixed a stupid bug in Key_List::output_lookup_function that + would always output the complicated `duplicate-handling' lookup + logic, even when there were no duplicates in the input! + + * Yikes, had to modify a bunch of stuff in key-list.cc to correctly + handle duplicate entries. Changed the generated code so that + the MIN_HASH_VALUE is no longer subtracted off when calculating + the hash value for a keyword. This required changing some other + code by substituting MAX_HASH_VALUE for TOTAL_KEYS in several places. + Finally, this means that the generated tables may contain leading + null entries, but I suppose it is better to trade-off space to get + faster performance... + +Mon Mar 26 13:08:43 1990 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Updated version number to 2.4 to reflect the latest changes. + + * Changed the main program so that it always prints out gperf's + execution timings to the generated output file. + +Sun Mar 25 12:39:30 1990 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Added the -Z option so that users can specify the name of the + generated class explicitly. Updated documentation to reflect + this change. + + * Modified the generated C++ class interface so that the functions + are declared static (to remove the overhead of passing the `this' + pointer). This means that operator()() can no longer be used, + since it only works on non-static member functions. + Also changed things so that there is no constructor (why waste + the extra call, when it doesn't do anything, eh?) + + * Modified the behavior of Key_List::output when the -L C++ option + is enabled. Previously the code generated use const data members + to record MIN_WORD_LENGTH, MIN_HASH_VALUE, etc. However, as + pointed out by James Clark this may result in suboptimal behavior + on the part of C++ compilers that can't inline these values. + Therefore, the new behavior is identical to what happens with + -L C, i.e., either #defines or function-specific enums are used. + Why sacrifice speed for some abstract notion of `code purity?' ;-) + +Tue Mar 6 18:17:42 1990 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Added the -E option that defines constant values using an enum + local to the lookup function rather than with #defines. This + also means that different lookup functions can reside in the + same file. Thanks to James Clark (jjc@ai.mit.edu). + +Sat Mar 3 20:19:00 1990 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Added a special case to key_list::output_switch that doesn't + generate extra comparisons when the `-S' is given an argument + of 1 (the normal case). This should speed up the generated + code output a tad... + +Fri Feb 23 14:21:28 1990 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Renamed all instances of member function get_keysig_size + to get_max_keysig_size, since this is more precise... + + * Changed all occurrences of charset to keysig (stands for ``key + signature'') to reflect the new naming convention used in the + USENIX paper. + +Thu Feb 22 11:28:36 1990 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Changed the name of the generated associated values table from + asso_value to asso_values to reflect conventions in the USENIX + C++ paper. + +Thu Feb 15 23:29:03 1990 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Updated the gperf.texinfo file to fix some formatting problems + that had crept in since last time. + +Wed Feb 14 23:27:24 1990 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Fixed stupid bug in key-list.cc (get_special_input), wher + gperf replaced each '%' with the succeeding character. + + * Added support for multiple target language generation. Currently + handled languages are C and C++, with C as the default. Updated + documentation and option handler to reflect the changes. + + * Added a global destructor to new.cc and removed the #ifdef, since + the bloody thing now works with libg++. + +Mon Feb 14 13:00:00 1990 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Found out that my gperf paper was accepted at the upcoming + USENIX C++ Conference in San Francisco. Yow! + +Tue Jan 30 09:00:29 1990 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * #ifdef'd out the new.cc memory allocator, since there are + problems with this and the libg++ stuff. + + * Changed key-list.h so that class Vectors is a public (rather + than private) base class for class Key_List. The previous + form was illegal C++, but wasn't being caught by the old + g++ compiler. Should work now... ;-) + +Sun Dec 10 14:08:23 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added several changes from rfg@ics.uci.edu. These changes + help to automate the build process. + +Wed Nov 15 15:49:33 1989 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Removed conditional compilation for GATHER_STATISTICS. There's + really no good reason to avoid collecting this info at run-time, + since that section of code is *hardly* the bottleneck... ;-) + + * Simplified the C output routines in Key_List::set_output_types + and Key_List::output_keyword_table a bit in order to + speed-up and clean up the code generation. + + * Modified function Key_List::get_special_input so that it does + not try to `delete' a buffer that turned out to be too short. + This is important since the new memory management scheme + does not handle deletions. However, adding a small amount of + garbage won't hurt anything, since we generally don't do this + operation more than a couple times *at most*! + + * Created a new file (new.cc) which includes my own overloaded + operator new. This function should dramatically reduce the + number of calls to malloc since it grabs large chunks and + doles them out in small pieces. As a result of this change + the class-specific `operator new' was removed from class List_Node. + +Tue Nov 14 21:45:30 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Continued to refine the great hack. The latest trick is to + try and replace most uses of dynamic memory (i.e., calls to + new) with uses of gcc dynamic arrays (i.e., an alloca solution). + This makes life much easier for the overall process-size, since + it reduces the amount of overhead for memory management. As a + side-effect from this change there is no reason to have the + Bool_Array::dispose member function, so it's outta here! + + * Fixed a stupid bug that was an disaster waiting to happen... + Instead of making the boolean array large enough to index + max_hash_value it was only large enough to index max_hash_value + - 1. Once again, an off-by-one mistake in C/C++!!!! + +Mon Nov 13 19:38:27 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added the final great hack! This allows us to generate hash tables + for near-perfect hash functions that contain duplicates, *without* + having to use switch statements! Since many compilers die on large + switch statements this feature is essential. Furthermore, it appears + that the generated code is often *smaller* than that put out by + compilers, even though a large, sparse array must be created. + Here's the general idea: + + a. Generate the wordlist as a contiguous block of keywords, + just as before when using a switch statement. This + wordlist *must* be sorted by hash value. + + b. Generate the lookup array, which is an array of signed + {chars,shorts,ints}, (which ever allows full coverage of + the wordlist dimensions). If the value v, where v = + lookup[hash(str,len)], is >= 0 and < TOTAL_KEYWORDS, then we + simply use this result as a direct access into the wordlist + array to snag the keyword for comparison. + + c. Otherwise, if v is < -TOTAL_KEYWORDS or > TOTAL_KEYWORDS + this is an indication that we'll need to search through + some number of duplicates hash values. Using a hash + linking scheme we'd then index into a different part of + the hash table that provides the starting index and total + length of the duplicate entries to find via linear search! + +Sun Nov 12 13:48:10 1989 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Simplified Key_List::output_min_max considerably by recognizing + that since the keyword list was already sorted by hash value finding + the min and max values is trivial! + + * Improved the debugging diagnostics considerably in classes Key_List, + Hash_Table, and Gen_Perf. + + * Modified the `-s' option so that a negative argument is now + interpreted to mean `allow the maximum associated value to be + about x times *smaller* than the number of input keys.' This + should help prevent massive explosion of generated hash table + size for large keysets. + +Sat Nov 11 11:31:13 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added a field in class Key_List that counts the total number + of duplicate keywords, both static and dynamic. + + * Added a new member function Bool_Array that deletes the dynamic + memory allocated to Bool_Array::storage_array. This space may + be needed for subsequent options, so it made sense to free it as + soon as possible... + + * Renamed file/class Alpha_Vectors to Vectors, to avoid problems + with 14 character length filenames on SYSV. Also changed file + adapredefined.gperf to adadefs.gperf in the ./tests directory. + + * Modified class Options by changing the member function + Options::total_positions to Options::get_charset_size and + Options::set_charset_size. These two routines now either return + the total charset size *or* the length of the largest keyword + if the user specifies the -k'*' (ALLCHARS) option. This change + cleans up client code. + + * Merged all the cperf changes into gperf. + + * Made sure to explicitly initialize perfect.fewest_collisions to + 0. + + * Cleaned up some loose ends noticed by Nels Olson. + 1. Removed `if (collisions <= perfect.fewest_collisions)' + from Gen_Perf::affects_prev since it was superfluous. + 2. Removed the fields best_char_value and best_asso_value + from Gen_Perf. There were also unnecessary. + 3. Fixed a braino in the Bool_Array::bool_array_reset + function. Since iteration numbers can never be zero + the `if (bool_array.iteration_number++ == 0)' must be + `if (++bool_array.iteration_number == 0).' + 4. Modified Std_Err::report_error so that it correctly handles + "%%". + + * It is important to note that -D no longer enables -S. + There is a good reason for this change, which will become + manifested in the next release... (suspense!). + + * Made some subtle changes to Key_List::print_switch so that if finally + seems to work correctly. Needs more stress testing, however... + + * Made a major change to the Key_List::print_switch function. + The user can now specify the number of switch statements to generate + via an argument to the -S option, i.e., -S1 means `generate 1 + switch statement with all keywords in it,' -S2 means generate + 2 switch statements with 1/2 the elements in each one, etc. + Hopefully this will fix the problem with C compilers not being + able to generate code for giant switch statements (but don't + hold your breath!) + + * Changed Key_List::length function to Key_List::keyword_list_length. + + * Added a feature to main.c that prints out the starting wall-clock + time before the program begins and prints out the ending wall-clock + time when the program is finished. + + * Added the GATHER_STATISTICS code in hash-table.c so we can + keep track of how well double hashing is doing. Eventually, + GATHER_STATISTICS will be added so that all instrumentation + code can be conditionally compiled in. + + * Fixed a stupid bug in Key_List::print_switch routine. This + was necessary to make sure the generated switch statement worked + correctly when *both* `natural,' i.e., static links and dynamic + links, i.e., unresolved duplicates, hash to the same value. + + * Modified Bool_Array::~Bool_Array destructor so that + it now frees the bool_array.storage_array when it is no longer + needed. Since this array is generally very large it makes sense + to return the memory to the freelist when it is no longer in use. + + * Changed the interface to constructor Hash_Table::Hash_Table. This + constructor now passed a pointer to a power-of-two sized buffer that + serve as storage for the hash table. Although this weakens information + hiding a little bit it greatly reduces dynamic memory fragmentation, + since we can now obtain the memory via a call to alloca, rather + than malloc. This change modified Key_List::read_keys calling + interface. + + * Since alloca is now being used more aggressively a conditional + compilation section was added in main.c. Taken from GNU GCC, + this code gets rid of any avoidable limit on stack size so that + alloca does not fail. It is only used if the -DRLIMIT_STACK + symbol is defined when gperf is compiled. + + * Added warnings in option.c so that user's would be informed + that -r superceeds -i on the command-line. + + * Rewrote Gen_Perf::affects_prev. First, the code structure + was cleaned up considerably (removing the need for a dreaded + goto!). Secondly, a major change occurred so that Gen_Perf::affects_prev + returns FALSE (success) when fewest_hits gets down to whatever + it was after inserting the previous key (instead of waiting for + it to reach 0). In other words, it stops trying if it can + resolve the new collisions added by a key, even if there are + still other old, unresolved collisions. This modification was + suggested by Nels Olson and seems to *greatly* increase the + speed of gperf for large keyfiles. Thanks Nels! + + * In a similar vein, inside the Gen_Perf::change routine + the variable `perfect.fewest_collisions is no longer initialized + with the length of the keyword list. Instead it starts out at + 0 and is incremented by 1 every time change () is called. + The rationale for this behavior is that there are times when a + collision causes the number of duplicates (collisions) to + increase by a large amount when it would presumably just have + gone up by 1 if none of the asso_values were changed. That is, + at the beginning of change(), you could initialize fewest_hits + to 1+(previous value of fewest_hits) instead of to the number of + keys. Thanks again, Nels. + + * Replaced alloca with new in the Gen_Perf::change function. + This should eliminate some overhead at the expense of a little + extra memory that is never reclaimed. + + * Renamed Gen_Perf::merge_sets to Gen_Perf::compute_disjoint_union + to reflect the change in behavior. + + * Added the -e option so users can supply a string containing + the characters used to separate keywords from their attributes. + The default behavior is ",\n". + + * Removed the char *uniq_set field from LIST_NODE and modified + uses of uniq_set in perfect.c and keylist.c. Due to changes + to Gen_Perf::compute_disjoint_sets this field was no longer + necessary, and its removal makes the program smaller and + potentially faster. + + * Added lots of changes/fixes suggested by Nels Olson + (umls.UUCP!olson@mis.ucsf.edu). In particular: + 1. Changed Bool_Array so that it would dynamically create + an array of unsigned shorts rather than ints if the + LO_CAL symbol was defined during program compilation. + This cuts the amount of dynamic memory usage in half, + which is important for large keyfile input. + 2. Added some additional debugging statements that print extra + info to stderr when the -d option is enabled. + 3. Fixed a really stupid bug in Key_List::print_switch + A right paren was placed at the wrong location, which broke + strlen (). + 4. Fixed a subtle problem with printing case values when keylinks + appear. The logic failed to account for the fact that there + can be keylinks *and* regular node info also! + 5. Changed the behavior of Key_List::read_keys so that it would + honor -D unequivocally, i.e., it doesn't try to turn off dup + handling if the user requests it, even if there are no + immediate links in the keyfile input. + 6. Modified the -j option so that -j 0 means `try random values + when searching for a way to resolve collisions.' + 7. Added a field `num_done' to the Gen_Perf struct. This is used + to report information collected when trying to resolve + hash collisions. + 8. Modified the merge_sets algorithm to perform a disjoint + union of two multisets. This ensures that subsequent + processing in Gen_Perf::affect_prev doesn't + waste time trying to change an associated value that is + shared between two conflicting keywords. + 9. Modified Gen_Perf::affects_prev so that it doesn't try + random jump values unless the -j 0 option is enabled. + 10. Fixed a silly bug in Gen_Perf::change. This problem caused + gperf to seg fault when the -k* option was given and the + keyfile file had long keywords. + +Sun Oct 29 00:18:55 1989 Doug Schmidt (schmidt at siam.ics.uci.edu) + + * Modified class-specific new operations for Read_Line and + List_Node so they don't fail if SIZE is larger than twice + the previous buffer size. Note we double buffer size + everytime the previous buffer runs out, as a heuristic + to reduce future calls to malloc. + +Sun Oct 22 13:49:43 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Updated gperf version number to 2.0. Send to Doug Lea for + incorporation into the long-awaited `official' libg++ 1.36 + release! + + * Thanks to Nels Olson a silly bug in Gen_Perf::change () + was fixed. This problem caused gperf to seg fault when + the -k* option was given and the keyfile file had long + keywords. + + * Modified Key_List::print_hash_function so that it output + max_hash_value + 1 (rather than just max_hash_value) for + any associated value entries that don't correspond to + keyword charset characters. This should speed up rejection + of non-keyword strings a little in some cases. + +Sat Oct 21 19:28:36 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Fixed Key_List::print_hash_function so that it no longer output + things like `return 0 + ...' Although this probably gets + optimized away by even the worst C compilers there isn't any + point tempting fate... ;-) + + * Fixed class List_Node's constructor so that it wouldn't a priori + refuse to consider trying to hash keys whose length is less + than the smallest user-specified key position. It turns out + this is not a problem unless the user also specifies the -n + (NOLENGTH) option, in which case such keys most likely + don't have a prayer of being hashed correctly! + + * Changed the name of the generated lookup table from `Hash_Table' + to `asso_value' to be consistent with the gperf paper. + +Tue Oct 17 14:19:48 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added a flag GATHER_STATISTICS in the Makefile. If defined + during compilation this turns on certain collection facilities + that track the performance of gperf during its execution. In + particular, I want to see how many collisions occur for the + double hashing Hash_Table. + + * Added a safety check so that we don't screw up if the total + number of `resets' of the Bool_Array exceeds MAX_INT. Since + this number is around 2^31 it is unlikely that this would ever + occur for most input, but why take the risk? + + * Changed the behavior for the -a (ANSI) option so that the + generated prototypes use int rather than size_t for the LEN + parameter. It was too ugly having to #include all + over the place... + +Mon Oct 16 11:00:35 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Continued to work on the gperf paper for the USENIX C++ + conference. At some point this will be merged back into + the gperf documentation... + +Sat Oct 14 20:29:43 1989 Doug Schmidt (schmidt at siam.ics.uci.edu) + + * Added a majorly neat hack to Bool_Array, suggested by rfg. + The basic idea was to throw away the Ullman array technique. + The Ullman array was used to remove the need to reinitialize all + the Bool_Array elements to zero everytime we needed to determine + whether there were duplicate hash values in the keyword list. + The current trick uses an `iteration number' scheme, which takes + about 1/3 the space and reduces the overall program running a + time by about 20 percent for large input! The hack works as + follows: + + 1. Dynamically allocation 1 boolean array of size k. + 2. Initialize the boolean array to zeros, and consider the first + iteration to be iteration 1. + 2. Then on all subsequent iterations we `reset' the bool array by + kicking the iteration count by 1. + 3. When it comes time to check whether a hash value is currently + in the boolean array we simply check its index location. If + the value stored there is *not* equal to the current iteration + number then the item is clearly *not* in the set. In that + case we assign the iteration number to that array's index + location for future reference. Otherwise, if the item at + the index location *is* equal to the iteration number we've + found a duplicate. No muss, no fuss! + +Mon Oct 2 12:30:54 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Changed some consts in options.h to enumerals, since g++ + doesn't seem to like them at the moment! + +Sat Sep 30 12:55:24 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Fixed a stupid bug in Key_List::print_hash_function that manifested + itself if the `-k$' option was given (i.e., only use the key[length] + character in the hash function). + + * Added support for the -C option. This makes the contents of + all generated tables `readonly'. + + * Changed the handling of generated switches so that there is + only one call to str[n]?cmp. This *greatly* reduces the size of + the generated assembly code on all compilers I've seen. + + * Fixed a subtle bug that occurred when the -l and -S option + was given. Code produced looked something like: + + if (len != key_len || !strcmp (s1, resword->name)) return resword; + + which doesn't make any sense. Clearly, this should be: + + if (len == key_len && !strcmp (s1, resword->name)) return resword; + +Tue Sep 26 10:36:50 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Changed class Read_Line's definition so that it no longer + needs to know about the buffering scheme used to speed up + dynamic memory allocation of input keywords and their + associated attributes. This means that operator new is no longer + a friend of Read_Line. + +Mon Sep 25 23:17:10 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Decided that Obstacks had too much overhead, so they were + removed in favor of super-efficient, low-overhead buffered + storage allocation hacks in Read_Line and List_Node. + + * No longer try to inline functions that g++ complains about + (Key_List::Merge and Key_List::Merge_Sort). + +Sun Sep 24 13:11:24 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Changed classes Read_Line and List_Node to use Obstacks in order + to cache memory allocation for keyword strings and List_Nodes. + + * Continued to experiment with inheritance schemes. + + * Added a new file `alpha.h', that declares static data shared + (i.e., inherited) between classes List_Node and Key_List. + +Tue Sep 12 16:14:41 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Made numerous changes to incorporate multiple inheritance in + gperf. + +Wed Aug 16 23:04:08 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added the -DCOMPILER_FIXED flag to the ./src/Makefile. This + implies that people trying to compile gperf need to have a + working version of the new g++ compiler (1.36.0). + + * Removed some extra spaces that were being added in the generated + C code. + +Mon Jul 24 17:09:46 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Fixed PRINT_HASH_FUNCTION and PRINT_LOOKUP_FUNCTION in keylist.c + so that the generated functions take an unsigned int length argument. + If -a is enabled the prototype is (const char *str, size_t len). + +Fri Jul 21 13:06:15 1989 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Fixed a typo in PRINT_KEYWORD_TABLE in keylist.cc that prevented + the indentation from working correctly. + + * Fixed a horrible typo in PRINT_KEYWORD_TABLE in keylist.cc + that prevented links from being printed correctly. + +Tue Jul 18 16:04:31 1989 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Fixed up readline.cc and readline.h so that they work OK + with g++ compilers that aren't completely up-to-date. + If symbol COMPILER_FIXED is defined then the behavior + that works on my more recent version of g++ is enabled. + +Sun Jul 9 17:53:28 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Changed the ./tests subdirectory Makefile so that it + uses $(CC) instead of gcc. + +Sun Jul 2 21:52:15 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Fixed a number of subtle bugs that occurred when -S was + combined with various and sundry options. + + * Added the -G option, that makes the generated keyword table + a global static variable, rather than hiding it inside + the lookup function. This allows other functions to directly + access the contents in this table. + + * Added the "#" feature, that allows comments inside the keyword + list from the input file. Comment handling takes place in readline.c. + This simplifies the code and reduces the number of malloc calls. + + * Also added the -H option (user can give the name of the hash + function) and the -T option (prevents the transfer of the type decl + to the output file, which is useful if the type is already defined + elsewhere). + +Thu Jun 22 20:39:39 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Modified many classes so that they would inherit Std_Err as + a base class. This makes things more abstract... + +Fri Jun 16 14:23:00 1989 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Modified the -f (FAST) option. This now takes an argument. + The argument corresponds to the number of iterations used + to resolve collisions. -f 0 uses the length of the + keyword list (which is what -f did before). This makes + life much easier when dealing with large keyword files. + +Tue Jun 6 17:53:27 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added the -c (comparison) option. Enabling this + will use the strncmp function for string comparisons. + The default is to use strcmp. + + * Fixed a typo in key_list.cc (PRINT_SWITCH). This caused + faulty C code to be generated when the -D, -p, and -t + options were all enabled. + +Thu May 25 14:07:21 1989 Doug Schmidt (schmidt at siam.ics.uci.edu) + + * Once again, changed class Read_Line to overload global operator + new. Hopefully, this will work...! + +Sun May 21 01:51:45 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Modified Key_List::print_hash_function () so that it properly + formats the associated values in the hash table according to + the maximum number of digits required to represent the largest + value. + + * Removed the named return value from class Hash_Table's + operator (), since this causes a seg fault when -O is enabled. + No sense tripping subtle g++ bugs if we don't have to.... ;-) + + * Removed the operator new hack from Read_Line, since this seemed + to create horrible bus error problems. + + * Changed many class member functions and data members to be `static', + if they don't manipulate this! + +Fri May 12 23:06:56 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Changed class Std_Err to use static member functions, a la + Ada or Modula 2. This eliminates the need for an explicit + error-handler class object. + + * Added the ``named return value'' feature to Hash_Table::operator () + and Bool_Array::operator [], just for the heck of it.... ;-) + + * Changed the previous hack in Read_Line so that we now use + the overloaded global `new' instead of NEW_STRING! + +Wed May 3 17:36:55 1989 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Updated to version 1.7. This reflects the recent major changes + and the new C port. + + * Modified the GNU getopt.cc routine to have a class-based interface. + + * Fixed a typo in Perfect.cc ~Perfect that prevented the actual maximum + hash table size from being printed (maybe the stream classes + weren't so bad after all.... ;-). + + * Added support for the -f option. This generates the perfect + hash function ``fast.'' It reduces the execution time of + gperf, at the cost of minimizing the range of hash values. + +Tue May 2 16:23:29 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Added an efficiency hack to Read_Line. Instead of making + a call to operator NEW (a.k.a. malloc) for each input string + a new member function NEW_STRING stores a large buffer from + which new strings are carved out, growing the buffer if + necessary. It might be useful to add this throughout the + program.... + + * Removed all unnecessary calls to DELETE. If the program is about + to exit it is silly to waste time freeing memory. + + * Added the GNU getopt program to the distribution. This makes + GPERF portable to systems that don't include getopt in libc. + + * Added a strcspn member to class Key_List. This also increases + portability. + + * Added the get_include_src function from keylist.c as a member + function in class Key_List. Hopefully every function is + now associated with a class. This aids abstraction and + modularity. + + * Ported gperf to C. From now on both K&R C and GNU G++ versions + will be supported. There will be two ChangeLog files, one + for each version of the program. + +Mon May 1 16:41:45 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Fixed a bug with -k'*'. This now prints out *all* the cases + up to the length of the longest word in the keyword set. + +Sun Apr 30 12:15:25 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Removed all use of the stream classes. Too ugly, slow, and + not handled by the c++-mode formatter.... + + * Modified the handling of links (i.e., keywords that have + identical hash values as other keywords). This should + speed up hash function generation for keyword sets with + many duplicate entries. The trick is to treat duplicate + values as equivalence classes, so that each set of duplicate + values is represented only once in the main list processing. + + * Fixed some capitialization typos and indentations mistakes in + Key_List::print_hash_function. + +Sat Apr 29 12:04:03 1989 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Fixed a typo/logico in Key_List::print_switch that prevented + the last keyword in the keyword list to be print out. This + requires further examination..... + + * Fixed a stupid bug in List_Node::List_node. If the -k'*' option + was enabled the KEY_SET string wasn't getting terminated with + '\0'! + +Fri Apr 28 12:38:35 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Renamed strexp.h and strexp.cc to iterator.h and iterator.cc. + Also changed the strexp class to iterator. Continued to work + on style... + + * Updated the version number to 1.6. This reflects all the + recent changes. + +Thu Apr 27 00:14:51 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added the -D option that properly handles keyword sets that + contain duplicate hash values. + + * Continued the stylistic changes. Added the #pragma once + directive to all the *.h files. Removed all #defines and + replaced them with static consts. Also moved the key_sort + routine from options.cc into the options class as a + member function. + +Mon Apr 3 13:26:55 1989 Doug Schmidt (schmidt at zola.ics.uci.edu) + + * Made massive stylistic changes to bring source code into + conformance with GNU style guidelines. + +Thu Mar 30 23:28:45 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Fixed up the output routines so that they generate code + corresponding to the GNU style guidelines. + +Sat Mar 11 13:12:37 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Fixed Stderr constructors so that they wouldn't try to + use the base class initializer syntax for the static + class variable Program_Name. G++ 1.34 is stricter in + enforcing the rules! + +Fri Mar 10 11:24:14 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Removed -v and ``| more'' from the Makefile to keep rfg happy... + +Thu Mar 2 12:37:30 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Sent latest GNU gperf version 1.5 to Doug Lea for inclusion + into libg++ 1.34. Note that there is a small bug with + the new %{ ... %} source inclusion facility, since it doesn't + understand comments and will barf if %{ or %} appear nested + inside the outermost delimiters. This is too trivial of + a defect to fix at the moment... + +Tue Feb 28 11:19:58 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added the -K option, which allows the user to provide a + alternative name for the keyword structure component. + The default is still ``name.'' + + * Added the LEX and YACC-like ability to include arbitrary + text at the beginning of the generated C source code output. + This required two new functions Get_Special_Input, + Key_List::Save_Include_Src; + + * Fixed memory allocation bug in Key_List::Set_Types. + Variable Return_Type needs 1 additional location + to store the "*" if the -p option is used. + + * Added code to NULL terminate both Struct_Tag and Return_Type, + *after* the strncpy (stupid mistake). + +Mon Feb 27 14:39:51 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added a new option -N. This allows the user to specify the + name to be used for the generated lookup function. The + default name is still ``in_word_set.'' This makes it + possible to completely automate the perfect hash function + generation process! + +Mon Feb 20 23:33:14 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Corrected the Hash_Table::operator () function so that + *it* is responsible for deciding when a new key has the + same signature as a previously seen key. The key length + information is now used internally to this function to + decide whether to add to the hash table those keys with + the same key sets, but different lengths. Before, this + was handled by the Key_List::Read_Keys function. However, + this failed to work for certain duplicate keys, since + they weren't being entered into the hash table properly. + +Sun Feb 19 16:02:51 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Modified class Options by moving the enum Option_Type out + of the class. This is to satisfy the new enumeration + scope rules in C++. + +Sun Jan 15 15:12:09 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Incremented the version number upto 1.4 to reflect the new + options that affect the generated code. Send the new + distribution off to Michael for use with g++ 1.33. + + * Added a fix to Key_List::Read_Keys so that it checks for links + properly when the -n option is used. Previously, it didn't + catch obvious links, which caused it to spend large amount + of time searching for a solution that could never occur! + + * Modified the Key_List data structure to record *both* the + minimum and the maximum key lengths. This information + is now computed in Key_List::Read_Keys, and thus + Key_List::Print_Min_Max doesn't need to bother. + + * Modifed the key position iterator scheme in options.cc to + eliminate the need for member function Options::Advance. + Now, the Options::Get function performs the advancement + automatically, obviating the need for an extra function call. + + * Added the new function Options::Print_Options, to print out + the user-specified command line options to generated C + output file. + + * Added a new function, Key_List::Print_Keylength_Table, + which creates a table of lengths for use in speeding + up the keyword search. This also meant that a new + option, -l (LENTABLE) is recognized. It controls + whether the length table is printed and the comparison + made in the generated function ``in_word_set.'' + + * Added a comment at the top of the generated C code + output file that tells what version of gperf was used. + Next, I'll also dump out the command line options + as a comment too. Thanks to Michael Tiemann for the + feedback on this. + + * Fixed the -n option to make it work correctly with + other parts of the program (most notably the Perfect::Hash + function and the computation of minimum and maximum lengths. + +Fri Jan 13 21:25:27 1989 Doug Schmidt (schmidt at siam.ics.uci.edu) + + * Realized the the need to add a test that will enable + optimziation of the generated C code in the ``hash'' function + by checking whether all the requested key positions are + guaranteed to exist due to the comparison in `in_word_set.'' + I'll put this in soon.... + +Thu Jan 12 20:09:21 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Added pascal, modula3, and modula2 tests inputs to the + Makefile + + * Recognised that there is a bug with the -n option. However + I'm too busy to fix it properly, right now. The problem + is that the generated #define end up being 0, since that's + my hack to make -n work. This needs complete rethinking! + +Tue Jan 10 00:08:16 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Added a new option, -n, that instructs gperf to not use the + length of an identifier when computing the hash functions. + I'm not sure how useful this is! + + * Retransmitted the distribution to rocky.oswego.edu. Hopefully, + this will work! + + * Began fixing the indentation and capitalization to conform + to the GNU coding guidelines. + +Mon Jan 9 22:23:18 1989 Doug Schmidt (schmidt at pompe.ics.uci.edu) + + * Fixed horrible bug in Read_Line::Readln_Aux. This was + a subtle and pernicous off-by-1 error, that overwrote + past the last character of the input string buffer. I + think this fault was killing the vax! + + * Yow, fixed an oversight in List_Node::List_Node, where the + pointer field Next was uninitialized. Luckily, the new routine + seems to return 0 filled objects the first time through! + +Sun Jan 8 13:43:14 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Modified the ``key linked'' diagnostic in Key_List::Read_Keys + to be more helpful and easy to read. + + * Fixed the List_Node::List_Node so that it would ignore trailing + fields if the -t option was not enabled. + + * Moved the List_Node declarations out of keylist.h and + into a file of its own, called listnode.cc and listnode.h + Made Set_Sort a member function of class List_Node. + + * Massively updated the documentation in the gperf.texinfo file. + + * Polished off the major revision to the print functions, + added a few new tests in the Makefile to check for the + validity of the program and ftp'ed the entire distribution + off to Doug Lea for libg++. ( changed it to + 1.3 to reflect the major changes with the generated + C code ). + + * Fixed Key_List::Print_Switch to deal with the -p and -t options. + This meant that the ``still-born'' function Key_List:: + Print_Type_Switch was superflous, so I removed it. + Also, removed the restriction in Option that the -p and + -t options couldn't be used simultaneously. + + * Modified List_Node::List_Node, to perform only 1 call to + ``new'' when dynamically allocating memory for the Key_Set + and the Uniq_Set. + +Sat Jan 7 14:10:51 1989 Doug Schmidt (schmidt at glacier.ics.uci.edu) + + * Fixed a big bug with the new policy of nesting the + wordlist inside of generated function ``in_word_set.'' + I'd forgotten to declare the wordlist array as static! + ( arrgh ). + + * Added a new function Key_List::Set_Types, that figures out + the return type for generated function ``in_word_set,'' + the user-defined ``struct tag,'' if one is used, and also + formates the array type for the static local array. + + * Changed the print routines to take advantage of the + new -p option. + + * Began adding the hooks to allow the return of a pointer + to a user defined struct location from the generated + ``in_word_set'' function instead of the current 0 or 1 + return value. Created function Key_List::Print_Type_Switch + and added option -p to class Option, allowing the user to + request generation of the aforementioned pointers returned + instead of booleans. + + * Put in checks in class Option to make sure that -S and -t + options are not used simultaneously. This restriction + will be removed in subsequent releases, once I decide on + a clean way to implement it. + + * Sent version 1.2 to Doug Lea for possible inclusion into + the libg++ distribution. + + * Moved the static word_list array inside the generated function + in_word_set. This supports better data hiding. + + * Added a texinfo file, gperf.texinfo + + * Revised the Makefile to cleanup the droppings from texinfo + and changed the name of gperf.cc and gperf.h to perfect.cc + and perfect.h. + +Fri Jan 6 13:04:45 1989 Doug Schmidt (schmidt at crimee.ics.uci.edu) + + * Implemented the switch statement output format. Much better + for large datasets in terms of space used. + + * Added new functions to break up the Key_List::Output function. + Functions added were Key_List::Print_Switch, + Key_List::Print_Min_Max, Key_List::Print_Keyword_Table, + Key_List::Print_Hash_Function, and + Key_List::Print_Lookup_Function. This simplifies the big mess + in Key_List::Output considerably! + + * Added switch statement option to Options, which potentially + trades time for space in the generated lookup code. + +Thu Jan 5 22:46:34 1989 Doug Schmidt (schmidt at siam.ics.uci.edu) + + * Released version 1.1 + + * Fixed a bug with Gperf::Merge_Set, it was skipping letters + shared between the Set_1 and Set_2. + + * Added the optimal min/max algorithm in Key_List::Output. This + runs in O (3n/2), rather than O (2n) time. + + * Changed Gperf::Sort_Set to use insertion sort, rather than + bubble sort. + + * Added a check in Key_List::Output for the special case where + the keys used are 1,$. It is possible to generate more + efficient C code in this case. diff --git a/apps/gperf/Makefile b/apps/gperf/Makefile new file mode 100644 index 00000000000..f9a0d4b9bd1 --- /dev/null +++ b/apps/gperf/Makefile @@ -0,0 +1,25 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Orbix applications +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +INFO = README + +DIRS = src \ + tests + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + diff --git a/apps/gperf/README b/apps/gperf/README new file mode 100644 index 00000000000..bd9d14ea680 --- /dev/null +++ b/apps/gperf/README @@ -0,0 +1,24 @@ +While teaching a data structures course at University of California, +Irvine, I developed a program called GPERF that generates perfect hash +functions for sets of key words. A perfect hash function is simply: + + A hash function and a data structure that allows + recognition of a key word in a set of words using + exactly 1 probe into the data structure. + +The gperf.texinfo file explains how the program works, the form of the +input, what options are available, and hints on choosing the best +options for particular key word sets. The texinfo file is readable +both via the GNU emacs `info' command, and is also suitable for +typesetting with TeX. + +The enclosed Makefile creates the executable program ``gperf'' and +also runs some tests. + +Output from the GPERF program is used to recognize reserved words in +the GNU C, GNU C++, and GNU Pascal compilers, as well as with the GNU +indent program. + +Happy hacking! + +Douglas C. Schmidt diff --git a/apps/gperf/gperf.1 b/apps/gperf/gperf.1 new file mode 100644 index 00000000000..5673c80062a --- /dev/null +++ b/apps/gperf/gperf.1 @@ -0,0 +1,23 @@ +.TH GPERF 1 "December 16, 1988 +.UC 4 +.SH NAME +gperf \- generate a perfect hash function from a key set +.SH SYNOPSIS +.B gperf +[ +.B \-adghijklnoprsStv +] [ +.I keyfile +] +.SH DESCRIPTION + +\fIgperf\fP reads a set of ``keys'' from \fIkeyfile\fP (or, by +default, from the standard input) and attempts to find a non-minimal +perfect hashing function that recognizes a member of the key set in +constant, i.e., O(1), time. If such a function is found the program +generates a pair of \fIC\fP source code routines that perform the +hashing and table lookup. All generated code is directed to the +standard output. + +Please refer to the \fIgperf.texinfo\fP file for more information. +This file is distributed with \fIgperf\fP release. diff --git a/apps/gperf/gperf.info b/apps/gperf/gperf.info new file mode 100644 index 00000000000..a0947230573 --- /dev/null +++ b/apps/gperf/gperf.info @@ -0,0 +1,1127 @@ +This is Info file gperf.info, produced by Makeinfo-1.55 from the input +file ./gperf.texi. + +START-INFO-DIR-ENTRY +* Gperf: (gperf). Perfect Hash Function Generator. +END-INFO-DIR-ENTRY + + This file documents the features of the GNU Perfect Hash Function +Generator + + Copyright (C) 1989 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. + + Permission is granted to copy and distribute modified versions of +this manual under the conditions for verbatim copying, provided also +that the section entitled "GNU General Public License" is included +exactly as in the original, and provided that the entire resulting +derived work is distributed under the terms of a permission notice +identical to this one. + + Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that the section entitled "GNU `gperf' General Public +License" an d this permission notice may be included in translations +approved by the Free Software Foundation instead of in the original +English. + + +File: gperf.info, Node: Top, Next: Copying, Prev: (dir), Up: (dir) + +Introduction +************ + + This manual documents the GNU `gperf' perfect hash function generator +utility, focusing on its features and how to use them, and how to report +bugs. + +* Menu: + +* Copying:: GNU `gperf' General Public License says + how you can copy and share `gperf'. +* Contributors:: People who have contributed to `gperf'. +* Motivation:: Static search structures and GNU GPERF. +* Search Structures:: Static search structures and GNU `gperf' +* Description:: High-level discussion of how GPERF functions. +* Options:: A description of options to the program. +* Bugs:: Known bugs and limitations with GPERF. +* Projects:: Things still left to do. +* Implementation:: Implementation Details for GNU GPERF. +* Bibliography:: Material Referenced in this Report. + + -- The Detailed Node Listing -- + +High-Level Description of GNU `gperf' + +* Input Format:: Input Format to `gperf' +* Output Format:: Output Format for Generated C Code with `gperf' + +Input Format to `gperf' + +* Declarations:: `struct' Declarations and C Code Inclusion. +* Keywords:: Format for Keyword Entries. +* Functions:: Including Additional C Functions. + + +File: gperf.info, Node: Copying, Next: Contributors, Prev: Top, Up: Top + +GNU GENERAL PUBLIC LICENSE +************************** + + Version 1, February 1989 + + Copyright (C) 1989 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +Preamble +======== + + The license agreements of most software companies try to keep users +at the mercy of those companies. By contrast, our General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. The +General Public License applies to the Free Software Foundation's +software and to any other program whose authors commit to using it. +You can use it for your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Specifically, the General Public License is designed to make +sure that you have the freedom to give away or sell copies of free +software, that you receive source code or can get it if you want it, +that you can change the software or use pieces of it in new free +programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of a such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must tell them their rights. + + We protect your rights with two steps: (1) copyright the software, +and (2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 1. This License Agreement applies to any program or other work which + contains a notice placed by the copyright holder saying it may be + distributed under the terms of this General Public License. The + "Program", below, refers to any such program or work, and a "work + based on the Program" means either the Program or any work + containing the Program or a portion of it, either verbatim or with + modifications. Each licensee is addressed as "you". + + 2. You may copy and distribute verbatim copies of the Program's source + code as you receive it, in any medium, provided that you + conspicuously and appropriately publish on each copy an + appropriate copyright notice and disclaimer of warranty; keep + intact all the notices that refer to this General Public License + and to the absence of any warranty; and give any other recipients + of the Program a copy of this General Public License along with + the Program. You may charge a fee for the physical act of + transferring a copy. + + 3. You may modify your copy or copies of the Program or any portion of + it, and copy and distribute such modifications under the terms of + Paragraph 1 above, provided that you also do the following: + + * cause the modified files to carry prominent notices stating + that you changed the files and the date of any change; and + + * cause the whole of any work that you distribute or publish, + that in whole or in part contains the Program or any part + thereof, either with or without modifications, to be licensed + at no charge to all third parties under the terms of this + General Public License (except that you may choose to grant + warranty protection to some or all third parties, at your + option). + + * If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the simplest and most usual way, to print + or display an announcement including an appropriate copyright + notice and a notice that there is no warranty (or else, + saying that you provide a warranty) and that users may + redistribute the program under these conditions, and telling + the user how to view a copy of this General Public License. + + * You may charge a fee for the physical act of transferring a + copy, and you may at your option offer warranty protection in + exchange for a fee. + + Mere aggregation of another independent work with the Program (or + its derivative) on a volume of a storage or distribution medium + does not bring the other work under the scope of these terms. + + 4. You may copy and distribute the Program (or a portion or + derivative of it, under Paragraph 2) in object code or executable + form under the terms of Paragraphs 1 and 2 above provided that you + also do one of the following: + + * accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Paragraphs 1 and 2 above; or, + + * accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal + charge for the cost of distribution) a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Paragraphs 1 and 2 above; or, + + * accompany it with the information you received as to where the + corresponding source code may be obtained. (This alternative + is allowed only for noncommercial distribution and only if you + received the program in object code or executable form alone.) + + Source code for a work means the preferred form of the work for + making modifications to it. For an executable file, complete + source code means all the source code for all modules it contains; + but, as a special exception, it need not include source code for + modules which are standard libraries that accompany the operating + system on which the executable file runs, or for standard header + files or definitions files that accompany that operating system. + + 5. You may not copy, modify, sublicense, distribute or transfer the + Program except as expressly provided under this General Public + License. Any attempt otherwise to copy, modify, sublicense, + distribute or transfer the Program is void, and will automatically + terminate your rights to use the Program under this License. + However, parties who have received copies, or rights to use + copies, from you under this General Public License will not have + their licenses terminated so long as such parties remain in full + compliance. + + 6. By copying, distributing or modifying the Program (or any work + based on the Program) you indicate your acceptance of this license + to do so, and all its terms and conditions. + + 7. Each time you redistribute the Program (or any work based on the + Program), the recipient automatically receives a license from the + original licensor to copy, distribute or modify the Program + subject to these terms and conditions. You may not impose any + further restrictions on the recipients' exercise of the rights + granted herein. + + 8. The Free Software Foundation may publish revised and/or new + versions of the General Public License from time to time. Such + new versions will be similar in spirit to the present version, but + may differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the + Program specifies a version number of the license which applies to + it and "any later version", you have the option of following the + terms and conditions either of that version or of any later + version published by the Free Software Foundation. If the Program + does not specify a version number of the license, you may choose + any version ever published by the Free Software Foundation. + + 9. If you wish to incorporate parts of the Program into other free + programs whose distribution conditions are different, write to the + author to ask for permission. For software which is copyrighted + by the Free Software Foundation, write to the Free Software + Foundation; we sometimes make exceptions for this. Our decision + will be guided by the two goals of preserving the free status of + all derivatives of our free software and of promoting the sharing + and reuse of software generally. + + NO WARRANTY + + 10. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO + WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE + LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT + HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT + WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT + NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE + QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE + PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY + SERVICING, REPAIR OR CORRECTION. + + 11. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN + WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY + MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE + LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, + INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR + INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF + DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU + OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY + OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + +Appendix: How to Apply These Terms to Your New Programs +======================================================= + + If you develop a new program, and you want it to be of the greatest +possible use to humanity, the best way to achieve this is to make it +free software which everyone can redistribute and change under these +terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES. + Copyright (C) 19YY NAME OF AUTHOR + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Also add information on how to contact you by electronic and paper +mail. + + If the program is interactive, make it output a short notice like +this when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19YY NAME OF AUTHOR + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + + The hypothetical commands `show w' and `show c' should show the +appropriate parts of the General Public License. Of course, the +commands you use may be called something other than `show w' and `show +c'; they could even be mouse-clicks or menu items--whatever suits your +program. + + You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the program, +if necessary. Here a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + program `Gnomovision' (a program to direct compilers to make passes + at assemblers) written by James Hacker. + + SIGNATURE OF TY COON, 1 April 1989 + Ty Coon, President of Vice + + That's all there is to it! + + +File: gperf.info, Node: Contributors, Next: Motivation, Prev: Copying, Up: Top + +Contributors to GNU `gperf' Utility +*********************************** + + * The GNU `gperf' perfect hash function generator utility was + originally written in GNU C++ by Douglas C. Schmidt. It is now + also available in a highly-portable "old-style" C version. The + general idea for the perfect hash function generator was inspired + by Keith Bostic's algorithm written in C, and distributed to + net.sources around 1984. The current program is a heavily + modified, enhanced, and extended implementation of Keith's basic + idea, created at the University of California, Irvine. Bugs, + patches, and suggestions should be reported to schmidt at + ics.uci.edu. + + * Special thanks is extended to Michael Tiemann and Doug Lea, for + providing a useful compiler, and for giving me a forum to exhibit + my creation. + + In addition, Adam de Boor and Nels Olson provided many tips and + insights that greatly helped improve the quality and functionality + of `gperf'. + + +File: gperf.info, Node: Motivation, Next: Search Structures, Prev: Contributors, Up: Top + +Introduction +************ + + `gperf' is a perfect hash function generator written in C++. It +transforms an *n* element user-specified keyword set *W* into a perfect +hash function *F*. *F* uniquely maps keywords in *W* onto the range +0..*k*, where *k* >= *n*. If *k = n* then *F* is a *minimal* perfect +hash function. `gperf' generates a 0..*k* element static lookup table +and a pair of C functions. These functions determine whether a given +character string *s* occurs in *W*, using at most one probe into the +lookup table. + + `gperf' currently generates the reserved keyword recognizer for +lexical analyzers in several production and research compilers and +language processing tools, including GNU C, GNU C++, GNU Pascal, GNU +Modula 3, and GNU indent. Complete C++ source code for `gperf' is +available via anonymous ftp from ics.uci.edu. `gperf' also is +distributed along with the GNU libg++ library. A highly portable, +functionally equivalent K&R C version of `gperf' is archived in +comp.sources.unix, volume 20. Finally, a paper describing `gperf''s +design and implementation in greater detail is available in the Second +USENIX C++ Conference proceedings. + + +File: gperf.info, Node: Search Structures, Next: Description, Prev: Motivation, Up: Top + +Static search structures and GNU `gperf' +**************************************** + + A "static search structure" is an Abstract Data Type with certain +fundamental operations, *e.g.*, *initialize*, *insert*, and *retrieve*. +Conceptually, all insertions occur before any retrievals. In +practice, `gperf' generates a `static' array containing search set +keywords and any associated attributes specified by the user. Thus, +there is essentially no execution-time cost for the insertions. It is +a useful data structure for representing *static search sets*. Static +search sets occur frequently in software system applications. Typical +static search sets include compiler reserved words, assembler +instruction opcodes, and built-in shell interpreter commands. Search +set members, called "keywords", are inserted into the structure only +once, usually during program initialization, and are not generally +modified at run-time. + + Numerous static search structure implementations exist, *e.g.*, +arrays, linked lists, binary search trees, digital search tries, and +hash tables. Different approaches offer trade-offs between space +utilization and search time efficiency. For example, an *n* element +sorted array is space efficient, though the average-case time +complexity for retrieval operations using binary search is proportional +to log *n*. Conversely, hash table implementations often locate a +table entry in constant time, but typically impose additional memory +overhead and exhibit poor worst case performance. + + *Minimal perfect hash functions* provide an optimal solution for a +particular class of static search sets. A minimal perfect hash +function is defined by two properties: + + * It allows keyword recognition in a static search set using at most + *one* probe into the hash table. This represents the "perfect" + property. + + * The actual memory allocated to store the keywords is precisely + large enough for the keyword set, and *no larger*. This is the + "minimal" property. + + For most applications it is far easier to generate *perfect* hash +functions than *minimal perfect* hash functions. Moreover, non-minimal +perfect hash functions frequently execute faster than minimal ones in +practice. This phenomena occurs since searching a sparse keyword table +increases the probability of locating a "null" entry, thereby reducing +string comparisons. `gperf''s default behavior generates +*near-minimal* perfect hash functions for keyword sets. However, +`gperf' provides many options that permit user control over the degree +of minimality and perfection. + + Static search sets often exhibit relative stability over time. For +example, Ada's 63 reserved words have remained constant for nearly a +decade. It is therefore frequently worthwhile to expend concerted +effort building an optimal search structure *once*, if it subsequently +receives heavy use multiple times. `gperf' removes the drudgery +associated with constructing time- and space-efficient search +structures by hand. It has proven a useful and practical tool for +serious programming projects. Output from `gperf' is currently used in +several production and research compilers, including GNU C, GNU C++, +GNU Pascal, and GNU Modula 3. The latter two compilers are not yet +part of the official GNU distribution. Each compiler utilizes `gperf' +to automatically generate static search structures that efficiently +identify their respective reserved keywords. + + +File: gperf.info, Node: Description, Next: Options, Prev: Search Structures, Up: Top + +High-Level Description of GNU `gperf' +************************************* + +* Menu: + +* Input Format:: Input Format to `gperf' +* Output Format:: Output Format for Generated C Code with `gperf' + + The perfect hash function generator `gperf' reads a set of +"keywords" from a "keyfile" (or from the standard input by default). +It attempts to derive a perfect hashing function that recognizes a +member of the "static keyword set" with at most a single probe into the +lookup table. If `gperf' succeeds in generating such a function it +produces a pair of C source code routines that perform hashing and +table lookup recognition. All generated C code is directed to the +standard output. Command-line options described below allow you to +modify the input and output format to `gperf'. + + By default, `gperf' attempts to produce time-efficient code, with +less emphasis on efficient space utilization. However, several options +exist that permit trading-off execution time for storage space and vice +versa. In particular, expanding the generated table size produces a +sparse search structure, generally yielding faster searches. +Conversely, you can direct `gperf' to utilize a C `switch' statement +scheme that minimizes data space storage size. Furthermore, using a C +`switch' may actually speed up the keyword retrieval time somewhat. +Actual results depend on your C compiler, of course. + + In general, `gperf' assigns values to the characters it is using for +hashing until some set of values gives each keyword a unique value. A +helpful heuristic is that the larger the hash value range, the easier +it is for `gperf' to find and generate a perfect hash function. +Experimentation is the key to getting the most from `gperf'. + + +File: gperf.info, Node: Input Format, Next: Output Format, Prev: Description, Up: Description + +Input Format to `gperf' +======================= + + You can control the input keyfile format by varying certain +command-line arguments, in particular the `-t' option. The input's +appearance is similar to GNU utilities `flex' and `bison' (or UNIX +utilities `lex' and `yacc'). Here's an outline of the general format: + + declarations + %% + keywords + %% + functions + + *Unlike* `flex' or `bison', all sections of `gperf''s input are +optional. The following sections describe the input format for each +section. + +* Menu: + +* Declarations:: `struct' Declarations and C Code Inclusion. +* Keywords:: Format for Keyword Entries. +* Functions:: Including Additional C Functions. + + +File: gperf.info, Node: Declarations, Next: Keywords, Prev: Input Format, Up: Input Format + +`struct' Declarations and C Code Inclusion +------------------------------------------ + + The keyword input file optionally contains a section for including +arbitrary C declarations and definitions, as well as provisions for +providing a user-supplied `struct'. If the `-t' option *is* enabled, +you *must* provide a C `struct' as the last component in the +declaration section from the keyfile file. The first field in this +struct must be a `char *' identifier called "name," although it is +possible to modify this field's name with the `-K' option described +below. + + Here is simple example, using months of the year and their +attributes as input: + + struct months { char *name; int number; int days; int leap_days; }; + %% + january, 1, 31, 31 + february, 2, 28, 29 + march, 3, 31, 31 + april, 4, 30, 30 + may, 5, 31, 31 + june, 6, 30, 30 + july, 7, 31, 31 + august, 8, 31, 31 + september, 9, 30, 30 + october, 10, 31, 31 + november, 11, 30, 30 + december, 12, 31, 31 + + Separating the `struct' declaration from the list of key words and +other fields are a pair of consecutive percent signs, `%%', appearing +left justified in the first column, as in the UNIX utility `lex'. + + Using a syntax similar to GNU utilities `flex' and `bison', it is +possible to directly include C source text and comments verbatim into +the generated output file. This is accomplished by enclosing the region +inside left-justified surrounding `%{', `%}' pairs. Here is an input +fragment based on the previous example that illustrates this feature: + + %{ + #include + /* This section of code is inserted directly into the output. */ + int return_month_days (struct months *months, int is_leap_year); + %} + struct months { char *name; int number; int days; int leap_days; }; + %% + january, 1, 31, 31 + february, 2, 28, 29 + march, 3, 31, 31 + ... + + It is possible to omit the declaration section entirely. In this +case the keyfile begins directly with the first keyword line, *e.g.*: + + january, 1, 31, 31 + february, 2, 28, 29 + march, 3, 31, 31 + april, 4, 30, 30 + ... + + +File: gperf.info, Node: Keywords, Next: Functions, Prev: Declarations, Up: Input Format + +Format for Keyword Entries +-------------------------- + + The second keyfile format section contains lines of keywords and any +associated attributes you might supply. A line beginning with `#' in +the first column is considered a comment. Everything following the `#' +is ignored, up to and including the following newline. + + The first field of each non-comment line is always the key itself. +It should be given as a simple name, *i.e.*, without surrounding string +quotation marks, and be left-justified flush against the first column. +In this context, a "field" is considered to extend up to, but not +include, the first blank, comma, or newline. Here is a simple example +taken from a partial list of C reserved words: + + # These are a few C reserved words, see the c.`gperf' file + # for a complete list of ANSI C reserved words. + unsigned + sizeof + switch + signed + if + default + for + while + return + + Note that unlike `flex' or `bison' the first `%%' marker may be +elided if the declaration section is empty. + + Additional fields may optionally follow the leading keyword. Fields +should be separated by commas, and terminate at the end of line. What +these fields mean is entirely up to you; they are used to initialize the +elements of the user-defined `struct' provided by you in the +declaration section. If the `-t' option is *not* enabled these fields +are simply ignored. All previous examples except the last one contain +keyword attributes. + + +File: gperf.info, Node: Functions, Prev: Keywords, Up: Input Format + +Including Additional C Functions +-------------------------------- + + The optional third section also corresponds closely with conventions +found in `flex' and `bison'. All text in this section, starting at the +final `%%' and extending to the end of the input file, is included +verbatim into the generated output file. Naturally, it is your +responsibility to ensure that the code contained in this section is +valid C. + + +File: gperf.info, Node: Output Format, Prev: Input Format, Up: Description + +Output Format for Generated C Code with `gperf' +=============================================== + + Several options control how the generated C code appears on the +standard output. Two C function are generated. They are called `hash' +and `in_word_set', although you may modify the name for `in_word_set' +with a command-line option. Both functions require two arguments, a +string, `char *' STR, and a length parameter, `int' LEN. Their default +function prototypes are as follows: + + static int hash (char *str, int len); + int in_word_set (char *str, int len); + + By default, the generated `hash' function returns an integer value +created by adding LEN to several user-specified STR key positions +indexed into an "associated values" table stored in a local static +array. The associated values table is constructed internally by +`gperf' and later output as a static local C array called HASH_TABLE; +its meaning and properties are described below. *Note +Implementation::. The relevant key positions are specified via the `-k' +option when running `gperf', as detailed in the *Options* section +below. *Note Options::. + + Two options, `-g' (assume you are compiling with GNU C and its +`inline' feature) and `-a' (assume ANSI C-style function prototypes), +alter the content of both the generated `hash' and `in_word_set' +routines. However, function `in_word_set' may be modified more +extensively, in response to your option settings. The options that +affect the `in_word_set' structure are: + + `-p' + Have function `in_word_set' return a pointer rather than a + boolean. + + `-t' + Make use of the user-defined `struct'. + + `-S TOTAL SWITCH STATEMENTS' + Generate 1 or more C `switch' statement rather than use a + large, (and potentially sparse) static array. Although the + exact time and space savings of this approach vary according + to your C compiler's degree of optimization, this method + often results in smaller and faster code. + + If the `-t', `-S', and `-p' options are omitted the default action +is to generate a `char *' array containing the keys, together with +additional null strings used for padding the array. By experimenting +with the various input and output options, and timing the resulting C +code, you can determine the best option choices for different keyword +set characteristics. + + +File: gperf.info, Node: Options, Next: Bugs, Prev: Description, Up: Top + +Options to the `gperf' Utility +****************************** + + There are *many* options to `gperf'. They were added to make the +program more convenient for use with real applications. "On-line" help +is readily available via the `-h' option. Other options include: + + `-a' + Generate ANSI Standard C code using function prototypes. The + default is to use "classic" K&R C function declaration syntax. + + `-c' + Generates C code that uses the `strncmp' function to perform + string comparisons. The default action is to use `strcmp'. + + `-C' + Makes the contents of all generated lookup tables constant, + *i.e.*, "readonly." Many compilers can generate more + efficient code for this by putting the tables in readonly + memory. + + `-d' + Enables the debugging option. This produces verbose + diagnostics to "standard error" when `gperf' is executing. + It is useful both for maintaining the program and for + determining whether a given set of options is actually + speeding up the search for a solution. Some useful + information is dumped at the end of the program when the `-d' + option is enabled. + + `-D' + Handle keywords whose key position sets hash to duplicate + values. Duplicate hash values occur for two reasons: + + * Since `gperf' does not backtrack it is possible for it + to process all your input keywords without finding a + unique mapping for each word. However, frequently only + a very small number of duplicates occur, and the + majority of keys still require one probe into the table. + + * Sometimes a set of keys may have the same names, but + possess different attributes. With the -D option + `gperf' treats all these keys as part of an equivalence + class and generates a perfect hash function with multiple + comparisons for duplicate keys. It is up to you to + completely disambiguate the keywords by modifying the + generated C code. However, `gperf' helps you out by + organizing the output. + + Option `-D' is extremely useful for certain large or highly + redundant keyword sets, *i.e.*, assembler instruction opcodes. + Using this option usually means that the generated hash + function is no longer perfect. On the other hand, it permits + `gperf' to work on keyword sets that it otherwise could not + handle. + + `-e KEYWORD DELIMITER LIST' + Allows the user to provide a string containing delimiters + used to separate keywords from their attributes. The default + is ",\n". This option is essential if you want to use + keywords that have embedded commas or newlines. One useful + trick is to use -e'TAB', where TAB is the literal tab + character. + + `-E' + Define constant values using an enum local to the lookup + function rather than with #defines. This also means that + different lookup functions can reside in the same file. + Thanks to James Clark (jjc at ai.mit.edu). + + `-f ITERATION AMOUNT' + Generate the perfect hash function "fast." This decreases + `gperf''s running time at the cost of minimizing generated + table-size. The iteration amount represents the number of + times to iterate when resolving a collision. `0' means + `iterate by the number of keywords. This option is probably + most useful when used in conjunction with options `-D' and/or + `-S' for *large* keyword sets. + + `-g' + Assume a GNU compiler, *e.g.*, `g++' or `gcc'. This makes + all generated routines use the "inline" keyword to remove the + cost of function calls. Note that `-g' does *not* imply + `-a', since other non-ANSI C compilers may have provisions + for a function `inline' feature. + + `-G' + Generate the static table of keywords as a static global + variable, rather than hiding it inside of the lookup function + (which is the default behavior). + + `-h' + Prints a short summary on the meaning of each program option. + Aborts further program execution. + + `-H HASH FUNCTION NAME' + Allows you to specify the name for the generated hash + function. Default name is `hash.' This option permits the + use of two hash tables in the same file. + + `-i INITIAL VALUE' + Provides an initial VALUE for the associate values array. + Default is 0. Increasing the initial value helps inflate the + final table size, possibly leading to more time efficient + keyword lookups. Note that this option is not particularly + useful when `-S' is used. Also, `-i' is overriden when the + `-r' option is used. + + `-j JUMP VALUE' + Affects the "jump value," *i.e.*, how far to advance the + associated character value upon collisions. JUMP VALUE is + rounded up to an odd number, the default is 5. If the JUMP + VALUE is 0 `gper f' jumps by random amounts. + + `-k KEYS' + Allows selection of the character key positions used in the + keywords' hash function. The allowable choices range between + 1-126, inclusive. The positions are separated by commas, + *e.g.*, `-k 9,4,13,14'; ranges may be used, *e.g.*, `-k 2-7'; + and positions may occur in any order. Furthermore, the + meta-character '*' causes the generated hash function to + consider *all* character positions in each key, whereas '$' + instructs the hash function to use the "final character" of a + key (this is the only way to use a character position greater + than 126, incidentally). + + For instance, the option `-k 1,2,4,6-10,'$'' generates a hash + function that considers positions 1,2,4,6,7,8,9,10, plus the + last character in each key (which may differ for each key, + obviously). Keys with length less than the indicated key + positions work properly, since selected key positions + exceeding the key length are simply not referenced in the + hash function. + + `-K KEY NAME' + By default, the program assumes the structure component + identifier for the keyword is "name." This option allows an + arbitrary choice of identifier for this component, although + it still must occur as the first field in your supplied + `struct'. + + `-l' + Compare key lengths before trying a string comparison. This + might cut down on the number of string comparisons made + during the lookup, since keys with different lengths are + never compared via `strcmp'. However, using `-l' might + greatly increase the size of the generated C code if the + lookup table range is large (which implies that the switch + option `-S' is not enabled), since the length table contains + as many elements as there are entries in the lookup table. + + `-L GENERATED LANGUAGE NAME' + Instructs `gperf' to generate code in the language specified + by the option's argument. Languages handled are currently + C++ and C. The default is C. + + `-n' + Instructs the generator not to include the length of a + keyword when computing its hash value. This may save a few + assembly instructions in the generated lookup table. + + `-N LOOKUP FUNCTION NAME' + Allows you to specify the name for the generated lookup + function. Default name is `in_word_set.' This option + permits completely automatic generation of perfect hash + functions, especially when multiple generated hash functions + are used in the same application. + + `-o' + Reorders the keywords by sorting the keywords so that + frequently occuring key position set components appear first. + A second reordering pass follows so that keys with "already + determined values" are placed towards the front of the + keylist. This may decrease the time required to generate a + perfect hash function for many keyword sets, and also produce + more minimal perfect hash functions. The reason for this is + that the reordering helps prune the search time by handling + inevitable collisions early in the search process. On the + other hand, if the number of keywords is *very* large using + `-o' may *increase* `gperf''s execution time, since + collisions will begin earlier and continue throughout the + remainder of keyword processing. See Cichelli's paper from + the January 1980 Communications of the ACM for details. + + `-p' + Changes the return value of the generated function + `in_word_set' from boolean (*i.e.*, 0 or 1), to either type + "pointer to user-defined struct," (if the `-t' option is + enabled), or simply to `char *', if `-t' is not enabled. + This option is most useful when the `-t' option (allowing + user-defined structs) is used. For example, it is possible + to automatically generate the GNU C reserved word lookup + routine with the options `-p' and `-t'. + + `-r' + Utilizes randomness to initialize the associated values + table. This frequently generates solutions faster than using + deterministic initialization (which starts all associated + values at 0). Furthermore, using the randomization option + generally increases the size of the table. If `gperf' has + difficultly with a certain keyword set try using `-r' or `-D'. + + `-s SIZE-MULTIPLE' + Affects the size of the generated hash table. The numeric + argument for this option indicates "how many times larger or + smaller" the maximum associated value range should be, in + relationship to the number of keys. If the SIZE-MULTIPLE is + negative the maximum associated value is calculated by + *dividing* it into the total number of keys. For example, a + value of 3 means "allow the maximum associated value to be + about 3 times larger than the number of input keys." + + Conversely, a value of -3 means "allow the maximum associated + value to be about 3 times smaller than the number of input + keys." Negative values are useful for limiting the overall + size of the generated hash table, though this usually + increases the number of duplicate hash values. + + If `generate switch' option `-S' is *not* enabled, the maximum + associated value influences the static array table size, and + a larger table should decrease the time required for an + unsuccessful search, at the expense of extra table space. + + The default value is 1, thus the default maximum associated + value about the same size as the number of keys (for + efficiency, the maximum associated value is always rounded up + to a power of 2). The actual table size may vary somewhat, + since this technique is essentially a heuristic. In + particular, setting this value too high slows down `gperf''s + runtime, since it must search through a much larger range of + values. Judicious use of the `-f' option helps alleviate this + overhead, however. + + `-S TOTAL SWITCH STATEMENTS' + Causes the generated C code to use a `switch' statement + scheme, rather than an array lookup table. This can lead to + a reduction in both time and space requirements for some + keyfiles. The argument to this option determines how many + `switch' statements are generated. A value of 1 generates 1 + `switch' containing all the elements, a value of 2 generates + 2 tables with 1/2 the elements in each `switch', etc. This + is useful since many C compilers cannot correctly generate + code for large `switch' statements. This option was inspired + in part by Keith Bostic's original C program. + + `-t' + Allows you to include a `struct' type declaration for + generated code. Any text before a pair of consecutive %% is + consider part of the type declaration. Key words and + additional fields may follow this, one group of fields per + line. A set of examples for generating perfect hash tables + and functions for Ada, C, and G++, Pascal, and Modula 2 and 3 + reserved words are distributed with this release. + + `-T' + Prevents the transfer of the type declaration to the output + file. Use this option if the type is already defined + elsewhere. + + `-v' + Prints out the current version number. + + `-Z CLASS NAME' + Allow user to specify name of generated C++ class. Default + name is `Perfect_Hash'. + + +File: gperf.info, Node: Bugs, Next: Projects, Prev: Options, Up: Top + +Known Bugs and Limitations with `gperf' +*************************************** + + The following are some limitations with the current release of +`gperf': + + * The `gperf' utility is tuned to execute quickly, and works quickly + for small to medium size data sets (around 1000 keywords). It is + extremely useful for maintaining perfect hash functions for + compiler keyword sets. Several recent enhancements now enable + `gperf' to work efficiently on much larger keyword sets (over + 15,000 keywords). When processing large keyword sets it helps + greatly to have over 8 megs of RAM. + + However, since `gperf' does not backtrack no guaranteed solution + occurs on every run. On the other hand, it is usually easy to + obtain a solution by varying the option parameters. In + particular, try the `-r' option, and also try changing the default + arguments to the `-s' and `-j' options. To *guarantee* a + solution, use the `-D' and `-S' options, although the final + results are not likely to be a *perfect* hash function anymore! + Finally, use the `-f' option if you want `gperf' to generate the + perfect hash function *fast*, with less emphasis on making it + minimal. + + * The size of the generate static keyword array can get *extremely* + large if the input keyword file is large or if the keywords are + quite similar. This tends to slow down the compilation of the + generated C code, and *greatly* inflates the object code size. If + this situation occurs, consider using the `-S' option to reduce + data size, potentially increasing keyword recognition time a + negligible amount. Since many C compilers cannot correctly + generated code for large switch statements it is important to + qualify the -S option with an appropriate numerical argument that + controls the number of switch statements generated. + + * The maximum number of key positions selected for a given key has an + arbitrary limit of 126. This restriction should be removed, and if + anyone considers this a problem write me and let me know so I can + remove the constraint. + + * The C++ source code only compiles correctly with GNU G++, version + 1.36 (and hopefully later versions). Porting to AT&T cfront would + be tedious, but possible (and desirable). There is also a K&R C + version available now. This should compile without change on most + BSD systems, but may require a bit of work to run on SYSV, since + `gperf' uses ALLOCA in several places. Send mail to schmidt at + ics.uci.edu for information. + + +File: gperf.info, Node: Projects, Next: Implementation, Prev: Bugs, Up: Top + +Things Still Left to Do +*********************** + + It should be "relatively" easy to replace the current perfect hash +function algorithm with a more exhaustive approach; the perfect hash +module is essential independent from other program modules. Additional +worthwhile improvements include: + + * Make the algorithm more robust. At present, the program halts + with an error diagnostic if it can't find a direct solution and + the `-D' option is not enabled. A more comprehensive, albeit + computationally expensive, approach would employ backtracking or + enable alternative options and retry. It's not clear how helpful + this would be, in general, since most search sets are rather small + in practice. + + * Another useful extension involves modifying the program to generate + "minimal" perfect hash functions (under certain circumstances, the + current version can be rather extravagant in the generated table + size). Again, this is mostly of theoretical interest, since a + sparse table often produces faster lookups, and use of the `-S' + `switch' option can minimize the data size, at the expense of + slightly longer lookups (note that the gcc compiler generally + produces good code for `switch' statements, reducing the need for + more complex schemes). + + * In addition to improving the algorithm, it would also be useful to + generate a C++ class or Ada package as the code output, in + addition to the current C routines. + + +File: gperf.info, Node: Implementation, Next: Bibliography, Prev: Projects, Up: Top + +Implementation Details of GNU `gperf' +************************************* + + A paper describing the high-level description of the data structures +and algorithms used to implement `gperf' will soon be available. This +paper is useful not only from a maintenance and enhancement perspective, +but also because they demonstrate several clever and useful programming +techniques, *e.g.*, `Iteration Number' boolean arrays, double hashing, +a "safe" and efficient method for reading arbitrarily long input from a +file, and a provably optimal algorithm for simultaneously determining +both the minimum and maximum elements in a list. + + +File: gperf.info, Node: Bibliography, Prev: Implementation, Up: Top + +Bibliography +************ + + [1] Chang, C.C.: A Scheme for Constructing Ordered Minimal Perfect +Hashing Functions Information Sciences 39(1986), 187-195. + + [2] Cichelli, Richard J. Author's Response to "On Cichelli's Minimal +Perfec t Hash Functions Method" Communications of the ACM, 23, +12(December 1980), 729. + + [3] Cichelli, Richard J. Minimal Perfect Hash Functions Made Simple +Communications of the ACM, 23, 1(January 1980), 17-19. + + [4] Cook, C. R. and Oldehoeft, R.R. A Letter Oriented Minimal +Perfect Hashing Function SIGPLAN Notices, 17, 9(September 1982), 18-27. + + [5] Cormack, G. V. and Horspool, R. N. S. and Kaiserwerth, M. +Practical Perfect Hashing Computer Journal, 28, 1(January 1985), 54-58. + + [6] Jaeschke, G. Reciprocal Hashing: A Method for Generating Minimal +Perfect Hashing Functions Communications of the ACM, 24, 12(December +1981), 829-833. + + [7] Jaeschke, G. and Osterburg, G. On Cichelli's Minimal Perfect +Hash Functions Method Communications of the ACM, 23, 12(December 1980), +728-729. + + [8] Sager, Thomas J. A Polynomial Time Generator for Minimal Perfect +Hash Functions Communications of the ACM, 28, 5(December 1985), 523-532 + + [9] Schmidt, Douglas C. GPERF: A Perfect Hash Function Generator +Second USENIX C++ Conference Proceedings, April 1990. + + [10] Sebesta, R.W. and Taylor, M.A. Minimal Perfect Hash Functions +for Reserved Word Lists SIGPLAN Notices, 20, 12(September 1985), 47-53. + + [11] Sprugnoli, R. Perfect Hashing Functions: A Single Probe +Retrieving Method for Static Sets Communications of the ACM, 20 +11(November 1977), 841-850. + + [12] Stallman, Richard M. Using and Porting GNU CC Free Software +Foundation, 1988. + + [13] Stroustrup, Bjarne The C++ Programming Language. +Addison-Wesley, 1986. + + [14] Tiemann, Michael D. User's Guide to GNU C++ Free Software +Foundation, 1989. + + + +Tag Table: +Node: Top1218 +Node: Copying2456 +Node: Contributors15759 +Node: Motivation16859 +Node: Search Structures18126 +Node: Description21679 +Node: Input Format23499 +Node: Declarations24294 +Node: Keywords26601 +Node: Functions28192 +Node: Output Format28686 +Node: Options31156 +Node: Bugs44526 +Node: Projects47213 +Node: Implementation48790 +Node: Bibliography49509 + +End Tag Table diff --git a/apps/gperf/gperf.texi b/apps/gperf/gperf.texi new file mode 100644 index 00000000000..649d05f7ec6 --- /dev/null +++ b/apps/gperf/gperf.texi @@ -0,0 +1,1184 @@ +\input texinfo @c -*-texinfo-*- + +@settitle User's Guide to @code{gperf} +@setfilename gperf.info + +@ifinfo +@format +START-INFO-DIR-ENTRY +* Gperf: (gperf). Perfect Hash Function Generator. +END-INFO-DIR-ENTRY +@end format +@end ifinfo + +@ifinfo +This file documents the features of the GNU Perfect Hash Function Generator + +Copyright (C) 1989 Free Software Foundation, Inc. + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +@ignore +Permission is granted to process this file through @TeX{} and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph +(this paragraph not being relevant to the printed manual). + +@end ignore + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that the +section entitled ``GNU General Public License'' is included exactly as +in the original, and provided that the entire resulting derived work is +distributed under the terms of a permission notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that the section entitled ``GNU @code{gperf} General Public License'' an +d +this permission notice may be included in translations approved by the +Free Software Foundation instead of in the original English. +@end ifinfo + +@setchapternewpage odd + +@titlepage +@center @titlefont{User's Guide} +@sp 2 +@center @titlefont{for the} +@sp 2 +@center @titlefont{GNU GPERF Utility} +@sp 4 +@center Douglas C. Schmidt +@sp 3 +@center last updated 1 November 1989 +@sp 1 +@center for version 2.0 +@page +@vskip 0pt plus 1filll +Copyright @copyright{} 1989 Free Software Foundation, Inc. + + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that the +section entitled ``GNU @code{gperf} General Public License'' is included exactl +y as +in the original, and provided that the entire resulting derived work is +distributed under the terms of a permission notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that the section entitled ``GNU @code{gperf} General Public License'' ma +y be +included in a translation approved by the author instead of in the original +English. +@end titlepage + +@ifinfo +@node Top, Copying, (dir), (dir) +@ichapter Introduction + +This manual documents the GNU @code{gperf} perfect hash function generator +utility, focusing on its features and how to use them, and how to report +bugs. + +@end ifinfo +@menu +* Copying:: GNU @code{gperf} General Public License says + how you can copy and share @code{gperf}. +* Contributors:: People who have contributed to @code{gperf}. +* Motivation:: Static search structures and GNU GPERF. +* Search Structures:: Static search structures and GNU @code{gperf} +* Description:: High-level discussion of how GPERF functions. +* Options:: A description of options to the program. +* Bugs:: Known bugs and limitations with GPERF. +* Projects:: Things still left to do. +* Implementation:: Implementation Details for GNU GPERF. +* Bibliography:: Material Referenced in this Report. + + --- The Detailed Node Listing --- + +High-Level Description of GNU @code{gperf} + +* Input Format:: Input Format to @code{gperf} +* Output Format:: Output Format for Generated C Code with @code{gperf} + +Input Format to @code{gperf} + +* Declarations:: @code{struct} Declarations and C Code Inclusion. +* Keywords:: Format for Keyword Entries. +* Functions:: Including Additional C Functions. +@end menu + +@node Copying, Contributors, Top, Top +@unnumbered GNU GENERAL PUBLIC LICENSE +@center Version 1, February 1989 + +@display +Copyright @copyright{} 1989 Free Software Foundation, Inc. +675 Mass Ave, Cambridge, MA 02139, USA + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. +@end display + +@unnumberedsec Preamble + + The license agreements of most software companies try to keep users +at the mercy of those companies. By contrast, our General Public +License is intended to guarantee your freedom to share and change free +software---to make sure the software is free for all its users. The +General Public License applies to the Free Software Foundation's +software and to any other program whose authors commit to using it. +You can use it for your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Specifically, the General Public License is designed to make +sure that you have the freedom to give away or sell copies of free +software, that you receive source code or can get it if you want it, +that you can change the software or use pieces of it in new free +programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of a such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must tell them their rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + The precise terms and conditions for copying, distribution and +modification follow. + +@iftex +@unnumberedsec TERMS AND CONDITIONS +@end iftex +@ifinfo +@center TERMS AND CONDITIONS +@end ifinfo + +@enumerate +@item +This License Agreement applies to any program or other work which +contains a notice placed by the copyright holder saying it may be +distributed under the terms of this General Public License. The +``Program'', below, refers to any such program or work, and a ``work based +on the Program'' means either the Program or any work containing the +Program or a portion of it, either verbatim or with modifications. Each +licensee is addressed as ``you''. + +@item +You may copy and distribute verbatim copies of the Program's source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this +General Public License and to the absence of any warranty; and give any +other recipients of the Program a copy of this General Public License +along with the Program. You may charge a fee for the physical act of +transferring a copy. + +@item +You may modify your copy or copies of the Program or any portion of +it, and copy and distribute such modifications under the terms of Paragraph +1 above, provided that you also do the following: + +@itemize @bullet +@item +cause the modified files to carry prominent notices stating that +you changed the files and the date of any change; and + +@item +cause the whole of any work that you distribute or publish, that +in whole or in part contains the Program or any part thereof, either +with or without modifications, to be licensed at no charge to all +third parties under the terms of this General Public License (except +that you may choose to grant warranty protection to some or all +third parties, at your option). + +@item +If the modified program normally reads commands interactively when +run, you must cause it, when started running for such interactive use +in the simplest and most usual way, to print or display an +announcement including an appropriate copyright notice and a notice +that there is no warranty (or else, saying that you provide a +warranty) and that users may redistribute the program under these +conditions, and telling the user how to view a copy of this General +Public License. + +@item +You may charge a fee for the physical act of transferring a +copy, and you may at your option offer warranty protection in +exchange for a fee. +@end itemize + +Mere aggregation of another independent work with the Program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other work under the scope of these terms. + +@item +You may copy and distribute the Program (or a portion or derivative of +it, under Paragraph 2) in object code or executable form under the terms of +Paragraphs 1 and 2 above provided that you also do one of the following: + +@itemize @bullet +@item +accompany it with the complete corresponding machine-readable +source code, which must be distributed under the terms of +Paragraphs 1 and 2 above; or, + +@item +accompany it with a written offer, valid for at least three +years, to give any third party free (except for a nominal charge +for the cost of distribution) a complete machine-readable copy of the +corresponding source code, to be distributed under the terms of +Paragraphs 1 and 2 above; or, + +@item +accompany it with the information you received as to where the +corresponding source code may be obtained. (This alternative is +allowed only for noncommercial distribution and only if you +received the program in object code or executable form alone.) +@end itemize + +Source code for a work means the preferred form of the work for making +modifications to it. For an executable file, complete source code means +all the source code for all modules it contains; but, as a special +exception, it need not include source code for modules which are standard +libraries that accompany the operating system on which the executable +file runs, or for standard header files or definitions files that +accompany that operating system. + +@item +You may not copy, modify, sublicense, distribute or transfer the +Program except as expressly provided under this General Public License. +Any attempt otherwise to copy, modify, sublicense, distribute or transfer +the Program is void, and will automatically terminate your rights to use +the Program under this License. However, parties who have received +copies, or rights to use copies, from you under this General Public +License will not have their licenses terminated so long as such parties +remain in full compliance. + +@item +By copying, distributing or modifying the Program (or any work based +on the Program) you indicate your acceptance of this license to do so, +and all its terms and conditions. + +@item +Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the original +licensor to copy, distribute or modify the Program subject to these +terms and conditions. You may not impose any further restrictions on the +recipients' exercise of the rights granted herein. + +@item +The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of the license which applies to it and ``any +later version'', you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +the license, you may choose any version ever published by the Free Software +Foundation. + +@item +If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + +@iftex +@heading NO WARRANTY +@end iftex +@ifinfo +@center NO WARRANTY +@end ifinfo + +@item +BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + +@item +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL +ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT +LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES +SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE +WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN +ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +@end enumerate + +@iftex +@heading END OF TERMS AND CONDITIONS +@end iftex +@ifinfo +@center END OF TERMS AND CONDITIONS +@end ifinfo + +@page +@unnumberedsec Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to humanity, the best way to achieve this is to make it +free software which everyone can redistribute and change under these +terms. + + To do so, attach the following notices to the program. It is safest to +attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the +``copyright'' line and a pointer to where the full notice is found. + +@smallexample +@var{one line to give the program's name and a brief idea of what it does.} +Copyright (C) 19@var{yy} @var{name of author} + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +@end smallexample + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + +@smallexample +Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author} +Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. +This is free software, and you are welcome to redistribute it +under certain conditions; type `show c' for details. +@end smallexample + +The hypothetical commands `show w' and `show c' should show the +appropriate parts of the General Public License. Of course, the +commands you use may be called something other than `show w' and `show +c'; they could even be mouse-clicks or menu items---whatever suits your +program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a ``copyright disclaimer'' for the program, if +necessary. Here a sample; alter the names: + +@example +Yoyodyne, Inc., hereby disclaims all copyright interest in the +program `Gnomovision' (a program to direct compilers to make passes +at assemblers) written by James Hacker. + +@var{signature of Ty Coon}, 1 April 1989 +Ty Coon, President of Vice +@end example + +That's all there is to it! + +@node Contributors, Motivation, Copying, Top +@unnumbered Contributors to GNU @code{gperf} Utility + +@itemize @bullet +@item +The GNU @code{gperf} perfect hash function generator utility was +originally written in GNU C++ by Douglas C. Schmidt. It is now also +available in a highly-portable ``old-style'' C version. The general +idea for the perfect hash function generator was inspired by Keith +Bostic's algorithm written in C, and distributed to net.sources around +1984. The current program is a heavily modified, enhanced, and extended +implementation of Keith's basic idea, created at the University of +California, Irvine. Bugs, patches, and suggestions should be reported +to schmidt at ics.uci.edu. + +@item +Special thanks is extended to Michael Tiemann and Doug Lea, for +providing a useful compiler, and for giving me a forum to exhibit my +creation. + +In addition, Adam de Boor and Nels Olson provided many tips and insights +that greatly helped improve the quality and functionality of @code{gperf}. +@end itemize + +@node Motivation, Search Structures, Contributors, Top +@chapter Introduction + +@code{gperf} is a perfect hash function generator written in C++. It +transforms an @emph{n} element user-specified keyword set @emph{W} into +a perfect hash function @emph{F}. @emph{F} uniquely maps keywords in +@emph{W} onto the range 0..@emph{k}, where @emph{k} >= @emph{n}. If +@emph{k = n} then @emph{F} is a @emph{minimal} perfect hash function. +@code{gperf} generates a 0..@emph{k} element static lookup table and a +pair of C functions. These functions determine whether a given +character string @emph{s} occurs in @emph{W}, using at most one probe +into the lookup table. + +@code{gperf} currently generates the reserved keyword recognizer for +lexical analyzers in several production and research compilers and +language processing tools, including GNU C, GNU C++, GNU Pascal, GNU +Modula 3, and GNU indent. Complete C++ source code for @code{gperf} is +available via anonymous ftp from ics.uci.edu. @code{gperf} also is +distributed along with the GNU libg++ library. A highly portable, +functionally equivalent K&R C version of @code{gperf} is archived in +comp.sources.unix, volume 20. Finally, a paper describing +@code{gperf}'s design and implementation in greater detail is available +in the Second USENIX C++ Conference proceedings. + +@node Search Structures, Description, Motivation, Top +@chapter Static search structures and GNU @code{gperf} + +A @dfn{static search structure} is an Abstract Data Type with certain +fundamental operations, @emph{e.g.}, @emph{initialize}, @emph{insert}, +and @emph{retrieve}. Conceptually, all insertions occur before any +retrievals. In practice, @code{gperf} generates a @code{static} array +containing search set keywords and any associated attributes specified +by the user. Thus, there is essentially no execution-time cost for the +insertions. It is a useful data structure for representing @emph{static +search sets}. Static search sets occur frequently in software system +applications. Typical static search sets include compiler reserved +words, assembler instruction opcodes, and built-in shell interpreter +commands. Search set members, called @dfn{keywords}, are inserted into +the structure only once, usually during program initialization, and are +not generally modified at run-time. + +Numerous static search structure implementations exist, @emph{e.g.}, +arrays, linked lists, binary search trees, digital search tries, and +hash tables. Different approaches offer trade-offs between space +utilization and search time efficiency. For example, an @emph{n} element +sorted array is space efficient, though the average-case time +complexity for retrieval operations using binary search is +proportional to log @emph{n}. Conversely, hash table implementations +often locate a table entry in constant time, but typically impose +additional memory overhead and exhibit poor worst case performance. + + +@emph{Minimal perfect hash functions} provide an optimal solution for a +particular class of static search sets. A minimal perfect hash +function is defined by two properties: + +@itemize @bullet +@item +It allows keyword recognition in a static search set using at most +@emph{one} probe into the hash table. This represents the ``perfect'' +property. +@item +The actual memory allocated to store the keywords is precisely large +enough for the keyword set, and @emph{no larger}. This is the +``minimal'' property. +@end itemize + +For most applications it is far easier to generate @emph{perfect} hash +functions than @emph{minimal perfect} hash functions. Moreover, +non-minimal perfect hash functions frequently execute faster than +minimal ones in practice. This phenomena occurs since searching a +sparse keyword table increases the probability of locating a ``null'' +entry, thereby reducing string comparisons. @code{gperf}'s default +behavior generates @emph{near-minimal} perfect hash functions for +keyword sets. However, @code{gperf} provides many options that permit +user control over the degree of minimality and perfection. + +Static search sets often exhibit relative stability over time. For +example, Ada's 63 reserved words have remained constant for nearly a +decade. It is therefore frequently worthwhile to expend concerted +effort building an optimal search structure @emph{once}, if it +subsequently receives heavy use multiple times. @code{gperf} removes +the drudgery associated with constructing time- and space-efficient +search structures by hand. It has proven a useful and practical tool +for serious programming projects. Output from @code{gperf} is currently +used in several production and research compilers, including GNU C, GNU +C++, GNU Pascal, and GNU Modula 3. The latter two compilers are not yet +part of the official GNU distribution. Each compiler utilizes +@code{gperf} to automatically generate static search structures that +efficiently identify their respective reserved keywords. + +@node Description, Options, Search Structures, Top +@chapter High-Level Description of GNU @code{gperf} + +@menu +* Input Format:: Input Format to @code{gperf} +* Output Format:: Output Format for Generated C Code with @code{gperf} +@end menu + +The perfect hash function generator @code{gperf} reads a set of +``keywords'' from a @dfn{keyfile} (or from the standard input by +default). It attempts to derive a perfect hashing function that +recognizes a member of the @dfn{static keyword set} with at most a +single probe into the lookup table. If @code{gperf} succeeds in +generating such a function it produces a pair of C source code routines +that perform hashing and table lookup recognition. All generated C code +is directed to the standard output. Command-line options described +below allow you to modify the input and output format to @code{gperf}. + +By default, @code{gperf} attempts to produce time-efficient code, with +less emphasis on efficient space utilization. However, several options +exist that permit trading-off execution time for storage space and vice +versa. In particular, expanding the generated table size produces a +sparse search structure, generally yielding faster searches. +Conversely, you can direct @code{gperf} to utilize a C @code{switch} +statement scheme that minimizes data space storage size. Furthermore, +using a C @code{switch} may actually speed up the keyword retrieval time +somewhat. Actual results depend on your C compiler, of course. + +In general, @code{gperf} assigns values to the characters it is using +for hashing until some set of values gives each keyword a unique value. +A helpful heuristic is that the larger the hash value range, the easier +it is for @code{gperf} to find and generate a perfect hash function. +Experimentation is the key to getting the most from @code{gperf}. + +@node Input Format, Output Format, Description, Description +@section Input Format to @code{gperf} + +You can control the input keyfile format by varying certain command-line +arguments, in particular the @samp{-t} option. The input's appearance +is similar to GNU utilities @code{flex} and @code{bison} (or UNIX +utilities @code{lex} and @code{yacc}). Here's an outline of the general +format: + +@example +@group +declarations +%% +keywords +%% +functions +@end group +@end example + +@emph{Unlike} @code{flex} or @code{bison}, all sections of @code{gperf}'s input +are optional. The following sections describe the input format for each +section. + +@menu +* Declarations:: @code{struct} Declarations and C Code Inclusion. +* Keywords:: Format for Keyword Entries. +* Functions:: Including Additional C Functions. +@end menu + +@node Declarations, Keywords, Input Format, Input Format +@subsection @code{struct} Declarations and C Code Inclusion + +The keyword input file optionally contains a section for including +arbitrary C declarations and definitions, as well as provisions for +providing a user-supplied @code{struct}. If the @samp{-t} option +@emph{is} enabled, you @emph{must} provide a C @code{struct} as the last +component in the declaration section from the keyfile file. The first +field in this struct must be a @code{char *} identifier called ``name,'' +although it is possible to modify this field's name with the @samp{-K} +option described below. + +Here is simple example, using months of the year and their attributes as +input: + +@example +@group +struct months @{ char *name; int number; int days; int leap_days; @}; +%% +january, 1, 31, 31 +february, 2, 28, 29 +march, 3, 31, 31 +april, 4, 30, 30 +may, 5, 31, 31 +june, 6, 30, 30 +july, 7, 31, 31 +august, 8, 31, 31 +september, 9, 30, 30 +october, 10, 31, 31 +november, 11, 30, 30 +december, 12, 31, 31 +@end group +@end example + +Separating the @code{struct} declaration from the list of key words and +other fields are a pair of consecutive percent signs, @code{%%}, +appearing left justified in the first column, as in the UNIX utility +@code{lex}. + +Using a syntax similar to GNU utilities @code{flex} and @code{bison}, it +is possible to directly include C source text and comments verbatim into +the generated output file. This is accomplished by enclosing the region +inside left-justified surrounding @code{%@{}, @code{%@}} pairs. Here is +an input fragment based on the previous example that illustrates this +feature: + +@example +@group +%@{ +#include +/* This section of code is inserted directly into the output. */ +int return_month_days (struct months *months, int is_leap_year); +%@} +struct months @{ char *name; int number; int days; int leap_days; @}; +%% +january, 1, 31, 31 +february, 2, 28, 29 +march, 3, 31, 31 +... +@end group +@end example + +It is possible to omit the declaration section entirely. In this case +the keyfile begins directly with the first keyword line, @emph{e.g.}: + +@example +@group +january, 1, 31, 31 +february, 2, 28, 29 +march, 3, 31, 31 +april, 4, 30, 30 +... +@end group +@end example + +@node Keywords, Functions, Declarations, Input Format +@subsection Format for Keyword Entries + +The second keyfile format section contains lines of keywords and any +associated attributes you might supply. A line beginning with @samp{#} +in the first column is considered a comment. Everything following the +@samp{#} is ignored, up to and including the following newline. + +The first field of each non-comment line is always the key itself. It +should be given as a simple name, @emph{i.e.}, without surrounding +string quotation marks, and be left-justified flush against the first +column. In this context, a ``field'' is considered to extend up to, but +not include, the first blank, comma, or newline. Here is a simple +example taken from a partial list of C reserved words: + +@example +@group +# These are a few C reserved words, see the c.@code{gperf} file +# for a complete list of ANSI C reserved words. +unsigned +sizeof +switch +signed +if +default +for +while +return +@end group +@end example + +Note that unlike @code{flex} or @code{bison} the first @code{%%} marker +may be elided if the declaration section is empty. + +Additional fields may optionally follow the leading keyword. Fields +should be separated by commas, and terminate at the end of line. What +these fields mean is entirely up to you; they are used to initialize the +elements of the user-defined @code{struct} provided by you in the +declaration section. If the @samp{-t} option is @emph{not} enabled +these fields are simply ignored. All previous examples except the last +one contain keyword attributes. + +@node Functions, , Keywords, Input Format +@subsection Including Additional C Functions + +The optional third section also corresponds closely with conventions +found in @code{flex} and @code{bison}. All text in this section, +starting at the final @code{%%} and extending to the end of the input +file, is included verbatim into the generated output file. Naturally, +it is your responsibility to ensure that the code contained in this +section is valid C. + +@node Output Format, , Input Format, Description +@section Output Format for Generated C Code with @code{gperf} + +Several options control how the generated C code appears on the standard +output. Two C function are generated. They are called @code{hash} and +@code{in_word_set}, although you may modify the name for +@code{in_word_set} with a command-line option. Both functions require +two arguments, a string, @code{char *} @var{str}, and a length +parameter, @code{int} @var{len}. Their default function prototypes are +as follows: + +@example +@group +static int hash (char *str, int len); +int in_word_set (char *str, int len); +@end group +@end example + +By default, the generated @code{hash} function returns an integer value +created by adding @var{len} to several user-specified @var{str} key +positions indexed into an @dfn{associated values} table stored in a +local static array. The associated values table is constructed +internally by @code{gperf} and later output as a static local C array called +@var{hash_table}; its meaning and properties are described below. +@xref{Implementation}. The relevant key positions are specified via the +@samp{-k} option when running @code{gperf}, as detailed in the @emph{Options} +section below. @xref{Options}. + +Two options, @samp{-g} (assume you are compiling with GNU C and its +@code{inline} feature) and @samp{-a} (assume ANSI C-style function +prototypes), alter the content of both the generated @code{hash} and +@code{in_word_set} routines. However, function @code{in_word_set} may +be modified more extensively, in response to your option settings. The +options that affect the @code{in_word_set} structure are: + +@itemize @bullet +@table @samp +@item -p +Have function @code{in_word_set} return a pointer rather than a boolean. + +@item -t +Make use of the user-defined @code{struct}. + +@item -S @var{total switch statements} +Generate 1 or more C @code{switch} statement rather than use a large, +(and potentially sparse) static array. Although the exact time and +space savings of this approach vary according to your C compiler's +degree of optimization, this method often results in smaller and faster +code. +@end table +@end itemize + +If the @samp{-t}, @samp{-S}, and @samp{-p} options are omitted the +default action is to generate a @code{char *} array containing the keys, +together with additional null strings used for padding the array. By +experimenting with the various input and output options, and timing the +resulting C code, you can determine the best option choices for +different keyword set characteristics. + +@node Options, Bugs, Description, Top +@chapter Options to the @code{gperf} Utility + +There are @emph{many} options to @code{gperf}. They were added to make +the program more convenient for use with real applications. ``On-line'' +help is readily available via the @samp{-h} option. Other options +include: + +@itemize @bullet +@table @samp +@item -a +Generate ANSI Standard C code using function prototypes. The default is +to use ``classic'' K&R C function declaration syntax. + +@item -c +Generates C code that uses the @code{strncmp} function to perform +string comparisons. The default action is to use @code{strcmp}. + +@item -C +Makes the contents of all generated lookup tables constant, @emph{i.e.}, +``readonly.'' Many compilers can generate more efficient code for this +by putting the tables in readonly memory. + +@item -d +Enables the debugging option. This produces verbose diagnostics to +``standard error'' when @code{gperf} is executing. It is useful both for +maintaining the program and for determining whether a given set of +options is actually speeding up the search for a solution. Some useful +information is dumped at the end of the program when the @samp{-d} +option is enabled. + +@item -D +Handle keywords whose key position sets hash to duplicate values. +Duplicate hash values occur for two reasons: + +@itemize @bullet +@item +Since @code{gperf} does not backtrack it is possible for it to process +all your input keywords without finding a unique mapping for each word. +However, frequently only a very small number of duplicates occur, and +the majority of keys still require one probe into the table. +@item +Sometimes a set of keys may have the same names, but possess different +attributes. With the -D option @code{gperf} treats all these keys as part of +an equivalence class and generates a perfect hash function with multiple +comparisons for duplicate keys. It is up to you to completely +disambiguate the keywords by modifying the generated C code. However, +@code{gperf} helps you out by organizing the output. +@end itemize + +Option @samp{-D} is extremely useful for certain large or highly +redundant keyword sets, @emph{i.e.}, assembler instruction opcodes. +Using this option usually means that the generated hash function is no +longer perfect. On the other hand, it permits @code{gperf} to work on +keyword sets that it otherwise could not handle. + +@item -e @var{keyword delimiter list} +Allows the user to provide a string containing delimiters used to +separate keywords from their attributes. The default is ",\n". This +option is essential if you want to use keywords that have embedded +commas or newlines. One useful trick is to use -e'TAB', where TAB is +the literal tab character. + +@item -E +Define constant values using an enum local to the lookup function rather +than with #defines. This also means that different lookup functions can +reside in the same file. Thanks to James Clark (jjc at ai.mit.edu). + +@item -f @var{iteration amount} +Generate the perfect hash function ``fast.'' This decreases @code{gperf}'s +running time at the cost of minimizing generated table-size. The +iteration amount represents the number of times to iterate when +resolving a collision. `0' means `iterate by the number of keywords. +This option is probably most useful when used in conjunction with options +@samp{-D} and/or @samp{-S} for @emph{large} keyword sets. + +@item -g +Assume a GNU compiler, @emph{e.g.}, @code{g++} or @code{gcc}. This +makes all generated routines use the ``inline'' keyword to remove the +cost of function calls. Note that @samp{-g} does @emph{not} imply +@samp{-a}, since other non-ANSI C compilers may have provisions for a +function @code{inline} feature. + +@item -G +Generate the static table of keywords as a static global variable, +rather than hiding it inside of the lookup function (which is the +default behavior). + +@item -h +Prints a short summary on the meaning of each program option. Aborts +further program execution. + +@item -H @var{hash function name} +Allows you to specify the name for the generated hash function. Default +name is `hash.' This option permits the use of two hash tables in the +same file. + +@item -i @var{initial value} +Provides an initial @var{value} for the associate values array. Default +is 0. Increasing the initial value helps inflate the final table size, +possibly leading to more time efficient keyword lookups. Note that this +option is not particularly useful when @samp{-S} is used. Also, +@samp{-i} is overriden when the @samp{-r} option is used. + +@item -j @var{jump value} +Affects the ``jump value,'' @emph{i.e.}, how far to advance the +associated character value upon collisions. @var{Jump value} is rounded +up to an odd number, the default is 5. If the @var{jump value} is 0 @code{gper +f} +jumps by random amounts. + +@item -k @var{keys} +Allows selection of the character key positions used in the keywords' +hash function. The allowable choices range between 1-126, inclusive. +The positions are separated by commas, @emph{e.g.}, @samp{-k 9,4,13,14}; +ranges may be used, @emph{e.g.}, @samp{-k 2-7}; and positions may occur +in any order. Furthermore, the meta-character '*' causes the generated +hash function to consider @strong{all} character positions in each key, +whereas '$' instructs the hash function to use the ``final character'' +of a key (this is the only way to use a character position greater than +126, incidentally). + +For instance, the option @samp{-k 1,2,4,6-10,'$'} generates a hash +function that considers positions 1,2,4,6,7,8,9,10, plus the last +character in each key (which may differ for each key, obviously). Keys +with length less than the indicated key positions work properly, since +selected key positions exceeding the key length are simply not +referenced in the hash function. + +@item -K @var{key name} +By default, the program assumes the structure component identifier for +the keyword is ``name.'' This option allows an arbitrary choice of +identifier for this component, although it still must occur as the first +field in your supplied @code{struct}. + +@item -l +Compare key lengths before trying a string comparison. This might cut +down on the number of string comparisons made during the lookup, since +keys with different lengths are never compared via @code{strcmp}. +However, using @samp{-l} might greatly increase the size of the +generated C code if the lookup table range is large (which implies that +the switch option @samp{-S} is not enabled), since the length table +contains as many elements as there are entries in the lookup table. + +@item -L @var{generated language name} +Instructs @code{gperf} to generate code in the language specified by the +option's argument. Languages handled are currently C++ and C. The +default is C. + +@item -n +Instructs the generator not to include the length of a keyword when +computing its hash value. This may save a few assembly instructions in +the generated lookup table. + +@item -N @var{lookup function name} +Allows you to specify the name for the generated lookup function. +Default name is `in_word_set.' This option permits completely automatic +generation of perfect hash functions, especially when multiple generated +hash functions are used in the same application. + +@item -o +Reorders the keywords by sorting the keywords so that frequently +occuring key position set components appear first. A second reordering +pass follows so that keys with ``already determined values'' are placed +towards the front of the keylist. This may decrease the time required +to generate a perfect hash function for many keyword sets, and also +produce more minimal perfect hash functions. The reason for this is +that the reordering helps prune the search time by handling inevitable +collisions early in the search process. On the other hand, if the +number of keywords is @emph{very} large using @samp{-o} may +@emph{increase} @code{gperf}'s execution time, since collisions will begin +earlier and continue throughout the remainder of keyword processing. +See Cichelli's paper from the January 1980 Communications of the ACM for +details. + +@item -p +Changes the return value of the generated function @code{in_word_set} +from boolean (@emph{i.e.}, 0 or 1), to either type ``pointer to +user-defined struct,'' (if the @samp{-t} option is enabled), or simply +to @code{char *}, if @samp{-t} is not enabled. This option is most +useful when the @samp{-t} option (allowing user-defined structs) is +used. For example, it is possible to automatically generate the GNU C +reserved word lookup routine with the options @samp{-p} and @samp{-t}. + +@item -r +Utilizes randomness to initialize the associated values table. This +frequently generates solutions faster than using deterministic +initialization (which starts all associated values at 0). Furthermore, +using the randomization option generally increases the size of the +table. If @code{gperf} has difficultly with a certain keyword set try using +@samp{-r} or @samp{-D}. + +@item -s @var{size-multiple} +Affects the size of the generated hash table. The numeric argument for +this option indicates ``how many times larger or smaller'' the maximum +associated value range should be, in relationship to the number of keys. +If the @var{size-multiple} is negative the maximum associated value is +calculated by @emph{dividing} it into the total number of keys. For +example, a value of 3 means ``allow the maximum associated value to be +about 3 times larger than the number of input keys.'' + +Conversely, a value of -3 means ``allow the maximum associated value to +be about 3 times smaller than the number of input keys.'' Negative +values are useful for limiting the overall size of the generated hash +table, though this usually increases the number of duplicate hash +values. + +If `generate switch' option @samp{-S} is @emph{not} enabled, the maximum +associated value influences the static array table size, and a larger +table should decrease the time required for an unsuccessful search, at +the expense of extra table space. + +The default value is 1, thus the default maximum associated value about +the same size as the number of keys (for efficiency, the maximum +associated value is always rounded up to a power of 2). The actual +table size may vary somewhat, since this technique is essentially a +heuristic. In particular, setting this value too high slows down +@code{gperf}'s runtime, since it must search through a much larger range +of values. Judicious use of the @samp{-f} option helps alleviate this +overhead, however. + +@item -S @var{total switch statements} +Causes the generated C code to use a @code{switch} statement scheme, +rather than an array lookup table. This can lead to a reduction in both +time and space requirements for some keyfiles. The argument to this +option determines how many @code{switch} statements are generated. A +value of 1 generates 1 @code{switch} containing all the elements, a +value of 2 generates 2 tables with 1/2 the elements in each +@code{switch}, etc. This is useful since many C compilers cannot +correctly generate code for large @code{switch} statements. This option +was inspired in part by Keith Bostic's original C program. + +@item -t +Allows you to include a @code{struct} type declaration for generated +code. Any text before a pair of consecutive %% is consider part of the +type declaration. Key words and additional fields may follow this, one +group of fields per line. A set of examples for generating perfect hash +tables and functions for Ada, C, and G++, Pascal, and Modula 2 and 3 +reserved words are distributed with this release. + +@item -T +Prevents the transfer of the type declaration to the output file. Use +this option if the type is already defined elsewhere. + +@item -v +Prints out the current version number. + +@item -Z @var{class name} +Allow user to specify name of generated C++ class. Default name is +@code{Perfect_Hash}. +@end table +@end itemize + +@node Bugs, Projects, Options, Top +@chapter Known Bugs and Limitations with @code{gperf} + +The following are some limitations with the current release of +@code{gperf}: + +@itemize @bullet +@item +The @code{gperf} utility is tuned to execute quickly, and works quickly +for small to medium size data sets (around 1000 keywords). It is +extremely useful for maintaining perfect hash functions for compiler +keyword sets. Several recent enhancements now enable @code{gperf} to +work efficiently on much larger keyword sets (over 15,000 keywords). +When processing large keyword sets it helps greatly to have over 8 megs +of RAM. + +However, since @code{gperf} does not backtrack no guaranteed solution +occurs on every run. On the other hand, it is usually easy to obtain a +solution by varying the option parameters. In particular, try the +@samp{-r} option, and also try changing the default arguments to the +@samp{-s} and @samp{-j} options. To @emph{guarantee} a solution, use +the @samp{-D} and @samp{-S} options, although the final results are not +likely to be a @emph{perfect} hash function anymore! Finally, use the +@samp{-f} option if you want @code{gperf} to generate the perfect hash +function @emph{fast}, with less emphasis on making it minimal. + +@item +The size of the generate static keyword array can get @emph{extremely} +large if the input keyword file is large or if the keywords are quite +similar. This tends to slow down the compilation of the generated C +code, and @emph{greatly} inflates the object code size. If this +situation occurs, consider using the @samp{-S} option to reduce data +size, potentially increasing keyword recognition time a negligible +amount. Since many C compilers cannot correctly generated code for +large switch statements it is important to qualify the @var{-S} option +with an appropriate numerical argument that controls the number of +switch statements generated. + +@item +The maximum number of key positions selected for a given key has an +arbitrary limit of 126. This restriction should be removed, and if +anyone considers this a problem write me and let me know so I can remove +the constraint. + +@item +The C++ source code only compiles correctly with GNU G++, version 1.36 +(and hopefully later versions). Porting to AT&T cfront would be +tedious, but possible (and desirable). There is also a K&R C version +available now. This should compile without change on most BSD systems, +but may require a bit of work to run on SYSV, since @code{gperf} uses +@var{alloca} in several places. Send mail to schmidt at ics.uci.edu for +information. +@end itemize + +@node Projects, Implementation, Bugs, Top +@chapter Things Still Left to Do + +It should be ``relatively'' easy to replace the current perfect hash +function algorithm with a more exhaustive approach; the perfect hash +module is essential independent from other program modules. Additional +worthwhile improvements include: + +@itemize @bullet +@item +Make the algorithm more robust. At present, the program halts with an +error diagnostic if it can't find a direct solution and the @samp{-D} +option is not enabled. A more comprehensive, albeit computationally +expensive, approach would employ backtracking or enable alternative +options and retry. It's not clear how helpful this would be, in +general, since most search sets are rather small in practice. + +@item +Another useful extension involves modifying the program to generate +``minimal'' perfect hash functions (under certain circumstances, the +current version can be rather extravagant in the generated table size). +Again, this is mostly of theoretical interest, since a sparse table +often produces faster lookups, and use of the @samp{-S} @code{switch} +option can minimize the data size, at the expense of slightly longer +lookups (note that the gcc compiler generally produces good code for +@code{switch} statements, reducing the need for more complex schemes). + +@item +In addition to improving the algorithm, it would also be useful to +generate a C++ class or Ada package as the code output, in addition to +the current C routines. +@end itemize + +@node Implementation, Bibliography, Projects, Top +@chapter Implementation Details of GNU @code{gperf} + +A paper describing the high-level description of the data structures and +algorithms used to implement @code{gperf} will soon be available. This +paper is useful not only from a maintenance and enhancement perspective, +but also because they demonstrate several clever and useful programming +techniques, @emph{e.g.}, `Iteration Number' boolean arrays, double +hashing, a ``safe'' and efficient method for reading arbitrarily long +input from a file, and a provably optimal algorithm for simultaneously +determining both the minimum and maximum elements in a list. + +@page + +@node Bibliography, , Implementation, Top +@chapter Bibliography + +[1] Chang, C.C.: @i{A Scheme for Constructing Ordered Minimal Perfect +Hashing Functions} Information Sciences 39(1986), 187-195. + +[2] Cichelli, Richard J. @i{Author's Response to ``On Cichelli's Minimal Perfec +t Hash +Functions Method''} Communications of the ACM, 23, 12(December 1980), 729. + +[3] Cichelli, Richard J. @i{Minimal Perfect Hash Functions Made Simple} +Communications of the ACM, 23, 1(January 1980), 17-19. + +[4] Cook, C. R. and Oldehoeft, R.R. @i{A Letter Oriented Minimal +Perfect Hashing Function} SIGPLAN Notices, 17, 9(September 1982), 18-27. + +[5] Cormack, G. V. and Horspool, R. N. S. and Kaiserwerth, M. +@i{Practical Perfect Hashing} Computer Journal, 28, 1(January 1985), 54-58. + +[6] Jaeschke, G. @i{Reciprocal Hashing: A Method for Generating Minimal +Perfect Hashing Functions} Communications of the ACM, 24, 12(December +1981), 829-833. + +[7] Jaeschke, G. and Osterburg, G. @i{On Cichelli's Minimal Perfect +Hash Functions Method} Communications of the ACM, 23, 12(December 1980), +728-729. + +[8] Sager, Thomas J. @i{A Polynomial Time Generator for Minimal Perfect +Hash Functions} Communications of the ACM, 28, 5(December 1985), 523-532 + +[9] Schmidt, Douglas C. @i{GPERF: A Perfect Hash Function Generator} +Second USENIX C++ Conference Proceedings, April 1990. + +[10] Sebesta, R.W. and Taylor, M.A. @i{Minimal Perfect Hash Functions +for Reserved Word Lists} SIGPLAN Notices, 20, 12(September 1985), 47-53. + +[11] Sprugnoli, R. @i{Perfect Hashing Functions: A Single Probe +Retrieving Method for Static Sets} Communications of the ACM, 20 +11(November 1977), 841-850. + +[12] Stallman, Richard M. @i{Using and Porting GNU CC} Free Software Foundation, +1988. + +[13] Stroustrup, Bjarne @i{The C++ Programming Language.} Addison-Wesley, 1986. + +[14] Tiemann, Michael D. @i{User's Guide to GNU C++} Free Software +Foundation, 1989. + +@contents +@bye diff --git a/apps/gperf/src/Bool_Array.cpp b/apps/gperf/src/Bool_Array.cpp new file mode 100644 index 00000000000..e3243565f41 --- /dev/null +++ b/apps/gperf/src/Bool_Array.cpp @@ -0,0 +1,89 @@ +/* Fast lookup table abstraction implemented as an Iteration Number Array +// @(#)Bool_Array.cpp 1.1 10/18/96 + + Copyright (C) 1989 Free Software Foundation, Inc. + written by Douglas C. Schmidt (schmidt@ics.uci.edu) + +This file is part of GNU GPERF. + +GNU GPERF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU GPERF is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU GPERF; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "Bool_Array.h" + +// Prints out debugging diagnostics. + +Bool_Array::~Bool_Array (void) +{ + if (option[DEBUG]) + fprintf (stderr, "\ndumping boolean array information\n" + "size = %d\niteration number = %d\nend of array dump\n", + size, generation_number); +} + +Bool_Array::Bool_Array (void) + : storage_array (0), + generation_number (0), + size (0) +{ +} + +void +Bool_Array::init (STORAGE_TYPE *buffer, STORAGE_TYPE s) +{ + size = s; + generation_number = 1; + storage_array = buffer; + + memset (storage_array, 0, s * sizeof *storage_array); + + if (option[DEBUG]) + fprintf (stderr, "\nbool array size = %d, total bytes = %d\n", + size, size * sizeof *storage_array); +} + +int +Bool_Array::find (int index) +{ + if (storage_array[index] == generation_number) + return 1; + else + { + storage_array[index] = generation_number; + return 0; + } +} + +void +Bool_Array::reset (void) +{ + if (++generation_number == 0) + { + if (option[DEBUG]) + { + fprintf (stderr, "(re-initializing bool_array)..."); + fflush (stderr); + } + + generation_number = 1; + memset (storage_array, 0, size * sizeof *storage_array); + + if (option[DEBUG]) + { + fprintf (stderr, "done\n"); + fflush (stderr); + } + } +} + diff --git a/apps/gperf/src/Bool_Array.h b/apps/gperf/src/Bool_Array.h new file mode 100644 index 00000000000..d890484e485 --- /dev/null +++ b/apps/gperf/src/Bool_Array.h @@ -0,0 +1,65 @@ +/* -*- C++ -*- */ +// @(#)Bool_Array.h 1.1 10/18/96 + +/* This may look like C code, but it is really -*- C++ -*- */ + +/* Simple lookup table abstraction implemented as an Generation Number Array. + + Copyright (C) 1989 Free Software Foundation, Inc. + written by Douglas C. Schmidt (schmidt@ics.uci.edu) + +This file is part of GNU GPERF. + +GNU GPERF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU GPERF is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU GPERF; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/ + +/* Define and implement a simple boolean array abstraction, + uses an Generation Numbering implementation to save on initialization time. */ + +#ifndef bool_array_h +#define bool_array_h 1 + +#include "Options.h" + +#ifdef LO_CAL +/* If we are on a memory diet then we'll only make these use a limited + amount of storage space. */ +typedef u_short STORAGE_TYPE; +#else +typedef int STORAGE_TYPE; +#endif + +class Bool_Array +{ +public: + Bool_Array (void); + ~Bool_Array (void); + + void init (STORAGE_TYPE *buffer, STORAGE_TYPE s); + int find (int hash_value); + void reset (void); + +private: + STORAGE_TYPE *storage_array; + // Initialization of the index space. + + STORAGE_TYPE generation_number; + // Keep track of the current Generation. + + int size; + // Keep track of array size. +}; + + +#endif diff --git a/apps/gperf/src/Gen_Perf.cpp b/apps/gperf/src/Gen_Perf.cpp new file mode 100644 index 00000000000..25c0299fd35 --- /dev/null +++ b/apps/gperf/src/Gen_Perf.cpp @@ -0,0 +1,345 @@ +/* Provides high-level routines to manipulate the keywork list +// @(#)Gen_Perf.cpp 1.1 10/18/96 + + structures the code generation output. + Copyright (C) 1989 Free Software Foundation, Inc. + written by Douglas C. Schmidt (schmidt@ics.uci.edu) + +This file is part of GNU GPERF. + +GNU GPERF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU GPERF is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU GPERF; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "Vectors.h" +#include "Gen_Perf.h" + +/* Current release version. */ +extern char *version_string; + +/* Reads input keys, possibly applies the reordering heuristic, sets + the maximum associated value size (rounded up to the nearest power + of 2), may initialize the associated values array, and determines + the maximum hash table size. Note: using the random numbers is + often helpful, though not as deterministic, of course! */ + +Gen_Perf::Gen_Perf (void) +{ + int asso_value_max; + int non_linked_length; + + this->key_list.read_keys (); + if (option[ORDER]) + this->key_list.reorder (); + asso_value_max = option.get_asso_max (); + non_linked_length = this->key_list.keyword_list_length (); + num_done = 1; + fewest_collisions = 0; + if (asso_value_max == 0) + asso_value_max = non_linked_length; + else if (asso_value_max > 0) + asso_value_max *= non_linked_length; + else /* if (asso_value_max < 0) */ + asso_value_max = non_linked_length / -asso_value_max; + option.set_asso_max (ACE_POW (asso_value_max)); + + if (option[RANDOM]) + { + srand (time (0)); + + for (int i = 0; i < ALPHA_SIZE; i++) + Vectors::asso_values[i] = (rand () & asso_value_max - 1); + } + else + { + int asso_value = option.initial_value (); + + if (asso_value) /* Initialize array if user requests non-zero default. */ + for (int i = ALPHA_SIZE - 1; i >= 0; i--) + Vectors::asso_values[i] = asso_value & option.get_asso_max () - 1; + } + max_hash_value = this->key_list.max_key_length () + option.get_asso_max () * + option.get_max_keysig_size (); + + printf ("/* "); + if (option[C]) + printf ("C"); + else if (option[CPLUSPLUS]) + printf ("C++"); + printf (" code produced by gperf version %s */\n", version_string); + Options::print_options (); + + if (option[DEBUG]) + fprintf (stderr, "total non-linked keys = %d\nmaximum associated value is %d" + "\nmaximum size of generated hash table is %d\n", + non_linked_length, asso_value_max, max_hash_value); +} + +/* Merge two disjoint hash key multisets to form the ordered disjoint union of the sets. + (In a multiset, an element can occur multiple times). + Precondition: both set_1 and set_2 must be ordered. Returns the length + of the combined set. */ + +inline int +Gen_Perf::compute_disjoint_union (char *set_1, char *set_2, char *set_3) +{ + char *base = set_3; + + while (*set_1 && *set_2) + if (*set_1 == *set_2) + set_1++, set_2++; + else + { + *set_3 = *set_1 < *set_2 ? *set_1++ : *set_2++; + if (set_3 == base || *set_3 != *(set_3-1)) set_3++; + } + + while (*set_1) + { + *set_3 = *set_1++; + if (set_3 == base || *set_3 != *(set_3-1)) set_3++; + } + + while (*set_2) + { + *set_3 = *set_2++; + if (set_3 == base || *set_3 != *(set_3-1)) set_3++; + } + *set_3 = '\0'; + return set_3 - base; +} + +/* Sort the UNION_SET in increasing frequency of occurrence. + This speeds up later processing since we may assume the resulting + set (Set_3, in this case), is ordered. Uses insertion sort, since + the UNION_SET is typically short. */ + +inline void +Gen_Perf::sort_set (char *union_set, int len) +{ + int i, j; + + for (i = 0, j = len - 1; i < j; i++) + { + char curr, tmp; + + for (curr = i + 1, tmp = union_set[curr]; + curr > 0 && Vectors::occurrences[tmp] < Vectors::occurrences[union_set[curr-1]]; + curr--) + union_set[curr] = union_set[curr - 1]; + + union_set[curr] = tmp; + } +} + +/* Generate a key set's hash value. */ + +inline int +Gen_Perf::hash (List_Node *key_node) +{ + int sum = option[NOLENGTH] ? 0 : key_node->length; + + for (char *ptr = key_node->char_set; *ptr; ptr++) + sum += Vectors::asso_values[*ptr]; + + return key_node->hash_value = sum; +} + +/* Find out how character value change affects successfully hashed + items. Returns FALSE if no other hash values are affected, else + returns TRUE. Note that because Option.Get_Asso_Max is a power of + two we can guarantee that all legal Vectors::Asso_Values are visited without + repetition since Option.Get_Jump was forced to be an odd value! */ + +inline int +Gen_Perf::affects_prev (char c, List_Node *curr) +{ + int original_char = Vectors::asso_values[c]; + int total_iterations = !option[FAST] + ? option.get_asso_max () : option.get_iterations () ? option.get_iterations () : this->key_list.keyword_list_length (); + + /* Try all legal associated values. */ + + for (int i = total_iterations - 1; i >= 0; i--) + { + int collisions = 0; + + Vectors::asso_values[c] = Vectors::asso_values[c] + (option.get_jump () ? option.get_jump () : rand ()) + & option.get_asso_max () - 1; + + /* Iteration Number array is a win, O(1) intialization time! */ + this->char_search.reset (); + + /* See how this asso_value change affects previous keywords. If + it does better than before we'll take it! */ + + for (List_Node *ptr = this->key_list.head; + !this->char_search.find (hash (ptr)) || ++collisions < fewest_collisions; + ptr = ptr->next) + if (ptr == curr) + { + fewest_collisions = collisions; + if (option[DEBUG]) + fprintf (stderr, "- resolved after %d iterations", total_iterations - i); + return 0; + } + } + + /* Restore original values, no more tries. */ + Vectors::asso_values[c] = original_char; + /* If we're this far it's time to try the next character.... */ + return 1; +} + +/* Change a character value, try least-used characters first. */ + +void +Gen_Perf::change (List_Node *prior, List_Node *curr) +{ + static char *union_set; + + if (!union_set) + union_set = new char [2 * option.get_max_keysig_size () + 1]; + + if (option[DEBUG]) + { + fprintf (stderr, "collision on keyword #%d, prior = \"%s\", curr = \"%s\" hash = %d\n", + num_done, prior->key, curr->key, curr->hash_value); + fflush (stderr); + } + sort_set (union_set, compute_disjoint_union (prior->char_set, curr->char_set, union_set)); + + /* Try changing some values, if change doesn't alter other values continue normal action. */ + fewest_collisions++; + + for (char *temp = union_set; *temp; temp++) + if (!affects_prev (*temp, curr)) + { + if (option[DEBUG]) + { + fprintf (stderr, " by changing asso_value['%c'] (char #%d) to %d\n", + *temp, temp - union_set + 1, Vectors::asso_values[*temp]); + fflush (stderr); + } + return; /* Good, doesn't affect previous hash values, we'll take it. */ + } + + for (List_Node *ptr = this->key_list.head; ptr != curr; ptr = ptr->next) + hash (ptr); + + hash (curr); + + if (option[DEBUG]) + { + fprintf (stderr, "** collision not resolved after %d iterations, %d duplicates remain, continuing...\n", + !option[FAST] ? option.get_asso_max () : option.get_iterations () ? option.get_iterations () : this->key_list.keyword_list_length (), + fewest_collisions + this->key_list.total_duplicates); + fflush (stderr); + } +} + +/* Does the hard stuff.... + Initializes the Iteration Number array, and attempts to find a perfect + function that will hash all the key words without getting any + duplications. This is made much easier since we aren't attempting + to generate *minimum* functions, only perfect ones. + If we can't generate a perfect function in one pass *and* the user + hasn't enabled the DUP option, we'll inform the user to try the + randomization option, use -D, or choose alternative key positions. + The alternatives (e.g., back-tracking) are too time-consuming, i.e, + exponential in the number of keys. */ + +int +Gen_Perf::generate (void) +{ +#if LARGE_STACK_ARRAYS + STORAGE_TYPE buffer[max_hash_value + 1]; +#else + // Note: we don't use new, because that invokes a custom operator new. + STORAGE_TYPE *buffer + = (STORAGE_TYPE*) malloc (sizeof(STORAGE_TYPE) * (max_hash_value + 1)); + if (buffer == NULL) + abort (); +#endif + + this->char_search.init (buffer, max_hash_value + 1); + + List_Node *curr; + + for (curr = this->key_list.head; + curr; + curr = curr->next) + { + hash (curr); + + for (List_Node *ptr = this->key_list.head; + ptr != curr; + ptr = ptr->next) + if (ptr->hash_value == curr->hash_value) + { + change (ptr, curr); + break; + } + num_done++; + } + + /* Make one final check, just to make sure nothing weird happened.... */ + + this->char_search.reset (); + + for (curr = this->key_list.head; + curr; + curr = curr->next) + if (this->char_search.find (hash (curr))) + if (option[DUP]) /* Keep track of this number... */ + this->key_list.total_duplicates++; + else /* Yow, big problems. we're outta here! */ + { + ACE_ERROR ((LM_ERROR, "\nInternal error, duplicate value %d:\n" + "try options -D or -r, or use new key positions.\n\n", hash (curr))); +#if !LARGE_STACK_ARRAYS + free (buffer); +#endif + return 1; + } + + /* Sorts the key word list by hash value, and then outputs the list. + The generated hash table code is only output if the early stage of + processing turned out O.K. */ + + this->key_list.sort (); + this->key_list.output (); +#if !LARGE_STACK_ARRAYS + free (buffer); +#endif + return 0; +} + +/* Prints out some diagnostics upon completion. */ + +Gen_Perf::~Gen_Perf (void) +{ + if (option[DEBUG]) + { + fprintf (stderr, "\ndumping occurrence and associated values tables\n"); + + for (int i = 0; i < ALPHA_SIZE; i++) + if (Vectors::occurrences[i]) + fprintf (stderr, "Vectors::asso_values[%c] = %6d, Vectors::occurrences[%c] = %6d\n", + i, Vectors::asso_values[i], i, Vectors::occurrences[i]); + + fprintf (stderr, "end table dumping\n"); + + } +} + diff --git a/apps/gperf/src/Gen_Perf.h b/apps/gperf/src/Gen_Perf.h new file mode 100644 index 00000000000..11817de4851 --- /dev/null +++ b/apps/gperf/src/Gen_Perf.h @@ -0,0 +1,65 @@ +/* -*- C++ -*- */ +// @(#)Gen_Perf.h 1.1 10/18/96 + +/* This may look like C code, but it is really -*- C++ -*- */ + +/* Provides high-level routines to manipulate the keyword list + structures the code generation output. + + Copyright (C) 1989 Free Software Foundation, Inc. + written by Douglas C. Schmidt (schmidt@ics.uci.edu) + +This file is part of GNU GPERF. + +GNU GPERF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU GPERF is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU GPERF; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#ifndef gen_perf_h +#define gen_perf_h 1 + +#include "Options.h" +#include "Key_List.h" +#include "Bool_Array.h" + +class Gen_Perf +{ +public: + Gen_Perf (void); + ~Gen_Perf (void); + int generate (void); + +private: + void change (List_Node *prior, List_Node *curr); + int affects_prev (char c, List_Node *curr); + static int hash (List_Node *key_node); + static int compute_disjoint_union (char *set_1, char *set_2, char *set_3); + static void sort_set (char *union_set, int len); + + int max_hash_value; + // Maximum possible hash value. + + int fewest_collisions; + // Records fewest # of collisions for asso value. + + int num_done; + // Number of keywords processed without a collision. + + Bool_Array char_search; + // Table that keeps track of key collisions. + + Key_List key_list; + // List of the keys we're trying to map into a perfect hash + // function. +}; +#endif diff --git a/apps/gperf/src/Hash_Table.cpp b/apps/gperf/src/Hash_Table.cpp new file mode 100644 index 00000000000..dfb008514ce --- /dev/null +++ b/apps/gperf/src/Hash_Table.cpp @@ -0,0 +1,84 @@ +/* Hash table for checking keyword links. Implemented using double hashing. +// @(#)Hash_Table.cpp 1.1 10/18/96 + + Copyright (C) 1989 Free Software Foundation, Inc. + written by Douglas C. Schmidt (schmidt@ics.uci.edu) + +This file is part of GNU GPERF. + +GNU GPERF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU GPERF is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU GPERF; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "ace/ACE.h" +#include "Hash_Table.h" + +#define NIL(TYPE) (TYPE *)0 + +// The size of the hash table is always the smallest power of 2 >= the +// size indicated by the user. This allows several optimizations, +// including the use of double hashing and elimination of the mod +// instruction. Note that the size had better be larger than the +// number of items in the hash table, else there's trouble!!! Note +// that the memory for the hash table is allocated *outside* the +// intialization routine. This compromises information hiding +// somewhat, but greatly reduces memory fragmentation, since we can +// now use alloca! + +Hash_Table::Hash_Table (List_Node **table_ptr, int s) + : collisions (0), + size (s), + table (table_ptr) +{ + memset ((char *) table, 0, size * sizeof *table); +} + +Hash_Table::~Hash_Table (void) +{ + if (option[DEBUG]) + { + int field_width = option.get_max_keysig_size (); + + fprintf (stderr, "\ndumping the hash table\ntotal available table slots = %d, total bytes = %d, total collisions = %d\n" + "location, %*s, keyword\n", size, size * sizeof *table, collisions, field_width, "keysig"); + + for (int i = size - 1; i >= 0; i--) + if (table[i]) + fprintf (stderr, "%8d, %*s, %s\n", + i, field_width, table[i]->char_set, table[i]->key); + + fprintf (stderr, "\nend dumping hash table\n\n"); + } +} + +// If the ITEM is already in the hash table return the item found in +// the table. Otherwise inserts the ITEM, and returns FALSE. Uses +// double hashing. + +List_Node * +Hash_Table::operator() (List_Node *item, int ignore_length) +{ + unsigned hash_val = ACE::hash_pjw (item->char_set); + int probe = hash_val & size - 1; + int increment = (hash_val ^ item->length | 1) & size - 1; + + while (table[probe] + && (strcmp (table[probe]->char_set, item->char_set) + || (!ignore_length && table[probe]->length != item->length))) + { + collisions++; + probe = probe + increment & size - 1; + } + + return table[probe] ? table[probe] : (table[probe] = item, NIL (List_Node)); +} diff --git a/apps/gperf/src/Hash_Table.h b/apps/gperf/src/Hash_Table.h new file mode 100644 index 00000000000..c7a77a1b37b --- /dev/null +++ b/apps/gperf/src/Hash_Table.h @@ -0,0 +1,50 @@ +/* -*- C++ -*- */ +// @(#)Hash_Table.h 1.1 10/18/96 + +/* This may look like C code, but it is really -*- C++ -*- */ + +/* Hash table used to check for duplicate keyword entries. + + Copyright (C) 1989 Free Software Foundation, Inc. + written by Douglas C. Schmidt (schmidt@ics.uci.edu) + +This file is part of GNU GPERF. + +GNU GPERF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU GPERF is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU GPERF; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#ifndef hash_table_h +#define hash_table_h 1 + +#include "Options.h" +#include "List_Node.h" + +class Hash_Table +{ +public: + Hash_Table (List_Node **t, int s); + ~Hash_Table (void); + List_Node *operator () (List_Node *item, int ignore_length); + +private: + List_Node **table; + // Vector of pointers to linked lists of List_Node's. + + int size; + // Size of the vector. + + int collisions; + // Find out how well our double hashing is working! +}; +#endif diff --git a/apps/gperf/src/Iterator.cpp b/apps/gperf/src/Iterator.cpp new file mode 100644 index 00000000000..2e5d37f8f00 --- /dev/null +++ b/apps/gperf/src/Iterator.cpp @@ -0,0 +1,90 @@ +/* Provides an Iterator for keyword characters. +// @(#)Iterator.cpp 1.1 10/18/96 + + Copyright (C) 1989 Free Software Foundation, Inc. + written by Douglas C. Schmidt (schmidt@ics.uci.edu) + +This file is part of GNU GPERF. + +GNU GPERF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU GPERF is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU GPERF; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "Iterator.h" + +// Constructor for Iterator. + +Iterator::Iterator (char *s, + int lo, + int hi, + int word_end, + int bad_val, + int key_end) + : end (key_end), + error_value (bad_val), + end_word (word_end), + str (s), + hi_bound (hi), + lo_bound (lo) +{ +} + +// Provide an Iterator, returning the ``next'' value from the list of +// valid values given in the constructor. + +int +Iterator::operator() (void) +{ + // Variables to record the Iterator's status when handling ranges, + // e.g., 3-12. + + static int size; + static int curr_value; + static int upper_bound; + + if (size) + { + if (++curr_value >= upper_bound) + size = 0; + return curr_value; + } + else + { + while (*str) + switch (*str) + { + default: return error_value; + case ',': str++; break; + case '$': str++; return end_word; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + for (curr_value = 0; isdigit (*str); str++) + curr_value = curr_value * 10 + *str - '0'; + + if (*str == '-') + { + + for (size = 1, upper_bound = 0; + isdigit (*++str); + upper_bound = upper_bound * 10 + *str - '0'); + + if (upper_bound <= curr_value || upper_bound > hi_bound) + return error_value; + } + return curr_value >= lo_bound && curr_value <= hi_bound + ? curr_value : error_value; + } + + return end; + } +} diff --git a/apps/gperf/src/Iterator.h b/apps/gperf/src/Iterator.h new file mode 100644 index 00000000000..d2c81039b3f --- /dev/null +++ b/apps/gperf/src/Iterator.h @@ -0,0 +1,67 @@ +/* -*- C++ -*- */ +// @(#)Iterator.h 1.1 10/18/96 + +/* This may look like C code, but it is really -*- C++ -*- */ + +/* Provides an Iterator for keyword characters. + + Copyright (C) 1989 Free Software Foundation, Inc. + written by Douglas C. Schmidt (schmidt@ics.uci.edu) + +This file is part of GNU GPERF. + +GNU GPERF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU GPERF is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU GPERF; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* Provides an Iterator that expands and decodes a control string + containing digits and ranges, returning an integer every time the + generator function is called. This is used to decode the user's + key position requests. For example: "-k 1,2,5-10,$" will return 1, + 2, 5, 6, 7, 8, 9, 10, and 0 ( representing the abstract ``last + character of the key'' on successive calls to the member function + operator (). No errors are handled in these routines, they are + passed back to the calling routines via a user-supplied Error_Value */ + +#ifndef iterator_h +#define iterator_h 1 + +#include "Options.h" + +class Iterator +{ +public: + Iterator (char *s, int lo, int hi, int word_end, int bad_val, int key_end); + int operator () (void); + +private: + char *str; + // A pointer to the string provided by the user. + + int end; + // Value returned after last key is processed. + + int end_word; + // A value marking the abstract ``end of word'' (usually '$'). + + int error_value; + // Error value returned when input is syntactically erroneous. + + int hi_bound; + // Greatest possible value, inclusive. + + int lo_bound; + // Smallest possible value, inclusive. +}; + +#endif diff --git a/apps/gperf/src/Key_List.cpp b/apps/gperf/src/Key_List.cpp new file mode 100644 index 00000000000..3a944b4b28b --- /dev/null +++ b/apps/gperf/src/Key_List.cpp @@ -0,0 +1,1345 @@ +/* Routines for building, ordering, and printing the keyword list. +// @(#)Key_List.cpp 1.1 10/18/96 + + Copyright (C) 1989 Free Software Foundation, Inc. + written by Douglas C. Schmidt (schmidt@ics.uci.edu) + +This file is part of GNU GPERF. + +GNU GPERF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU GPERF is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU GPERF; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "ace/Read_Buffer.h" +#include "Hash_Table.h" +#include "Vectors.h" +#include "Key_List.h" + +/* Make the hash table 10 times larger than the number of keyword entries. */ +static const int TABLE_MULTIPLE = 10; + +/* Default type for generated code. */ +static char *const default_array_type = "char *"; + +/* in_word_set return type, by default. */ +static char *const default_return_type = "char *"; + +/* How wide the printed field width must be to contain the maximum hash value. */ +static int field_width = 0; + +static int determined[ALPHA_SIZE]; + +/* Destructor dumps diagnostics during debugging. */ + +Key_List::~Key_List (void) +{ + if (option[DEBUG]) + { + fprintf (stderr, "\nDumping key list information:\ntotal non-static linked keywords = %d" + "\ntotal keywords = %d\ntotal duplicates = %d\nmaximum key length = %d\n", + list_len, total_keys, total_duplicates ? total_duplicates + 1 : 0, max_key_len); + dump (); + ACE_ERROR ((LM_ERROR, "End dumping list.\n\n")); + } +} + +/* Gathers the input stream into a buffer until one of two things occur: + + 1. We read a '%' followed by a '%' + 2. We read a '%' followed by a '}' + + The first symbolizes the beginning of the keyword list proper, + The second symbolizes the end of the C source code to be generated + verbatim in the output file. + + I assume that the keys are separated from the optional preceding struct + declaration by a consecutive % followed by either % or } starting in + the first column. The code below uses an expandible buffer to scan off + and return a pointer to all the code (if any) appearing before the delimiter. */ + +char * +Key_List::get_special_input (char delimiter) +{ + int size = 80; + char *buf = new char[size]; + int c, i; + + for (i = 0; (c = getchar ()) != EOF; i++) + { + if (c == '%') + { + if ((c = getchar ()) == delimiter) + { + + while ((c = getchar ()) != '\n') + ; /* discard newline */ + + if (i == 0) + return ""; + else + { + buf[delimiter == '%' && buf[i - 2] == ';' ? i - 2 : i - 1] = '\0'; + return buf; + } + } + else + buf[i++] = '%'; + } + else if (i >= size) /* Yikes, time to grow the buffer! */ + { + char *temp = new char[size *= 2]; + int j; + + for (j = 0; j < i; j++) + temp[j] = buf[j]; + + buf = temp; + } + buf[i] = c; + } + + return 0; /* Problem here. */ +} + +/* Stores any C text that must be included verbatim into the + generated code output. */ + +char * +Key_List::save_include_src (void) +{ + int c; + + if ((c = getchar ()) != '%') + ungetc (c, stdin); + else if ((c = getchar ()) != '{') + ACE_ERROR ((LM_ERROR, "internal error, %c != '{' on line %d in file %s%a", c, __LINE__, __FILE__, 1)); + else + return get_special_input ('}'); + return ""; +} + +/* Determines from the input file whether the user wants to build a table + from a user-defined struct, or whether the user is content to simply + use the default array of keys. */ + +char * +Key_List::get_array_type (void) +{ + return get_special_input ('%'); +} + +/* strcspn - find length of initial segment of S consisting entirely + ANSI string package, when GNU libc comes out I'll replace this...). */ + +inline int +Key_List::strcspn (const char *s, const char *reject) +{ + const char *scan; + const char *rej_scan; + int count = 0; + + for (scan = s; *scan; scan++) + { + + for (rej_scan = reject; *rej_scan; rej_scan++) + if (*scan == *rej_scan) + return count; + + count++; + } + + return count; +} + +/* Sets up the Return_Type, the Struct_Tag type and the Array_Type + based upon various user Options. */ + +void +Key_List::set_output_types (void) +{ + if (option[TYPE] && !(array_type = get_array_type ())) + return; /* Something's wrong, bug we'll catch it later on.... */ + else if (option[TYPE]) /* Yow, we've got a user-defined type... */ + { + int struct_tag_length = strcspn (array_type, "{\n\0"); + + if (option[POINTER]) /* And it must return a pointer... */ + { + return_type = new char[struct_tag_length + 2]; + strncpy (return_type, array_type, struct_tag_length); + return_type[struct_tag_length] = '*'; + return_type[struct_tag_length + 1] = '\0'; + } + + struct_tag = new char[struct_tag_length + 1]; + strncpy (struct_tag, array_type, struct_tag_length); + struct_tag[struct_tag_length] = '\0'; + } + else if (option[POINTER]) /* Return a char *. */ + return_type = default_array_type; +} + +/* Reads in all keys from standard input and creates a linked list pointed + to by Head. This list is then quickly checked for ``links,'' i.e., + unhashable elements possessing identical key sets and lengths. */ + +void +Key_List::read_keys (void) +{ + include_src = save_include_src (); + set_output_types (); + + ACE_Read_Buffer input (stdin); + + char *ptr = input.read ('\n'); + + if (ptr == 0) + // Oops, problem with the input file. + ACE_ERROR ((LM_ERROR, "No words in input file, did you forget to prepend %s" + " or use -t accidentally?\n%a", "%%", 1)); + + /* Read in all the keywords from the input file. */ + else + { + const char *delimiter = option.get_delimiter (); + List_Node *temp, *trail = 0; + + head = new List_Node (ptr, strcspn (ptr, delimiter)); + + for (temp = head; + (ptr = input.read ('\n')) && strcmp (ptr, "%%"); + temp = temp->next) + { + temp->next = new List_Node (ptr, strcspn (ptr, delimiter)); + total_keys++; + } + + /* See if any additional source code is included at end of this file. */ + if (ptr) + additional_code = 1; + + /* Hash table this number of times larger than keyword number. */ + int table_size = (list_len = total_keys) * TABLE_MULTIPLE; + +#if LARGE_STACK_ARRAYS + /* By allocating the memory here we save on dynamic allocation overhead. + Table must be a power of 2 for the hash function scheme to work. */ + List_Node *table[ACE_POW (table_size)]; +#else + // Note: we don't use new, because that invokes a custom operator new. + int malloc_size = ACE_POW (table_size) * sizeof(List_Node*); + if (malloc_size == 0) malloc_size = 1; + List_Node **table = (List_Node**)malloc(malloc_size); + if (table == NULL) + abort (); +#endif + + /* Make large hash table for efficiency. */ + Hash_Table found_link (table, table_size); + + /* Test whether there are any links and also set the maximum length of + an identifier in the keyword list. */ + + for (temp = head; temp; temp = temp->next) + { + List_Node *ptr = found_link (temp, option[NOLENGTH]); + + /* Check for links. We deal with these by building an equivalence class + of all duplicate values (i.e., links) so that only 1 keyword is + representative of the entire collection. This *greatly* simplifies + processing during later stages of the program. */ + + if (ptr) + { + total_duplicates++; + list_len--; + trail->next = temp->next; + temp->link = ptr->link; + ptr->link = temp; + + /* Complain if user hasn't enabled the duplicate option. */ + if (!option[DUP] || option[DEBUG]) + ACE_ERROR ((LM_ERROR, "Key link: \"%s\" = \"%s\", with key set \"%s\".\n", + temp->key, ptr->key, temp->char_set)); + } + else + trail = temp; + + /* Update minimum and maximum keyword length, if needed. */ + if (max_key_len < temp->length) + max_key_len = temp->length; + if (min_key_len > temp->length) + min_key_len = temp->length; + } + +#if !LARGE_STACK_ARRAYS + free (table); +#endif + + /* Exit program if links exists and option[DUP] not set, since we can't continue */ + if (total_duplicates) + ACE_ERROR ((LM_ERROR, option[DUP] + ? "%d input keys have identical hash values, examine output carefully...\n" + : "%d input keys have identical hash values,\ntry different key positions or use option -D.\n%a", total_duplicates, 1)); + if (option[ALLCHARS]) + option.set_keysig_size (max_key_len); + } +} + +/* Recursively merges two sorted lists together to form one sorted list. The + ordering criteria is by frequency of occurrence of elements in the key set + or by the hash value. This is a kludge, but permits nice sharing of + almost identical code without incurring the overhead of a function + call comparison. */ + +List_Node * +Key_List::merge (List_Node *list1, List_Node *list2) +{ + if (!list1) + return list2; + else if (!list2) + return list1; + else if (occurrence_sort && list1->occurrence < list2->occurrence + || hash_sort && list1->hash_value > list2->hash_value) + { + list2->next = merge (list2->next, list1); + return list2; + } + else + { + list1->next = merge (list1->next, list2); + return list1; + } +} + +/* Applies the merge sort algorithm to recursively sort the key list by + frequency of occurrence of elements in the key set. */ + +List_Node * +Key_List::merge_sort (List_Node *a_head) +{ + if (!a_head || !a_head->next) + return a_head; + else + { + List_Node *middle = a_head; + List_Node *temp = a_head->next->next; + + while (temp) + { + temp = temp->next; + middle = middle->next; + if (temp) + temp = temp->next; + } + + temp = middle->next; + middle->next = 0; + return merge (merge_sort (a_head), merge_sort (temp)); + } +} + +/* Returns the frequency of occurrence of elements in the key set. */ + +inline int +Key_List::get_occurrence (List_Node *ptr) +{ + int value = 0; + + for (char *temp = ptr->char_set; *temp; temp++) + value += Vectors::occurrences[*temp]; + + return value; +} + +/* Enables the index location of all key set elements that are now + determined. */ + +inline void +Key_List::set_determined (List_Node *ptr) +{ + for (char *temp = ptr->char_set; *temp; temp++) + determined[*temp] = 1; +} + +/* Returns TRUE if PTR's key set is already completely determined. */ + +inline int +Key_List::already_determined (List_Node *ptr) +{ + int is_determined = 1; + + for (char *temp = ptr->char_set; is_determined && *temp; temp++) + is_determined = determined[*temp]; + + return is_determined; +} + +/* Reorders the table by first sorting the list so that frequently occuring + keys appear first, and then the list is reorded so that keys whose values + are already determined will be placed towards the front of the list. This + helps prune the search time by handling inevitable collisions early in the + search process. See Cichelli's paper from Jan 1980 JACM for details.... */ + +void +Key_List::reorder (void) +{ + List_Node *ptr; + + for (ptr = head; ptr; ptr = ptr->next) + ptr->occurrence = get_occurrence (ptr); + + occurrence_sort = !(hash_sort = 0); /* Pretty gross, eh?! */ + + for (ptr = head = merge_sort (head); ptr->next; ptr = ptr->next) + { + set_determined (ptr); + + if (already_determined (ptr->next)) + continue; + else + { + List_Node *trail_ptr = ptr->next; + List_Node *run_ptr = trail_ptr->next; + + for (; run_ptr; run_ptr = trail_ptr->next) + { + + if (already_determined (run_ptr)) + { + trail_ptr->next = run_ptr->next; + run_ptr->next = ptr->next; + ptr = ptr->next = run_ptr; + } + else + trail_ptr = run_ptr; + } + } + } +} + +/* Outputs the maximum and minimum hash values. Since the + list is already sorted by hash value all we need to do is + find the final item! */ + +void +Key_List::output_min_max () +{ + List_Node *temp; + for (temp = head; temp->next; temp = temp->next) + ; + + min_hash_value = head->hash_value; + max_hash_value = temp->hash_value; + + if (!option[ENUM]) + printf ("\n#define TOTAL_KEYWORDS %d\n#define MIN_WORD_LENGTH %d" + "\n#define MAX_WORD_LENGTH %d\n#define MIN_HASH_VALUE %d" + "\n#define MAX_HASH_VALUE %d\n#define HASH_VALUE_RANGE %d" + "\n#define DUPLICATES %d\n\n", + total_keys, min_key_len, max_key_len, min_hash_value, + max_hash_value, max_hash_value - min_hash_value + 1, + total_duplicates ? total_duplicates + 1 : 0); + else if (option[GLOBAL]) + printf ("enum\n{\n" + " TOTAL_KEYWORDS = %d,\n" + " MIN_WORD_LENGTH = %d,\n" + " MAX_WORD_LENGTH = %d,\n" + " MIN_HASH_VALUE = %d,\n" + " MAX_HASH_VALUE = %d,\n" + " HASH_VALUE_RANGE = %d,\n" + " DUPLICATES = %d\n};\n\n", + total_keys, min_key_len, max_key_len, min_hash_value, + max_hash_value, max_hash_value - min_hash_value + 1, + total_duplicates ? total_duplicates + 1 : 0); +} + +/* Generates the output using a C switch. This trades increased + search time for decreased table space (potentially *much* less + space for sparse tables). It the user has specified their own + struct in the keyword file *and* they enable the POINTER option we + have extra work to do. The solution here is to maintain a local + static array of user defined struct's, as with the + Output_Lookup_Function. Then we use for switch statements to + perform either a strcmp or strncmp, returning 0 if the str fails to + match, and otherwise returning a pointer to appropriate index + location in the local static array. */ + +void +Key_List::output_switch (void) +{ + char *comp_buffer; + List_Node *curr = head; + int pointer_and_type_enabled = option[POINTER] && option[TYPE]; + int total_switches = option.get_total_switches (); + int switch_size = keyword_list_length () / total_switches; + + if (pointer_and_type_enabled) + { +#if defined (__GNUG__) + comp_buffer = (char *) alloca (strlen ("charmap[*str] == *resword->%s && !strncasecmp (str + 1, resword->%s + 1, len - 1)") + + 2 * strlen (option.get_key_name ()) + 1); +#else + comp_buffer = new char [strlen ("charmap[*str] == *resword->%s && !strncasecmp (str + 1, resword->%s + 1, len - 1)") + + 2 * strlen (option.get_key_name ()) + 1]; +#endif + if (option[COMP]) + sprintf (comp_buffer, "%s == *resword->%s && !%s (str + 1, resword->%s + 1, len - 1)", + option[STRCASECMP] ? "charmap[*str]" : "*str", option.get_key_name (), + option[STRCASECMP] ? "strncasecmp" : "strncmp", option.get_key_name ()); + else + sprintf (comp_buffer, "%s == *resword->%s && !%s (str + 1, resword->%s + 1)", + option[STRCASECMP] ? "charmap[*str]" : "*str", option.get_key_name (), + option[STRCASECMP] ? "strcasecmp" : "strcmp", option.get_key_name ()); + } + else + { + if (option[COMP]) + comp_buffer = option[STRCASECMP] + ? "charmap[*str] == *resword && !strncasecmp (str + 1, resword + 1, len - 1)" + : "*str == *resword && !strncmp (str + 1, resword + 1, len - 1)"; + else + comp_buffer = option[STRCASECMP] + ? "charmap[*str] == *resword && !strcasecmp (str + 1, resword + 1, len - 1)" + : "*str == *resword && !strcmp (str + 1, resword + 1, len - 1)"; + } + if (!option[OPTIMIZE]) + printf (" if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)\n {\n"); + printf (" register int key = %s (str, len);\n\n", option.get_hash_name ()); + if (!option[OPTIMIZE]) + printf (" if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE)\n"); + + printf (" {\n"); + + /* Properly deal with user's who request multiple switch statements. */ + + while (curr) + { + List_Node *temp = curr; + int lowest_case_value = curr->hash_value; + int number_of_cases = 0; + + /* Figure out a good cut point to end this switch. */ + + for (; temp && ++number_of_cases < switch_size; temp = temp->next) + if (temp->next && temp->hash_value == temp->next->hash_value) + while (temp->next && temp->hash_value == temp->next->hash_value) + temp = temp->next; + + if (temp && total_switches != 1) + printf (" if (key <= %d)\n {\n", temp->hash_value); + else + printf (" {\n"); + + /* Output each keyword as part of a switch statement indexed by hash value. */ + + if (option[POINTER] || option[DUP]) + { + int i = 0; + + printf (" %s%s *resword; %s\n\n", + option[CONST] ? "const " : "", + pointer_and_type_enabled ? struct_tag : "char", + option[LENTABLE] && !option[DUP] ? "int key_len;" : ""); + if (total_switches == 1) + { + printf (" switch (key)\n {\n"); + lowest_case_value = 0; + } + else + printf (" switch (key - %d)\n {\n", lowest_case_value); + + for (temp = curr; temp && ++i <= number_of_cases; temp = temp->next) + { + printf (" case %*d:", field_width, temp->hash_value - lowest_case_value); + if (option[DEBUG]) + printf (" /* hash value = %4d, keyword = \"%s\" */", temp->hash_value, temp->key); + putchar ('\n'); + + /* Handle `natural links,' i.e., those that occur statically. */ + + if (temp->link) + { + List_Node *links; + + for (links = temp; links; links = links->link) + { + if (pointer_and_type_enabled) + printf (" resword = &wordlist[%d];\n", links->index); + else + printf (" resword = \"%s\";\n", links->key); + printf (" if (%s) return resword;\n", comp_buffer); + } + } + /* Handle unresolved duplicate hash values. These are guaranteed + to be adjacent since we sorted the keyword list by increasing + hash values. */ + if (temp->next && temp->hash_value == temp->next->hash_value) + { + + for ( ; temp->next && temp->hash_value == temp->next->hash_value; + temp = temp->next) + { + if (pointer_and_type_enabled) + printf (" resword = &wordlist[%d];\n", temp->index); + else + printf (" resword = \"%s\";\n", temp->key); + printf (" if (%s) return resword;\n", comp_buffer); + } + if (pointer_and_type_enabled) + printf (" resword = &wordlist[%d];\n", temp->index); + else + printf (" resword = \"%s\";\n", temp->key); + printf (" return %s ? resword : 0;\n", comp_buffer); + } + else if (temp->link) + printf (" return 0;\n"); + else + { + if (pointer_and_type_enabled) + printf (" resword = &wordlist[%d];", temp->index); + else + printf (" resword = \"%s\";", temp->key); + if (option[LENTABLE] && !option[DUP]) + printf (" key_len = %d;", temp->length); + printf (" break;\n"); + } + } + printf (" default: return 0;\n }\n"); + if (option[OPTIMIZE]) + printf (" return resword;\n"); + else + { + printf (option[LENTABLE] && !option[DUP] + ? " if (len == key_len && %s)\n return resword;\n" + : " if (%s)\n return resword;\n", comp_buffer); + printf (" return 0;\n"); + } + printf (" }\n"); + curr = temp; + } + else /* Nothing special required here. */ + { + int i = 0; + printf (" char *s;\n\n switch (key - %d)\n {\n", + lowest_case_value); + + for (temp = curr; temp && ++i <= number_of_cases; temp = temp->next) + if (option[LENTABLE]) + printf (" case %*d: if (len == %d) s = \"%s\"; else return 0; break;\n", + field_width, temp->hash_value - lowest_case_value, + temp->length, temp->key); + else + printf (" case %*d: s = \"%s\"; break;\n", + field_width, temp->hash_value - lowest_case_value, temp->key); + + printf (" default: return 0;\n }\n "); + if (option[COMP]) + printf ("return %s == *s && !%s;\n }\n", + option[STRCASECMP] ? "charmap[*str]" : "*str", + option[STRCASECMP] ? "strncasecmp (s + 1, str + 1, len - 1)" : "strcmp (s + 1, str + 1)"); + else + printf ("return %s == *s && !%s;\n }\n", + option[STRCASECMP] ? "charmap[*str]" : "*str", + option[STRCASECMP] ? "strcasecmp (s + 1, str + 1, len - 1)" : "strcmp (s + 1, str + 1)"); + curr = temp; + } + } + printf (" }\n %s\n}\n", option[OPTIMIZE] ? "" : "}\n return 0;"); +} + +/* Prints out a table of keyword lengths, for use with the + comparison code in generated function ``in_word_set.'' */ + +void +Key_List::output_keylength_table (void) +{ + const int max_column = 15; + int index = 0; + int column = 0; + char *indent = option[GLOBAL] ? "" : " "; + List_Node *temp; + + if (!option[DUP] && !option[SWITCH]) + { + printf ("\n%sstatic %sunsigned %s lengthtable[] =\n%s%s{\n ", + indent, option[CONST] ? "const " : "", + max_key_len <= UCHAR_MAX ? "char" : (max_key_len <= USHRT_MAX ? "short" : "long"), + indent, indent); + + for (temp = head; temp; temp = temp->next, index++) + { + + if (index < temp->hash_value) + for ( ; index < temp->hash_value; index++) + printf ("%3d,%s", 0, ++column % (max_column - 1) ? "" : "\n "); + + printf ("%3d,%s", temp->length, ++column % (max_column - 1 ) ? "" : "\n "); + } + + printf ("\n%s%s};\n", indent, indent); + } +} +/* Prints out the array containing the key words for the Gen_Perf + hash function. */ + +void +Key_List::output_keyword_table (void) +{ + char *l_brace = *head->rest ? "{" : ""; + char *r_brace = *head->rest ? "}," : ""; + char *indent = option[GLOBAL] ? "" : " "; + int index = 0; + List_Node *temp; + + printf ("%sstatic %s%swordlist[] =\n%s%s{\n", + indent, option[CONST] ? "const " : "", struct_tag, indent, indent); + + /* Skip over leading blank entries if there are no duplicates. */ + + if (0 < head->hash_value) + printf (" "); + for (int column = 1; index < head->hash_value; index++, column++) + printf ("%s\"\",%s %s", l_brace, r_brace, column % 9 ? "" : "\n "); + if (0 < head->hash_value && column % 10) + printf ("\n"); + + /* Generate an array of reserved words at appropriate locations. */ + + for (temp = head ; temp; temp = temp->next, index++) + { + temp->index = index; + + if (!option[SWITCH] && (total_duplicates == 0 || !option[DUP]) && index < temp->hash_value) + { + int column; + + printf (" "); + + for (column = 1; index < temp->hash_value; index++, column++) + printf ("%s\"\",%s %s", l_brace, r_brace, column % 9 ? "" : "\n "); + + if (column % 10) + printf ("\n"); + else + { + printf ("%s\"%s\", %s%s", l_brace, temp->key, temp->rest, r_brace); + if (option[DEBUG]) + printf (" /* hash value = %d, index = %d */", temp->hash_value, temp->index); + putchar ('\n'); + continue; + } + } + + printf (" %s\"%s\", %s%s", l_brace, temp->key, temp->rest, r_brace); + if (option[DEBUG]) + printf (" /* hash value = %d, index = %d */", temp->hash_value, temp->index); + putchar ('\n'); + + /* Deal with links specially. */ + if (temp->link) + for (List_Node *links = temp->link; links; links = links->link) + { + links->index = ++index; + printf (" %s\"%s\", %s%s", l_brace, links->key, links->rest, r_brace); + if (option[DEBUG]) + printf (" /* hash value = %d, index = %d */", links->hash_value, links->index); + putchar ('\n'); + } + } + printf ("%s%s};\n\n", indent, indent); +} + +/* Generates C code for the hash function that returns the + proper encoding for each key word. */ + +void +Key_List::output_hash_function (void) +{ + const int max_column = 10; + int count = max_hash_value; + + /* Calculate maximum number of digits required for MAX_HASH_VALUE. */ + + for (field_width = 2; (count /= 10) > 0; field_width++) + ; + + if (option[GNU]) + printf ("#ifdef __GNUC__\ninline\n#endif\n"); + + if (option[C]) + printf ("static "); + printf ("unsigned int\n"); + if (option[CPLUSPLUS]) + printf ("%s::", option.get_class_name ()); + + printf (option[ANSI] + ? "%s (register const char *str, register int len)\n{\n static %sunsigned %s asso_values[] =\n {" + : "%s (str, len)\n register char *str;\n register int unsigned len;\n{\n static %sunsigned %s asso_values[] =\n {", + option.get_hash_name (), option[CONST] ? "const " : "", + max_hash_value <= UCHAR_MAX ? "char" : (max_hash_value <= USHRT_MAX ? "short" : "int")); + + for (count = 0; count < ALPHA_SIZE; ++count) + { + if (!(count % max_column)) + printf ("\n "); + + printf ("%*d,", + field_width, + Vectors::occurrences[count] ? Vectors::asso_values[count] : max_hash_value + 1); + } + + /* Optimize special case of ``-k 1,$'' */ + if (option[DEFAULTCHARS]) + { + if (option[STRCASECMP]) + printf ("\n };\n return %sasso_values[charmap[str[len - 1]]] + asso_values[charmap[str[0]]];\n}\n\n", + option[NOLENGTH] ? "" : "len + "); + else + printf ("\n };\n return %sasso_values[str[len - 1]] + asso_values[str[0]];\n}\n\n", + option[NOLENGTH] ? "" : "len + "); + } + else + { + int key_pos; + + option.reset (); + + /* Get first (also highest) key position. */ + key_pos = option.get (); + + /* We can perform additional optimizations here. */ + if (!option[ALLCHARS] && key_pos <= min_key_len) + { + printf ("\n };\n return %s", option[NOLENGTH] ? "" : "len + "); + + for (; key_pos != WORD_END; ) + { + printf (option[STRCASECMP] ? "asso_values[charmap[str[%d]]]" : "asso_values[str[%d]]", key_pos - 1); + if ((key_pos = option.get ()) != EOS) + printf (" + "); + else + break; + } + + printf ("%s;\n}\n\n", key_pos == WORD_END + ? (option[STRCASECMP] ? "asso_values[charmap[str[len - 1]]]" : "asso_values[str[len - 1]]") + : ""); + } + + /* We've got to use the correct, but brute force, technique. */ + else + { + printf ("\n };\n register int hval = %s;\n\n switch (%s)\n {\n default:\n", + option[NOLENGTH] ? "0" : "len", option[NOLENGTH] ? "len" : "hval"); + + /* User wants *all* characters considered in hash. */ + if (option[ALLCHARS]) + { + int i; + + /* Break these options up for speed (gee, is this misplaced efficiency or what?! */ + if (option[STRCASECMP]) + + for (i = max_key_len; i > 0; i--) + printf (" case %d:\n hval += asso_values[charmap[str[%d]]];\n", i, i - 1); + + else + + for (i = max_key_len; i > 0; i--) + printf (" case %d:\n hval += asso_values[str[%d]];\n", i, i - 1); + + printf (" }\n return hval;\n}\n\n"); + } + else /* do the hard part... */ + { + count = key_pos + 1; + + do + { + + while (--count > key_pos) + printf (" case %d:\n", count); + + printf (option[STRCASECMP] + ? " case %d:\n hval += asso_values[charmap[str[%d]]];\n" + : " case %d:\n hval += asso_values[str[%d]];\n", + key_pos, key_pos - 1); + } + while ((key_pos = option.get ()) != EOS && key_pos != WORD_END); + + printf (" }\n return hval%s;\n}\n\n", + key_pos == WORD_END + ? (option[STRCASECMP] ? " + asso_values[charmap[str[len - 1]]]" : " + asso_values[str[len - 1]]") + : ""); + } + } + } +} + +/* Generates the large, sparse table that maps hash values into + the smaller, contiguous range of the keyword table. */ + +void +Key_List::output_lookup_array (void) +{ + if (total_duplicates > 0) + { + const int DEFAULT_VALUE = -1; + + struct duplicate_entry + { + int hash_value; /* Hash value for this particular duplicate set. */ + int index; /* Index into the main keyword storage array. */ + int count; /* Number of consecutive duplicates at this index. */ + }; +#if LARGE_STACK_ARRAYS + duplicate_entry duplicates[total_duplicates]; + int lookup_array[max_hash_value + 1]; +#else + // Note: we don't use new, because that invokes a custom operator new. + duplicate_entry *duplicates = (duplicate_entry*) + malloc (total_duplicates * sizeof(duplicate_entry)); + int *lookup_array = (int*)malloc(sizeof(int) * (max_hash_value + 1)); + if (duplicates == NULL || lookup_array == NULL) + abort(); +#endif + duplicate_entry *dup_ptr = duplicates; + int *lookup_ptr = lookup_array + max_hash_value + 1; + + while (lookup_ptr > lookup_array) + *--lookup_ptr = DEFAULT_VALUE; + + for (List_Node *temp = head; temp; temp = temp->next) + { + int hash_value = temp->hash_value; + lookup_array[hash_value] = temp->index; + if (option[DEBUG]) + fprintf (stderr, "keyword = %s, index = %d\n", temp->key, temp->index); + if (!temp->link && + (!temp->next || hash_value != temp->next->hash_value)) + continue; +#if LARGE_STACK_ARRAYS + *dup_ptr = (duplicate_entry) { hash_value, temp->index, 1 }; +#else + duplicate_entry _dups; + _dups.hash_value = hash_value; + _dups.index = temp->index; + _dups.count = 1; + *dup_ptr = _dups; +#endif + + for (List_Node *ptr = temp->link; ptr; ptr = ptr->link) + { + dup_ptr->count++; + if (option[DEBUG]) + fprintf (stderr, "static linked keyword = %s, index = %d\n", ptr->key, ptr->index); + } + + while (temp->next && hash_value == temp->next->hash_value) + { + temp = temp->next; + dup_ptr->count++; + if (option[DEBUG]) + fprintf (stderr, "dynamic linked keyword = %s, index = %d\n", temp->key, temp->index); + + for (List_Node *ptr = temp->link; ptr; ptr = ptr->link) + { + dup_ptr->count++; + if (option[DEBUG]) + fprintf (stderr, "static linked keyword = %s, index = %d\n", ptr->key, ptr->index); + } + } + dup_ptr++; + } + + while (--dup_ptr >= duplicates) + { + if (option[DEBUG]) + fprintf (stderr, "dup_ptr[%d]: hash_value = %d, index = %d, count = %d\n", + dup_ptr - duplicates, dup_ptr->hash_value, dup_ptr->index, dup_ptr->count); + + /* Start searching for available space towards the right part of the lookup array. */ + int i; + for (i = dup_ptr->hash_value; i < max_hash_value; i++) + if (lookup_array[i] == DEFAULT_VALUE && lookup_array[i + 1] == DEFAULT_VALUE) + { + lookup_array[i] = -dup_ptr->index; + lookup_array[i + 1] = -dup_ptr->count; + lookup_array[dup_ptr->hash_value] = max_hash_value + (i - dup_ptr->hash_value); + break; + } + + /* If we didn't find it to the right look to the left instead... */ + if (i == max_hash_value) + { + + for (i = dup_ptr->hash_value; i > 0; i--) + if (lookup_array[i] == DEFAULT_VALUE && lookup_array[i - 1] == DEFAULT_VALUE) + { + lookup_array[i - 1] = -dup_ptr->index; + lookup_array[i] = -dup_ptr->count; + lookup_array[dup_ptr->hash_value] = -(max_hash_value + (dup_ptr->hash_value - i + 1)); + break; + } + + /* We are in *big* trouble if this happens! */ + assert (i != 0); + } + } + + int max = INT_MIN; + lookup_ptr = lookup_array + max_hash_value + 1; + while (lookup_ptr > lookup_array) + { + int val = abs (*--lookup_ptr); + if (max < val) + max = val; + } + + char *indent = option[GLOBAL] ? "" : " "; + printf ("%sstatic %s%s lookup[] =\n%s%s{\n ", indent, option[CONST] ? "const " : "", + max <= SCHAR_MAX ? "char" : (max <= USHRT_MAX ? "short" : "int"), + indent, indent); + + int count = max; + + /* Calculate maximum number of digits required for MAX_HASH_VALUE. */ + + for (field_width = 2; (count /= 10) > 0; field_width++) + ; + + const int max_column = 15; + int column = 0; + + for (lookup_ptr = lookup_array; + lookup_ptr < lookup_array + max_hash_value + 1; + lookup_ptr++) + printf ("%*d,%s", field_width, *lookup_ptr, ++column % (max_column - 1) ? "" : "\n "); + + printf ("\n%s%s};\n\n", indent, indent); +#if !LARGE_STACK_ARRAYS + free (duplicates); + free (lookup_array); +#endif + } +} +/* Generates C code to perform the keyword lookup. */ + +void +Key_List::output_lookup_function (void) +{ + if (!option[OPTIMIZE]) + printf (" if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)\n {\n"); + printf (" register int key = %s (str, len);\n\n", option.get_hash_name ()); + if (!option[OPTIMIZE]) + printf (" if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE)\n"); + printf (" {\n"); + + if (option[DUP] && total_duplicates > 0) + { + printf (" register int index = lookup[key];\n\n" + " if (index >= 0 && index < MAX_HASH_VALUE)\n"); + if (option[OPTIMIZE]) + printf (" return %swordlist[index];\n", option[TYPE] && option[POINTER] ? "&" : ""); + else + { + printf (" {\n" + " register %schar *s = wordlist[index]", option[CONST] ? "const " : ""); + if (array_type != default_array_type) + printf (".%s", option.get_key_name ()); + + printf (";\n\n if (%s%s == *s && !%s)\n return %s;\n }\n", + option[LENTABLE] ? "len == lengthtable[key]\n && " : "", + option[STRCASECMP] ? "charmap[*str]" : "*str", + option[COMP] ? (option[STRCASECMP] ? "strncasecmp (str + 1, s + 1, len - 1)" : "strncmp (str + 1, s + 1, len - 1)") + : (option[STRCASECMP] ? "strcasecmp (str + 1, s + 1)" : "strcmp (str + 1, s + 1)"), + option[TYPE] && option[POINTER] ? "&wordlist[index]" : "s"); + printf (" else if (index < 0 && index >= -MAX_HASH_VALUE)\n" + " return 0;\n"); + } + printf (" else\n {\n" + " register int offset = key + index + (index > 0 ? -MAX_HASH_VALUE : MAX_HASH_VALUE);\n" + " register %s%s*base = &wordlist[-lookup[offset]];\n" + " register %s%s*ptr = base + -lookup[offset + 1];\n\n" + " while (--ptr >= base)\n ", + option[CONST] ? "const " : "", struct_tag, + option[CONST] ? "const " : "", struct_tag); + if (array_type != default_array_type) + { + if (option[COMP]) + printf ("if (%s == *ptr->%s && !%s (str + 1, ptr->%s + 1, len - 1", + option[STRCASECMP] ? "charmap[*str]" : "*str", option.get_key_name (), + option[STRCASECMP] ? "strncasecmp" : "strncmp", option.get_key_name ()); + else + printf ("if (%s == *ptr->%s && !%s (str + 1, ptr->%s + 1", + option[STRCASECMP] ? "charmap[*str]" : "*str", option.get_key_name (), + option[STRCASECMP] ? "strcasecmp" : "strcmp", option.get_key_name ()); + } + else + printf (option[STRCASECMP] ? "if (charmap[*str] == **ptr && !%s" : "if (*str == **ptr && !%s", + option[COMP] + ? (option[STRCASECMP] ? "strncasecmp (str + 1, *ptr + 1, len - 1" : "strncmp (str + 1, *ptr + 1, len - 1") + : (option[STRCASECMP] ? "strcasecmp (str + 1, *ptr + 1" : "strcmp (str + 1, *ptr + 1")); + printf ("))\n return %sptr;" + "\n }\n }\n %s\n}\n", array_type == + default_array_type ? "*" : "", option[OPTIMIZE] ? "" : "}\n return 0;"); + } + else + { + if (option[OPTIMIZE]) + printf (" return %swordlist[key]", option[TYPE] && option[POINTER] ? "&" : ""); + else + { + printf (" register %schar *s = wordlist[key]", option[CONST] ? "const " : ""); + + if (array_type != default_array_type) + printf (".%s", option.get_key_name ()); + + printf (";\n\n if (%s%s == *s && !%s)\n return %s", + option[LENTABLE] ? "len == lengthtable[key]\n && " : "", + option[STRCASECMP] ? "charmap[*str]" : "*str", + option[COMP] + ? (option[STRCASECMP] ? "strncasecmp (str + 1, s + 1, len - 1)" : "strncmp (str + 1, s + 1, len - 1)") + : (option[STRCASECMP] ? "strcasecmp (str + 1, s + 1)" : "strcmp (str + 1, s + 1)"), + option[TYPE] && option[POINTER] ? "&wordlist[key]" : "s"); + } + printf (";\n }\n %s\n}\n", option[OPTIMIZE] ? "" : "}\n return 0;"); + } +} + +/* Output the table and the functions that map upper case into lower case! */ + +void +Key_List::output_strcasecmp (void) +{ + printf ("%s", + "/* This array is designed for mapping upper and lower case letter\n" + " * together for a case independent comparison. The mappings are\n" + " * based upon ascii character sequences.\n */" + "static char charmap[] = {\n" + " '\\000', '\\001', '\\002', '\\003', '\\004', '\\005', '\\006', '\\007',\n" + " '\\010', '\\011', '\\012', '\\013', '\\014', '\\015', '\\016', '\\017',\n" + " '\\020', '\\021', '\\022', '\\023', '\\024', '\\025', '\\026', '\\027',\n" + " '\\030', '\\031', '\\032', '\\033', '\\034', '\\035', '\\036', '\\037',\n" + " '\\040', '\\041', '\\042', '\\043', '\\044', '\\045', '\\046', '\\047',\n" + " '\\050', '\\051', '\\052', '\\053', '\\054', '\\055', '\\056', '\\057',\n" + " '\\060', '\\061', '\\062', '\\063', '\\064', '\\065', '\\066', '\\067',\n" + " '\\070', '\\071', '\\072', '\\073', '\\074', '\\075', '\\076', '\\077',\n" + " '\\100', '\\141', '\\142', '\\143', '\\144', '\\145', '\\146', '\\147',\n" + " '\\150', '\\151', '\\152', '\\153', '\\154', '\\155', '\\156', '\\157',\n" + " '\\160', '\\161', '\\162', '\\163', '\\164', '\\165', '\\166', '\\167',\n" + " '\\170', '\\171', '\\172', '\\133', '\\134', '\\135', '\\136', '\\137',\n" + " '\\140', '\\141', '\\142', '\\143', '\\144', '\\145', '\\146', '\\147',\n" + " '\\150', '\\151', '\\152', '\\153', '\\154', '\\155', '\\156', '\\157',\n" + " '\\160', '\\161', '\\162', '\\163', '\\164', '\\165', '\\166', '\\167',\n" + " '\\170', '\\171', '\\172', '\\173', '\\174', '\\175', '\\176', '\\177',\n" + " '\\200', '\\201', '\\202', '\\203', '\\204', '\\205', '\\206', '\\207',\n" + " '\\210', '\\211', '\\212', '\\213', '\\214', '\\215', '\\216', '\\217',\n" + " '\\220', '\\221', '\\222', '\\223', '\\224', '\\225', '\\226', '\\227',\n" + " '\\230', '\\231', '\\232', '\\233', '\\234', '\\235', '\\236', '\\237',\n" + " '\\240', '\\241', '\\242', '\\243', '\\244', '\\245', '\\246', '\\247',\n" + " '\\250', '\\251', '\\252', '\\253', '\\254', '\\255', '\\256', '\\257',\n" + " '\\260', '\\261', '\\262', '\\263', '\\264', '\\265', '\\266', '\\267',\n" + " '\\270', '\\271', '\\272', '\\273', '\\274', '\\275', '\\276', '\\277',\n" + " '\\300', '\\341', '\\342', '\\343', '\\344', '\\345', '\\346', '\\347',\n" + " '\\350', '\\351', '\\352', '\\353', '\\354', '\\355', '\\356', '\\357',\n" + " '\\360', '\\361', '\\362', '\\363', '\\364', '\\365', '\\366', '\\367',\n" + " '\\370', '\\371', '\\372', '\\333', '\\334', '\\335', '\\336', '\\337',\n" + " '\\340', '\\341', '\\342', '\\343', '\\344', '\\345', '\\346', '\\347',\n" + " '\\350', '\\351', '\\352', '\\353', '\\354', '\\355', '\\356', '\\357',\n" + " '\\360', '\\361', '\\362', '\\363', '\\364', '\\365', '\\366', '\\367',\n" + " '\\370', '\\371', '\\372', '\\373', '\\374', '\\375', '\\376', '\\377',\n};\n\nstatic int\n"); + if (option[COMP]) + { + printf ("%s", option[ANSI] + ? "strncasecmp (register char *s1, register char *s2, register int n)" + : "strncasecmp (s1, s2, n)\n register char *s1, *s2;\n register int n;"); + printf ("\n{\n register char *cm = charmap;\n\n while (--n >= 0 && cm[*s1] == cm[*s2++])\n" + " if (*s1++ == '\\0')\n return 0;\n" + "\n return n < 0 ? 0 : cm[*s1] - cm[*--s2];\n}\n\n"); + } + else + { + printf ("%s", option[ANSI] + ? "strcasecmp (register char *s1, register char *s2)" + : "strcasecmp (s1, s2)\n register char *s1, *s2;"); + printf ("\n{\n register char *cm = charmap;\n\n while (cm[*s1] == cm[*s2++])\n" + " if (*s1++ == '\\0')\n return 0;\n" + "\n return cm[*s1] - cm[*--s2];\n}\n\n"); + } +} + +/* Generates the hash function and the key word recognizer function + based upon the user's Options. */ + +void +Key_List::output (void) +{ + printf ("%s\n", include_src); + + if (option[TYPE] && !option[NOTYPE]) /* Output type declaration now, reference it later on.... */ + printf ("%s;\n", array_type); + + output_min_max (); + + if (option[STRCASECMP]) + output_strcasecmp (); + if (option[CPLUSPLUS]) + printf ("class %s\n{\nprivate:\n" + " static unsigned int hash (const char *str, int len);\npublic:\n" + " static %s%s%s (const char *str, int len);\n};\n\n", + option.get_class_name (), option[CONST] ? "const " : "", + return_type, option.get_function_name ()); + + output_hash_function (); + + if (option[GLOBAL]) + if (option[SWITCH]) + { + if (option[LENTABLE] && option[DUP]) + output_keylength_table (); + if (option[POINTER] && option[TYPE]) + output_keyword_table (); + } + else + { + if (option[LENTABLE]) + output_keylength_table (); + output_keyword_table (); + output_lookup_array (); + } + + if (option[GNU]) /* Use the inline keyword to remove function overhead. */ + printf ("#ifdef __GNUC__\ninline\n#endif\n"); + + printf ("%s%s\n", option[CONST] ? "const " : "", return_type); + if (option[CPLUSPLUS]) + printf ("%s::", option.get_class_name ()); + + printf (option[ANSI] + ? "%s (register const char *str, register int len)\n{\n" + : "%s (str, len)\n register char *str;\n register unsigned int len;\n{\n", + option.get_function_name ()); + + if (option[ENUM] && !option[GLOBAL]) + printf (" enum\n {\n" + " TOTAL_KEYWORDS = %d,\n" + " MIN_WORD_LENGTH = %d,\n" + " MAX_WORD_LENGTH = %d,\n" + " MIN_HASH_VALUE = %d,\n" + " MAX_HASH_VALUE = %d,\n" + " HASH_VALUE_RANGE = %d,\n" + " DUPLICATES = %d\n };\n\n", + total_keys, min_key_len, max_key_len, min_hash_value, + max_hash_value, max_hash_value - min_hash_value + 1, + total_duplicates ? total_duplicates + 1 : 0); + /* Use the switch in place of lookup table. */ + if (option[SWITCH]) + { + if (!option[GLOBAL]) + { + if (option[LENTABLE] && option[DUP]) + output_keylength_table (); + if (option[POINTER] && option[TYPE]) + output_keyword_table (); + } + output_switch (); + } + /* Use the lookup table, in place of switch. */ + else + { + if (!option[GLOBAL]) + { + if (option[LENTABLE]) + output_keylength_table (); + output_keyword_table (); + } + if (!option[GLOBAL]) + output_lookup_array (); + output_lookup_function (); + } + + if (additional_code) + { + for (;;) + { + int c = getchar (); + + if (c == EOF) + break; + else + putchar (c); + } + } + + fflush (stdout); +} + +/* Sorts the keys by hash value. */ + +void +Key_List::sort (void) +{ + hash_sort = 1; + occurrence_sort = 0; + + head = merge_sort (head); +} + +/* Dumps the key list to stderr stream. */ + +void +Key_List::dump () +{ + int field_width = option.get_max_keysig_size (); + + fprintf (stderr, "\nList contents are:\n(hash value, key length, index, %*s, keyword):\n", + field_width, "char_set"); + + for (List_Node *ptr = head; ptr; ptr = ptr->next) + fprintf (stderr, "%11d,%11d,%6d, %*s, %s\n", + ptr->hash_value, ptr->length, ptr->index, + field_width, ptr->char_set, ptr->key); +} + +/* Simple-minded constructor action here... */ + +Key_List::Key_List (void) +{ + total_keys = 1; + max_key_len = INT_MIN; + min_key_len = INT_MAX; + return_type = default_return_type; + array_type = struct_tag = default_array_type; + head = 0; + total_duplicates = 0; + additional_code = 0; +} + +/* Returns the length of entire key list. */ + +int +Key_List::keyword_list_length (void) +{ + return list_len; +} + +/* Returns length of longest key read. */ + +int +Key_List::max_key_length (void) +{ + return max_key_len; +} + diff --git a/apps/gperf/src/Key_List.h b/apps/gperf/src/Key_List.h new file mode 100644 index 00000000000..14276eb975d --- /dev/null +++ b/apps/gperf/src/Key_List.h @@ -0,0 +1,116 @@ +/* -*- C++ -*- */ +// @(#)Key_List.h 1.1 10/18/96 + +/* This may look like C code, but it is really -*- C++ -*- */ + +/* Data and function member declarations for the keyword list class. + + Copyright (C) 1989 Free Software Foundation, Inc. + written by Douglas C. Schmidt (schmidt@ics.uci.edu) + +This file is part of GNU GPERF. + +GNU GPERF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU GPERF is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU GPERF; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +// The key word list is a useful abstraction that keeps track of +// various pieces of information that enable that fast generation of +// the Gen_Perf.hash function. A Key_List is a singly-linked list of +// List_Nodes. + +#ifndef key_list_h +#define key_list_h 1 + +#include "Options.h" +#include "List_Node.h" + +class Key_List +{ +public: + Key_List (void); + ~Key_List (void); + int keyword_list_length (void); + int max_key_length (void); + void reorder (void); + void sort (void); + void read_keys (void); + void output (void); + + List_Node *head; + // Points to the head of the linked list. + + int total_duplicates; + // Total number of duplicate hash values. + +private: + static int get_occurrence (List_Node *ptr); + static int strcspn (const char *s, const char *reject); + static int already_determined (List_Node *ptr); + static void set_determined (List_Node *ptr); + void output_min_max (void); + void output_switch (void); + void output_keyword_table (void); + void output_keylength_table (void); + void output_hash_function (void); + void output_lookup_function (void); + void output_lookup_array (void); + void output_strcasecmp (void); + void set_output_types (void); + void dump (void); + char *get_array_type (void); + char *save_include_src (void); + char *get_special_input (char delimiter); + List_Node *merge (List_Node *list1, List_Node *list2); + List_Node *merge_sort (List_Node *head); + + char *array_type; + // Pointer to the type for word list. + + char *return_type; + // Pointer to return type for lookup function. + + char *struct_tag; + // Shorthand for user-defined struct tag type. + + char *include_src; + // C source code to be included verbatim. + + int max_key_len; + // Maximum length of the longest keyword. + + int min_key_len; + // Minimum length of the shortest keyword. + + int min_hash_value; + // Minimum hash value for all keywords. + + int max_hash_value; + // Maximum hash value for all keywords. + + int occurrence_sort; + // True if sorting by occurrence. + + int hash_sort; + // True if sorting by hash value. + + int additional_code; + // True if any additional C code is included. + + int list_len; + // Length of head's Key_List, not counting duplicates. + + int total_keys; + // Total number of keys, counting duplicates. +}; +#endif diff --git a/apps/gperf/src/List_Node.cpp b/apps/gperf/src/List_Node.cpp new file mode 100644 index 00000000000..d72cc699c13 --- /dev/null +++ b/apps/gperf/src/List_Node.cpp @@ -0,0 +1,110 @@ +/* Creates and initializes a new list node. +// @(#)List_Node.cpp 1.1 10/18/96 + + Copyright (C) 1989 Free Software Foundation, Inc. + written by Douglas C. Schmidt (schmidt@ics.uci.edu) + +This file is part of GNU GPERF. + +GNU GPERF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU GPERF is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU GPERF; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "Vectors.h" +#include "List_Node.h" + +/* Defined as a macro in string.h on some systems, which causes + conflicts. */ +#undef index + +/* Sorts the key set alphabetically to speed up subsequent operations. + Uses insertion sort since the set is probably quite small. */ + +inline void +List_Node::set_sort (char *base, int len) +{ + int i, j; + + for (i = 0, j = len - 1; i < j; i++) + { + char curr, tmp; + + for (curr = i + 1, tmp = base[curr]; curr > 0 && tmp < base[curr-1]; curr--) + base[curr] = base[curr - 1]; + + base[curr] = tmp; + + } +} + +/* Initializes a List_Node. This requires obtaining memory for the + CHAR_SET initializing them using the information stored in the + KEY_POSITIONS array in Options, and checking for simple errors. + It's important to note that KEY and REST are both pointers to the + different offsets into the same block of dynamic memory pointed to + by parameter K. The data member REST is used to store any + additional fields of the input file (it is set to the "" string if + Option[TYPE] is not enabled). This is useful if the user wishes to + incorporate a lookup structure, rather than just an array of keys. + Finally, KEY_NUMBER contains a count of the total number of keys + seen so far. This is used to initialize the INDEX field to some + useful value. */ + +List_Node::List_Node (char *k, int len) + : key (k), + next (0), + index (0), + length (len), + link (0), + rest (option[TYPE] ? k + len + 1 : "") +{ + char *ptr = new char[(option[ALLCHARS] ? len : option.get_max_keysig_size ()) + 1]; + char_set = ptr; + k[len] = '\0'; /* Null terminate KEY to separate it from REST. */ + + /* Lower case if STRCASECMP option is enabled. */ + if (option[STRCASECMP]) + for (char *p = k; *p; p++) + if (isupper (*p)) + *p = tolower (*p); + + if (option[ALLCHARS]) /* Use all the character position in the KEY. */ + for (; *k; k++, ptr++) + ++Vectors::occurrences[*ptr = *k]; + else /* Only use those character positions specified by the user. */ + { + int i; + + /* Iterate thru the list of key_positions, initializing occurrences table + and char_set (via char * pointer ptr). */ + + for (option.reset (); (i = option.get ()) != EOS; ) + { + if (i == WORD_END) /* Special notation for last KEY position, i.e. '$'. */ + *ptr = key[len - 1]; + else if (i <= len) /* Within range of KEY length, so we'll keep it. */ + *ptr = key[i - 1]; + else /* Out of range of KEY length, so we'll just skip it. */ + continue; + ++Vectors::occurrences[*ptr++]; + } + + /* Didn't get any hits and user doesn't want to consider the + keylength, so there are essentially no usable hash positions! */ + if (ptr == char_set && option[NOLENGTH]) + ACE_ERROR ((LM_ERROR, "Can't hash keyword %s with chosen key positions.\n%a", key, 1)); + } + *ptr = '\0'; /* Terminate this bastard.... */ + /* Sort the KEY_SET items alphabetically. */ + set_sort (char_set, ptr - char_set); +} diff --git a/apps/gperf/src/List_Node.h b/apps/gperf/src/List_Node.h new file mode 100644 index 00000000000..0cb512f0894 --- /dev/null +++ b/apps/gperf/src/List_Node.h @@ -0,0 +1,65 @@ +/* -*- C++ -*- */ +// @(#)List_Node.h 1.1 10/18/96 + +/* This may look like C code, but it is really -*- C++ -*- */ + +/* Data and function members for defining values and operations of a list node. + + Copyright (C) 1989 Free Software Foundation, Inc. + written by Douglas C. Schmidt (schmidt@ics.uci.edu) + +This file is part of GNU GPERF. + +GNU GPERF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU GPERF is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU GPERF; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#ifndef list_node_h +#define list_node_h 1 + +#include "Options.h" + +struct List_Node +{ + List_Node (char *key, int len); + static void set_sort (char *base, int len); + + List_Node *link; + // TRUE if key has an identical KEY_SET as another key. + + List_Node *next; + // Points to next element on the list. + + char *key; + // Each keyword string stored here. + + char *rest; + // Additional information for building hash function. + + char *char_set; + // Set of characters to hash, specified by user. + + int length; + // Length of the key. + + int hash_value; + // Hash value for the key. + + int occurrence; + // A metric for frequency of key set occurrences. + + int index; + // Position of this node relative to other nodes. +}; + +#endif diff --git a/apps/gperf/src/Makefile b/apps/gperf/src/Makefile new file mode 100644 index 00000000000..ca6221f7156 --- /dev/null +++ b/apps/gperf/src/Makefile @@ -0,0 +1,155 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for GPERF release +#---------------------------------------------------------------------------- + +BIN = gperf +LIB = libGperf.a + +FILES = new \ + Options \ + Iterator \ + Gen_Perf \ + Key_List \ + List_Node \ + Hash_Table \ + Bool_Array \ + Vectors \ + Version + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(addsuffix .o,$(FILES)) + +LDLIBS = -lGperf + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VLIB) $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/new.o .shobj/new.so: new.cpp Options.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i +.obj/Options.o .shobj/Options.so: Options.cpp \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + Options.h Iterator.h +.obj/Iterator.o .shobj/Iterator.so: Iterator.cpp Iterator.h Options.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i +.obj/Gen_Perf.o .shobj/Gen_Perf.so: Gen_Perf.cpp Gen_Perf.h Options.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + Key_List.h List_Node.h Bool_Array.h +.obj/Key_List.o .shobj/Key_List.so: Key_List.cpp \ + $(WRAPPER_ROOT)/ace/Read_Buffer.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Read_Buffer.i \ + Hash_Table.h Options.h List_Node.h Vectors.h Key_List.h +.obj/List_Node.o .shobj/List_Node.so: List_Node.cpp Vectors.h List_Node.h Options.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i +.obj/Hash_Table.o .shobj/Hash_Table.so: Hash_Table.cpp \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + Hash_Table.h Options.h List_Node.h +.obj/Bool_Array.o .shobj/Bool_Array.so: Bool_Array.cpp Bool_Array.h Options.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i +.obj/Version.o .shobj/Version.so: Version.cpp + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/apps/gperf/src/Options.cpp b/apps/gperf/src/Options.cpp new file mode 100644 index 00000000000..184187b5a4a --- /dev/null +++ b/apps/gperf/src/Options.cpp @@ -0,0 +1,616 @@ +/* Handles parsing the Options provided to the user. +// @(#)Options.cpp 1.1 10/18/96 + + Copyright (C) 1989 Free Software Foundation, Inc. + written by Douglas C. Schmidt (schmidt@ics.uci.edu) + +This file is part of GNU GPERF. + +GNU GPERF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU GPERF is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU GPERF; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "ace/Get_Opt.h" +#include "Options.h" +#include "Iterator.h" + +/* Global option coordinator for the entire program. */ +Options option; + +/* Current program version. */ +extern char *version_string; + +/* Size to jump on a collision. */ +static const int DEFAULT_JUMP_VALUE = 5; + +/* Default name for generated lookup function. */ +static const char *const DEFAULT_NAME = "in_word_set"; + +/* Default name for the key component. */ +static const char *const DEFAULT_KEY = "name"; + +/* Default name for the generated class. */ +static const char *const DEFAULT_CLASS_NAME = "Perfect_Hash"; + +/* Default name for generated hash function. */ +static const char *const DEFAULT_HASH_NAME = "hash"; + +/* Default delimiters that separate keywords from their attributes. */ +static const char *const DEFAULT_DELIMITERS = ",\n"; + +int Options::option_word; +int Options::total_switches; +int Options::total_keysig_size; +int Options::size; +int Options::key_pos; +int Options::jump; +int Options::initial_asso_value; +int Options::argument_count; +int Options::iterations; +char **Options::argument_vector; +const char *Options::function_name; +const char *Options::key_name; +const char *Options::class_name; +const char *Options::hash_name; +const char *Options::delimiters; +char Options::key_positions[MAX_KEY_POS]; + +/* Prints program usage to standard error stream. */ + +inline void +Options::usage (void) +{ + ACE_ERROR ((LM_ERROR, "Usage: %n [-acCdDef[num]gGhHiIjkKlLnNoOprsStTvZ].\n" + "(type %n -h for help)\n")); +} + +/* Output command-line Options. */ + +void +Options::print_options (void) +{ + int i; + + printf ("/* Command-line: "); + + for (i = 0; i < argument_count; i++) + printf ("%s ", argument_vector[i]); + + printf (" */"); +} + +/* Sorts the key positions *IN REVERSE ORDER!!* + This makes further routines more efficient. Especially when generating code. + Uses a simple Insertion Sort since the set is probably ordered. + Returns 1 if there are no duplicates, 0 otherwise. */ + +inline int +Options::key_sort (char *base, int len) +{ + int i, j; + + for (i = 0, j = len - 1; i < j; i++) + { + int curr, tmp; + + for (curr = i + 1,tmp = base[curr]; curr > 0 && tmp >= base[curr - 1]; curr--) + if ((base[curr] = base[curr - 1]) == tmp) /* oh no, a duplicate!!! */ + return 0; + + base[curr] = tmp; + } + + return 1; +} + +/* Sets the default Options. */ + +Options::Options (void) +{ + key_positions[0] = WORD_START; + key_positions[1] = WORD_END; + key_positions[2] = EOS; + total_keysig_size = 2; + delimiters = DEFAULT_DELIMITERS; + jump = DEFAULT_JUMP_VALUE; + option_word = DEFAULTCHARS | C; + function_name = DEFAULT_NAME; + key_name = DEFAULT_KEY; + hash_name = DEFAULT_HASH_NAME; + class_name = DEFAULT_CLASS_NAME; + total_switches = size = 1; + initial_asso_value = iterations = 0; +} + +/* Dumps option status when debug is set. */ + +Options::~Options (void) +{ + if (option_word & DEBUG) + { + char *ptr; + + fprintf (stderr, "\ndumping Options:\nDEBUG is.......: %s\nORDER is.......: %s" + "\nANSI is........: %s\nTYPE is........: %s\nGNU is.........: %s" + "\nRANDOM is......: %s\nDEFAULTCHARS is: %s\nSWITCH is......: %s" + "\nPOINTER is.....: %s\nNOLENGTH is....: %s\nLENTABLE is....: %s" + "\nDUP is.........: %s\nFAST is........: %s\nCOMP is.....: %s" + "\nNOTYPE is......: %s\nGLOBAL is......: %s\nCONST is....: %s" + "\nCPLUSPLUS is...: %s\nC is...........: %s\nENUM is.....: %s" + "\nSTRCASECMP is...: %s\nOPTIMIZE is...........: %s" + "\niterations = %d\nlookup function name = %s\nhash function name = %s" + "\nkey name = %s\njump value = %d\nmax associcated value = %d" + "\ninitial associated value = %d\ndelimiters = %s\nnumber of switch statements = %d\n", + option_word & DEBUG ? "enabled" : "disabled", + option_word & ORDER ? "enabled" : "disabled", + option_word & ANSI ? "enabled" : "disabled", + option_word & TYPE ? "enabled" : "disabled", + option_word & GNU ? "enabled" : "disabled", + option_word & RANDOM ? "enabled" : "disabled", + option_word & DEFAULTCHARS ? "enabled" : "disabled", + option_word & SWITCH ? "enabled" : "disabled", + option_word & POINTER ? "enabled" : "disabled", + option_word & NOLENGTH ? "enabled" : "disabled", + option_word & LENTABLE ? "enabled" : "disabled", + option_word & DUP ? "enabled" : "disabled", + option_word & FAST ? "enabled" : "disabled", + option_word & COMP ? "enabled" : "disabled", + option_word & NOTYPE ? "enabled" : "disabled", + option_word & GLOBAL ? "enabled" : "disabled", + option_word & CONST ? "enabled" : "disabled", + option_word & CPLUSPLUS ? "enabled" : "disabled", + option_word & C ? "enabled" : "disabled", + option_word & ENUM ? "enabled" : "disabled", + option_word & STRCASECMP ? "enabled" : "disabled", + option_word & OPTIMIZE ? "enabled" : "disabled", + iterations, function_name, hash_name, key_name, jump, size - 1, + initial_asso_value, delimiters, total_switches); + if (option_word & ALLCHARS) + fprintf (stderr, "all characters are used in the hash function\n"); + + fprintf (stderr, "maximum keysig size = %d\nkey positions are: \n", + total_keysig_size); + + for (ptr = key_positions; *ptr != EOS; ptr++) + if (*ptr == WORD_END) + fprintf (stderr, "$\n"); + else + fprintf (stderr, "%d\n", *ptr); + + fprintf (stderr, "finished dumping Options\n"); + } +} + + +/* Parses the command line Options and sets appropriate flags in option_word. */ + +void +Options::operator() (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0]); + + ACE_Get_Opt getopt (argc, argv, "adcCDe:Ef:gGhH:i:Ij:k:K:lL:nN:oOprs:S:tTvZ:"); + int option_char; + + argument_count = argc; + argument_vector = argv; + + while ((option_char = getopt ()) != -1) + { + switch (option_char) + { + case 'a': /* Generated coded uses the ANSI prototype format. */ + { + option_word |= ANSI; + break; + } + case 'c': /* Generate strncmp rather than strcmp. */ + { + option_word |= COMP; + break; + } + case 'C': /* Make the generated tables readonly (const). */ + { + option_word |= CONST; + break; + } + case 'd': /* Enable debugging option. */ + { + option_word |= DEBUG; + ACE_ERROR ((LM_ERROR, "Starting program %n, version %s, with debuggin on.\n", + version_string)); + break; + } + case 'D': /* Enable duplicate option. */ + { + option_word |= DUP; + break; + } + case 'e': /* Allows user to provide keyword/attribute separator */ + { + option.delimiters = getopt.optarg; + break; + } + case 'E': + { + option_word |= ENUM; + break; + } + case 'f': /* Generate the hash table ``fast.'' */ + { + option_word |= FAST; + if ((iterations = atoi (getopt.optarg)) < 0) + { + ACE_ERROR ((LM_ERROR, "iterations value must not be negative, assuming 0\n")); + iterations = 0; + } + break; + } + case 'g': /* Use the ``inline'' keyword for generated sub-routines. */ + { + option_word |= GNU; + break; + } + case 'G': /* Make the keyword table a global variable. */ + { + option_word |= GLOBAL; + break; + } + case 'h': /* Displays a list of helpful Options to the user. */ + { + ACE_ERROR ((LM_ERROR, + "-a\tGenerate ANSI standard C output code, i.e., function prototypes.\n" + "-c\tGenerate comparison code using strncmp rather than strcmp.\n" + "-C\tMake the contents of generated lookup tables constant, i.e., readonly.\n" + "-d\tEnables the debugging option (produces verbose output to the standard error).\n" + "-D\tHandle keywords that hash to duplicate values. This is useful\n" + "\tfor certain highly redundant keyword sets. It enables the -S option.\n" + "-e\tAllow user to provide a string containing delimiters used to separate\n" + "\tkeywords from their attributes. Default is \",\\n\"\n" + "-E\tDefine constant values using an enum local to the lookup function\n" + "\trather than with defines\n" + "-f\tGenerate the gen-perf.hash function ``fast.'' This decreases GPERF's\n" + "\trunning time at the cost of minimizing generated table-size.\n" + "\tThe numeric argument represents the number of times to iterate when\n" + "\tresolving a collision. `0' means ``iterate by the number of keywords.''\n" + "-g\tAssume a GNU compiler, e.g., g++ or gcc. This makes all generated\n" + "\troutines use the ``inline'' keyword to remove cost of function calls.\n" + "-G\tGenerate the static table of keywords as a static global variable,\n" + "\trather than hiding it inside of the lookup function (which is the\n" + "\tdefault behavior).\n" + "-h\tPrints this mesage.\n" + "-H\tAllow user to specify name of generated hash function. Default\n" + "\tis `hash'.\n" + "-i\tProvide an initial value for the associate values array. Default is 0.\n" + "-I\tGenerate comparison code using case insensitive string comparison, e.g.,\n" + "\tstrncasecmp or strcasecmp.\n" + "\tSetting this value larger helps inflate the size of the final table.\n" + "-j\tAffects the ``jump value,'' i.e., how far to advance the associated\n" + "\tcharacter value upon collisions. Must be an odd number, default is %d.\n" + "-k\tAllows selection of the key positions used in the hash function.\n" + "\tThe allowable choices range between 1-%d, inclusive. The positions\n" + "\tare separated by commas, ranges may be used, and key positions may\n" + "\toccur in any order. Also, the meta-character '*' causes the generated\n" + "\thash function to consider ALL key positions, and $ indicates the\n" + "\t``final character'' of a key, e.g., $,1,2,4,6-10.\n" + "-K\tAllow use to select name of the keyword component in the keyword structure.\n" + "-l\tCompare key lengths before trying a string comparison. This helps\n" + "\tcut down on the number of string comparisons made during the lookup.\n" + "-L\tGenerates code in the language specified by the option's argument. Languages\n" + "\thandled are currently C++ and C. The default is C.\n" + "-n\tDo not include the length of the keyword when computing the hash function\n" + "-N\tAllow user to specify name of generated lookup function. Default\n" + "\tname is `in_word_set.'\n" + "-o\tReorders input keys by frequency of occurrence of the key sets.\n" + "\tThis should decrease the search time dramatically.\n" + "-O\tOptimize the generated lookup function by assuming that all input keywords \n" + "\tare members of the keyset from the keyfile.\n" + "-p\tChanges the return value of the generated function ``in_word_set''\n" + "\tfrom its default boolean value (i.e., 0 or 1), to type ``pointer\n" + "\tto wordlist array'' This is most useful when the -t option, allowing\n" + "\tuser-defined structs, is used.\n" + "-r\tUtilizes randomness to initialize the associated values table.\n" + "-s\tAffects the size of the generated hash table. The numeric argument\n" + "\tfor this option indicates ``how many times larger or smaller'' the associated\n" + "\tvalue range should be, in relationship to the number of keys, e.g. a value of 3\n" + "\tmeans ``allow the maximum associated value to be about 3 times larger than the\n" + "\tnumber of input keys.'' Conversely, a value of -3 means ``make the maximum\n" + "\tassociated value about 3 times smaller than the number of input keys.\n" + "\tA larger table should decrease the time required for an unsuccessful search,\n" + "\tat the expense of extra table space. Default value is 1.\n" + "-S\tCauses the generated C code to use a switch statement scheme, rather\n" + "\tthan an array lookup table. This can lead to a reduction in both\n" + "\ttime and space requirements for some keyfiles. The argument to\n" + "\tthis option determines how many switch statements are generated.\n" + "\tA value of 1 generates 1 switch containing all the elements, a value of 2\n" + "\tgenerates 2 tables with 1/2 the elements in each table, etc. This\n" + "\tis useful since many C compilers cannot correctly generate code for\n" + "\tlarge switch statements.\n" + "-t\tAllows the user to include a structured type declaration for \n" + "\tgenerated code. Any text before %%%% is consider part of the type\n" + "\tdeclaration. Key words and additional fields may follow this, one\n" + "\tgroup of fields per line.\n" + "-T\tPrevents the transfer of the type declaration to the output file.\n" + "\tUse this option if the type is already defined elsewhere.\n" + "-v\tPrints out the current version number\n" + "-Z\tAllow user to specify name of generated C++ class. Default\n" + "\tname is `Perfect_Hash.'\n%e%a", DEFAULT_JUMP_VALUE, (MAX_KEY_POS - 1), usage, 1)); + } + case 'H': /* Sets the name for the hash function */ + { + hash_name = getopt.optarg; + break; + } + case 'i': /* Sets the initial value for the associated values array. */ + { + if ((initial_asso_value = atoi (getopt.optarg)) < 0) + ACE_ERROR ((LM_ERROR, "Initial value %d should be non-zero, ignoring and continuing.\n", initial_asso_value)); + if (option[RANDOM]) + ACE_ERROR ((LM_ERROR, "warning, -r option superceeds -i, ignoring -i option and continuing\n")); + break; + } + case 'I': + { + option_word |= STRCASECMP; + break; + } + case 'j': /* Sets the jump value, must be odd for later algorithms. */ + { + if ((jump = atoi (getopt.optarg)) < 0) + ACE_ERROR ((LM_ERROR, "Jump value %d must be a positive number.\n%e%a", jump, usage, 1)); + else if (jump && ACE_EVEN (jump)) + ACE_ERROR ((LM_ERROR, "Jump value %d should be odd, adding 1 and continuing...\n", jump++)); + break; + } + case 'k': /* Sets key positions used for hash function. */ + { + const int BAD_VALUE = -1; + int value; + Iterator expand (getopt.optarg, 1, MAX_KEY_POS - 1, WORD_END, BAD_VALUE, EOS); + + if (*getopt.optarg == '*') /* Use all the characters for hashing!!!! */ + option_word = (option_word & ~DEFAULTCHARS) | ALLCHARS; + else + { + char *l_key_pos; + + for (l_key_pos = key_positions; (value = expand ()) != EOS; l_key_pos++) + if (value == BAD_VALUE) + ACE_ERROR ((LM_ERROR, "Illegal key value or range, use 1,2,3-%d,'$' or '*'.\n%e%a", + MAX_KEY_POS - 1, usage, 1)); + else + *l_key_pos = value;; + + *l_key_pos = EOS; + + if (! (total_keysig_size = (l_key_pos - key_positions))) + ACE_ERROR ((LM_ERROR, "No keys selected.\n%e%a", usage, 1)); + else if (! key_sort (key_positions, total_keysig_size)) + ACE_ERROR ((LM_ERROR, "Duplicate keys selected\n%e%a", usage, 1)); + + if (total_keysig_size != 2 + || (key_positions[0] != 1 || key_positions[1] != WORD_END)) + option_word &= ~DEFAULTCHARS; + } + break; + } + case 'K': /* Make this the keyname for the keyword component field. */ + { + key_name = getopt.optarg; + break; + } + case 'l': /* Create length table to avoid extra string compares. */ + { + option_word |= LENTABLE; + break; + } + case 'L': /* Deal with different generated languages. */ + { + option_word &= ~C; + if (!strcmp (getopt.optarg, "C++")) + option_word |= (CPLUSPLUS | ANSI); + else if (!strcmp (getopt.optarg, "C")) + option_word |= C; + else + { + ACE_ERROR ((LM_ERROR, "unsupported language option %s, defaulting to C\n", getopt.optarg)); + option_word |= C; + } + break; + } + case 'n': /* Don't include the length when computing hash function. */ + { + option_word |= NOLENGTH; + break; + } + case 'N': /* Make generated lookup function name be optarg */ + { + function_name = getopt.optarg; + break; + } + case 'o': /* Order input by frequency of key set occurrence. */ + { + option_word |= ORDER; + break; + } + case 'O': + { + option_word |= OPTIMIZE; + break; + } + case 'p': /* Generated lookup function now a pointer instead of int. */ + { + option_word |= POINTER; + break; + } + case 'r': /* Utilize randomness to initialize the associated values table. */ + { + option_word |= RANDOM; + if (option.initial_asso_value != 0) + ACE_ERROR ((LM_ERROR, "warning, -r option superceeds -i, disabling -i option and continuing\n")); + break; + } + case 's': /* Range of associated values, determines size of final table. */ + { + if (abs (size = atoi (getopt.optarg)) > 50) + ACE_ERROR ((LM_ERROR, "%d is excessive, did you really mean this?! (type %n -h for help)\n", size)); + break; + } + case 'S': /* Generate switch statement output, rather than lookup table. */ + { + option_word |= SWITCH; + if ((option.total_switches = atoi (getopt.optarg)) <= 0) + ACE_ERROR ((LM_ERROR, "number of switches %s must be a positive number\n%e%a", getopt.optarg, usage, 1)); + break; + } + case 't': /* Enable the TYPE mode, allowing arbitrary user structures. */ + { + option_word |= TYPE; + break; + } + case 'T': /* Don't print structure definition. */ + { + option_word |= NOTYPE; + break; + } + case 'v': /* Print out the version and quit. */ + ACE_ERROR ((LM_ERROR, "%n: version %s\n%e\n%a", version_string, usage, 1)); + case 'Z': /* Set the class name. */ + { + class_name = getopt.optarg; + break; + } + default: + ACE_ERROR ((LM_ERROR, "%e%a", usage, 1)); + } + + } + + if (argv[getopt.optind] && ! freopen (argv[getopt.optind], "r", stdin)) + ACE_ERROR ((LM_ERROR, "Cannot open keyword file %p\n%e%a", argv[getopt.optind], usage, 1)); + + if (++getopt.optind < argc) + ACE_ERROR ((LM_ERROR, "Extra trailing arguments to %n.\n%e%a", usage, 1)); +} + +int +Options::operator[] (Option_Type option) /* True if option enable, else false. */ +{ + return option_word & option; +} + +void +Options::operator = (enum Option_Type opt) /* Enables option OPT. */ +{ + option_word |= opt; +} + +void +Options::operator != (enum Option_Type opt) /* Disables option OPT. */ +{ + option_word &= ~opt; +} + +void +Options::reset (void) /* Initializes the key Iterator. */ +{ + key_pos = 0; +} + +int +Options::get (void) /* Returns current key_position and advanced index. */ +{ + return key_positions[key_pos++]; +} + +void +Options::set_asso_max (int r) /* Sets the size of the table size. */ +{ + size = r; +} + +int +Options::get_asso_max (void) /* Returns the size of the table size. */ +{ + return size; +} + +int +Options::get_max_keysig_size (void) /* Returns total distinct key positions. */ +{ + return total_keysig_size; +} + +void +Options::set_keysig_size (int a_size) /* Sets total distinct key positions. */ +{ + total_keysig_size = a_size; +} + +int +Options::get_jump (void) /* Returns the jump value. */ +{ + return jump; +} + +const char * +Options::get_function_name (void) /* Returns the generated function name. */ +{ + return function_name; +} + +const char * +Options::get_key_name (void) /* Returns the keyword key name. */ +{ + return key_name; +} + +const char * +Options::get_hash_name (void) /* Returns the hash function name. */ +{ + return hash_name; +} + +const char * +Options::get_class_name (void) /* Returns the generated class name. */ +{ + return class_name; +} + +int +Options::initial_value (void) /* Returns the initial associated character value. */ +{ + return initial_asso_value; +} + +int +Options::get_iterations (void) /* Returns the iterations value. */ +{ + return iterations; +} + +const char * +Options::get_delimiter () /* Returns the string used to delimit keywords from other attributes. */ +{ + return delimiters; +} + +int +Options::get_total_switches () /* Gets the total number of switch statements to generate. */ +{ + return total_switches; +} + + + + diff --git a/apps/gperf/src/Options.h b/apps/gperf/src/Options.h new file mode 100644 index 00000000000..2d67003d991 --- /dev/null +++ b/apps/gperf/src/Options.h @@ -0,0 +1,140 @@ +/* -*- C++ -*- */ +// @(#)Options.h 1.1 10/18/96 + +/* This may look like C code, but it is really -*- C++ -*- */ + +/* Handles parsing the Options provided to the user. + + Copyright (C) 1989 Free Software Foundation, Inc. + written by Douglas C. Schmidt (schmidt@ics.uci.edu) + +This file is part of GNU GPERF. + +GNU GPERF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU GPERF is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU GPERF; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +/* This module provides a uniform interface to the various options + available to a user of the gperf hash function generator. In + addition to the run-time options, found in the Option_Type below, + there is also the hash table Size and the Keys to be used in the + hashing. The overall design of this module was an experiment in + using C++ classes as a mechanism to enhance centralization of + option and and error handling, which tend to get out of hand in a C + program. */ + +#ifndef options_h +#define options_h 1 + +#include "ace/Log_Msg.h" + +/* Enumerate the potential debugging Options. */ + +enum Option_Type +{ + DEBUG = 01, /* Enable debugging (prints diagnostics to stderr). */ + ORDER = 02, /* Apply ordering heuristic to speed-up search time. */ + ANSI = 04, /* Generate ANSI prototypes. */ + ALLCHARS = 010, /* Use all characters in hash function. */ + GNU = 020, /* Assume GNU extensions (primarily function inline). */ + TYPE = 040, /* Handle user-defined type structured keyword input. */ + RANDOM = 0100, /* Randomly initialize the associated values table. */ + DEFAULTCHARS = 0200, /* Make default char positions be 1,$ (end of keyword). */ + SWITCH = 0400, /* Generate switch output to save space. */ + POINTER = 01000, /* Have in_word_set function return pointer, not boolean. */ + NOLENGTH = 02000, /* Don't include keyword length in hash computations. */ + LENTABLE = 04000, /* Generate a length table for string comparison. */ + DUP = 010000, /* Handle duplicate hash values for keywords. */ + FAST = 020000, /* Generate the hash function ``fast.'' */ + NOTYPE = 040000, /* Don't include user-defined type definition in output -- it's already defined elsewhere. */ + COMP = 0100000, /* Generate strncmp rather than strcmp. */ + GLOBAL = 0200000, /* Make the keyword table a global variable. */ + CONST = 0400000, /* Make the generated tables readonly (const). */ + CPLUSPLUS = 01000000, /* Generate C++ code. */ + C = 02000000, /* Generate C code. */ + ENUM = 04000000, /* Use enum for constants. */ + STRCASECMP = 010000000, /* Use the case insensitive comparison. */ + OPTIMIZE = 020000000, /* Assume all input keywords are in the keyset. */ + ADA = 040000000 /* Generate Ada code. */ +}; + +/* Define some useful constants (these don't really belong here, but I'm + not sure where else to put them!). These should be consts, but g++ + doesn't seem to do the right thing with them at the moment... ;-( */ + +enum +{ + MAX_KEY_POS = 128 - 1, /* Max size of each word's key set. */ + WORD_START = 1, /* Signals the start of a word. */ + WORD_END = 0, /* Signals the end of a word. */ + EOS = MAX_KEY_POS /* Signals end of the key list. */ +}; + +/* Class manager for gperf program Options. */ + +class Options +{ +public: + Options (void); + ~Options (void); + int operator[] (Option_Type option); + void operator() (int argc, char *argv[]); + void operator= (enum Option_Type); + void operator!= (enum Option_Type); + static void print_options (void); + static void set_asso_max (int r); + static int get_asso_max (void); + static void reset (void); + static int get (void); + static int get_iterations (void); + static int get_max_keysig_size (void); + static void set_keysig_size (int); + static int get_jump (void); + static int initial_value (void); + static int get_total_switches (void); + static const char *get_function_name (void); + static const char *get_key_name (void); + static const char *get_class_name (void); + static const char *get_hash_name (void); + static const char *get_delimiter (void); + +private: + static int option_word; /* Holds the user-specified Options. */ + static int total_switches; /* Number of switch statements to generate. */ + static int total_keysig_size; /* Total number of distinct key_positions. */ + static int size; /* Range of the hash table. */ + static int key_pos; /* Tracks current key position for Iterator. */ + static int jump; /* Jump length when trying alternative values. */ + static int initial_asso_value; /* Initial value for asso_values table. */ + static int argument_count; /* Records count of command-line arguments. */ + static int iterations; /* Amount to iterate when a collision occurs. */ + static char **argument_vector; /* Stores a pointer to command-line vector. */ + static const char *function_name; /* Names used for generated lookup function. */ + static const char *key_name; /* Name used for keyword key. */ + static const char *class_name; /* Name used for generated C++ class. */ + static const char *hash_name; /* Name used for generated hash function. */ + static const char *delimiters; /* Separates keywords from other attributes. */ + static char key_positions[MAX_KEY_POS]; /* Contains user-specified key choices. */ + static int key_sort (char *base, int len); /* Sorts key positions in REVERSE order. */ + static void usage (void); /* Prints proper program usage. */ +}; + +/* Global option coordinator for the entire program. */ +extern Options option; + +/* Set to 1 if your want to stack-allocate some large arrays. */ +#ifndef LARGE_STACK_ARRAYS +#define LARGE_STACK_ARRAYS 0 +#endif + +#endif diff --git a/apps/gperf/src/Vectors.cpp b/apps/gperf/src/Vectors.cpp new file mode 100644 index 00000000000..761e08b2672 --- /dev/null +++ b/apps/gperf/src/Vectors.cpp @@ -0,0 +1,33 @@ +/* This may look like C code, but it is really -*- C++ -*- */ +// @(#)Vectors.cpp 1.1 10/18/96 + + +/* Static class data members that are shared between several classes via + inheritance. + + Copyright (C) 1989 Free Software Foundation, Inc. + written by Douglas C. Schmidt (schmidt@ics.uci.edu) + +This file is part of GNU GPERF. + +GNU GPERF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU GPERF is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU GPERF; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "Vectors.h" + +// Counts occurrences of each key set character. +int Vectors::occurrences[ALPHA_SIZE]; + +// Value associated with each character. +int Vectors::asso_values[ALPHA_SIZE]; diff --git a/apps/gperf/src/Vectors.h b/apps/gperf/src/Vectors.h new file mode 100644 index 00000000000..c01e9f27d8f --- /dev/null +++ b/apps/gperf/src/Vectors.h @@ -0,0 +1,44 @@ +/* -*- C++ -*- */ +// @(#)Vectors.h 1.1 10/18/96 + +#include + +/* This may look like C code, but it is really -*- C++ -*- */ + +/* Static class data members that are shared between several classes via + inheritance. + + Copyright (C) 1989 Free Software Foundation, Inc. + written by Douglas C. Schmidt (schmidt@ics.uci.edu) + +This file is part of GNU GPERF. + +GNU GPERF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU GPERF is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU GPERF; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#ifndef vectors_h +#define vectors_h 1 + +static const int ALPHA_SIZE = 128; + +struct Vectors +{ + static int occurrences[ALPHA_SIZE]; + // Counts occurrences of each key set character. + + static int asso_values[ALPHA_SIZE]; + // Value associated with each character. +}; + +#endif diff --git a/apps/gperf/src/Version.cpp b/apps/gperf/src/Version.cpp new file mode 100644 index 00000000000..8fb0d398887 --- /dev/null +++ b/apps/gperf/src/Version.cpp @@ -0,0 +1,25 @@ +/* Current program version number. +// @(#)Version.cpp 1.1 10/18/96 + + + Copyright (C) 1989 Free Software Foundation, Inc. + written by Douglas C. Schmidt (schmidt@ics.uci.edu) + +This file is part of GNU GPERF. + +GNU GPERF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU GPERF is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU GPERF; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, +USA. */ + +char *version_string = "2.6 (GNU C++ version)"; diff --git a/apps/gperf/src/gperf.cpp b/apps/gperf/src/gperf.cpp new file mode 100644 index 00000000000..2e6aa2c6406 --- /dev/null +++ b/apps/gperf/src/gperf.cpp @@ -0,0 +1,66 @@ +/* Driver program for the Gen_Perf hash function generator Copyright +// @(#)gperf.cpp 1.1 10/18/96 + + (C) 1989 Free Software Foundation, Inc. written by Douglas + C. Schmidt (schmidt@ics.uci.edu) + +This file is part of GNU GPERF. + +GNU GPERF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU GPERF is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU GPERF; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +// Simple driver program for the Gen_Perf.hash function generator. +// All the hard work is done in class Gen_Perf and its class methods. + +#include "Options.h" +#include "Gen_Perf.h" + +int +main (int argc, char *argv[]) +{ + + struct tm *tm; + time_t clock; + + time (&clock); + tm = localtime (&clock); + printf ("/* starting time is %d:%02d:%02d */\n", tm->tm_hour, tm->tm_min, tm->tm_sec); + +#if defined(RLIMIT_STACK) && LARGE_STACK_ARRAYS + /* Get rid of any avoidable limit on stack size. */ + { + struct rlimit rlim; + + /* Set the stack limit huge so that alloca does not fail. */ + getrlimit (RLIMIT_STACK, &rlim); + rlim.rlim_cur = rlim.rlim_max; + setrlimit (RLIMIT_STACK, &rlim); + } +#endif /* RLIMIT_STACK */ + + /* Sets the Options. */ + option (argc, argv); + + // Initializes the key word list. + Gen_Perf table; + + // Generates and prints the Gen_Perf hash table. Don't use exit + // here, it skips the destructors. + int status = table.generate (); + + time (&clock); + tm = localtime (&clock); + printf ("/* ending time is %d:%02d:%02d */\n", tm->tm_hour, tm->tm_min, tm->tm_sec); + return status; +} diff --git a/apps/gperf/src/new.cpp b/apps/gperf/src/new.cpp new file mode 100644 index 00000000000..ebaafa16917 --- /dev/null +++ b/apps/gperf/src/new.cpp @@ -0,0 +1,75 @@ +/* Defines a buffered memory allocation abstraction that reduces calls to +// @(#)new.cpp 1.1 10/18/96 + + malloc. + Copyright (C) 1989 Free Software Foundation, Inc. + written by Douglas C. Schmidt (schmidt@ics.uci.edu) + +This file is part of GNU GPERF. + +GNU GPERF is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU GPERF is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU GPERF; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "Options.h" + +/* Determine default alignment. If your C++ compiler does not like + this then try something like #define DEFAULT_ALIGNMENT 8. */ +struct fooalign {char x; double d;}; +const int ALIGNMENT = ((char *)&((struct fooalign *) 0)->d - (char *)0); + +/* Provide an abstraction that cuts down on the number of calls to NEW + by buffering the memory pool from which strings are allocated. */ + +void * +operator new (size_t size) +{ + static char *buf_start = 0; /* Large array used to reduce calls to NEW. */ + static char *buf_end = 0; /* Indicates end of BUF_START. */ + static int buf_size = 4 * BUFSIZ; /* Size of buffer pointed to by BUF_START. */ + char *temp; + + /* Align this on correct boundaries, just to be safe... */ + size = ((size + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT; + + /* If we are about to overflow our buffer we'll just grab another + chunk of memory. Since we never free the original memory it + doesn't matter that no one points to the beginning of that + chunk. Note we use a heuristic that grows the buffer either by + size of the request or by twice the previous size, whichever is + larger. */ + + if (buf_start + size >= buf_end) + { + buf_size *= 2; + if (buf_size < size) + buf_size = size; + if (buf_start = (char *)malloc (buf_size)) + buf_end = buf_start + buf_size; + else + ACE_ERROR ((LM_ERROR, "Virtual memory failed at %s, %s in function %s\n%a", __FILE__, __LINE__, "operator new", 1)); + } + + temp = buf_start; + buf_start += size; + return temp; +} + +/* We need this deletion operator in order to make the linker happy. */ + +void +operator delete (void *ptr) +{ + // We cannot call free here, as it doesn't match the mallocs. + // free ((char *) ptr); +} diff --git a/apps/gperf/tests/Makefile.in b/apps/gperf/tests/Makefile.in new file mode 100644 index 00000000000..f702fc804f2 --- /dev/null +++ b/apps/gperf/tests/Makefile.in @@ -0,0 +1,72 @@ +# Copyright (C) 1989, 1992, 1993 Free Software Foundation, Inc. +# written by Douglas C. Schmidt (schmidt@ics.uci.edu) +# +# This file is part of GNU GPERF. +# +# GNU GPERF is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 1, or (at your option) +# any later version. +# +# GNU GPERF is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU GPERF; see the file COPYING. If not, write to the Free +# Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. + +srcdir = . + +#### package, host, target, and site dependent Makefile fragments come in here. +## + +GPERF = ../src/gperf + +check: + @echo "performing some tests of the perfect hash generator" + $(CC) -c $(CFLAGS) $(srcdir)/test.c + $(GPERF) -p -c -l -S1 -o $(srcdir)/c.gperf > cinset.c + $(CC) $(CFLAGS) -o cout cinset.c test.o + @echo "testing ANSI C reserved words, all items should be found in the set" + ./cout -v < $(srcdir)/c.gperf > c.out + -diff -b $(srcdir)/c.exp c.out + $(GPERF) -k1,4,'$$' $(srcdir)/ada.gperf > adainset.c +# double '$$' is only there since make gets confused; programn wants only 1 '$' + $(CC) $(CFLAGS) -o aout adainset.c test.o + @echo "testing Ada reserved words, all items should be found in the set" + ./aout -v < $(srcdir)/ada.gperf > ada-res.out + -diff -b $(srcdir)/ada-res.exp ada-res.out + $(GPERF) -p -D -k1,'$$' -s 2 -o $(srcdir)/adadefs.gperf > preinset.c + $(CC) $(CFLAGS) -o preout preinset.c test.o + @echo "testing Ada predefined words, all items should be found in the set" + ./preout -v < $(srcdir)/adadefs.gperf > ada-pred.out + -diff -b $(srcdir)/ada-pred.exp ada-pred.out + $(GPERF) -k1,2,'$$' -o $(srcdir)/modula3.gperf > m3inset.c + $(CC) $(CFLAGS) -o m3out m3inset.c test.o + @echo "testing Modula3 reserved words, all items should be found in the set" + ./m3out -v < $(srcdir)/modula3.gperf > modula.out + -diff -b $(srcdir)/modula.exp modula.out + $(GPERF) -o -S2 -p < $(srcdir)/pascal.gperf > pinset.c + $(CC) $(CFLAGS) -o pout pinset.c test.o + @echo "testing Pascal reserved words, all items should be found in the set" + ./pout -v < $(srcdir)/pascal.gperf > pascal.out + -diff -b $(srcdir)/pascal.exp pascal.out +# these next 5 are demos that show off the generated code + $(GPERF) -p -j1 -g -o -t -N is_reserved_word -k1,3,'$$' < $(srcdir)/c-parse.gperf > test-1.out + -diff -b $(srcdir)/test-1.exp test-1.out + $(GPERF) -n -k1-8 -l <$(srcdir)/modula2.gperf > test-2.out + -diff -b $(srcdir)/test-2.exp test-2.out + $(GPERF) -p -j 1 -o -a -C -g -t -k1,4,$$ < $(srcdir)/gplus.gperf > test-3.out + -diff -b $(srcdir)/test-3.exp test-3.out + $(GPERF) -D -p -t < $(srcdir)/c-parse.gperf > test-4.out + -diff -b $(srcdir)/test-4.exp test-4.out + $(GPERF) -g -o -j1 -t -p -N is_reserved_word < $(srcdir)/gpc.gperf > test-5.out + -diff -b $(srcdir)/test-5.exp test-5.out +# prints out the help message + -$(GPERF) -h > test-6.out 2>&1 || [ a = a ] + -diff -b $(srcdir)/test-6.exp test-6.out + @echo "only if, do, for, case, goto, else, while, and return should be found " + ./aout -v < $(srcdir)/c.gperf > test-7.out + -diff -b $(srcdir)/test-7.exp test-7.out diff --git a/apps/gperf/tests/ada-pred.exp b/apps/gperf/tests/ada-pred.exp new file mode 100644 index 00000000000..33caaa32ea1 --- /dev/null +++ b/apps/gperf/tests/ada-pred.exp @@ -0,0 +1,54 @@ +in word set boolean +in word set character +in word set constraint_error +in word set false +in word set float +in word set integer +in word set natural +in word set numeric_error +in word set positive +in word set program_error +in word set storage_error +in word set string +in word set tasking_error +in word set true +in word set address +in word set aft +in word set base +in word set callable +in word set constrained +in word set count +in word set delta +in word set digits +in word set emax +in word set epsilon +in word set first +in word set firstbit +in word set fore +in word set image +in word set large +in word set last +in word set lastbit +in word set length +in word set machine_emax +in word set machine_emin +in word set machine_mantissa +in word set machine_overflows +in word set machine_radix +in word set machine_rounds +in word set mantissa +in word set pos +in word set position +in word set pred +in word set range +in word set safe_emax +in word set safe_large +in word set safe_small +in word set size +in word set small +in word set storage_size +in word set succ +in word set terminated +in word set val +in word set value +in word set width diff --git a/apps/gperf/tests/ada-res.exp b/apps/gperf/tests/ada-res.exp new file mode 100644 index 00000000000..8134fe861f5 --- /dev/null +++ b/apps/gperf/tests/ada-res.exp @@ -0,0 +1,63 @@ +in word set else +in word set exit +in word set terminate +in word set type +in word set raise +in word set range +in word set reverse +in word set declare +in word set end +in word set record +in word set exception +in word set not +in word set then +in word set return +in word set separate +in word set select +in word set digits +in word set renames +in word set subtype +in word set elsif +in word set function +in word set for +in word set package +in word set procedure +in word set private +in word set while +in word set when +in word set new +in word set entry +in word set delay +in word set case +in word set constant +in word set at +in word set abort +in word set accept +in word set and +in word set delta +in word set access +in word set abs +in word set pragma +in word set array +in word set use +in word set out +in word set do +in word set others +in word set of +in word set or +in word set all +in word set limited +in word set loop +in word set null +in word set task +in word set in +in word set is +in word set if +in word set rem +in word set mod +in word set begin +in word set body +in word set xor +in word set goto +in word set generic +in word set with diff --git a/apps/gperf/tests/ada.gperf b/apps/gperf/tests/ada.gperf new file mode 100644 index 00000000000..332bdc740ad --- /dev/null +++ b/apps/gperf/tests/ada.gperf @@ -0,0 +1,63 @@ +else +exit +terminate +type +raise +range +reverse +declare +end +record +exception +not +then +return +separate +select +digits +renames +subtype +elsif +function +for +package +procedure +private +while +when +new +entry +delay +case +constant +at +abort +accept +and +delta +access +abs +pragma +array +use +out +do +others +of +or +all +limited +loop +null +task +in +is +if +rem +mod +begin +body +xor +goto +generic +with diff --git a/apps/gperf/tests/adadefs.gperf b/apps/gperf/tests/adadefs.gperf new file mode 100644 index 00000000000..875be69abc9 --- /dev/null +++ b/apps/gperf/tests/adadefs.gperf @@ -0,0 +1,54 @@ +boolean +character +constraint_error +false +float +integer +natural +numeric_error +positive +program_error +storage_error +string +tasking_error +true +address +aft +base +callable +constrained +count +delta +digits +emax +epsilon +first +firstbit +fore +image +large +last +lastbit +length +machine_emax +machine_emin +machine_mantissa +machine_overflows +machine_radix +machine_rounds +mantissa +pos +position +pred +range +safe_emax +safe_large +safe_small +size +small +storage_size +succ +terminated +val +value +width diff --git a/apps/gperf/tests/c++.gperf b/apps/gperf/tests/c++.gperf new file mode 100644 index 00000000000..650d32d0edd --- /dev/null +++ b/apps/gperf/tests/c++.gperf @@ -0,0 +1,47 @@ +asm +auto +break +case +catch +char +class +const +continue +default +delete +do +double +else +enum +extern +float +for +friend +goto +if +inline +int +long +new +operator +overload +private +protected +public +register +return +short +signed +sizeof +static +struct +switch +template +this +typedef +union +unsigned +virtual +void +volatile +while diff --git a/apps/gperf/tests/c-parse.gperf b/apps/gperf/tests/c-parse.gperf new file mode 100644 index 00000000000..feef59babb0 --- /dev/null +++ b/apps/gperf/tests/c-parse.gperf @@ -0,0 +1,56 @@ +%{ +/* Command-line: gperf -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */ +%} +struct resword { char *name; short token; enum rid rid; }; +%% +__alignof, ALIGNOF, NORID +__alignof__, ALIGNOF, NORID +__asm, ASM, NORID +__asm__, ASM, NORID +__attribute, ATTRIBUTE, NORID +__attribute__, ATTRIBUTE, NORID +__const, TYPE_QUAL, RID_CONST +__const__, TYPE_QUAL, RID_CONST +__inline, SCSPEC, RID_INLINE +__inline__, SCSPEC, RID_INLINE +__signed, TYPESPEC, RID_SIGNED +__signed__, TYPESPEC, RID_SIGNED +__typeof, TYPEOF, NORID +__typeof__, TYPEOF, NORID +__volatile, TYPE_QUAL, RID_VOLATILE +__volatile__, TYPE_QUAL, RID_VOLATILE +asm, ASM, NORID +auto, SCSPEC, RID_AUTO +break, BREAK, NORID +case, CASE, NORID +char, TYPESPEC, RID_CHAR +const, TYPE_QUAL, RID_CONST +continue, CONTINUE, NORID +default, DEFAULT, NORID +do, DO, NORID +double, TYPESPEC, RID_DOUBLE +else, ELSE, NORID +enum, ENUM, NORID +extern, SCSPEC, RID_EXTERN +float, TYPESPEC, RID_FLOAT +for, FOR, NORID +goto, GOTO, NORID +if, IF, NORID +inline, SCSPEC, RID_INLINE +int, TYPESPEC, RID_INT +long, TYPESPEC, RID_LONG +register, SCSPEC, RID_REGISTER +return, RETURN, NORID +short, TYPESPEC, RID_SHORT +signed, TYPESPEC, RID_SIGNED +sizeof, SIZEOF, NORID +static, SCSPEC, RID_STATIC +struct, STRUCT, NORID +switch, SWITCH, NORID +typedef, SCSPEC, RID_TYPEDEF +typeof, TYPEOF, NORID +union, UNION, NORID +unsigned, TYPESPEC, RID_UNSIGNED +void, TYPESPEC, RID_VOID +volatile, TYPE_QUAL, RID_VOLATILE +while, WHILE, NORID diff --git a/apps/gperf/tests/c.exp b/apps/gperf/tests/c.exp new file mode 100644 index 00000000000..10c8b7f6116 --- /dev/null +++ b/apps/gperf/tests/c.exp @@ -0,0 +1,32 @@ +in word set if +in word set do +in word set int +in word set for +in word set case +in word set char +in word set auto +in word set goto +in word set else +in word set long +in word set void +in word set enum +in word set float +in word set short +in word set union +in word set break +in word set while +in word set const +in word set double +in word set static +in word set extern +in word set struct +in word set return +in word set sizeof +in word set switch +in word set signed +in word set typedef +in word set default +in word set unsigned +in word set continue +in word set register +in word set volatile diff --git a/apps/gperf/tests/c.gperf b/apps/gperf/tests/c.gperf new file mode 100644 index 00000000000..8672d6c25ed --- /dev/null +++ b/apps/gperf/tests/c.gperf @@ -0,0 +1,32 @@ +if +do +int +for +case +char +auto +goto +else +long +void +enum +float +short +union +break +while +const +double +static +extern +struct +return +sizeof +switch +signed +typedef +default +unsigned +continue +register +volatile diff --git a/apps/gperf/tests/configure.in b/apps/gperf/tests/configure.in new file mode 100644 index 00000000000..d93c7bb1840 --- /dev/null +++ b/apps/gperf/tests/configure.in @@ -0,0 +1,26 @@ +# This file is a shell script fragment that supplies the information +# necessary to tailor a template configure script into the configure +# script appropriate for this directory. For more information, check +# any existing configure script. + +configdirs="" +srctrigger=c-parse.gperf +srcname="test perfect hash function generator" + +target_makefile_frag=../../target-mkfrag +package_makefile_frag=Make.pack + +# per-host: + +# per-target: + +TOLIBGXX=../../ +ALL='$(NOTHING)' +CHECK=check +MOSTLYCLEAN='*.o \#* core *inset.c output.* *.out aout cout m3out pout preout' + +(. ${srcdir}/../../config.shared) >${package_makefile_frag} + +# post-target: + +rm -f ${package_makefile_frag} diff --git a/apps/gperf/tests/gpc.gperf b/apps/gperf/tests/gpc.gperf new file mode 100644 index 00000000000..8fb469e46bc --- /dev/null +++ b/apps/gperf/tests/gpc.gperf @@ -0,0 +1,48 @@ +%{ +/* ISO Pascal 7185 reserved words. + * + * For GNU Pascal compiler (GPC) by jtv@hut.fi + * + * run this through the Doug Schmidt's gperf program + * with command + * gperf -g -o -j1 -t -p -N is_reserved_word + * + */ +%} +struct resword { char *name; short token; short iclass;}; +%% +And, AND, PASCAL_ISO +Array, ARRAY, PASCAL_ISO +Begin, BEGIN_, PASCAL_ISO +Case, CASE, PASCAL_ISO +Const, CONST, PASCAL_ISO +Div, DIV, PASCAL_ISO +Do, DO, PASCAL_ISO +Downto, DOWNTO, PASCAL_ISO +Else, ELSE, PASCAL_ISO +End, END, PASCAL_ISO +File, FILE_, PASCAL_ISO +For, FOR, PASCAL_ISO +Function, FUNCTION, PASCAL_ISO +Goto, GOTO, PASCAL_ISO +If, IF, PASCAL_ISO +In, IN, PASCAL_ISO +Label, LABEL, PASCAL_ISO +Mod, MOD, PASCAL_ISO +Nil, NIL, PASCAL_ISO +Not, NOT, PASCAL_ISO +Of, OF, PASCAL_ISO +Or, OR, PASCAL_ISO +Packed, PACKED, PASCAL_ISO +Procedure, PROCEDURE, PASCAL_ISO +Program,PROGRAM,PASCAL_ISO +Record, RECORD, PASCAL_ISO +Repeat, REPEAT, PASCAL_ISO +Set, SET, PASCAL_ISO +Then, THEN, PASCAL_ISO +To, TO, PASCAL_ISO +Type, TYPE, PASCAL_ISO +Until, UNTIL, PASCAL_ISO +Var, VAR, PASCAL_ISO +While, WHILE, PASCAL_ISO +With, WITH, PASCAL_ISO diff --git a/apps/gperf/tests/gplus.gperf b/apps/gperf/tests/gplus.gperf new file mode 100644 index 00000000000..4a93315be52 --- /dev/null +++ b/apps/gperf/tests/gplus.gperf @@ -0,0 +1,76 @@ +%{ +/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$ gplus.gperf */ +%} +struct resword { char *name; short token; enum rid rid;}; +%% +__alignof, ALIGNOF, NORID +__alignof__, ALIGNOF, NORID +__asm, ASM, NORID +__asm__, ASM, NORID +__attribute, ATTRIBUTE, NORID +__attribute__, ATTRIBUTE, NORID +__const, TYPE_QUAL, RID_CONST +__const__, TYPE_QUAL, RID_CONST +__inline, SCSPEC, RID_INLINE +__inline__, SCSPEC, RID_INLINE +__signed, TYPESPEC, RID_SIGNED +__signed__, TYPESPEC, RID_SIGNED +__typeof, TYPEOF, NORID +__typeof__, TYPEOF, NORID +__volatile, TYPE_QUAL, RID_VOLATILE +__volatile__, TYPE_QUAL, RID_VOLATILE +all, ALL, NORID /* Extension */, +except, EXCEPT, NORID /* Extension */, +exception, AGGR, RID_EXCEPTION /* Extension */, +raise, RAISE, NORID /* Extension */, +raises, RAISES, NORID /* Extension */, +reraise, RERAISE, NORID /* Extension */, +try, TRY, NORID /* Extension */, +asm, ASM, NORID, +auto, SCSPEC, RID_AUTO, +break, BREAK, NORID, +case, CASE, NORID, +catch, CATCH, NORID, +char, TYPESPEC, RID_CHAR, +class, AGGR, RID_CLASS, +const, TYPE_QUAL, RID_CONST, +continue, CONTINUE, NORID, +default, DEFAULT, NORID, +delete, DELETE, NORID, +do, DO, NORID, +double, TYPESPEC, RID_DOUBLE, +dynamic, DYNAMIC, NORID, +else, ELSE, NORID, +enum, ENUM, NORID, +extern, SCSPEC, RID_EXTERN, +float, TYPESPEC, RID_FLOAT, +for, FOR, NORID, +friend, SCSPEC, RID_FRIEND, +goto, GOTO, NORID, +if, IF, NORID, +inline, SCSPEC, RID_INLINE, +int, TYPESPEC, RID_INT, +long, TYPESPEC, RID_LONG, +new, NEW, NORID, +operator, OPERATOR, NORID, +overload, OVERLOAD, NORID, +private, PRIVATE, NORID, +protected, PROTECTED, NORID, +public, PUBLIC, NORID, +register, SCSPEC, RID_REGISTER, +return, RETURN, NORID, +short, TYPESPEC, RID_SHORT, +signed, TYPESPEC, RID_SIGNED, +sizeof, SIZEOF, NORID, +static, SCSPEC, RID_STATIC, +struct, AGGR, RID_RECORD, +switch, SWITCH, NORID, +this, THIS, NORID, +typedef, SCSPEC, RID_TYPEDEF, +typeof, TYPEOF, NORID, +union, AGGR, RID_UNION, +unsigned, TYPESPEC, RID_UNSIGNED, +virtual, SCSPEC, RID_VIRTUAL, +void, TYPESPEC, RID_VOID, +volatile, TYPE_QUAL, RID_VOLATILE, +while, WHILE, NORID, diff --git a/apps/gperf/tests/irc.gperf b/apps/gperf/tests/irc.gperf new file mode 100644 index 00000000000..afe53c59e7d --- /dev/null +++ b/apps/gperf/tests/irc.gperf @@ -0,0 +1,63 @@ +%{ +extern int m_text(), m_private(), m_who(), m_whois(), m_user(), m_list(); +extern int m_topic(), m_invite(), m_channel(), m_version(), m_quit(); +extern int m_server(), m_kill(), m_info(), m_links(), m_summon(), m_stats(); +extern int m_users(), m_nick(), m_error(), m_help(), m_whoreply(); +extern int m_squit(), m_restart(), m_away(), m_die(), m_connect(); +extern int m_ping(), m_pong(), m_oper(), m_pass(), m_wall(), m_trace(); +extern int m_time(), m_rehash(), m_names(), m_namreply(), m_admin(); +extern int m_linreply(), m_notice(), m_lusers(), m_voice(), m_grph(); +extern int m_xtra(), m_motd(); +%} +struct Message { + char *cmd; + int (* func)(); + int count; + int parameters; +}; +%% +NICK, m_nick, 0, 1 +MSG, m_text, 0, 1 +PRIVMSG, m_private, 0, 2 +WHO, m_who, 0, 1 +WHOIS, m_whois, 0, 4 +USER, m_user, 0, 4 +SERVER, m_server, 0, 2 +LIST, m_list, 0, 1 +TOPIC, m_topic, 0, 1 +INVITE, m_invite, 0, 2 +CHANNEL, m_channel, 0, 1 +VERSION, m_version, 0, 1 +QUIT, m_quit, 0, 2 +SQUIT, m_squit, 0, 2 +KILL, m_kill, 0, 2 +INFO, m_info, 0, 1 +LINKS, m_links, 0, 1 +SUMMON, m_summon, 0, 1 +STATS, m_stats, 0, 1 +USERS, m_users, 0, 1 +RESTART, m_restart, 0, 1 +WHOREPLY,m_whoreply, 0, 7 +HELP, m_help, 0, 2 +ERROR, m_error, 0, 1 +AWAY, m_away, 0, 1 +DIE, m_die, 0, 1 +CONNECT, m_connect, 0, 3 +PING, m_ping, 0, 2 +PONG, m_pong, 0, 3 +OPER, m_oper, 0, 3 +PASS, m_pass, 0, 2 +WALL, m_wall, 0, 1 +TIME, m_time, 0, 1 +REHASH, m_rehash, 0, 1 +NAMES, m_names, 0, 1 +NAMREPLY,m_namreply, 0, 3 +ADMIN, m_admin, 0, 1 +TRACE, m_trace, 0, 1 +LINREPLY,m_linreply, 0, 2 +NOTICE, m_notice, 0, 2 +LUSERS, m_lusers, 0, 1 +VOICE, m_voice, 0, 2 +GRPH, m_grph, 0, 2 +XTRA, m_xtra, 0, 2 +MOTD, m_motd, 0, 2 diff --git a/apps/gperf/tests/makeinfo.gperf b/apps/gperf/tests/makeinfo.gperf new file mode 100644 index 00000000000..1488b8e38fb --- /dev/null +++ b/apps/gperf/tests/makeinfo.gperf @@ -0,0 +1,116 @@ +COMMAND; +%% +!, cm_force_sentence_end, false +', insert_self, false +*, cm_asterisk, false +., cm_force_sentence_end, false +:, cm_force_abbreviated_whitespace, false +?, cm_force_sentence_end, false +@, insert_self, false +TeX, cm_TeX, true +`, insert_self, false +appendix, cm_appendix, false +appendixsec, cm_appendixsec, false +appendixsubsec, cm_appendixsubsec, false +asis, cm_asis, true +b, cm_bold, true +br, cm_br, false +bullet, cm_bullet, true +bye, cm_bye, false +c, cm_comment, false +center, cm_center, false +chapter, cm_chapter, false +cindex, cm_cindex, false +cite, cm_cite, true +code, cm_code, true +comment, cm_comment, false +contents, do_nothing, false +copyright, cm_copyright, true +ctrl, cm_ctrl, true +defcodeindex, cm_defindex, false +defindex, cm_defindex, false +dfn, cm_dfn, true +display, cm_display, false +dots, cm_dots, true +emph, cm_emph, true +end, cm_end, false +enumerate, cm_enumerate, false +equiv, cm_equiv, true +error, cm_error, true +example, cm_example, false +exdent, cm_exdent, false +expansion, cm_expansion, true +file, cm_file, true +findex, cm_findex, false +format, cm_format, false +group, cm_group, false +i, cm_italic, true +iappendix, cm_appendix, false +iappendixsec, cm_appendixsec, false +iappendixsubsec, cm_appendixsubsec, false +ichapter, cm_chapter, false +ifinfo, cm_ifinfo, false +iftex, cm_iftex, false +ignore, cm_ignore, false +include, cm_include, false +inforef, cm_inforef, true +input, cm_include, false +isection, cm_section, false +isubsection, cm_subsection, false +isubsubsection, cm_subsubsection, false +item, cm_item, false +itemize, cm_itemize, false +itemx, cm_itemx, false +iunnumbered, cm_unnumbered, false +iunnumberedsec, cm_unnumberedsec, false +iunnumberedsubsec, cm_unnumberedsubsec, false +kbd, cm_kbd, true +key, cm_key, true +kindex, cm_kindex, false +lisp, cm_lisp, false +menu, cm_menu +minus, cm_minus, true +need, cm_need, false +node, cm_node, false +noindent, cm_noindent, false +page, do_nothing, false +pindex, cm_pindex, false +point, cm_point, true +print, cm_print, true +printindex, cm_printindex, false +pxref, cm_pxref, true +quotation, cm_quotation, false +r, cm_roman, true +ref, cm_xref, true +refill, cm_refill, false +result, cm_result, true +samp, cm_samp, true +sc, cm_sc, true +section, cm_section, false +setchapternewpage, cm_setchapternewpage, false +setfilename, cm_setfilename, false +settitle, cm_settitle, false +smallexample, cm_smallexample, false +sp, cm_sp, false +strong, cm_strong, true +subsection, cm_subsection, false +subsubsection, cm_subsubsection, false +summarycontents, do_nothing, false +syncodeindex, cm_synindex, false +synindex, cm_synindex, false +t, cm_title, true +table, cm_table, false +tex, cm_tex, false +tindex, cm_tindex, false +titlepage, cm_titlepage, false +unnumbered, cm_unnumbered, false +unnumberedsec, cm_unnumberedsec, false +unnumberedsubsec, cm_unnumberedsubsec, false +var, cm_var, true +vindex, cm_vindex, false +w, cm_w, true +xref, cm_xref, true +{, insert_self, false +}, insert_self, false +infoinclude, cm_infoinclude, false +footnote, cm_footnote, false diff --git a/apps/gperf/tests/modula.exp b/apps/gperf/tests/modula.exp new file mode 100644 index 00000000000..cef7d5acad8 --- /dev/null +++ b/apps/gperf/tests/modula.exp @@ -0,0 +1,106 @@ +in word set AND +in word set ARRAY +in word set BEGIN +in word set BITS +in word set BY +in word set CASE +in word set CONST +in word set DIV +in word set DO +in word set ELSE +in word set ELSIF +in word set END +in word set EVAL +in word set EXCEPT +in word set EXCEPTION +in word set EXIT +in word set EXPORTS +in word set FINALLY +in word set FOR +in word set FROM +in word set IF +in word set IMPORT +in word set INTERFACE +in word set IN +in word set INLINE +in word set LOCK +in word set METHODS +in word set MOD +in word set MODULE +in word set NOT +in word set OBJECT +in word set OF +in word set OR +in word set PROCEDURE +in word set RAISES +in word set READONLY +in word set RECORD +in word set REF +in word set REPEAT +in word set RETURN +in word set SET +in word set THEN +in word set TO +in word set TRY +in word set TYPE +in word set TYPECASE +in word set UNSAFE +in word set UNTIL +in word set UNTRACED +in word set VALUE +in word set VAR +in word set WHILE +in word set WITH +in word set and +in word set array +in word set begin +in word set bits +in word set by +in word set case +in word set const +in word set div +in word set do +in word set else +in word set elsif +in word set end +in word set eval +in word set except +in word set exception +in word set exit +in word set exports +in word set finally +in word set for +in word set from +in word set if +in word set import +in word set interface +in word set in +in word set inline +in word set lock +in word set methods +in word set mod +in word set module +in word set not +in word set object +in word set of +in word set or +in word set procedure +in word set raises +in word set readonly +in word set record +in word set ref +in word set repeat +in word set return +in word set set +in word set then +in word set to +in word set try +in word set type +in word set typecase +in word set unsafe +in word set until +in word set untraced +in word set value +in word set var +in word set while +in word set with diff --git a/apps/gperf/tests/modula2.gperf b/apps/gperf/tests/modula2.gperf new file mode 100644 index 00000000000..5ef9c753835 --- /dev/null +++ b/apps/gperf/tests/modula2.gperf @@ -0,0 +1,40 @@ +AND +ARRAY +BEGIN +BY +CASE +CONST +DEFINITION +DIV +DO +ELSE +ELSIF +END +EXIT +EXPORT +FOR +FROM +IF +IMPLEMENTATION +IMPORT +IN +LOOP +MOD +MODULE +NOT +OF +OR +POINTER +PROCEDURE +QUALIFIED +RECORD +REPEAT +RETURN +SET +THEN +TO +TYPE +UNTIL +VAR +WHILE +WITH diff --git a/apps/gperf/tests/modula3.gperf b/apps/gperf/tests/modula3.gperf new file mode 100644 index 00000000000..d0243460d9b --- /dev/null +++ b/apps/gperf/tests/modula3.gperf @@ -0,0 +1,106 @@ +AND +ARRAY +BEGIN +BITS +BY +CASE +CONST +DIV +DO +ELSE +ELSIF +END +EVAL +EXCEPT +EXCEPTION +EXIT +EXPORTS +FINALLY +FOR +FROM +IF +IMPORT +INTERFACE +IN +INLINE +LOCK +METHODS +MOD +MODULE +NOT +OBJECT +OF +OR +PROCEDURE +RAISES +READONLY +RECORD +REF +REPEAT +RETURN +SET +THEN +TO +TRY +TYPE +TYPECASE +UNSAFE +UNTIL +UNTRACED +VALUE +VAR +WHILE +WITH +and +array +begin +bits +by +case +const +div +do +else +elsif +end +eval +except +exception +exit +exports +finally +for +from +if +import +interface +in +inline +lock +methods +mod +module +not +object +of +or +procedure +raises +readonly +record +ref +repeat +return +set +then +to +try +type +typecase +unsafe +until +untraced +value +var +while +with diff --git a/apps/gperf/tests/pascal.exp b/apps/gperf/tests/pascal.exp new file mode 100644 index 00000000000..765e44c6a0f --- /dev/null +++ b/apps/gperf/tests/pascal.exp @@ -0,0 +1,36 @@ +in word set with +in word set array +in word set and +in word set function +in word set case +in word set var +in word set const +in word set until +in word set then +in word set set +in word set record +in word set program +in word set procedure +in word set or +in word set packed +in word set not +in word set nil +in word set label +in word set in +in word set repeat +in word set of +in word set goto +in word set forward +in word set for +in word set while +in word set file +in word set else +in word set downto +in word set do +in word set div +in word set to +in word set type +in word set end +in word set mod +in word set begin +in word set if diff --git a/apps/gperf/tests/pascal.gperf b/apps/gperf/tests/pascal.gperf new file mode 100644 index 00000000000..fed3fbb30ea --- /dev/null +++ b/apps/gperf/tests/pascal.gperf @@ -0,0 +1,36 @@ +with +array +and +function +case +var +const +until +then +set +record +program +procedure +or +packed +not +nil +label +in +repeat +of +goto +forward +for +while +file +else +downto +do +div +to +type +end +mod +begin +if diff --git a/apps/gperf/tests/test-1.exp b/apps/gperf/tests/test-1.exp new file mode 100644 index 00000000000..5788cf7dfc3 --- /dev/null +++ b/apps/gperf/tests/test-1.exp @@ -0,0 +1,140 @@ +/* C code produced by gperf version 2.5 (GNU C++ version) */ +/* Command-line: ../src/gperf -p -j1 -g -o -t -N is_reserved_word -k1,3,$ */ +/* Command-line: gperf -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */ +struct resword { char *name; short token; enum rid rid; }; + +#define TOTAL_KEYWORDS 51 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 13 +#define MIN_HASH_VALUE 8 +#define MAX_HASH_VALUE 82 +/* maximum key range = 75, duplicates = 0 */ + +#ifdef __GNUC__ +inline +#endif +static unsigned int +hash (str, len) + register char *str; + register int unsigned len; +{ + static unsigned char asso_values[] = + { + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 0, 83, 1, 2, 34, + 19, 6, 11, 29, 0, 17, 83, 0, 23, 28, + 26, 30, 31, 83, 15, 1, 0, 28, 13, 4, + 83, 83, 5, 83, 83, 83, 83, 83, + }; + register int hval = len; + + switch (hval) + { + default: + case 3: + hval += asso_values[str[2]]; + case 2: + case 1: + hval += asso_values[str[0]]; + break; + } + return hval + asso_values[str[len - 1]]; +} + +#ifdef __GNUC__ +inline +#endif +struct resword * +is_reserved_word (str, len) + register char *str; + register unsigned int len; +{ + static struct resword wordlist[] = + { + {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, + {"__asm__", ASM, NORID}, + {"",}, + {"__typeof__", TYPEOF, NORID}, + {"__signed__", TYPESPEC, RID_SIGNED}, + {"__alignof__", ALIGNOF, NORID}, + {"break", BREAK, NORID}, + {"__attribute__", ATTRIBUTE, NORID}, + {"",}, {"",}, + {"else", ELSE, NORID}, + {"__attribute", ATTRIBUTE, NORID}, + {"__typeof", TYPEOF, NORID}, + {"int", TYPESPEC, RID_INT}, + {"__alignof", ALIGNOF, NORID}, + {"struct", STRUCT, NORID}, + {"sizeof", SIZEOF, NORID}, + {"switch", SWITCH, NORID}, + {"__volatile__", TYPE_QUAL, RID_VOLATILE}, + {"",}, + {"__inline__", SCSPEC, RID_INLINE}, + {"__signed", TYPESPEC, RID_SIGNED}, + {"__volatile", TYPE_QUAL, RID_VOLATILE}, + {"if", IF, NORID}, + {"__inline", SCSPEC, RID_INLINE}, + {"while", WHILE, NORID}, + {"",}, + {"__asm", ASM, NORID}, + {"auto", SCSPEC, RID_AUTO}, + {"short", TYPESPEC, RID_SHORT}, + {"default", DEFAULT, NORID}, + {"extern", SCSPEC, RID_EXTERN}, + {"",}, {"",}, + {"__const", TYPE_QUAL, RID_CONST}, + {"static", SCSPEC, RID_STATIC}, + {"__const__", TYPE_QUAL, RID_CONST}, + {"for", FOR, NORID}, + {"case", CASE, NORID}, + {"float", TYPESPEC, RID_FLOAT}, + {"return", RETURN, NORID}, + {"typeof", TYPEOF, NORID}, + {"typedef", SCSPEC, RID_TYPEDEF}, + {"volatile", TYPE_QUAL, RID_VOLATILE}, + {"do", DO, NORID}, + {"inline", SCSPEC, RID_INLINE}, + {"void", TYPESPEC, RID_VOID}, + {"char", TYPESPEC, RID_CHAR}, + {"signed", TYPESPEC, RID_SIGNED}, + {"unsigned", TYPESPEC, RID_UNSIGNED}, + {"",}, {"",}, + {"double", TYPESPEC, RID_DOUBLE}, + {"asm", ASM, NORID}, + {"",}, {"",}, + {"goto", GOTO, NORID}, + {"",}, + {"const", TYPE_QUAL, RID_CONST}, + {"enum", ENUM, NORID}, + {"register", SCSPEC, RID_REGISTER}, + {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, + {"continue", CONTINUE, NORID}, + {"",}, + {"union", UNION, NORID}, + {"",}, {"",}, {"",}, {"",}, {"",}, + {"long", TYPESPEC, RID_LONG}, + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register char *s = wordlist[key].name; + + if (*s == *str && !strcmp (str + 1, s + 1)) + return &wordlist[key]; + } + } + return 0; +} diff --git a/apps/gperf/tests/test-2.exp b/apps/gperf/tests/test-2.exp new file mode 100644 index 00000000000..f74124155eb --- /dev/null +++ b/apps/gperf/tests/test-2.exp @@ -0,0 +1,183 @@ +/* C code produced by gperf version 2.5 (GNU C++ version) */ +/* Command-line: ../src/gperf -n -k1-8 -l */ + +#define TOTAL_KEYWORDS 40 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 14 +#define MIN_HASH_VALUE 1 +#define MAX_HASH_VALUE 256 +/* maximum key range = 256, duplicates = 0 */ + +static unsigned int +hash (str, len) + register char *str; + register int unsigned len; +{ + static unsigned short asso_values[] = + { + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 25, 30, 35, 21, 0, + 30, 15, 30, 45, 257, 257, 0, 5, 45, 0, + 10, 0, 1, 20, 25, 15, 30, 40, 15, 5, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, + }; + register int hval = 0; + + switch (len) + { + default: + case 8: + hval += asso_values[str[7]]; + case 7: + hval += asso_values[str[6]]; + case 6: + hval += asso_values[str[5]]; + case 5: + hval += asso_values[str[4]]; + case 4: + hval += asso_values[str[3]]; + case 3: + hval += asso_values[str[2]]; + case 2: + hval += asso_values[str[1]]; + case 1: + hval += asso_values[str[0]]; + break; + } + return hval; +} + +char * +in_word_set (str, len) + register char *str; + register unsigned int len; +{ + + static unsigned char lengthtable[] = + { + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 2, 0, 0, 0, 2, 3, 0, + 0, 0, 2, 3, 0, 0, 0, 2, 4, 0, 0, 0, 4, 6, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 3, 5, 6, 0, 0, 6, 0, 0, 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 0, 9, + 0, 4, 6, 6, 0, 0, 2, 3, 0, 0, 0, 5, 3, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 7, 0, 0, 0, 5, 0, 0, 0, 0, 5, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 10, + }; + static char *wordlist[] = + { + "", + "OR", + "", "", "", "", "", "", "", "", + "LOOP", + "", "", "", "", "", "", "", "", "", + "ELSE", + "DO", + "", "", "", + "TO", + "MOD", + "", "", "", + "OF", + "FOR", + "", "", "", + "BY", + "FROM", + "", "", "", + "TYPE", + "MODULE", + "", "", "", + "SET", + "", "", "", "", "", + "EXPORT", + "", "", "", "", + "VAR", + "ARRAY", + "RECORD", + "", "", + "REPEAT", + "", "", "", "", + "END", + "", "", "", + "NOT", + "", "", "", "", + "IF", + "", "", "", "", + "CASE", + "", "", + "PROCEDURE", + "", + "EXIT", + "IMPORT", + "RETURN", + "", "", + "IN", + "AND", + "", "", "", + "ELSIF", + "DIV", + "", "", "", + "THEN", + "", "", "", "", "", "", "", "", "", + "IMPLEMENTATION", + "", "", "", "", + "WHILE", + "", "", "", "", "", "", "", "", "", + "CONST", + "POINTER", + "", "", "", + "UNTIL", + "", "", "", "", + "BEGIN", + "", "", "", "", + "WITH", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", "QUALIFIED", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", + "", "", "", "", "", + "DEFINITION", + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register char *s = wordlist[key]; + + if (len == lengthtable[key] + && *s == *str && !strcmp (str + 1, s + 1)) + return s; + } + } + return 0; +} diff --git a/apps/gperf/tests/test-3.exp b/apps/gperf/tests/test-3.exp new file mode 100644 index 00000000000..5e889020657 --- /dev/null +++ b/apps/gperf/tests/test-3.exp @@ -0,0 +1,169 @@ +/* C code produced by gperf version 2.5 (GNU C++ version) */ +/* Command-line: ../src/gperf -p -j 1 -o -a -C -g -t -k1,4,$ */ +/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$ gplus.gperf */ +struct resword { char *name; short token; enum rid rid;}; + +#define TOTAL_KEYWORDS 71 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 13 +#define MIN_HASH_VALUE 4 +#define MAX_HASH_VALUE 147 +/* maximum key range = 144, duplicates = 0 */ + +#ifdef __GNUC__ +inline +#endif +static unsigned int +hash (register const char *str, register int len) +{ + static const unsigned char asso_values[] = + { + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 0, 148, 19, 6, 27, + 37, 0, 12, 1, 15, 63, 148, 4, 0, 56, + 20, 15, 42, 148, 31, 5, 26, 39, 32, 10, + 148, 40, 148, 148, 148, 148, 148, 148, + }; + register int hval = len; + + switch (hval) + { + default: + case 4: + hval += asso_values[str[3]]; + case 3: + case 2: + case 1: + hval += asso_values[str[0]]; + break; + } + return hval + asso_values[str[len - 1]]; +} + +#ifdef __GNUC__ +inline +#endif +const struct resword * +in_word_set (register const char *str, register int len) +{ + static const struct resword wordlist[] = + { + {"",}, {"",}, {"",}, {"",}, + {"else", ELSE, NORID,}, + {"",}, + {"long", TYPESPEC, RID_LONG,}, + {"",}, {"",}, {"",}, {"",}, + {"__alignof__", ALIGNOF, NORID}, + {"__asm__", ASM, NORID}, + {"",}, {"",}, + {"while", WHILE, NORID,}, + {"",}, {"",}, {"",}, {"",}, {"",}, + {"__alignof", ALIGNOF, NORID}, + {"all", ALL, NORID /* Extension */,}, + {"sizeof", SIZEOF, NORID,}, + {"__const__", TYPE_QUAL, RID_CONST}, + {"__volatile", TYPE_QUAL, RID_VOLATILE}, + {"extern", SCSPEC, RID_EXTERN,}, + {"__volatile__", TYPE_QUAL, RID_VOLATILE}, + {"__inline", SCSPEC, RID_INLINE}, + {"exception", AGGR, RID_EXCEPTION /* Extension */,}, + {"__inline__", SCSPEC, RID_INLINE}, + {"case", CASE, NORID,}, + {"except", EXCEPT, NORID /* Extension */,}, + {"new", NEW, NORID,}, + {"break", BREAK, NORID,}, + {"goto", GOTO, NORID,}, + {"",}, + {"__attribute", ATTRIBUTE, NORID}, + {"",}, + {"__attribute__", ATTRIBUTE, NORID}, + {"this", THIS, NORID,}, + {"raise", RAISE, NORID /* Extension */,}, + {"class", AGGR, RID_CLASS,}, + {"delete", DELETE, NORID,}, + {"typeof", TYPEOF, NORID,}, + {"typedef", SCSPEC, RID_TYPEDEF,}, + {"for", FOR, NORID,}, + {"raises", RAISES, NORID /* Extension */,}, + {"__const", TYPE_QUAL, RID_CONST}, + {"double", TYPESPEC, RID_DOUBLE,}, + {"__typeof__", TYPEOF, NORID}, + {"",}, + {"switch", SWITCH, NORID,}, + {"auto", SCSPEC, RID_AUTO,}, + {"do", DO, NORID,}, + {"friend", SCSPEC, RID_FRIEND,}, + {"",}, + {"reraise", RERAISE, NORID /* Extension */,}, + {"",}, + {"volatile", TYPE_QUAL, RID_VOLATILE,}, + {"__typeof", TYPEOF, NORID}, + {"continue", CONTINUE, NORID,}, + {"float", TYPESPEC, RID_FLOAT,}, + {"const", TYPE_QUAL, RID_CONST,}, + {"static", SCSPEC, RID_STATIC,}, + {"virtual", SCSPEC, RID_VIRTUAL,}, + {"__asm", ASM, NORID}, + {"short", TYPESPEC, RID_SHORT,}, + {"signed", TYPESPEC, RID_SIGNED,}, + {"try", TRY, NORID /* Extension */,}, + {"",}, {"",}, {"",}, + {"__signed__", TYPESPEC, RID_SIGNED}, + {"catch", CATCH, NORID,}, + {"public", PUBLIC, NORID,}, + {"struct", AGGR, RID_RECORD,}, + {"if", IF, NORID,}, + {"asm", ASM, NORID,}, + {"union", AGGR, RID_UNION,}, + {"",}, + {"private", PRIVATE, NORID,}, + {"",}, {"",}, {"",}, + {"operator", OPERATOR, NORID,}, + {"",}, {"",}, {"",}, + {"default", DEFAULT, NORID,}, + {"dynamic", DYNAMIC, NORID,}, + {"overload", OVERLOAD, NORID,}, + {"int", TYPESPEC, RID_INT,}, + {"char", TYPESPEC, RID_CHAR,}, + {"",}, {"",}, + {"return", RETURN, NORID,}, + {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, + {"",}, {"",}, + {"__signed", TYPESPEC, RID_SIGNED}, + {"",}, + {"void", TYPESPEC, RID_VOID,}, + {"",}, {"",}, {"",}, + {"protected", PROTECTED, NORID,}, + {"",}, + {"enum", ENUM, NORID,}, + {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, + {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, + {"inline", SCSPEC, RID_INLINE,}, + {"register", SCSPEC, RID_REGISTER,}, + {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, + {"",}, {"",}, {"",}, {"",}, + {"unsigned", TYPESPEC, RID_UNSIGNED,}, + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register const char *s = wordlist[key].name; + + if (*s == *str && !strcmp (str + 1, s + 1)) + return &wordlist[key]; + } + } + return 0; +} diff --git a/apps/gperf/tests/test-4.exp b/apps/gperf/tests/test-4.exp new file mode 100644 index 00000000000..5238bf94d98 --- /dev/null +++ b/apps/gperf/tests/test-4.exp @@ -0,0 +1,138 @@ +/* C code produced by gperf version 2.5 (GNU C++ version) */ +/* Command-line: ../src/gperf -D -p -t */ +/* Command-line: gperf -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */ +struct resword { char *name; short token; enum rid rid; }; + +#define TOTAL_KEYWORDS 51 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 13 +#define MIN_HASH_VALUE 4 +#define MAX_HASH_VALUE 82 +/* maximum key range = 79, duplicates = 2 */ + +static unsigned int +hash (str, len) + register char *str; + register int unsigned len; +{ + static unsigned char asso_values[] = + { + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 0, 83, 40, 20, 50, + 25, 10, 30, 0, 0, 50, 83, 0, 15, 0, + 35, 0, 83, 83, 20, 0, 10, 40, 5, 15, + 83, 83, 83, 83, 83, 83, 83, 83, + }; + return len + asso_values[str[len - 1]] + asso_values[str[0]]; +} + +struct resword * +in_word_set (str, len) + register char *str; + register unsigned int len; +{ + static struct resword wordlist[] = + { + {"",}, {"",}, {"",}, {"",}, + {"goto", GOTO, NORID}, + {"__asm", ASM, NORID}, + {"switch", SWITCH, NORID}, + {"__asm__", ASM, NORID}, + {"__const__", TYPE_QUAL, RID_CONST}, + {"__inline__", SCSPEC, RID_INLINE}, + {"__typeof__", TYPEOF, NORID}, + {"__signed__", TYPESPEC, RID_SIGNED}, + {"__alignof__", ALIGNOF, NORID}, + {"__volatile__", TYPE_QUAL, RID_VOLATILE}, + {"__attribute__", ATTRIBUTE, NORID}, + {"enum", ENUM, NORID}, + {"short", TYPESPEC, RID_SHORT}, + {"struct", STRUCT, NORID}, + {"__const", TYPE_QUAL, RID_CONST}, + {"__inline", SCSPEC, RID_INLINE}, + {"long", TYPESPEC, RID_LONG}, + {"__volatile", TYPE_QUAL, RID_VOLATILE}, + {"__attribute", ATTRIBUTE, NORID}, + {"volatile", TYPE_QUAL, RID_VOLATILE}, + {"else", ELSE, NORID}, + {"break", BREAK, NORID}, + {"do", DO, NORID}, + {"while", WHILE, NORID}, + {"signed", TYPESPEC, RID_SIGNED}, + {"__signed", TYPESPEC, RID_SIGNED}, + {"void", TYPESPEC, RID_VOID}, + {"sizeof", SIZEOF, NORID}, + {"__typeof", TYPEOF, NORID}, + {"__alignof", ALIGNOF, NORID}, + {"double", TYPESPEC, RID_DOUBLE}, + {"default", DEFAULT, NORID}, + {"asm", ASM, NORID}, + {"auto", SCSPEC, RID_AUTO}, + {"float", TYPESPEC, RID_FLOAT}, + {"typeof", TYPEOF, NORID}, + {"typedef", SCSPEC, RID_TYPEDEF}, + {"register", SCSPEC, RID_REGISTER}, + {"extern", SCSPEC, RID_EXTERN}, + {"for", FOR, NORID}, + {"static", SCSPEC, RID_STATIC}, + {"return", RETURN, NORID}, + {"int", TYPESPEC, RID_INT}, + {"case", CASE, NORID}, + {"const", TYPE_QUAL, RID_CONST}, + {"inline", SCSPEC, RID_INLINE}, + {"continue", CONTINUE, NORID}, + {"unsigned", TYPESPEC, RID_UNSIGNED}, + {"char", TYPESPEC, RID_CHAR}, + {"union", UNION, NORID}, + {"if", IF, NORID}, + }; + + static char lookup[] = + { + -1, -1, -1, -1, 4, 5, 6, 7, -1, 8, 100, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, -1, 23, 24, 25, -1, 26, + -9, -3, 27, 28, -1, 29, 30, -1, 31, -1, 32, 33, -1, 34, + 35, 36, 37, 38, 39, 40, 41, -1, -1, 42, -1, 43, -1, -1, + 44, -1, -1, -1, -1, 45, -1, 46, 47, 48, 49, -1, 50, -1, + -1, -1, -1, 51, 52, -1, -1, -1, -1, -1, 53, -1, 54, + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int index = lookup[key]; + + if (index >= 0 && index < MAX_HASH_VALUE) + { + register char *s = wordlist[index].name; + + if (*s == *str && !strcmp (str + 1, s + 1)) + return &wordlist[index]; + } + else if (index < 0 && index >= -MAX_HASH_VALUE) + return 0; + else + { + register int offset = key + index + (index > 0 ? -MAX_HASH_VALUE : MAX_HASH_VALUE); + register struct resword *base = &wordlist[-lookup[offset]]; + register struct resword *ptr = base + -lookup[offset + 1]; + + while (--ptr >= base) + if (*str == *ptr->name && !strcmp (str + 1, ptr->name + 1)) + return ptr; + } + } + } + return 0; +} diff --git a/apps/gperf/tests/test-5.exp b/apps/gperf/tests/test-5.exp new file mode 100644 index 00000000000..101e2798d40 --- /dev/null +++ b/apps/gperf/tests/test-5.exp @@ -0,0 +1,111 @@ +/* C code produced by gperf version 2.5 (GNU C++ version) */ +/* Command-line: ../src/gperf -g -o -j1 -t -p -N is_reserved_word */ +/* ISO Pascal 7185 reserved words. + * + * For GNU Pascal compiler (GPC) by jtv@hut.fi + * + * run this through the Doug Schmidt's gperf program + * with command + * gperf -g -o -j1 -t -p -N is_reserved_word + * + */ +struct resword { char *name; short token; short iclass;}; + +#define TOTAL_KEYWORDS 35 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 9 +#define MIN_HASH_VALUE 2 +#define MAX_HASH_VALUE 43 +/* maximum key range = 42, duplicates = 0 */ + +#ifdef __GNUC__ +inline +#endif +static unsigned int +hash (str, len) + register char *str; + register int unsigned len; +{ + static unsigned char asso_values[] = + { + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 18, 29, 14, 6, 7, + 10, 20, 44, 28, 44, 44, 28, 19, 22, 15, + 0, 44, 9, 23, 0, 23, 26, 2, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 0, 0, 13, 44, 30, 44, 44, 44, 0, 25, + 1, 0, 44, 44, 0, 44, 1, 44, 25, 44, + 44, 0, 44, 44, 44, 44, 44, 44, + }; + return len + asso_values[str[len - 1]] + asso_values[str[0]]; +} + +#ifdef __GNUC__ +inline +#endif +struct resword * +is_reserved_word (str, len) + register char *str; + register unsigned int len; +{ + static struct resword wordlist[] = + { + {"",}, {"",}, + {"To", TO, PASCAL_ISO}, + {"",}, + {"Type", TYPE, PASCAL_ISO}, + {"Then", THEN, PASCAL_ISO}, + {"Packed", PACKED, PASCAL_ISO}, + {"While", WHILE, PASCAL_ISO}, + {"Do", DO, PASCAL_ISO}, + {"Procedure", PROCEDURE, PASCAL_ISO}, + {"End", END, PASCAL_ISO}, + {"Else", ELSE, PASCAL_ISO}, + {"Downto", DOWNTO, PASCAL_ISO}, + {"For", FOR, PASCAL_ISO}, + {"File", FILE_, PASCAL_ISO}, + {"Record", RECORD, PASCAL_ISO}, + {"Repeat", REPEAT, PASCAL_ISO}, + {"Or", OR, PASCAL_ISO}, + {"Case", CASE, PASCAL_ISO}, + {"Function", FUNCTION, PASCAL_ISO}, + {"Const", CONST, PASCAL_ISO}, + {"And", AND, PASCAL_ISO}, + {"Mod", MOD, PASCAL_ISO}, + {"Array", ARRAY, PASCAL_ISO}, + {"Goto", GOTO, PASCAL_ISO}, + {"Nil", NIL, PASCAL_ISO}, + {"Not", NOT, PASCAL_ISO}, + {"Set", SET, PASCAL_ISO}, + {"Until", UNTIL, PASCAL_ISO}, + {"Var", VAR, PASCAL_ISO}, + {"Of", OF, PASCAL_ISO}, + {"In", IN, PASCAL_ISO}, + {"Program", PROGRAM,PASCAL_ISO}, + {"Label", LABEL, PASCAL_ISO}, + {"Div", DIV, PASCAL_ISO}, + {"Begin", BEGIN_, PASCAL_ISO}, + {"With", WITH, PASCAL_ISO}, + {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, + {"If", IF, PASCAL_ISO}, + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register char *s = wordlist[key].name; + + if (*s == *str && !strcmp (str + 1, s + 1)) + return &wordlist[key]; + } + } + return 0; +} diff --git a/apps/gperf/tests/test-6.exp b/apps/gperf/tests/test-6.exp new file mode 100644 index 00000000000..eba6e3cac9a --- /dev/null +++ b/apps/gperf/tests/test-6.exp @@ -0,0 +1,74 @@ +-a Generate ANSI standard C output code, i.e., function prototypes. +-c Generate comparison code using strncmp rather than strcmp. +-C Make the contents of generated lookup tables constant, i.e., readonly. +-d Enables the debugging option (produces verbose output to the standard error). +-D Handle keywords that hash to duplicate values. This is useful + for certain highly redundant keyword sets. It enables the -S option. +-e Allow user to provide a string containing delimiters used to separate + keywords from their attributes. Default is ",\n" +-E Define constant values using an enum local to the lookup function + rather than with defines +-f Generate the gen-perf.hash function ``fast.'' This decreases GPERF's + running time at the cost of minimizing generated table-size. + The numeric argument represents the number of times to iterate when + resolving a collision. `0' means ``iterate by the number of keywords.'' +-g Assume a GNU compiler, e.g., g++ or gcc. This makes all generated + routines use the ``inline'' keyword to remove cost of function calls. +-G Generate the static table of keywords as a static global variable, + rather than hiding it inside of the lookup function (which is the + default behavior). +-h Prints this mesage. +-H Allow user to specify name of generated hash function. Default + is `hash'. +-i Provide an initial value for the associate values array. Default is 0. + Setting this value larger helps inflate the size of the final table. +-j Affects the ``jump value,'' i.e., how far to advance the associated + character value upon collisions. Must be an odd number, default is 5. +-k Allows selection of the key positions used in the hash function. + The allowable choices range between 1-126, inclusive. The positions + are separated by commas, ranges may be used, and key positions may + occur in any order. Also, the meta-character '*' causes the generated + hash function to consider ALL key positions, and $ indicates the + ``final character'' of a key, e.g., $,1,2,4,6-10. +-K Allow use to select name of the keyword component in the keyword structure. +-l Compare key lengths before trying a string comparison. This helps + cut down on the number of string comparisons made during the lookup. +-L Generates code in the language specified by the option's argument. Languages + handled are currently C++ and C. The default is C. +-n Do not include the length of the keyword when computing the hash function +-N Allow user to specify name of generated lookup function. Default + name is `in_word_set.' +-o Reorders input keys by frequency of occurrence of the key sets. + This should decrease the search time dramatically. +-p Changes the return value of the generated function ``in_word_set'' + from its default boolean value (i.e., 0 or 1), to type ``pointer + to wordlist array'' This is most useful when the -t option, allowing + user-defined structs, is used. +-r Utilizes randomness to initialize the associated values table. +-s Affects the size of the generated hash table. The numeric argument + for this option indicates ``how many times larger or smaller'' the associated + value range should be, in relationship to the number of keys, e.g. a value of 3 + means ``allow the maximum associated value to be about 3 times larger than the + number of input keys.'' Conversely, a value of -3 means ``make the maximum + associated value about 3 times smaller than the number of input keys. + A larger table should decrease the time required for an unsuccessful search, + at the expense of extra table space. Default value is 1. +-S Causes the generated C code to use a switch statement scheme, rather + than an array lookup table. This can lead to a reduction in both + time and space requirements for some keyfiles. The argument to + this option determines how many switch statements are generated. + A value of 1 generates 1 switch containing all the elements, a value of 2 + generates 2 tables with 1/2 the elements in each table, etc. This + is useful since many C compilers cannot correctly generate code for + large switch statements. +-t Allows the user to include a structured type declaration for + generated code. Any text before %% is consider part of the type + declaration. Key words and additional fields may follow this, one + group of fields per line. +-T Prevents the transfer of the type declaration to the output file. + Use this option if the type is already defined elsewhere. +-v Prints out the current version number +-Z Allow user to specify name of generated C++ class. Default + name is `Perfect_Hash.' +Usage: ../src/gperf [-acCdDef[num]gGhHijkKlLnNoprsStTvZ]. +(type ../src/gperf -h for help) diff --git a/apps/gperf/tests/test-7.exp b/apps/gperf/tests/test-7.exp new file mode 100644 index 00000000000..c5c942c10d1 --- /dev/null +++ b/apps/gperf/tests/test-7.exp @@ -0,0 +1,32 @@ +in word set if +in word set do +NOT in word set int +in word set for +in word set case +NOT in word set char +NOT in word set auto +in word set goto +in word set else +NOT in word set long +NOT in word set void +NOT in word set enum +NOT in word set float +NOT in word set short +NOT in word set union +NOT in word set break +in word set while +NOT in word set const +NOT in word set double +NOT in word set static +NOT in word set extern +NOT in word set struct +in word set return +NOT in word set sizeof +NOT in word set switch +NOT in word set signed +NOT in word set typedef +NOT in word set default +NOT in word set unsigned +NOT in word set continue +NOT in word set register +NOT in word set volatile diff --git a/apps/gperf/tests/test.c b/apps/gperf/tests/test.c new file mode 100644 index 00000000000..35d9015bba7 --- /dev/null +++ b/apps/gperf/tests/test.c @@ -0,0 +1,28 @@ +/* +// @(#)test.c 1.1 10/18/96 + + Tests the generated perfect has function. + The -v option prints diagnostics as to whether a word is in + the set or not. Without -v the program is useful for timing. +*/ + +#include + +#define MAX_LEN 80 + +int +main (argc, argv) + int argc; + char *argv[]; +{ + int verbose = argc > 1 ? 1 : 0; + char buf[MAX_LEN]; + + while (gets (buf)) + if (in_word_set (buf, strlen (buf)) && verbose) + printf ("in word set %s\n", buf); + else if (verbose) + printf ("NOT in word set %s\n", buf); + + return 0; +} diff --git a/bin/Makefile b/bin/Makefile new file mode 100644 index 00000000000..3125c849be6 --- /dev/null +++ b/bin/Makefile @@ -0,0 +1,37 @@ +############################################################################# +# +# Makefile for assignment 1 +# +############################################################################# + +CXX = CC +CFILES = clone.cpp +OFILES = clone.o +DFLAGS = -g +CFLAGS = $(DFLAGS) -I$(WRAPPER_ROOT) + +############################################################################# +# C++ directives + +.SUFFIXES: .cpp +.cpp.o: + $(CXX) $(CFLAGS) -c $< +############################################################################# + +clone: $(OFILES) + $(CXX) $(CFLAGS) -o $@ $(OFILES) + +clean: + -/bin/rm -f *.o *.out *~ core + +realclean: clean + -/bin/rm -fr clone + +depend: + g++dep -f Makefile $(CFILES) +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +clone.o : clone.cpp +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY + diff --git a/bin/README.html b/bin/README.html new file mode 100644 index 00000000000..6c6577b411e --- /dev/null +++ b/bin/README.html @@ -0,0 +1,136 @@ + + + +ACE OSE Tools + + + +
+

Modified Version of the OSE Documentation Tools

+ +This directory +contains versions of the freely available OSE +tools modified by Karlheinz Dorn (kdorn@erlh.siemens.de). I (Doug +Schmidt) am grateful to him for contributing his efforts to help +improve ACE. You can obtain these files via the ACE release.

+ +The primary goal of the modifications was to create a class.hxx and +class.cxx file (for each class, struct, union included within the +original ACE header file) from the ACE *.h header files by collecting +the comments from that file and feeding them into the newly created +files, but keeping the ACE *.h file untouched.

+ +This helps when making product documentation using commercial +documentation tools (e.g., GEORGE) by feeding in these newly created +files with a customizable layout. The modifications should be an +upgrade to the original OSE-tools, but many bug-fixes are also done +for the OSE-tool files (some are listed below).

+ +This extensions make it very easy to include new ACE versions into +commercial documentations without doing any painful modifications of +the deltas within a frozen ACE-version or directly within ACE source +files when a new release arises.

+ +The following changes were made to the original OSE tools: + +

    + +
  • The vendor headers can be suppressed within the hiding.fmt file, +so it is possible to generate class.cxx and +class.hxx files consisting only of pure class description +(hxx) and pure prototypes (cxx). Look at the vendor.fmt file and +change the field vendor in replacing it with your company +identifying line.

    + +

  • Added a new script class2hxxcxx for making a class.hxx file for each + class, struct, union included in an ACE *.h file as well as a *.cxx + file that includes the correct prototypes for all classes within that + *.h file.

    + +

  • Added new script info2headsrc for creating a class.hxx file for each + class, struct, union included in an ACE *.h file as well as a class.cxx + file that includes the correct prototypes for that class.

    + +

  • added a new script class2hxxcxxsingle for the feature listed above.

    + +

  • added a new format file named "hiding.fmt" to control more fine grained output + of a class in separating/suppressing PUBLIC, PROTECTED, PRIVATE parts of a + class, struct, union for output explicitly.

    + +

  • added a new format file named "vendor.fmt" to control vendor specific + compilation-unit headers as well as class and method headers for the newly + created class.hxx and class.cxx files. The information for these headers + is collected from the headers and comments of the according ACE *.h files.

    + +

  • changed info2doc and info2src for the features listed above.

    + +

  • added the ability for handling multiline ENUMs properly (class2info,info2doc).

    + +

  • added the ability for handling operator functions properly (info2src).

    + +

  • added the ability for handling template functions properly (info2src).

    + +

  • added the ability for handling nested classes, structs, unions properly + by introducing nawk-function recursion within info2doc (class2info, + info2doc, info2src).

    + +

  • added the ability for handling default values properly (info2src).

    + +

+ +

+

Known Bugs

+ +Some bugs inherited from the original OSE-tools are remaining. So the +developer of the *.h files should the following keep in mind: + +- do not write multiline inheritance!

+ +INCORRECT:

+ +


+  class x :
+        public y
+  {
+  }
+
+ +CORRECT:

+ +


+  class x : public y
+  {
+  }
+
+ +- do not write multiline templates!

+ +INCORRECT:

+ +


+  template <class t,
+            class>
+  class x 
+  {
+  }
+
+ +CORRECT:

+ +


+  template <class t, class u>
+  class x 
+  {
+  }
+
+ +


+Back to the ACE home page. + + + diff --git a/bin/class2hxxcxx b/bin/class2hxxcxx new file mode 100755 index 00000000000..2254f645d75 --- /dev/null +++ b/bin/class2hxxcxx @@ -0,0 +1,80 @@ +#! /bin/sh +# ============================================================================= +# +# = DESCRIPTION +# Script to combine class2info and info2head and info2src. +# +# = AUTHOR(S) +# K. Dorn +# +# = COPYRIGHT +# Copyright 1991 OTC LIMITED +# +# ============================================================================= + +OSE_HOST= + +OSE_RELEASE_NAME= +export OSE_RELEASE_NAME + +OSE_ROOT=${OSE_ROOT-$WRAPPER_ROOT} +export OSE_ROOT + +OSE_VERSION_ROOT=$OSE_ROOT/$OSE_RELEASE_NAME +export OSE_VERSION_ROOT + +BINDIR="$OSE_VERSION_ROOT/$OSE_HOST/bin" +LIBDIR=${CLASSINFOLIBDIR-"$OSE_VERSION_ROOT/lib"} + +CLASS2INFO="$BINDIR/class2info" +INFO2HEAD="$BINDIR/info2head" +INFO2SRC="$BINDIR/info2src" + +# +# Error. +# +ERROR() +{ + echo "`basename $0`: $1" >&2 + shift + while test $# != "0" + do + echo $1 >&2 + shift + done + exit 1 +} + +# +# Usage message. +# +USAGE() +{ + ERROR "Usage: `basename $0` files" +} + +# +# Check usage. +# +if test "$#" = "0" +then + USAGE +fi + +while test "$#" != "0" +do + $CLASS2INFO $1 + if test "$?" != "0" + then + exit 1 + fi + file=`basename $1` + base="`echo $file | sed -e 's/\..*$//'`" + if test -f "$base.ci" + then + $INFO2SRC $base.ci + $INFO2HEAD $base.ci +# rm -f $base.ci + fi + shift +done diff --git a/bin/class2hxxcxxsingle b/bin/class2hxxcxxsingle new file mode 100755 index 00000000000..94c869cb739 --- /dev/null +++ b/bin/class2hxxcxxsingle @@ -0,0 +1,80 @@ +#! /bin/sh +# ============================================================================= +# +# = DESCRIPTION +# Script to combine class2info and info2head and info2src. +# +# = AUTHOR(S) +# K. Dorn +# +# = COPYRIGHT +# Copyright 1991 OTC LIMITED +# +# ============================================================================= + +OSE_HOST= + +OSE_RELEASE_NAME= +export OSE_RELEASE_NAME + +OSE_ROOT=${OSE_ROOT-$WRAPPER_ROOT} +export OSE_ROOT + +OSE_VERSION_ROOT=$OSE_ROOT/$OSE_RELEASE_NAME +export OSE_VERSION_ROOT + +BINDIR="$OSE_VERSION_ROOT/$OSE_HOST/bin" +LIBDIR=${CLASSINFOLIBDIR-"$OSE_VERSION_ROOT/lib"} + +CLASS2INFO="$BINDIR/class2info" +INFO2HEADSRC="$BINDIR/info2headsrc" +INFO2SRC="$BINDIR/info2src" + +# +# Error. +# +ERROR() +{ + echo "`basename $0`: $1" >&2 + shift + while test $# != "0" + do + echo $1 >&2 + shift + done + exit 1 +} + +# +# Usage message. +# +USAGE() +{ + ERROR "Usage: `basename $0` files" +} + +# +# Check usage. +# +if test "$#" = "0" +then + USAGE +fi + +while test "$#" != "0" +do + $CLASS2INFO $1 + if test "$?" != "0" + then + exit 1 + fi + file=`basename $1` + base="`echo $file | sed -e 's/\..*$//'`" + if test -f "$base.ci" + then +# $INFO2SRC $base.ci + $INFO2HEADSRC $base.ci +# rm -f $base.ci + fi + shift +done diff --git a/bin/class2info b/bin/class2info new file mode 100755 index 00000000000..752ced3ebce --- /dev/null +++ b/bin/class2info @@ -0,0 +1,197 @@ +#! /bin/sh +# ============================================================================= +# +# = DESCRIPTION +# Converts a C++ class header file into a classinfo description file. +# +# = AUTHOR(S) +# Graham Dumpleton +# K. Dorn +# +# = COPYRIGHT +# Copyright - OTC LIMITED (1991) +# +# ============================================================================= + +OSE_HOST= + +OSE_RELEASE_NAME= +export OSE_RELEASE_NAME + +OSE_ROOT=${OSE_ROOT-$WRAPPER_ROOT} +export OSE_ROOT + +OSE_VERSION_ROOT=$OSE_ROOT +export OSE_VERSION_ROOT + +BINDIR="$OSE_VERSION_ROOT/$OSE_HOST/bin" +LIBDIR=${CLASSINFOLIBDIR-"$OSE_VERSION_ROOT/bin"} + +INFO2INFO="$BINDIR/info2info" + +AWK="nawk" + +if test "$AWK" = "nawk" +then + VARG="-v" +fi + + +FILES= +V2= + +trap 'rm -f /tmp/ci.$$; exit' 1 2 3 13 15 + +# +# Error. +# +ERROR() +{ + echo "`basename $0`: $1" >&2 + shift + while test $# != "0" + do + echo $1 >&2 + shift + done + exit 1 +} + +# +# Usage message. +# +USAGE() +{ + ERROR "Usage: `basename $0` file.h ..." +} + +# +# Check usage. +# +if test $# = 0 +then + USAGE +fi + +# +# Parse command line. +# +while test $# != 0 +do + case $1 in +# -v2) +# V2=YES +# shift +# ;; + *.h|*.hh|*.H|*.hxx|*.hpp|*.h++) + FILES="$FILES $1" + shift + ;; + *) + USAGE + ;; + esac +done + +# +# Check usage again. +# +if test -z "$FILES" +then + USAGE +fi + +# +# Check for awk file. +# +CLASS2INFO=$LIBDIR/class2info.awk +HIDINGFMT=$LIBDIR/hiding.fmt + +if test ! -f $HIDINGFMT +then + ERROR "Can't find $HIDINGFMT" +fi + + +if ( test ! -f $CLASS2INFO ) +then + ERROR "Can't find $CLASS2INFO" +fi + + + +VCSA=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^CSAHEADER$" { + if ( $2 ~ "on" ) + printf("%s","csaprintheader=on"); + else + printf("%s","csaprintheader="); +}' $HIDINGFMT` + +VPUBL=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^PUBLIC$" { + if ( $2 ~ "on" ) + printf("%s","publ=on"); + else + printf("%s","publ="); +}' $HIDINGFMT` + +VPROT=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^PROTECTED$" { + if ( $2 ~ "on" ) + printf("%s","prot=on"); + else + printf("%s","prot="); +}' $HIDINGFMT` + +VPRIV=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^PRIVATE$" { + if ( $2 ~ "on" ) + printf("%s","priv=on"); + else + printf("%s","priv="); +}' $HIDINGFMT` + +#echo " $VPUBL $VPROT $VPRIV " + + +# +# Parse each file. +# +# $VARG publ=on $VARG prot=off $VARG priv=off \ +for i in $FILES +do + if test ! -f $i + then + ERROR "$i doesn't exist." + fi + FILENAME=`basename $i` + INFOFILE=`echo $FILENAME | sed -e 's/\..*$//'`.ci + rm -f $INFOFILE + if test "$?" != 0 + then + ERROR "Couldn't remove info file $INFOFILE." + fi + expand $i > /tmp/ci.$$ + $AWK \ + -f $CLASS2INFO $VARG filename=$i \ + $VARG $VPUBL $VARG $VPROT $VARG $VPRIV \ + /tmp/ci.$$ > $INFOFILE + rm -f /tmp/ci.$$ +# if test ! -z "$V2" +# then +# $INFO2INFO $INFOFILE +# fi +done diff --git a/bin/class2info.awk b/bin/class2info.awk new file mode 100644 index 00000000000..1810a8f3e0c --- /dev/null +++ b/bin/class2info.awk @@ -0,0 +1,1594 @@ +# ============================================================================= +# +# = DESCRIPTION +# Awk script for converting C++ class header file to classinfo file. +# Requires nawk or gawk. +# comments like /* ... */ with ... goes over multiple lines are not ok +# and will be not printed as comments! +# class xxx +# : public yyyy is not allowed but : class xxx : public yyyy +# +# = AUTHOR(S) +# Graham Dumpleton +# K. Dorn +# +# = COPYRIGHT +# Copyright 1991 OTC LIMITED +# +# ============================================================================= + +BEGIN { + initialised = 0 + accpubl = "on" + accprot = "on" + accpriv = "on" + accpubl = publ + accprot = prot + accpriv = priv + accpubl = "on" + accprot = "off" + accpriv = "off" +} +{ + if ( initialised == 0 ) + { + initialised = 1 + "date" | getline line + printf( "CLASS2INFO\n%s\n%s\n\n", line, filename ) + anonenum = 1 + } + doParse(); + next +} + + + +{ + print "error" | "cat 1>&2" + exit +} + +# +# If a comment starts with '// ==', discard lines until the end of the +# comment or a line of the form '// = NAME' is found. This is special +# case to deal with comment headers in files. e.g: +# +# // ========== ... +# // +# // = LIBRARY +# // ... +# +# lines up to '// = LIBRARY' would be discarded. +# +# /^[\t ]*\/\/[\t ]*==+[\t ]*$/ { +# handleHeader() +# } + +function handleHeader() +{ + getline + while ( \ + ( $0 ~ "^[\t ]*//" ) \ + && \ + ( $0 !~ "^[\t ]*//[\t ]*= [a-zA-Z0-9]+[^<>]*[\t ]*$" ) \ + ) + { + getline + } +} + +# +# Extract labelled comments. These are denoted by '// = NAME', where the word +# NAME is actually replaced by the some identifying label. +# A labelled section is terminated by the end of the comment block, another +# labelled comment, or a comment line of the form '// =='. e.g: +# Note: a label cannot contain the characters '<>', these are identified +# as being special commands and are simply passed through. +# +# // = LIBRARY +# // C++ +# // +# // = VERSION +# // ... +# // +# // ========== ... +# +# the LIBRARY section would be terminated by '// = VERSION', and the VERSION +# section by '// =====...'. +# +# /^[\t ]*\/\/[\t ]*= [a-zA-Z0-9]+[^<>]*[\t ]*$/ { +# handleInfo() +# } + +function handleInfo( label ) +{ + sub( "^[\t ]*//", "", $0 ) + while ( $0 ~ "^[\t ]*= [a-zA-Z0-9]+[^<>]*[\t ]*$" ) + { + match( $0, " [a-zA-Z0-9]+[^<>]*$" ) + label = substr( $0, RSTART, RLENGTH ) + sub( "^[\t ]*", "", label ) + if ( name ~ "^$" ) + printf( "INFO\nGLOBAL\n%s\n", label ) + else if ( hiding ~ "^$" ) + printf( "INFO\nHDR\n%s\n%s\n", label, name ) + else + printf( "INFO\nBODY\n%s\n%s\n%s\n", label, name, hiding ) + $0 = outputComment() + } +} + +function SetCommentClrComment( line, comment) +{ + if ( match( line, "(\/\\*.*\\*\/)?$" ) > 0) + { + comment = substr( line, RSTART, RLENGTH ) + sub( "//.*$", "", line ) + } + else + if ( match( line, "(//.*)?$" ) > 0) + { + comment = substr( line, RSTART, RLENGTH ) + sub( "\/\\*.*$", "", line ) + } +} + + +function check_print_first() +{ + if ( ((hiding == "private") && (accpriv == "on") ) || ((hiding == "public") && (accpubl == "on") ) || ((hiding == "protected") && (accprot == "on") ) ) + pra = 1 + else + { + pra = 0 + $0 = "" + } + return pra +} + +function check_print() +{ + if ( ( type ~ "class" ) && ( hiding ~ "^$" ) ) + { + if (accpriv == "on") + { + pra = 1 + return pra + } + else + { + pra = 0 + $0 = "" + return pra + } + } + else + { + + if ((accpubl == "on") || ( hiding ~ "^$" )) + { + pra = 1 + return pra + } + else + { + pra = 0 + $0 = "" + return pra + } + } + + if ( ((hiding == "private") && (accpriv == "on") ) || ((hiding == "public") && (accpubl == "on") ) || ((hiding == "protected") && (accprot == "on") ) ) + { + pra = 1 + } + else + { + pra = 0 + $0 = "" + } + return pra +} + +# +# transfer a c comment /* ... */ to a C++ // ... comment +# the comment comes in feld and goes back in feld +# + +function Set_c_Comment_to_CPP_Comment( feld) +{ + if ( match( feld, "\/\\*.*\\*\/$" ) > 0) + { +# printf("\n----feldb=|%s|----\n",feld); + sub( "\/\\*", "\/\/", feld ) + sub( "\\*\/", "", feld ) +# printf("\n----felda=|%s|----\n",feld); + } + return feld +} + + + +# +# Gather up unlabelled comments. +# +# /^[\t ]*\/\/.*$/ { +# handleComment() +# } + +function handleComment() +{ + if ( name ~ "^$" ) + printf( "COMMENT\nGLOBAL\n" ) + else if ( hiding ~ "^$" ) + printf( "COMMENT\nHDR\n%s\n", name ) + else + printf( "COMMENT\nBODY\n%s\n%s\n", name, hiding ) + $0 = outputComment( $0 ) +} + +# +# Skip past '#define's. Leave it up to programmers to document important +# definitions with a section. +# +# /^[\t ]*#[\t ]*define/ { +# handleDefine() +# } + +function handleDefine( line ) +{ + if ( $0 ~ ".*\\\\$" ) + { + end = 0 + while ( end == 0 ) + { + getline line + if ( line !~ ".*\\\\$" ) + end = 1 + } + } + # next + $0 = "" +} + +# +# Record name of files which are included. +# Note: Since we do not process '#if's we will get all includes, even if +# some are particular to some systems etc. +# +# /^[\t ]*#[\t ]*include[\t ]*<.+>/ { +# () +# } + +function handleInclude() +{ + match( $0, "<.+>" ) + $0 = substr( $0, RSTART, RLENGTH ) + printf( "INCLUDE\n%s\n\n", $0 ) + # next + $0 = "" +} + +# /^[\t ]*#[\t ]*include[\t ]*".+"/ { +# handleLocalInclude() +# } + +function handleLocalInclude() +{ + match( $0, "\".+\"" ) + $0 = substr( $0, RSTART, RLENGTH ) + printf( "INCLUDE\n%s\n\n", $0 ) + # next + $0 = "" +} + +# +# Skip any other pre-processor directives. +# +# /^[\t ]*#.*$/ { +# handlePreprocessor() +# } + +function handlePreprocessor_alt() +{ + # next + $0 = "" +} + +function handlePreprocessor() +{ + printf( "PREPROC\n%s\n\n", $0 ) + # next + $0 = "" +} + +# +# Trap typedefs. +# +# /^typedef[\t ]+/ { +# handleTypedef() +# } + +function handleTypedef( comment, line ) +{ + line = $0 + while ( line !~ ";[\t ]*(//.*)?$" ) + { + line = uncomment( line ) + getline + sub( "^[\t ]*", "", $0 ) + line = line " " $0 + sub( "\\) \\(", ")(", line ) + } + match( line, "(//.*)?$" ) + comment = substr( line, RSTART, RLENGTH ) + sub( "//.*$", "", line ) + sub( "^[\t ]*typedef[\t ]*", "typedef ", line ) + if ( name ~ "^$" ) + printf( "TYPEDEF\n%s\n%s\n%s\n", "::", "public", line ) + else + printf( "TYPEDEF\n%s\n%s\n%s\n", name, hiding, line ) + $0 = outputComment( comment ) +} + +# +# Trap externs. +# +# /^extern[\t ]+/ { +# handleExtern() +# } + +function handleExtern( lang, comment ) +{ + if ( $0 ~ "\"C\"[\t ]*$" || $0 ~ "\"C\"[\t ]*\{[\t ]*$" ) + { + # Bracketed includes (??). Skip them for now. + while ( $0 !~ "}[\t]*$" && $0 !~ "}[\t ]*;[\t]*$" ) + getline + getline + } + else + { + if ( $0 !~ ";[\t ]*(//.*)?$" ) + $0 = handleArgs( $0 ) + match( $0, "(//.*)?$" ) + comment = substr( $0, RSTART, RLENGTH ) + sub( "//.*$", "", $0 ) + sub( "^extern[\t ]*", "", $0 ) + if ( match( $0, "\"[^\"]*\"" ) != 0 ) + { + lang = substr( $0, RSTART, RLENGTH ) + sub( "^\"[\t ]*", "", lang ) + sub( "[\t ]*\"$", "", lang ) + } + else + lang = "C++" + sub( "\"[^\"]*\"[\t ]*", "", $0 ) + printf( "EXTERN\n%s\n%s\n", lang , $0 ) + $0 = outputComment( comment ) + } +} + +# +# Trap class, struct, union and template definitions. +# Note: handleADT() does the hard work of determining if the particular +# use is in a definition, declaration or other. +# +# /^[\t ]*class/ { +# handleClass() +# } + +function handleClass() +{ + class = 1 + sub( "^[\t ]*class[\t ]+(ACE_[.]*Export[\t ]+)?", "", $0 ) + if ( handleADT( $0 ) == 1 ) + { + if ( topName ~ "^$" ) + printf( "CLASS\n%s\n", name ) + else + printf( "CLASS\n%s::%s\n", topName, name ) + outputSuperClasses( bases ) + bases = "" + } + class = 0 + # next + $0 = "" +} + +# /^[\t ]*enum/ { +# handleEnumCsa() +# } + +function handleEnumCsa() +{ + enum = 1 + sub( "^[\t ]*enum[\t ]+", "", $0 ) + if ( handleADT( $0 ) == 1 ) + { + if ( topName ~ "^$" ) + printf( "ENUM\n%s\n", name ) + else + printf( "ENUM\n%s::%s\n", topName, name ) + bases = "" + } + enum = 0 + # next + $0 = "" +} + +# /^[\t ]*struct/ { +# handleStruct() +# } + +function handleStruct() +{ + struct = 1 + sub( "^[\t ]*struct[\t ]+", "", $0 ) + if ( handleADT( $0 ) == 1 ) + { + if ( topName ~ "^$" ) + printf( "STRUCT\n%s\n", name ) + else + printf( "STRUCT\n%s::%s\n", topName, name ) + outputSuperClasses( bases ) + bases = "" + } + struct = 0 + # next + $0 = "" +} + +# /^[\t ]*union/ { +# handleUnion() +# } + +function handleUnion() +{ + union = 1 + sub( "^[\t ]*union[\t ]+", "", $0 ) + if ( handleADT( $0 ) == 1 ) + { + if ( topName ~ "^$" ) + printf( "UNION\n%s\n", name ) + else + printf( "UNION\n%s::%s\n", topName, name ) + outputSuperClasses( bases ) + bases = "" + } + union = 0 + # next + $0 = "" +} + +# /^[\t ]*template[\t ]*<.+>[\t ]+class/ { +# handleTemplate() +# } + +function handleTemplate() +{ + template = 1 + + match( $0, "^[\t ]*template[\t ]*<.+>[\t ]+(class|struct|union)[\t ]+" ) +# nested template error!!! match( $0, "^template[\t ]*<.+>[\t ]+(class|struct|union)[\t ]+" ) + + line = substr( $0, RSTART, RLENGTH ) + match( line, "[\t ]+(class|struct|union)[\t ]+$" ) + adttype = substr( line, RSTART, RLENGTH ) + sub( "^[\t ]*", "", adttype ) + sub( "[\t ]*$", "", adttype ) + match( line, "<.+>" ) + targs = substr( line, RSTART, RLENGTH ) + sub( "^[\t ]*template[\t ]*<.+>[\t ]+(class|struct|union)[\t ]+", "", $0 ) + if ( handleADT( $0 ) == 1 ) + { +# printf( "TEMPLATE\n%s\n%s\n%s\n", adttype, name, targs ) + if ( topName !~ "^$" ) + printf( "TEMPLATE\n%s\n%s::%s\n%s\n", adttype, topName, name, targs ) + else + printf( "TEMPLATE\n%s\n%s\n%s\n", adttype, name, targs ) + outputSuperClasses( bases ) + bases = "" + } + template = 0 + # next + $0 = "" +} + +# +# Trap enumerated types. +# + +# This handles enums where there is potentially more than one entry on +# a line. We throw away all comments in this case. + +function handleLineEnum() +{ + enum = 1 + sub( "^[\t ]*enum[\t ]*", "", $0 ) + line = $0 + sub( "[\t ]*\{.*", "", line ) + pushLevel() + name = line + if ( name != "" ) + { + if ( topName ~ "^$" ) + printf( "ENUM\n%s\n\n", name ) + else + printf( "ENUM\n%s::%s\n\n", topName, name ) + } + else + { + name = anonenum + anonenum++ + if ( topName ~ "^$" ) + printf( "ANONENUM\n%s\n\n", name ) + else + printf( "ANONENUM\n%s::%s\n\n", topName, name ) + } + line = $0 + sub( "^.*\{[\t ]*", "", line ) + sub( "[\t ]*//.*$", "", line ) + while ( line !~ "}.*" ) + { + getline + line = line $0 + sub( "[\t ]*//.*$", "", line ) + } + # Forget about variables for now. + sub( "[\t ]*}.*", "", line ) + gsub( "[\t ]+", "", line ) + num = split( line, item, "," ) + for ( i=1; i<=num; i++ ) + { + if ( topName ~ "^$" ) + printf( "ENUMITEM\n%s\n%s\n\n", name, item[i] ) + else + printf( "ENUMITEM\n%s::%s\n%s\n\n", topName, name, item[i] ) + } + $0 = "" + popLevel( $0 ) + enum = 0 +} + +# This handles enums which are formatted to preferred style. +# Can collect comments meaningfully in this format. + +function handleEnum() +{ + enum = 1 + sub( "^[\t ]*enum[\t ]*", "", $0 ) + sub( "([\t ]*\{)?[\t ]*$", "", $0 ) + sub( "^[\t ]*", "", $0 ) + pushLevel() + name = $0 + if ( name != "" ) + { + if ( topName ~ "^$" ) + printf( "ENUM\n%s\n\n", name ) + else + printf( "ENUM\n%s::%s\n\n", topName, name ) + } + else + { + name = anonenum + anonenum++ + if ( topName ~ "^$" ) + printf( "ANONENUM\n%s\n\n", name ) + else + printf( "ANONENUM\n%s::%s\n\n", topName, name ) + } + getline + while ( $0 ~ /^[\t ]*\/\/[\t ]*=/ ) + handleInfo() + while ( 1 ) + { + while ( $0 ~ /^[\t ]*$/ || $0 ~ /^[\t ]*\{/ ) + getline + + if ( $0 ~ /,[^\/]*,/ ) + { + line = $0 + sub( "[,\t ]*//.*", " ", line ) + gsub( "[\t ]+", "", line ) + num = split( line, item, "," ) + for ( i=1; i<=num; i++ ) + { + if ( topName ~ "^$" ) + printf( "ENUMITEM\n%s\n%s\n", name, item[i] ) + else + printf( "ENUMITEM\n%s::%s\n%s\n", topName, name, item[i] ) + if ( i != num ) + printf( "\n" ) + } + sub( "^.*//", "//", $0 ) + currentlevel = level + $0 = outputComment( $0 ) +# if ( $0 ~ /^$/ ) + if ( currentlevel != level ) + { + enum = 0 + return + } + } + else if ( $0 ~ /^.*,[\t ]*(\/\/.*)?$/ ) + { + match( $0, ".*,([\t ]*//)?" ) + enumval = substr( $0, RSTART, RLENGTH ) + sub( "[\t ]*,.*$", "", enumval ) + sub( "^[\t ]*", "", enumval ) + if ( topName ~ "^$" ) + printf( "ENUMITEM\n%s\n%s\n", name, enumval ) + else + printf( "ENUMITEM\n%s::%s\n%s\n", topName, name, enumval ) + sub( "^.*//", "//", $0 ) + currentlevel = level + $0 = outputComment( $0 ) +# if ( $0 ~ /^$/ ) + if ( currentlevel != level ) + { + enum = 0 + return + } + } + else if ( $0 ~ /^.*(\/\/.*)?$/ ) + { + match( $0, ".*([\t ]*//)?" ) + enumval = substr( $0, RSTART, RLENGTH ) + sub( "[\t ]*([\t ]*//.*)?$", "", enumval ) + sub( "^[\t ]*", "", enumval ) + if ( topName ~ "^$" ) + printf( "ENUMITEM\n%s\n%s\n", name, enumval ) + else + printf( "ENUMITEM\n%s::%s\n%s\n", topName, name, enumval ) + sub( "^.*//", "//", $0 ) + currentlevel = level + $0 = outputComment( $0 ) +# if ( $0 ~ /^$/ ) + if ( currentlevel != level ) + { + enum = 0 + return + } + $0 = "" + } + else if ( $0 ~ /^[\t ]*}[\t ]*;/ ) + { + # Shouldn't happen, but just in case. + popLevel( $0 ) + enum = 0 + return + } + } + enum = 0 +} + +# +# Trap the end of a abstract data type or enumerated type. +# Note: arrays are going to cause a problem here. e.g: +# +# int foo[] = +# { +# }; +# +# so this needs to be cleaned up a bit. +# +# /^[\t ]*}.*;[\t ]*/ { +# handleEndADT() +# } + +function handleEndADT() +{ + popLevel( $0 ) + # next + $0 = "" +} + +# +# Trap private, protected and public keywords in class, struct or union. +# +# ( name !~ "^$" ) && +# ( type !~ "enum" ) && +# /^[\t ]*private[\t ]*:[\t ]*(\/\/.*)?$/ { +# handlePrivate() +# } + +function handlePrivate() +{ +#if (accpriv == "on" ) + printf( "ACCESS\n%s\nprivate\n\n", name ) + hiding = "private" + # next + $0 = "" +} + +# ( name !~ "^$" ) && +# ( type !~ "enum" ) && +# /^[\t ]*protected[\t ]*:[\t ]*(\/\/.*)?$/ { +# handleProtected() +# } + +function handleProtected() +{ +#if (accprot == "on" ) + printf( "ACCESS\n%s\nprotected\n\n", name ) + hiding = "protected" + # next + $0 = "" +} + +# ( name !~ "^$" ) && +# ( type !~ "enum" ) && +# /^[\t ]*public[\t ]*:[\t ]*(\/\/.*)?$/ { +# handlePublic() +# } + +function handlePublic() +{ +#if (accpubl == "on" ) + printf( "ACCESS\n%s\npublic\n\n", name ) + hiding = "public" + # next + $0 = "" +} + +# +# Handle friend declaration. +# +function handleFriend( comment, line ) +{ + line = $0 + if ( $0 ~ /[,(][\t ]*(\/\/.*)?$/ ) + { + line = uncomment( line ) + line = handleArgs( line ) + } + if ( line !~ /;[\t ]*(\/\/.*)?$/ ) + { + line = uncomment( line ) + comment = handleInline() + line = line ";" + } + else + { + match( line, "//.*$" ) + comment = substr( line, RSTART, RLENGTH ) + } + gsub( "\t", " ", line ) + gsub( " +", " ", line ) + sub( "^ *", "", line ) + if ( name ~ "^$" ) + printf( "FRIEND\n%s\n%s\n%s\n", "::", "public", line ) + else + if ( hiding ~ "^$" ) + printf( "FRIEND\n%s\n%s\n%s\n", name, "public", line ) + else + printf( "FRIEND\n%s\n%s\n%s\n", name, hiding, line ) + $0 = outputComment( comment ) +} + +# +# Trap inline constructors with an initialiser list. +# +# ( name !~ "^$" ) && +# ( type !~ "enum" ) && +# /\)[\t ]*:[\t ]*.*\(.*\)[\t ]*({(.*})?[\t ]*)?(\/\/.*)?$/ { +# handleInlineCtor() +# } + +function handleInlineCtor() +{ + sub( "[\t ]*//.*", "", $0 ) + match( $0, ".*\\)[\t ]*:[\t ]*" ) + prototype = substr( $0, RSTART, RLENGTH ) + sub( "[\t ]*:[\t ]*$", "", prototype ) + outputFunction( prototype ) + if ( $0 !~ "}[\t ]*$" ) + { + $0 = handleInline() + if ( $0 ~ "^[\t ]*//.*$" ) + $0 = outputComment( $0 ) + } + else + $0 = outputComment( "" ) +} + +# +# Trap any inline functions, including constructors/destructors, with +# a complete prototype on the first line. +# +# ( name !~ "^$" ) && +# ( type !~ "enum" ) && +# /\)[\t ]*(const[\t ]*)?({(.*})?[\t ]*)?(\/\/.*)?$/ { +# handleInlineFunction() +# } + +function handleInlineFunction() +{ + sub( "[\t ]*//.*$", "", $0 ) + +# XXXX v1 match( $0, ".*\\)[\t ]*(const[\t ]*)?([^{]*{)?[\t ]*" ) +# XXXX v2 match( $0, ".*\\)[\t ]*(const)?([\t ]*\{)?[\t ]*" ) +# XXXX v2 prototype = substr( $0, RSTART, RLENGTH ) + + pos = index($0,"{") + if ( pos != 0 ) + prototype = substr( $0, 1, pos-1 ) + else + prototype = $0 + + sub( "[\t ]*\{[\t ]*$", "", prototype ) + outputFunction( prototype ) + if ( $0 !~ "}[\t ]*$" ) + { + savename = name + $0 = handleInline() + if ( $0 ~ "^[\t ]*//.*$" ) + $0 = outputComment( $0 ) + else + { + if ( savename == name ) + printf( "\n" ) + } + } + else + $0 = outputComment() +} + +# +# Trap normal Enum declaration. +# +# ( name !~ "^$" ) && +# ( type !~ "enum" ) && +# /\)[\t ]*(enum[\t ]*)?(=[\t ]*0[\t ]*)?,[\t ]*(\/\/.*)?$/ { +# handleenum() +# } + +function handleEnumFun() +{ + $0 = Set_c_Comment_to_CPP_Comment( $0) + match( $0, "//.*" ) + comment = substr( $0, RSTART, RLENGTH ) + $0 = uncomment( $0 ) + outputEnum( $0 ) + $0 = outputComment( comment ) +} + +# +# Trap normal function declaration. +# +# ( name !~ "^$" ) && +# ( type !~ "enum" ) && +# /\)[\t ]*(const[\t ]*)?(=[\t ]*0[\t ]*)?;[\t ]*(\/\/.*)?$/ { +# handleFunction() +# } + +function handleFunction() +{ + $0 = Set_c_Comment_to_CPP_Comment( $0) + match( $0, "//.*" ) + comment = substr( $0, RSTART, RLENGTH ) + $0 = uncomment( $0 ) + outputFunction( $0 ) + $0 = outputComment( comment ) +} + +# +# Trap member variables. +# +# ( name !~ "^$" ) && +# ( type !~ "enum" ) && +# /[\t ]*;[\t ]*(\/\/.*)?$/ { +# handleMember() +# } + +function handleMember() +{ + $0 = Set_c_Comment_to_CPP_Comment( $0) + match( $0, "//.*" ) + comment = substr( $0, RSTART, RLENGTH ) + sub( "[\t ]*//.*", "", $0 ) + outputMember( $0 ) + $0 = outputComment( comment ) +} + +function handleMember_orig() +{ + match( $0, "//.*" ) + comment = substr( $0, RSTART, RLENGTH ) + sub( "[\t ]*//.*", "", $0 ) + outputMember( $0 ) + $0 = outputComment( comment ) +} + +function handleMember_neu() +{ + match( $0, "/\\*.*\\*/" ) + comment = substr( $0, RSTART, RLENGTH ) + if ( length(comment) == 0 ) + { + match( $0, "//.*" ) + comment = substr( $0, RSTART, RLENGTH ) + } +# else +# sub( "[\t ]*//.*", "", $0 ) + $0 = uncomment( $0 ) + outputMember( $0 ) + $0 = outputComment( comment ) +} + +# +# Trap remainder of functions and constructors, where prototypes go +# over more than one line. +# +# ( name !~ "^$" ) && +# ( type !~ "enum" ) && +# /((\((.*,)?)|([_a-zA-Z0-9_]+))[\t ]*(\/\/.*)?$/ { +# handleMultilineEnums() +# } + +function handleMultilineEnums( prototype ) +{ + $0 = uncomment( $0 ) + prototype = handleEnumArgs( $0 ) + prototype = uncomment( prototype ) + sub( "\{.*}[\t ]*$", "", prototype ) + outputEnum( prototype ) + if ( prototype !~ ";[\t ]*" ) + { + savename = name + $0 = handleInline() + if ( line ~ "^[\t ]*//.*$" ) + $0 = outputComment( $0 ) + else + { + if ( savename == name ) + printf( "\n" ) + } + } + else + $0 = outputComment() +} + +# +# Trap remainder of functions and constructors, where prototypes go +# over more than one line. +# +# ( name !~ "^$" ) && +# ( type !~ "enum" ) && +# /((\((.*,)?)|([_a-zA-Z0-9_]+))[\t ]*(\/\/.*)?$/ { +# handleMultilineFunctions() +# } + +function handleMultilineFunctions( prototype ) +{ + $0 = uncomment( $0 ) + prototype = handleArgs( $0 ) + prototype = uncomment( prototype ) + sub( "\{.*}[\t ]*$", "", prototype ) + outputFunction( prototype ) + if ( prototype !~ ";[\t ]*" ) + { + savename = name + $0 = handleInline() + if ( line ~ "^[\t ]*//.*$" ) + $0 = outputComment( $0 ) + else + { + if ( savename == name ) + printf( "\n" ) + } + } + else + $0 = outputComment() +} + +# +# pushLevel() and popLevel() implement a stack for classes encountered. +# This is to handle class definitions local to classes. +# pushLevel() is invoked when entering a abstract data type, and +# popLevel() is executed when leaving. +# +function pushLevel() +{ + level++ + names[level] = name + types[level] = type + hidings[level] = hiding + topName = name + +# 3.11.95 evtl auskommentieren! + hiding = "" + + if ( class == 1 ) + { + type = "class" +# hiding = "private" + } + else if ( struct == 1 ) + { + type = "struct" +# hiding = "public" + } + else if ( union == 1 ) + { + type = "union" +# hiding = "public" + } + else if ( enum == 1 ) + type = "enum" +} + +function popLevel( line ) +{ + if ( name !~ "^$" ) + { + printf( "END\n%s\n\n", name ) + oldname = name + name = names[level] + type = types[level] + hiding = hidings[level] + level-- + topName = names[level] + if ( line ~ "^[\t ]*}.*[_a-zA-Z0-9]+.*;[\t ]*(//.*)?$" ) + { + line = uncomment( line ) + sub( "^[\t ]*}[\t ]*", "", line ) + if ( line ~ "^[_a-zA-Z0-9]+" ) + line = oldname " " line + else + line = oldname line + outputMember( line ) + return outputComment() + } + return "" + } +} + +# +# Removes comments from a line. +# +function uncomment( line ) +{ + sub( "/\\*.*\\*/", "", line ) + sub( "[\t ]*//.*$", "" , line ) + return line +} + +# +# Accumulates comment blocks and outputs them, followed by a blank line. +# +function outputComment( line ) +{ + if ( line !~ "^[\t ]*//" ) + getline line + + num = 0 + while ( line ~ "^[\t ]*//" ) + { + sub( "^[\t ]*//", "", line ) + if ( line ~ "^[\t ]*=(( [a-zA-Z0-9]+[^<>]*)|(=+))[\t ]*$" ) + break + else + lines[num++] = line + + getline line + } + indent = -1 + for ( i=0; i)?[\t ]*" ) + { + printf( "// %s\n", substr( lines[i], indent+1 ) ) + } + else + { + sub( "^[\t ]*", "", lines[i] ) + printf( "// %s\n", lines[i] ) + } + } + } + printf( "\n" ) + if ( line ~ "^[\t ]*}.*;[\t ]*$" ) + line = popLevel( line ) + + return line +} + +# +# Checks occurences of ADT and determines if they are in fact a definition +# or a declaration. If they are definition, it will generate any superclasses +# for the ADT. +# +function handleADT( line ) +{ + # + # Check for class declaration: + # class Foo; + # + if ( line ~ "[_a-zA-Z][ <,>_0-9a-zA-Z]*[\t ]*;" ) + { + # Do nothing, this is a declaration. + return 0 + } + # + # Check for derived classes: + # class Foo : Foobar + # + else if ( line ~ "[^:]:[^:]*" ) + { + pushLevel() + match( line, ".*[^:]:[^:]?" ) + name = substr( line, RSTART, RLENGTH-1 ) + sub( ":.*", "", name ) + sub( "[\t ]*$", "", name ) + if ( template == 1) + { + if ( name ~ "<.+>" ) + { + match( name, "<.+>" ) + args = substr( name, RSTART, RLENGTH ) + sub( "[\t ]*<.+>[\t ]*", "", name ) + } + } + match( line, ":.*" ) + bases = substr( line, RSTART, RLENGTH ) + sub( ":[\t ]*", "", bases ) + sub( "[\t ]*$", "", bases ) + if ( bases !~ ",$" && bases !~ "^$" ) + { + sub( "[\t ]*\{[\t ]*$", "", bases ) + } + else + { + while ( bases ~ ".*,[\t ]*$" || bases ~ "^$" ) + { + getline contbases + contbases = uncomment( contbases ) + while ( length( contbases ) == 0 ) + { + getline contbases + contbases = uncomment( contbases ) + } + bases = bases " " contbases + } + sub( "[\t ]*\{[\t ]*$", "", bases ) + } + } + # + # Check for non-derived classes: + # class Foo + # + # else if ( line ~ "[_a-zA-Z][ <>,_0-9a-zA-Z]*(<.+>)?[\t ]*\{*$" ) + else if ( line ~ "[_a-zA-Z][ <>,_0-9a-zA-Z]*(<.+>)?[\t ]*(\{[\t ]*)?$" ) + { + pushLevel() + if ( template == 1) + match( line, "[_a-zA-Z][_0-9a-zA-Z]*" ) + else + match( line, "[_a-zA-Z][ <>,_0-9a-zA-Z]*" ) + name = substr( line, RSTART, RLENGTH ) + sub( "[\t ]*$", "", name ) + if ( template == 1) + { + sub( "[_a-zA-Z][_0-9a-zA-Z]*", "", line ) + if ( line ~ "^<" ) + { + match( line, "<.+>" ) + args = substr( line, RSTART, RLENGTH ) + } + } + } + else + { + # Discard anything else. + return 0 + } + return 1 +} + +# +# Generates the actual list of superclasses. +# +function outputSuperClasses( line ) +{ + if ( line ~ /^[\t ]*$/ ) + printf( "\n" ) + else + { + gsub( "(\t| )+", " ", line ) + narg = 0 + while ( match( line, "[^<>,# ]*<[^<>]*>" ) ) + { + narg++ + arg = substr( line, RSTART, RLENGTH ) + sub( "[^<>,# ]*<[^<>]*>", "#" narg, line ) + bargs["#" narg] = arg + # Need the following to stop resubstitution of the pattern matched + # back into the string. + gsub( "&", "\\\\&", bargs["#" narg] ) + } + num = split( line, item, "," ) + i = 1 + while ( i<=num ) + { + access = "private" + inherit = "" + + if ( item[i] ~ "[\t ]*public[\t ]*" ) + { + access = "public" + sub( "[\t ]*public[\t ]*", "", item[i] ) + } + else if ( item[i] ~ "[\t ]*protected[\t ]*" ) + { + access = "protected" + sub( "[\t ]*protected[\t ]*", "", item[i] ) + } + sub( "[\t ]*private[\t ]*", "", item[i] ) + + if ( item[i] ~ "[\t ]*virtual[\t ]*" ) + { + inherit = " virtual" + sub( "[\t ]*virtual[\t ]*", "", item[i] ) + } + + while ( match( item[i], "#[0-9]+" ) ) + { + arg = substr( item[i], RSTART, RLENGTH ) + sub( arg, bargs[arg], item[i] ) + } + sub( "^[\t ]*", "", item[i] ) + sub( "[\t ]*$", "", item[i] ) + + printf( "%s%s %s\n", access, inherit, item[i] ) + + ++i + } + printf( "\n" ) + } +} + +# +# Outputs enum prototypes. +# +function outputEnum( line ) +{ + if ( line !~ ";[\t ]*$" ) + { + sub( "[\t ]*$", ";", line ) + if ( line !~ /^[\t ]*inline[\t ]+/ ) + sub( "^[\t ]*", "inline ", line ) + } + if ( ( type ~ "class" ) && ( hiding ~ "^$" ) ) + hide = "private" + else + hide = "public" + printf( "ENUM\n%s\n%s\n", name, hiding ~ "^$" ? hide : hiding ) + gsub( "\t", " ", line ) + gsub( " +", " ", line ) + sub( "^ *", "", line ) + sub( " *$", "", line ) + sub( "( ?;)*$", ";", line ) + printf( "%s\n", line ) +} + +# +# Outputs function prototypes. +# +function outputFunction( line ) +{ + if ( line !~ ";[\t ]*$" ) + { + sub( "[\t ]*$", ";", line ) + if ( line !~ /^[\t ]*inline[\t ]+/ ) + sub( "^[\t ]*", "inline ", line ) + } + if ( ( type ~ "class" ) && ( hiding ~ "^$" ) ) + hide = "private" + else + hide = "public" + printf( "FUNC\n%s\n%s\n", name, hiding ~ "^$" ? hide : hiding ) + gsub( "\t", " ", line ) + gsub( " +", " ", line ) + sub( "^ *", "", line ) + sub( " *$", "", line ) + sub( "( ?;)*$", ";", line ) + printf( "%s\n", line ) +} + +# +# Output member variables. +# +function outputMember( line ) +{ + if ( ( type ~ "class" ) && ( hiding ~ "^$" ) ) + hide = "private" + else + hide = "public" + printf( "MEMBER\n%s\n%s\n", name, hiding ~ "^$" ? hide : hiding ) + gsub( "\t", " ", line ) + gsub( " +", " ", line ) + sub( "^ *", "", line ) + sub( " *$", "", line ) + sub( "( ?;)*$", ";", line ) + printf( "%s\n", line ) +} + +# +# Output member variables. +# +function outputMemberEnum( line ) +{ + if ( ( type ~ "class" ) && ( hiding ~ "^$" ) ) + hide = "private" + else + hide = "public" + printf( "ENUM\n%s\n%s\n", name, hiding ~ "^$" ? hide : hiding ) + gsub( "\t", " ", line ) + gsub( " +", " ", line ) + sub( "^ *", "", line ) + sub( " *$", "", line ) + sub( "( ?;)*$", ";", line ) + printf( "%s\n", line ) +} + +# +# Gathers up argument lists which cover more than one line. +# +function handleArgs( prototype ) +{ + getline line + line = uncomment( line ) + sub( "^[\t ]*", "", line ) + sub( "[\t ]*$", "", line ) + + # 3.11.95 supress preproc in fuctions args + sub( "#.*$", "", line ) + + if ( ( prototype ~ "\\($" || line ~ "^\\(" || line ~ "^\\)" ) && \ + prototype !~ ",$" ) + prototype = prototype line + else + prototype = prototype " " line + while ( \ + ( prototype !~ "\\)[\t ]*(const[\t ]*)?((\{.*)|(//.*))?$" ) \ + && \ + ( prototype !~ "\\)[\t ]*(const[\t ]*)?(=[\t ]*0[\t ]*)?;[\t ]*(//.*)?$" ) \ + && \ + ( prototype !~ "\\)[\t ]*:.*$" ) \ + ) + { + getline line + line = uncomment( line ) + sub( "^[\t ]*", "", line ) + sub( "[\t ]*$", "", line ) + + # 3.11.95 supress preproc in fuctions args + sub( "#.*$", "", line ) + + if ( ( prototype ~ "\\($" || line ~ "^\\(" || line ~ "^\\)" ) && \ + prototype !~ ",$" ) + prototype = prototype line + else + prototype = prototype " " line + } + if ( prototype ~ "\\)[\t ]*:.*$" ) + sub( "\\)[\t ]*:.*$", ")", prototype ) + else if ( prototype ~ "\\)[\t ]*\{.*$" ) + sub( "\\)[\t ]*\{.*$", ")", prototype ) + return prototype +} + +# +# Gathers up enum argument lists which cover more than one line. +# +function handleEnumArgs( prototype ) +{ + getline line + line = uncomment( line ) + sub( "^[\t ]*", "", line ) + sub( "[\t ]*$", "", line ) + if ( ( prototype ~ "\\{$" || line ~ "^\\{" || line ~ "^\\}" ) && \ + prototype !~ ",$" ) + prototype = prototype line + else + prototype = prototype " " line + while ( \ + ( prototype !~ "\\}[\t ]*(const[\t ]*)?((\{.*)|(//.*))?$" ) \ + && \ + ( prototype !~ "\\}[\t ]*(const[\t ]*)?(=[\t ]*0[\t ]*)?;[\t ]*(//.*)?$" ) \ + && \ + ( prototype !~ "\\}[\t ]*:.*$" ) \ + ) + { + getline line + line = uncomment( line ) + sub( "^[\t ]*", "", line ) + sub( "[\t ]*$", "", line ) + if ( ( prototype ~ "\\($" || line ~ "^\\(" || line ~ "^\\)" ) && \ + prototype !~ ",$" ) + prototype = prototype line + else + prototype = prototype " " line + } + if ( prototype ~ "\\}[\t ]*:.*$" ) + sub( "\\}[\t ]*:.*$", "}", prototype ) + else if ( prototype ~ "\\}[\t ]*\{.*$" ) + sub( "\\}[\t ]*\{.*$", "}", prototype ) + return prototype +} + +# +# Skips inline code. End of such code is determined when either a blank line, +# comment, or end of ADT is encountered. +# +function handleInline() +{ + getline line + while (line !~ "^[\t ]*(}.*;[\t ]*)?(//.*)?$" ) + getline line + + if ( line ~ "[\t ]*}[\t ]*[_a-zA-Z0-9]*[\t ]*;[\t ]*$" ) + { + printf( "\n" ) + popLevel( line ) + } + + if ( line ~ "^[\t ]*//.*" ) + return line + else + return "" +} + +# +# The main parsing loop. +# This implements a recursive descent parser of sorts. +# +function doParse() +{ + while ( $0 !~ "^$" ) + { + if ( $0 ~ /^[\t ]*template[\t ]*<[^:]+>[\t ]*$/ ) + { + getline line + $0 = $0 " " line + } + + if ( $0 ~ /^[\t ]*\/\/[\t ]*==+[\t ]*$/ ) + { + handleHeader() + } + else if ( $0 ~ /^[\t ]*\/\/[\t ]*= [a-zA-Z0-9]+[^<>]*[\t ]*$/ ) + { + handleInfo() + } + else if ( $0 ~ /^[\t ]*\/\/.*$/ ) + { + handleComment() + } + else if ( $0 ~ /^[\t ]*#[\t ]*define/ ) + { + handleDefine() + } + else if ( $0 ~ /^[\t ]*#[\t ]*include[\t ]*<.+>/ ) + { + handleInclude() + } + else if ( $0 ~ /^[\t ]*#[\t ]*include[\t ]*".+"/ ) + { + handleLocalInclude() + } + else if ( $0 ~ /^[\t ]*#.*$/ ) + { + handlePreprocessor() + } + else if ( $0 ~ /^[\t ]*typedef[\t ]+/ ) + { + handleTypedef() + } + else if ( $0 ~ /^extern[\t ]+/ ) + { + handleExtern() + } + else if ( $0 ~ /^[\t ]*class[\t ]/ ) + { + handleClass() + } + else if ( $0 ~ /^[\t ]*struct[\t ]/ ) + { + handleStruct() + } + else if ( $0 ~ /^[\t ]*union[\t ]/ ) + { + handleUnion() + } + else if ( $0 ~ /^[\t ]*template[\t ]*<.+>[\t ]+class[\t ]/ ) + { + handleTemplate() + } + else if ( $0 ~ /^[\t ]*enum[\t ]*.*;[\t ]*(\/\/.*)?$/ ) + { +#printf("\ntype=%s-------single------\n",type); + handleEnumFun() + } + else if ( ($0 ~ /((\((.*,)?)|([_a-zA-Z0-9_]+))[\t ]*(\/\/.*)?$/) && ( name !~ "^$" ) && ( $0 ~ /^[\t ]*enum/ ) ) + { +#printf("\ntype=%s-------multi------\n",type); + handleMultilineEnums() + } + else if ( $0 ~ /^[\t ]*}.*;[\t ]*/ ) + { + handleEndADT() + } + else if ( ( name !~ "^$" ) && ( type !~ "enum" ) ) + { + if ( $0 ~ /^[\t ]*private[\t ]*:[\t ]*(\/\/.*)?$/ ) + { + handlePrivate() + } + else if ( $0 ~ /^[\t ]*protected[\t ]*:[\t ]*(\/\/.*)?$/ ) + { + handleProtected() + } + else if ( $0 ~ /^[\t ]*public[\t ]*:[\t ]*(\/\/.*)?$/ ) + { + handlePublic() + } + else if ( $0 ~ /^[\t ]*friend[\t ]+/ ) + { + handleFriend() + } + else if ( $0 ~ /\)[\t ]*:[\t ]*.*\(.*\)[\t ]*(\{(.*})?[\t ]*)(\/\/.*)?$/ ) + { + handleInlineCtor() + } + else if ( $0 ~ /\)[\t ]*(const[\t ]*)?(\{(.*})?[\t ]*)?(\/\/.*)?$/ && + $0 !~ /^.*operator[\t ]*\(\)[\t ]*(\/\/.*)?$/ ) + { + handleInlineFunction() + } + else if ( $0 ~ /\)[\t ]*(const[\t ]*)?(=[\t ]*0[\t ]*)?;?[\t ]*(\/\/.*)?$/ && + $0 !~ /^.*operator[\t ]*\(\)[\t ]*(\/\/.*)?$/ ) + { + handleFunction() + } + else if ( $0 ~ /[\t ]*;[\t ]*(\/\/.*)?(\/\\*.*\\*\/)?$/ ) + { + handleMember() + } + else if ( $0 ~ /((\((.*,)?)|([_a-zA-Z0-9_>)]+[*&]?))[\t ]*(\/\/.*)?$/ ) + { + handleMultilineFunctions() + } + else + $0 = "" + } + else + $0 = "" + } +} diff --git a/bin/class2man b/bin/class2man new file mode 100755 index 00000000000..dd18b742712 --- /dev/null +++ b/bin/class2man @@ -0,0 +1,78 @@ +#! /bin/sh +# ============================================================================= +# +# = DESCRIPTION +# Script to combine class2info and info2man. +# +# = AUTHOR(S) +# Graham Dumpleton +# +# = COPYRIGHT +# Copyright 1991 OTC LIMITED +# +# ============================================================================= + +OSE_HOST= + +OSE_RELEASE_NAME= +export OSE_RELEASE_NAME + +OSE_ROOT=${OSE_ROOT-$WRAPPER_ROOT} +export OSE_ROOT + +OSE_VERSION_ROOT=$OSE_ROOT/$OSE_RELEASE_NAME +export OSE_VERSION_ROOT + +BINDIR="$OSE_VERSION_ROOT/$OSE_HOST/bin" +LIBDIR=${CLASSINFOLIBDIR-"$OSE_VERSION_ROOT/lib"} + +CLASS2INFO="$BINDIR/class2info" +INFO2MAN="$BINDIR/info2man" + +# +# Error. +# +ERROR() +{ + echo "`basename $0`: $1" >&2 + shift + while test $# != "0" + do + echo $1 >&2 + shift + done + exit 1 +} + +# +# Usage message. +# +USAGE() +{ + ERROR "Usage: `basename $0` files" +} + +# +# Check usage. +# +if test "$#" = "0" +then + USAGE +fi + +while test "$#" != "0" +do + $CLASS2INFO $1 + if test "$?" != "0" + then + exit 1 + fi + file=`basename $1` + base="`echo $file | sed -e 's/\..*$//'`" + if test -f "$base.ci" + then + $INFO2MAN $base.ci + rm -f $base.ci + fi + shift +done diff --git a/bin/class2mml b/bin/class2mml new file mode 100755 index 00000000000..20453e0010b --- /dev/null +++ b/bin/class2mml @@ -0,0 +1,79 @@ +#! /bin/sh +# ============================================================================= +# +# = DESCRIPTION +# Script to combine class2info and info2mml. +# +# = AUTHOR(S) +# Graham Dumpleton +# +# = COPYRIGHT +# Copyright 1991 OTC LIMITED +# Copyright 1994 DUMPLETON SOFTWARE CONSULTING PTY LIMITED +# +# ============================================================================= + +OSE_HOST= + +OSE_RELEASE_NAME= +export OSE_RELEASE_NAME + +OSE_ROOT=${OSE_ROOT-$WRAPPER_ROOT} +export OSE_ROOT + +OSE_VERSION_ROOT=$OSE_ROOT/$OSE_RELEASE_NAME +export OSE_VERSION_ROOT + +BINDIR="$OSE_VERSION_ROOT/$OSE_HOST/bin" +LIBDIR=${CLASSINFOLIBDIR-"$OSE_VERSION_ROOT/lib"} + +CLASS2INFO="$BINDIR/class2info" +INFO2MAN="$BINDIR/info2mml" + +# +# Error. +# +ERROR() +{ + echo "`basename $0`: $1" >&2 + shift + while test $# != "0" + do + echo $1 >&2 + shift + done + exit 1 +} + +# +# Usage message. +# +USAGE() +{ + ERROR "Usage: `basename $0` files" +} + +# +# Check usage. +# +if test "$#" = "0" +then + USAGE +fi + +while test "$#" != "0" +do + $CLASS2INFO $1 + if test "$?" != "0" + then + exit 1 + fi + file=`basename $1` + base="`echo $file | sed -e 's/\..*$//'`" + if test -f "$base.ci" + then + $INFO2MAN $base.ci + rm -f $base.ci + fi + shift +done diff --git a/bin/class2src b/bin/class2src new file mode 100755 index 00000000000..9feb23fe857 --- /dev/null +++ b/bin/class2src @@ -0,0 +1,79 @@ +#! /bin/sh +# ============================================================================= +# +# = DESCRIPTION +# Generates member function stubs for the src file to standard output. +# +# = AUTHOR(S) +# Graham Dumpleton +# K. Dorn +# +# = COPYRIGHT +# Copyright 1991 OTC LIMITED +# +# ============================================================================= + +OSE_HOST= + +OSE_RELEASE_NAME= +export OSE_RELEASE_NAME + +OSE_ROOT=${OSE_ROOT-$WRAPPER_ROOT} +export OSE_ROOT + +OSE_VERSION_ROOT=$OSE_ROOT/$OSE_RELEASE_NAME +export OSE_VERSION_ROOT + +BINDIR="$OSE_VERSION_ROOT/$OSE_HOST/bin" +LIBDIR=${CLASSINFOLIBDIR-"$OSE_VERSION_ROOT/lib"} + +CLASS2INFO="$BINDIR/class2info" +INFO2SRC="$BINDIR/info2src" + +# +# Error. +# +ERROR() +{ + echo "`basename $0`: $1" >&2 + shift + while test $# != "0" + do + echo $1 >&2 + shift + done + exit 1 +} + +# +# Usage message. +# +USAGE() +{ + ERROR "Usage: `basename $0` files" +} + +# +# Check usage. +# +if test "$#" = "0" +then + USAGE +fi + +while test "$#" != "0" +do + $CLASS2INFO $1 + if test "$?" != "0" + then + exit 1 + fi + file=`basename $1` + base="`echo $file | sed -e 's/\..*$//'`" + if test -f "$base.ci" + then + $INFO2SRC $base.ci $2 $3 $4 + rm -f $base.ci + fi + shift +done diff --git a/bin/classinfo.ps b/bin/classinfo.ps new file mode 100755 index 00000000000..950535ed86e --- /dev/null +++ b/bin/classinfo.ps @@ -0,0 +1,868 @@ +%!PS-Adobe-3.0 +%%BoundingBox: 54 72 558 720 +%%Creator: Mozilla (NetScape) HTML->PS +%%DocumentData: Clean7Bit +%%Orientation: Portrait +%%Pages: 9 +%%PageOrder: Ascend +%%Title: Classinfo Tools +%%EndComments +%%BeginProlog +[ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash /zero /one + /two /three /four /five /six /seven /eight /nine /colon /semicolon + /less /equal /greater /question /at /A /B /C /D /E + /F /G /H /I /J /K /L /M /N /O + /P /Q /R /S /T /U /V /W /X /Y + /Z /bracketleft /backslash /bracketright /asciicircum /underscore /quoteleft /a /b /c + /d /e /f /g /h /i /j /k /l /m + /n /o /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /space /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright + /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf + /threequarters /questiondown /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde + /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring + /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis + /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave + /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis] /isolatin1encoding exch def +/c { matrix currentmatrix currentpoint translate + 3 1 roll scale newpath 0 0 1 0 360 arc setmatrix } bind def +/F0 + /Times-Roman findfont + dup length dict begin + {1 index /FID ne {def} {pop pop} ifelse} forall + /Encoding isolatin1encoding def + currentdict end +definefont pop +/f0 { /F0 findfont exch scalefont setfont } bind def +/F1 + /Times-Bold findfont + dup length dict begin + {1 index /FID ne {def} {pop pop} ifelse} forall + /Encoding isolatin1encoding def + currentdict end +definefont pop +/f1 { /F1 findfont exch scalefont setfont } bind def +/F2 + /Times-Italic findfont + dup length dict begin + {1 index /FID ne {def} {pop pop} ifelse} forall + /Encoding isolatin1encoding def + currentdict end +definefont pop +/f2 { /F2 findfont exch scalefont setfont } bind def +/F3 + /Times-BoldItalic findfont + dup length dict begin + {1 index /FID ne {def} {pop pop} ifelse} forall + /Encoding isolatin1encoding def + currentdict end +definefont pop +/f3 { /F3 findfont exch scalefont setfont } bind def +/F4 + /Courier findfont + dup length dict begin + {1 index /FID ne {def} {pop pop} ifelse} forall + /Encoding isolatin1encoding def + currentdict end +definefont pop +/f4 { /F4 findfont exch scalefont setfont } bind def +/F5 + /Courier-Bold findfont + dup length dict begin + {1 index /FID ne {def} {pop pop} ifelse} forall + /Encoding isolatin1encoding def + currentdict end +definefont pop +/f5 { /F5 findfont exch scalefont setfont } bind def +/F6 + /Courier-Oblique findfont + dup length dict begin + {1 index /FID ne {def} {pop pop} ifelse} forall + /Encoding isolatin1encoding def + currentdict end +definefont pop +/f6 { /F6 findfont exch scalefont setfont } bind def +/F7 + /Courier-BoldOblique findfont + dup length dict begin + {1 index /FID ne {def} {pop pop} ifelse} forall + /Encoding isolatin1encoding def + currentdict end +definefont pop +/f7 { /F7 findfont exch scalefont setfont } bind def +/rhc { + { + currentfile read { + dup 97 ge + { 87 sub true exit } + { dup 48 ge { 48 sub true exit } { pop } ifelse } + ifelse + } { + false + exit + } ifelse + } loop +} bind def + +/cvgray { % xtra_char npix cvgray - (string npix long) + dup string + 0 + { + rhc { cvr 4.784 mul } { exit } ifelse + rhc { cvr 9.392 mul } { exit } ifelse + rhc { cvr 1.824 mul } { exit } ifelse + add add cvi 3 copy put pop + 1 add + dup 3 index ge { exit } if + } loop + pop + 3 -1 roll 0 ne { rhc { pop } if } if + exch pop +} bind def + +/smartimage12rgb { % w h b [matrix] smartimage12rgb - + /colorimage where { + pop + { currentfile rowdata readhexstring pop } + false 3 + colorimage + } { + exch pop 8 exch + 3 index 12 mul 8 mod 0 ne { 1 } { 0 } ifelse + 4 index + 6 2 roll + { 2 copy cvgray } + image + pop pop + } ifelse +} def +/cshow { dup stringwidth pop 2 div neg 0 rmoveto show } bind def +/rshow { dup stringwidth pop neg 0 rmoveto show } bind def +%%EndProlog +%%Page: 1 1 +%%BeginPageSetup +/pagelevel save def +54 0 translate +%%EndPageSetup +newpath 0 72 moveto 504 0 rlineto 0 648 rlineto -504 0 rlineto closepath clip newpath +24 f1 0 697.5 moveto +(OSE - Tools User Guide) show +12 f2 0 668.5 moveto +(Graham Dumpleton) show +12 f2 0 655.4 moveto +(Dumpleton Software Consulting Pty Limited) show +12 f2 0 642.3 moveto +(PO BOX 3150) show +12 f2 0 629.2 moveto +(Parramatta, 2124) show +12 f2 0.2 616.1 moveto +(N.S.W, Australia) show +12 f2 0 603 moveto +(email: grahamd@nms.otc.com.au) show +0 593.9 moveto +504 0 rlineto 0 -1.4 rlineto -504 0 rlineto closepath fill +18 f1 0 557.2 moveto +(Table of Contents) show +12 f1 0 528.8 moveto +(Classinfo Tools) show +12 f0 78.3 528.8 moveto +( ) show +12 f1 28 501.7 moveto +(1 Available Programs) show +12 f0 139.3 501.7 moveto +( ) show +12 f1 28 487.9 moveto +(2 Global Sections) show +12 f0 116.6 487.9 moveto +( ) show +12 f1 28 474.1 moveto +(3 Block Formatting) show +12 f0 127.9 474.1 moveto +( ) show +12 f1 28 460.3 moveto +(4 Inline Formatting) show +12 f0 128.6 460.3 moveto +( ) show +12 f1 28 446.5 moveto +(5 Class Sections) show +12 f0 109.3 446.5 moveto +( ) show +12 f1 28 432.7 moveto +(6 Member Documentation) show +12 f0 162.6 432.7 moveto +( ) show +12 f1 28 418.9 moveto +(7 Contract Section) show +12 f0 123.3 418.9 moveto +( ) show +0 396.5 moveto +504 0 rlineto 0 -1.4 rlineto -504 0 rlineto closepath fill +24 f1 0 354 moveto +(Classinfo Tools) show +18 f1 0 318.7 moveto +(1 Available Programs) show +12 f0 0 290.8 moveto +(The documentation tools provided with the OSE build environment, allow comments in your code files,) show +12 f0 0 277.5 moveto +(to be extracted and formatted into end user documentation. To enable the tools to do this in a predictable) show +12 f0 0 264.2 moveto +(manner, the comments must be formatted according to a small set of rules. At present, the tools can) show +12 f0 0 250.9 moveto +(extract comments from C++ class header files and produce either UNIX style manual pages, of Frame) show +12 f0 0 237.6 moveto +(mml files. The tools provided are described below.) show +10 f4 0 213.7 moveto +(-------------------------------------------------------------------------------) show +10 f5 0 203.2 moveto +(Program) show +10 f4 42.2 203.2 moveto +( ) show +10 f5 72.2 203.2 moveto +(Purpose) show +10 f4 114.2 203.2 moveto +( ) show +10 f4 0 192.7 moveto +(-------------------------------------------------------------------------------) show +10 f4 0 182.2 moveto +(class2info Parses a C++ header file and produces a file which contains infor ) show +10 f4 0 171.7 moveto +( mation about the class in the header file, in a form which is more ) show +10 f4 0 161.2 moveto +( easily parsed by other tools. ) show +10 f4 0 150.7 moveto +(info2man Takes the output file from class2info and produces a UNIX ) show +10 f4 0 140.2 moveto +( style manual page for each class described in the input file. ) show +10 f4 0 129.7 moveto +(class2man Combines the programs class2info and info2man, to pro ) show +10 f4 0 119.2 moveto +( duce a UNIX style manual page for each class declaration in a ) show +10 f4 0 108.7 moveto +( header file. ) show +10 f4 0 98.2 moveto +(info2mml Takes the output file from class2info and produces a Frame ) show +10 f4 0 87.7 moveto +( mml file for each class described in the inout file. ) show +10 f4 0 77.2 moveto +(class2mml Combines the programs class2info and info2mml, to pro ) show +pagelevel restore +showpage +%%Page: 2 2 +%%BeginPageSetup +/pagelevel save def +54 0 translate +%%EndPageSetup +newpath 0 72 moveto 504 0 rlineto 0 648 rlineto -504 0 rlineto closepath clip newpath +10 f4 0 711.9 moveto +( duce a Frame mml file for each class declaration in a header file. ) show +10 f4 0 701.4 moveto +(-------------------------------------------------------------------------------) show +12 f0 0 677.7 moveto +(Using the same front end parser as the documentation extraction tools, are the following tools:) show +10 f4 0 653.8 moveto +(----------------------------------------------------------------------------) show +10 f5 0 643.3 moveto +(Program) show +10 f4 42.2 643.3 moveto +( ) show +10 f5 66.2 643.3 moveto +(Purpose) show +10 f4 108.2 643.3 moveto +( ) show +10 f4 0 632.8 moveto +(----------------------------------------------------------------------------) show +10 f4 0 622.3 moveto +(info2src Takes the output file from class2info and produces on stan ) show +10 f4 0 611.8 moveto +( dard output, empty stub functions for each of the member func ) show +10 f4 0 601.3 moveto +( tions listed in the class declarations described in the file. ) show +10 f4 0 590.8 moveto +(class2src Combines the programs class2info and info2src, to pro ) show +10 f4 0 580.3 moveto +( duce on standard output, empty stub functions for each of the ) show +10 f4 0 569.8 moveto +( member functions listed in the class declarations described in a ) show +10 f4 0 559.3 moveto +( header file. ) show +10 f4 0 548.8 moveto +(----------------------------------------------------------------------------) show +12 f0 0 525.1 moveto +(These use information contained in a C++ class header file, to produce code stubs suitable for the) show +12 f0 0 511.8 moveto +(corresponding implementation file for that class.) show +12 f0 0 485.2 moveto +(The format which C++ class header files must adhere to is the subject of the remainder of this document.) show +18 f1 0 452.5 moveto +(2 Global Sections) show +12 f0 0 424.6 moveto +(To include a section in the manual page of each class in a header file, the comment containing the body) show +12 f0 0 411.3 moveto +(text of the section, must appear at global scope within the header file. The title of the section must) show +12 f0 0 398 moveto +(appear on a separate line, immediately prior to the body text of the section. To distinguish the title of the) show +12 f0 0 384.7 moveto +(section from the body text, you must precede it with a tag, consisting of the character `='. There must be) show +12 f0 0 371.4 moveto +(a single space only, before and after the tag. For example:) show +10 f4 0 347.5 moveto +( // = SECTION TITLE) show +10 f4 0 326.5 moveto +( // Body text.) show +12 f0 0 302.8 moveto +(Any text following the title of the section, up till the end of the comment, the start of another section, or) show +12 f0 0 289.5 moveto +(a line commencing with `==', is interpreted to be the body text for that section. Multiple sections may be) show +12 f0 0 276.2 moveto +(documented in a single comment block. Any leading, or trailing blank lines will be discarded in the) show +12 f0 0 262.9 moveto +(output. An example of a comment block containing multiple sections is given below.) show +10 f4 0 239 moveto +( // =====================================================) show +10 f4 0 218 moveto +( //) show +10 f4 0 197 moveto +( // = SECTION TITLE1) show +10 f4 0 176 moveto +( // Body text.) show +10 f4 0 155 moveto +( //) show +10 f4 0 134 moveto +( // = SECTION TITLE2) show +10 f4 0 113 moveto +( // Body text.) show +10 f4 0 92 moveto +( //) show +pagelevel restore +showpage +%%Page: 3 3 +%%BeginPageSetup +/pagelevel save def +54 0 translate +%%EndPageSetup +newpath 0 72 moveto 504 0 rlineto 0 648 rlineto -504 0 rlineto closepath clip newpath +10 f4 0 711.9 moveto +( // =====================================================) show +12 f0 0 688.2 moveto +(Certain sections, appearing at global scope, are given special treatment in the generated manual pages.) show +12 f0 0 674.9 moveto +(These are:) show +10 f4 0 651 moveto +(-------------------------------------------------------------------------------) show +10 f5 0 640.5 moveto +(Section) show +10 f4 42 640.5 moveto +( ) show +10 f5 90 640.5 moveto +(Description) show +10 f4 156 640.5 moveto +( ) show +10 f4 0 630 moveto +(-------------------------------------------------------------------------------) show +10 f4 0 619.5 moveto +(LIBRARY The name of the library, of which the file is a part. This will ) show +10 f4 0 609 moveto +( appear in the header of each manual page. ) show +10 f4 0 598.5 moveto +(FILENAME The name of the file. This will be used in conjunction with ) show +10 f4 0 588 moveto +( the library name, to produce an include line in the synopsis. ) show +10 f4 0 577.5 moveto +(AUTHOR\(S\) The names of the authors. If the authors are placed on sepa ) show +10 f4 0 567 moveto +( rate lines, commas should not be used to terminate each line. ) show +10 f4 0 556.5 moveto +( If more than one author is placed on a single line, a comma ) show +10 f4 0 546 moveto +( should be used to separate each. ) show +10 f4 0 535.5 moveto +(COPYRIGHT The copyright applying to the contents of the file. ) show +10 f4 0 525 moveto +(VERSION The version number of the file. If using RCS, this would be ) show +10 f4 0 514.5 moveto +( set to `$Revision$'. ) show +10 f4 0 504 moveto +(DATE RELEASED The date that the current version of the file was released. If ) show +10 f4 0 493.5 moveto +( using RCS, this would be set to `$Date$'. ) show +10 f4 0 483 moveto +(RCSID The raw ID produced by RCS. Normally set to `$Id$'. ) show +10 f4 0 472.5 moveto +(SCCSID The raw ID produced by SCCS. Normally set to `%W%'. ) show +10 f4 0 462 moveto +(-------------------------------------------------------------------------------) show +12 f0 0 438.3 moveto +(Using these tags, you can construct a comment block at the start of each file, which describes the file,) show +12 f0 0 425 moveto +(authors and version of the file. For example:) show +10 f4 0 401.1 moveto +( /*) show +10 f4 0 380.1 moveto +( // ========================================================) show +10 f4 0 359.1 moveto +( //) show +10 f4 0 338.1 moveto +( // = LIBRARY) show +10 f4 0 317.1 moveto +( // OTC) show +10 f4 0 296.1 moveto +( //) show +10 f4 0 275.1 moveto +( // = FILENAME) show +10 f4 0 254.1 moveto +( // collctn/list.hh) show +10 f4 0 233.1 moveto +( //) show +10 f4 0 212.1 moveto +( // = RCSID) show +10 f4 0 191.1 moveto +( // $Id$) show +10 f4 0 170.1 moveto +( //) show +10 f4 0 149.1 moveto +( // = AUTHOR\(S\)) show +10 f4 0 128.1 moveto +( // Graham Dumpleton) show +10 f4 0 107.1 moveto +( //) show +10 f4 0 86.1 moveto +( // = COPYRIGHT) show +pagelevel restore +showpage +%%Page: 4 4 +%%BeginPageSetup +/pagelevel save def +54 0 translate +%%EndPageSetup +newpath 0 72 moveto 504 0 rlineto 0 648 rlineto -504 0 rlineto closepath clip newpath +10 f4 0 711.9 moveto +( // Copyright 1991 1992 1993 OTC LIMITED) show +10 f4 0 690.9 moveto +( //) show +10 f4 0 669.9 moveto +( // =====================================================) show +10 f4 0 648.9 moveto +( */) show +18 f1 0 619.1 moveto +(3 Block Formatting) show +12 f0 0 591.2 moveto +(When the text of your comments appear in the manual page, they will be reformatted. If you need to) show +12 f0 0 577.9 moveto +(include an excerpt of code in the manual page, for example:) show +10 f4 0 554 moveto +( // = EXAMPLE) show +10 f4 0 533 moveto +( // void dump\(Class* theClass\)) show +10 f4 0 512 moveto +( // {) show +10 f4 0 491 moveto +( // cout << theClass->name\(\) << endl;) show +10 f4 0 470 moveto +( // }) show +12 f0 0 446.3 moveto +(it will appear as:) show +10 f4 0 422.4 moveto +( void dump\(Class* theClass\) { cout << *theClass << endl; }) show +12 f0 0 398.7 moveto +(If the example is complicated, the result will be unreadable.) show +12 f0 0 372.1 moveto +(To let the documentation tools know that the text you have included is special and should not be) show +12 f0 0 358.8 moveto +(reformatted, you can mark it as being a code example. For example:) show +10 f4 0 334.9 moveto +( // = EXAMPLE) show +10 f4 0 313.9 moveto +( // = BEGIN) show +10 f4 0 292.9 moveto +( // void dump\(Class* theClass\)) show +10 f4 0 271.9 moveto +( // {) show +10 f4 0 250.9 moveto +( // cout << *theClass << endl;) show +10 f4 0 229.9 moveto +( // }) show +10 f4 0 208.9 moveto +( // = END) show +12 f0 0 185.2 moveto +(The commands in this example are, `BEGIN'and `END'. In all cases, the format of) show +12 f0 0 171.9 moveto +(commands used to change the formatting of a block of text is:) show +10 f4 0 148 moveto +( // = BEGIN) show +10 f4 0 127 moveto +( // ....) show +10 f4 0 106 moveto +( // = END) show +12 f0 0 82.3 moveto +(The `BEGIN' for a command, must always have a matching `END'. The commands which are currently) show +pagelevel restore +showpage +%%Page: 5 5 +%%BeginPageSetup +/pagelevel save def +54 0 translate +%%EndPageSetup +newpath 0 72 moveto 504 0 rlineto 0 648 rlineto -504 0 rlineto closepath clip newpath +12 f0 0 709.2 moveto +(understood by the documentation tools are:) show +10 f4 0 685.3 moveto +(--------------------------------------------------------------------) show +10 f5 0 674.8 moveto +(Command) show +10 f4 42 674.8 moveto +( ) show +10 f5 54 674.8 moveto +(Description) show +10 f4 120 674.8 moveto +( ) show +10 f4 0 664.3 moveto +(--------------------------------------------------------------------) show +10 f4 0 653.8 moveto +(INDENT Text will be indented with respect to the surrounding text. ) show +10 f4 0 643.3 moveto +(NOFILL Text will be output with indentation and formatting as it ) show +10 f4 0 632.8 moveto +( appears. ) show +10 f4 0 622.3 moveto +(CODE Text is output in `NOFILL' mode using a fixed width font. ) show +10 f4 0 611.8 moveto +(COMMENT Text will not be output. This command would be used to sur ) show +10 f4 0 601.3 moveto +( round comments about the implementation, which should not ) show +10 f4 0 590.8 moveto +( appear in the user documentation. ) show +10 f4 0 580.3 moveto +(--------------------------------------------------------------------) show +12 f0 0 556.6 moveto +(Commands may be nested, with the exception that no commands should be nested within a `CODE') show +12 f0 0 543.3 moveto +(block.) show +18 f1 0 510.6 moveto +(4 Inline Formatting) show +12 f0 0 482.7 moveto +(As well as changing the formatting of a block of text, you can change the font style used. This is done) show +12 f0 0 469.4 moveto +(by placing special sequences of characters in the body of the text. Inline formatting commands come in) show +12 f0 0 456.1 moveto +(the following three forms:) show +10 f4 0 432.2 moveto +(----------------------------------------------------------------------------------) show +10 f5 0 421.7 moveto +(Command) show +10 f4 42 421.7 moveto +( ) show +10 f5 96 421.7 moveto +(Description) show +10 f4 162 421.7 moveto +( ) show +10 f4 0 411.2 moveto +(----------------------------------------------------------------------------------) show +10 f4 0 400.7 moveto +( Text between `<` and `>', is displayed in a fixed with font. ) show +10 f4 0 390.2 moveto +(<{text}> Text between `<{` and `}>', is displayed in an italic font. ) show +10 f4 0 379.7 moveto +(<[text]> Text between `<[` and `]>', is displayed in a bold font. ) show +10 f4 0 369.2 moveto +(----------------------------------------------------------------------------------) show +12 f0 0 345.5 moveto +(`' should be used for all C++ keywords, function names, variable names, class names, expressions) show +12 f0 0 332.2 moveto +(etc. The others can be used to highlight text. An example of how inline formatting commands may be) show +12 f0 0 318.9 moveto +(used, follows:) show +10 f4 0 295 moveto +( // = ASSERTIONS) show +10 f4 0 274 moveto +( // Assertion checks can be placed into code using) show +10 f4 0 253 moveto +( // the macro. Note that you should) show +10 f4 0 232 moveto +( // <[NOT]> use an expression in the condition check,) show +10 f4 0 211 moveto +( // which has a side effect, the result of which is) show +10 f4 0 190 moveto +( // necessary for the correct operation of the) show +10 f4 0 169 moveto +( // program. The reason for this, is that assertions) show +10 f4 0 148 moveto +( // can be compiled out of your code by defining the) show +10 f4 0 127 moveto +( // symbol.) show +12 f0 0 103.3 moveto +(Since `<`, and `>' are special characters, you must prefix them with a `\\' if the actual character needs to) show +12 f0 0 90 moveto +(printed. For example:) show +pagelevel restore +showpage +%%Page: 6 6 +%%BeginPageSetup +/pagelevel save def +54 0 translate +%%EndPageSetup +newpath 0 72 moveto 504 0 rlineto 0 648 rlineto -504 0 rlineto closepath clip newpath +10 f4 0 711.9 moveto +( ) show +12 f0 0 688.2 moveto +(If `{`, `}', `[` or `]' appear adjacent to either `<` or `>' in the forms described above, they will also need) show +12 f0 0 674.9 moveto +(to be prefixed with a `\\'. For example:) show +10 f4 0 651 moveto +( <\\[A-Za-z_]*>) show +18 f1 0 621.2 moveto +(5 Class Sections) show +12 f0 0 593.3 moveto +(Sections pertaining to a class, are placed in the class declaration before the initial opening brace. For) show +12 f0 0 580 moveto +(example:) show +10 f4 0 556.1 moveto +( template) show +10 f4 0 535.1 moveto +( class OTC_List : public OTC_Collection) show +10 f4 0 514.1 moveto +( // = SECTION NAME) show +10 f4 0 493.1 moveto +( // Body text.) show +10 f4 0 472.1 moveto +( {) show +10 f4 0 451.1 moveto +( ...) show +10 f4 0 430.1 moveto +( };) show +12 f0 0 406.4 moveto +(These sections will only appear in the manual page for that class. Sections appearing with a class, which) show +12 f0 0 393.1 moveto +(are given special treatment in the manual page are:) show +10 f4 0 369.2 moveto +(-----------------------------------------------------------------------------) show +10 f5 0 358.7 moveto +(Section) show +10 f4 42 358.7 moveto +( ) show +10 f5 78 358.7 moveto +(Description) show +10 f4 144 358.7 moveto +( ) show +10 f4 0 348.2 moveto +(-----------------------------------------------------------------------------) show +10 f4 0 337.7 moveto +(TITLE A one line description of the class. This will be used in the ) show +10 f4 0 327.2 moveto +( `NAME' section of the manual page. ) show +10 f4 0 316.7 moveto +(CLASS TYPE The type of class. For example: Abstract or Concrete. ) show +10 f4 0 306.2 moveto +(AUDIENCE Who may use the class. For example, the class may only be ) show +10 f4 0 295.7 moveto +( of interest to the class librarian. ) show +10 f4 0 285.2 moveto +(DESCRIPTION A description of the class. ) show +10 f4 0 274.7 moveto +(NOTES Any special features, unimplemented but desirable features, ) show +10 f4 0 264.2 moveto +( side effects, or known bugs. ) show +10 f4 0 253.7 moveto +(SEE ALSO References to any associated documents, systems or classes. ) show +10 f4 0 243.2 moveto +( If listed separately on each line, no comma should be used at ) show +10 f4 0 232.7 moveto +( the end of the line. If more than one appears on a single line, ) show +10 f4 0 222.2 moveto +( a comma should be used to separate them. ) show +10 f4 0 211.7 moveto +(EXAMPLE If realistic, a brief example of how the class may be used. ) show +10 f4 0 201.2 moveto +( Copious examples should not be included here, but should be ) show +10 f4 0 190.7 moveto +( described in a separate user guide. ) show +10 f4 0 180.2 moveto +(-----------------------------------------------------------------------------) show +18 f1 0 150.4 moveto +(6 Member Documentation) show +12 f0 0 122.5 moveto +(Documentation for member variables and member functions do not have to be tagged, as has been the) show +12 f0 0 109.2 moveto +(case so far. It does however have to be put in a certain place with respect to the member variable or) show +12 f0 0 95.9 moveto +(function declaration. The locations, where comments related to a member function or variable can be) show +12 f0 0 82.6 moveto +(placed, are on the same line as the declaration following the semi-colon,) show +pagelevel restore +showpage +%%Page: 7 7 +%%BeginPageSetup +/pagelevel save def +54 0 translate +%%EndPageSetup +newpath 0 72 moveto 504 0 rlineto 0 648 rlineto -504 0 rlineto closepath clip newpath +10 f4 0 706.7 moveto +( void func1\(\); // Comment) show +10 f4 0 685.7 moveto +( void func2\(\); // Comment) show +12 f0 0 662 moveto +(or on the line immediately following the declaration.) show +10 f4 0 638.1 moveto +( void func1\(\);) show +10 f4 0 617.1 moveto +( // Comment) show +10 f4 0 585.6 moveto +( void func2\(\);) show +10 f4 0 564.6 moveto +( // Comment) show +12 f0 0 540.9 moveto +(The comment may extend over more than one line. A comment for a particular member variable or) show +12 f0 0 527.6 moveto +(function will be terminated by any line which doesn't contain only a comment. A comment will only be) show +12 f0 0 514.3 moveto +(associated with the declaration which immediately preceeds it. For example:) show +10 f4 0 490.4 moveto +( void func1\(\);) show +10 f4 0 469.4 moveto +( void func2\(\);) show +10 f4 0 448.4 moveto +( // Comment) show +12 f0 0 424.7 moveto +(the comment is associated with func2\(\) only and not func1\(\).) show +12 f0 0 398.1 moveto +(If a member function is defined inline, the comment must be placed after the code. For example:) show +10 f4 0 374.2 moveto +( void func1\(\) { ... }) show +10 f4 0 353.2 moveto +( // Comment) show +10 f4 0 321.7 moveto +( void func2\(\)) show +10 f4 0 300.7 moveto +( { ... }) show +10 f4 0 279.7 moveto +( // Comment) show +12 f0 0 256 moveto +(A limitation of the extraction tools, currently requires that you do not place comments, or blank lines,) show +12 f0 0 242.7 moveto +(within the body of the inline code.) show +18 f1 0 210 moveto +(7 Contract Section) show +12 f0 0 182.1 moveto +(Contracts allow grouping of related member functions and variables. This) show +12 f0 0 155.5 moveto +(makes it easier to find a function which serves the purpose you require.) show +12 f0 0 128.9 moveto +(A contract is a grouping of operations which fulfill a responsibility of the class. Contracts could include:) show +18.1 106.4 moveto +3.3 3.3 c fill +12 f0 28 102.3 moveto +(Initialisation of the class.) show +18.1 93.1 moveto +3.3 3.3 c fill +12 f0 28 89 moveto +(Destruction of the class.) show +18.1 79.8 moveto +3.3 3.3 c fill +12 f0 28 75.7 moveto +(The ability to insert items into, or modify a particular aspect of a class.) show +pagelevel restore +showpage +%%Page: 8 8 +%%BeginPageSetup +/pagelevel save def +54 0 translate +%%EndPageSetup +newpath 0 72 moveto 504 0 rlineto 0 648 rlineto -504 0 rlineto closepath clip newpath +18.1 713.3 moveto +3.3 3.3 c fill +12 f0 28 709.2 moveto +(The ability to make queries about a class or iterate over data it contains.) show +12 f0 0 682.6 moveto +(A contract section is started by placing a comment containing the section title, prior to the functions in) show +12 f0 0 669.3 moveto +(the class that are being grouped together. The list of functions in a contract is terminated by the) show +12 f0 0 656 moveto +(commencement of another contract, a new public, protected, or private section, or the end of the class.) show +12 f0 0 629.4 moveto +(If contract sections are used, only functions which appear under a contract section will appear in the) show +12 f0 0 616.1 moveto +(manual page. Functions which are not in a contract section are not displayed. If no contract sections are) show +12 f0 0 602.8 moveto +(used, two default contract sections, with labels `PROTECTED MEMBERS' and `PUBLIC) show +12 f0 0 589.5 moveto +(MEMBERS', will be created.) show +12 f0 0 562.9 moveto +(An example of a class using contracts is:) show +10 f4 0 539 moveto +( class Class) show +10 f4 0 518 moveto +( // ...) show +10 f4 0 497 moveto +( {) show +10 f4 0 476 moveto +( public:) show +10 f4 0 444.5 moveto +( ~Class\(\);) show +10 f4 0 423.5 moveto +( // This will not appear in the) show +10 f4 0 402.5 moveto +( // manual page.) show +10 f4 0 371 moveto +( // = INITIALISATION) show +10 f4 0 339.5 moveto +( Class\(char const* theString\);) show +10 f4 0 318.5 moveto +( // This will appear in the manual) show +10 f4 0 297.5 moveto +( // page in section INITIALISATION.) show +10 f4 0 276.5 moveto +( //) show +10 f4 0 255.5 moveto +( // Inline formatting, for example:) show +10 f4 0 234.5 moveto +( // , may be used, as may) show +10 f4 0 213.5 moveto +( // block formatting commands.) show +10 f4 0 182 moveto +( // = QUERY) show +10 f4 0 161 moveto +( // As with all other sections, a contract) show +10 f4 0 140 moveto +( // section can have body text. This will appear) show +10 f4 0 119 moveto +( // in the manual page after the section name and) show +10 f4 0 98 moveto +( // before the functions are listed.) show +pagelevel restore +showpage +%%Page: 9 9 +%%BeginPageSetup +/pagelevel save def +54 0 translate +%%EndPageSetup +newpath 0 72 moveto 504 0 rlineto 0 648 rlineto -504 0 rlineto closepath clip newpath +10 f4 0 711.9 moveto +( char const* string\(\);) show +10 f4 0 680.4 moveto +( // Extra information for the current contract may) show +10 f4 0 659.4 moveto +( // also be included between members. This is) show +10 f4 0 638.4 moveto +( // generally used where it is necessary to make a) show +10 f4 0 617.4 moveto +( // comment about a specific set of members in a) show +10 f4 0 596.4 moveto +( // contract.) show +10 f4 0 564.9 moveto +( OTC_Boolean isValid\(\) const;) show +10 f4 0 543.9 moveto +( };) show +10 f4 0 522.9 moveto +( ) show +pagelevel restore +showpage +%%EOF diff --git a/bin/clone.1 b/bin/clone.1 new file mode 100644 index 00000000000..7c36d90fd85 --- /dev/null +++ b/bin/clone.1 @@ -0,0 +1,297 @@ +.TH CLONE 1 "6 June 1989" "" +.SH NAME +clone \- make a clone of an entire directory tree +.SH SYNOPSIS +.B clone +[ +.B -q +] [ +.B -v +] [ +.B -f +] [ +.B -c | -s +] [ +.B -S +] +.I "dir1 dir2" +.SH DESCRIPTION +.I Clone +makes an identical copy of an entire (source) directory tree rooted at +the directory named +.I dir1 +into the (target) directory tree +rooted at +.I dir2. +The target directory +.I dir2 +will be created if it does not already exist. +On the other hand, if the directory +.I dir2 +exists, or if the +.I dir2 +directory has any existing subdirectories, then these +directories will +.B not +be deleted or replaced by +.I clone. +.PP +.I Clone +normally creates the clone +directory tree by creating any new directories needed +beneath +.I dir2 +(possibly including +.I dir2 +itself). +.I Clone +then fills in the new directories with hard links +to all of the files in the original (source) directory tree +.I dir1 +such that the new (target) directory tree appears to also contain +all of the files and subdirectories contained in the original (source) +directory tree. +Hard links are normally used when creating +.I clones +of the files in the source directory tree +inside the new (target) directory tree. +This insures that the cost (in disk space) of +.I cloning +a given source directory tree will be very low. +If desired, the new (clone) directory tree can be filled in with +symbolic links or with actual copies of the original files (instead of +using hard links). +.PP +.I Clone +may be particularly useful for maintaining multiple versions +of nearly identical source trees. +.PP +An important feature of +.I clone +is that the +.I dir2 +argument may already exist and may already contain some +files and subdirectories. In such cases, +.I clone +does not disturb these existing files or subdirectories. +Rather, it simply adds the material from the source directory, +.I dir1, +to the material already present within +.I dir2. +In cases where +there are conflicts between files or directories which +already exist in +.I dir2 +but which also exist in +.I dir1, +.I clone +(by default) leaves the files or directories in the target directory +.I dir2 +untouched unless the +.B -f +(force) flag is used, in which case, +.I clone +will override (i.e. delete) the conflicting entries +from the target directory +.I dir2 +and replace them with clones from the source directory +.I dir1. +.SH OPTIONS +.I Clone +recognizes the following options: +.TP +.BI \-q +Quite mode. Suppress all warnings and non-fatal error messages. +.TP +.BI \-v +Verbose mode. Print verbose messages which describe each individual +linking (or copying) action, as well as all +.I mkdir +actions that +.I clone +executes. +.TP +.BI \-f +Force mode. In cases where an item (i.e. either a file or a directory) +exists in the source directory tree +.I dir1, +and also already exists in the target directory tree +.I dir2, +delete the item (ether a file or a directory) in +the target directory tree and then replace it with a clone +of the corresponding item from the source directory tree. +All such deletions causes warning to be issued to +.I stderr +unless the +.B \-q +(quite mode) +option is also specified. +Note that if a given item already exists in the target directory tree, +and if it also exists in the source directory tree, and if both the +(existing) source and target items are themselves directories, then the +.B \-f +option has no effect for these items. Existing directories in the +target directory tree are never deleted by +.I clone +unless there is a corresponding item in the source directory tree which is +.B not +a directory (i.e. is a regular file) and the +.B \-f +option is in effect. +.TP +.BI \-s +Symbolic link mode (not available on System V). When used, this +option causes all non-directory files to be +.I cloned +by making symbolic links from the target directory tree into the source +directory tree. This mode overrides the default mode in which +hard links are used to clone all non-directory files. +.TP +.BI \-c +Copy mode. +In this mode, a physical copy of each non-directory file in the source directory +tree is created in the target directory tree. Note that when this mode is used, +it is an error for the source directory tree to contain any block or character +device files, or any named pipe files. +.TP +.BI \-S +SCCS mode. +In this mode, only the source tree structure is cloned, not its contents. +Symbolic links are created within the destination tree to subdirectories +in the source tree named +.B SCCS. +This mode is useful when multiple developers work from a common SCCS project +tree. To accomplish this, each developer creates a local project tree by +.I cloning +the common SCCS project directory, specifying the +.B \-S +option. +Individual developers are then able to work within their local project tree while +ensuring that all SCCS operations are applied to the common SCCS project tree. +Use of the +.B \-S +option implies the use of the +.B \-s +option and is thus not available on System V. +.SH EXAMPLES +Assume that you have +two directory trees called +.I src1 +and +.I src2 +and that you wish to combine the contents of these +two directories into a new directory named +.I dst +such that if there are any files with duplicate names in both +.I src1 +and in +.I src2 +the files from the +.I src2 +directory tree will take precedence +over the corresponding files in the directory tree +.I src1. +The following commands would accomplish this task: +.sp 1 +.in +0.4i +.ft B +clone src1 dst +.br +clone -f src2 dst +.sp 1 +.in -0.4i +.ft R +Or alternatively, for this simple case, you could have said: +.ft B +.in +0.4i +.sp 1 +clone src2 dst +.br +clone src1 dst +.br +.sp 1 +.in -04.i +.ft R +.PP +To clone an SCCS project tree, such as +.B /pub/EOS_client_server, +one might use the following command, shown with the resulting output: +.sp 1 +.in +0.4i +.ft B +doc% clone -S -v /pub/EOS_client_server ~/EOS_CS +.br +clone: created new output directory: /home/ebupsn/EOS_CS +.br +clone: created new output directory: /home/ebupsn/EOS_CS/bin +.br +clone: created new output directory: /home/ebupsn/EOS_CS/lib +.br +clone: created new output directory: /home/ebupsn/EOS_CS/include +.br +clone: created new output directory: /home/ebupsn/EOS_CS/cmd +.br +clone: created new output directory: /home/ebupsn/EOS_CS/cmd/clone +.br +clone: created symlink /home/ebupsn/EOS_CS/cmd/clone/SCCS -> /pub/EOS_client_server/cmd/clone/SCCS +.br +clone: created symlink /home/ebupsn/EOS_CS/cmd/SCCS -> /pub/EOS_client_server/cmd/SCCS +.br +clone: created new output directory: /home/ebupsn/EOS_CS/man +.br +clone: created new output directory: /home/ebupsn/EOS_CS/man/man1 +.br +clone: created new output directory: /home/ebupsn/EOS_CS/man/man3 +.br +clone: created new output directory: /home/ebupsn/EOS_CS/man/cat1 +.br +clone: created new output directory: /home/ebupsn/EOS_CS/man/cat3 +.br +clone: created symlink /home/ebupsn/EOS_CS/SCCS -> /pub/EOS_client_server/SCCS +.br +.sp 1 +.in -0.4i +.ft R +.SH CAVEATS +On BSD systems, if there are symbolic links in the source tree, +the effects of +.I cloning +may not be what you expect. +A symbolic link within the source tree results in the creation of an +identical symbolic link within the destination tree. +A warning is issued if the symbolic link is either absolute and points +into the source directory or if the symbolic link is relative and +points out of the source tree. +.PP +If the +.B \-S +option is in effect and the source directory is itself a symbolic link +to a directory, the contents of the symbolic link are cloned in the +destination directory rather than setting the destination directory +to be an identical symbolic link. +The rational for this is as follows. +In networked environments, SCCS project directories are often configured +as NFS file systems managed by an NFS auto-mount daemon. +The NFS auto-mount daemon mounts NFS file systems in a temporary locations +and then creates symbolic links to the temporary locations. +Accesses to this symbolic links trigger the NFS auto-mount daemon. +It is therefore necessary that symbolic links in the destination tree +refer to the NFS auto-mount point symbolic link rather than to the NFS +auto-mount point itself. +Symbolic links within the source tree are ignored. +.SH WARNINGS +There are numerous possible warning and/or error messages which +.I clone +will issue for strange circumstances. +These should all be self-explanatory. +.SH FILES +.ta 1.7i +/usr/local/bin/clone The clone program +.SH "SEE ALSO" +ln(1), link(2), symlink(2), readlink(2), mkdir (1), mkdir (2) +.SH AUTHORS +Written by Ron Guilmette at the Microelectronics and Computer Technology +Corporation. Current E-mail address is rfg@ics.uci.edu. +.PP +SCCS mode added 07-April-1993 by Paul Stephenson at Ericsson Business +Communications. Current E-mail address is paul.stephenson@ebu.ericsson.se. diff --git a/bin/clone.cpp b/bin/clone.cpp new file mode 100644 index 00000000000..98d85b1baa3 --- /dev/null +++ b/bin/clone.cpp @@ -0,0 +1,955 @@ +#include "ace/OS.h" +// @(#)clone.cpp 1.1 10/18/96 + + +#if 0 +#if defined (USG) +#define lstat stat +#else +extern "C" char *getwd (char *); +#define getcwd(str,len) (getwd(str)) +#endif +#endif + +#ifndef MAXPATHLEN +#define MAXPATHLEN 1024 +#endif + +#ifndef BLKDEV_IOSIZE +#define BLKDEV_IOSIZE 1024 +#endif + +extern char *sys_errlist[]; +static void clone (char* s_path, char* d_path, int sroot_flag); + +static char *pname; +static int errors = 0; + +static char* src_path = 0; +static char* dst_path = 0; + +static int quiet_flag = 0; +static int verbose_flag = 0; +static int force_flag = 0; +#ifndef USG +static int symlink_flag = 0; +#endif +static int copy_flag = 0; +static int sccs_flag = 0; + +static void +usage (void) +{ +#ifdef USG + fprintf (stderr, "%s: usage: '%s [-q][-v][-f][-c] pathname1 pathname2'\n", pname, pname); +#else + fprintf (stderr, "%s: usage: '%s [-q][-v][-f][-S][-c | -s | -S] pathname1 pathname2'\n", pname, pname); +#endif + exit (1); +} + +/* abspath(): return the absolutized pathname for the given relative + pathname. Note that if that pathname is already absolute, it may + still be returned in a modified form because this routine also + eliminates redundant slashes and single dots and eliminates double + dots to get a shortest possible pathname from the given input + pathname. The absolutization of relative pathnames is made by + assuming that the given pathname is to be taken as relative to the + first argument (cwd) or to the current directory if cwd is null. */ + +static char * +abspath (char *cwd, char *rel_pathname) +{ + static char cwd_buffer[MAXPATHLEN]; + char abs_buffer[MAXPATHLEN]; + register char *endp; + register char *p; + register char *inp = abs_buffer; + register char *outp = abs_buffer; + + /* Setup the current working directory as needed. */ + + if (!cwd) + { + if (!cwd_buffer[0]) + getcwd (cwd_buffer, MAXPATHLEN); + cwd = cwd_buffer; + } + else if (*cwd != '/') + abort (); /* base path must be absolute */ + + /* Copy the pathname (possibly preceeded by the current working + directory name) into the absolutization buffer. */ + + endp = abs_buffer; + if (rel_pathname[0] != '/') + { + p = cwd; + while (*endp++ = *p++) + continue; + *(endp-1) = '/'; /* overwrite null */ + } + p = rel_pathname; + while (*endp++ = *p++) + continue; + if (endp[-1] == '/') + *endp = (char) 0; + + /* Now make a copy of abs_buffer into abs_buffer, shortening the + pathname (by taking out slashes and dots) as we go. */ + + *outp++ = *inp++; /* copy first slash */ + for (;;) + { + if (!inp[0]) + break; + else if (inp[0] == '/' && outp[-1] == '/') + { + inp++; + continue; + } + else if (inp[0] == '.' && outp[-1] == '/') + { + if (!inp[1]) + break; + else if (inp[1] == '/') + { + inp += 2; + continue; + } + else if ((inp[1] == '.') && (inp[2] == 0 || inp[2] == '/')) + { + inp += (inp[2] == '/') ? 3 : 2; + outp -= 2; + while (outp >= abs_buffer && *outp != '/') + outp--; + if (outp < abs_buffer) + { + /* Catch cases like /.. where we try to backup to a + point above the absolute root of the logical file + system. */ + + fprintf (stderr, "%s: fatal: invalid pathname: %s\n", + pname, rel_pathname); + exit (1); + } + *++outp = (char) 0; + continue; + } + } + *outp++ = *inp++; + } + + /* On exit, make sure that there is a trailing null, and make sure that + the last character of the returned string is *not* a slash. */ + + *outp = (char) 0; + if (outp[-1] == '/') + *--outp = (char) 0; + + /* Make a copy (in the heap) of the stuff left in the absolutization + buffer and return a pointer to the copy. */ + + return strcpy ((char *) malloc (outp - abs_buffer + 1), abs_buffer); +} + +static char* +path_concat (char* s1, char* s2) +{ + int s1_len; + char* ret_val = (char *) malloc ((s1_len = strlen (s1)) + strlen (s2) + 2); + + strcpy (ret_val, s1); + ret_val[s1_len] = '/'; + strcpy (&ret_val[s1_len+1], s2); + return ret_val; +} + +/* Decide if the given path (which may be relative to . or absolute) designa +tes + a point within the original "src_path" directory, and return non-zero if +it + does, or zero otherwise. */ + +static int +in_original_tree (char* other_path) +{ + char* abs_src_path = abspath (NULL, src_path); + char* abs_src_path_slash = path_concat (abs_src_path, ""); + char* abs_other_path = abspath (NULL, other_path); + int ret_val = !strncmp (abs_src_path_slash, abs_other_path, strlen (abs_src_path_slash)); + + free (abs_src_path); + free (abs_src_path_slash); + free (abs_other_path); + return ret_val; +} + +static void +fix_mode (int new_mode, char* d_path) +{ + if (chmod (d_path, new_mode)) + { + if (!quiet_flag) + fprintf (stderr, "%s: warning: can't chmod on output entity %s: %s\n", + pname, d_path, sys_errlist[errno]); + } +} + +static int +remove_item (char* s_path, char* d_path) +{ + struct stat dst_stat_buf; + DIR* dirp; + char containing_dir[MAXPATHLEN]; + + if (lstat (d_path, &dst_stat_buf) == -1) + { + if (!quiet_flag) + fprintf (stderr, "%s: error: cannot get status of %s: %s\n", + pname, d_path, sys_errlist[errno]); + return -1; + } + + /* Before wasting a lot of time sniffing at the thing we are trying to + delete, first make sure that we have write permission into the + directory that contains this thing. Otherwise, it is all a waste + of time. */ + + if (*d_path == '/') + strcpy(containing_dir, d_path); + else + { + containing_dir[0] = '.'; + containing_dir[1] = '/'; + strcpy(containing_dir+2, d_path); + } + *(strrchr (containing_dir, '/')) = '\0'; + if (containing_dir[0] == '\0') + { + containing_dir[0] = '/'; + containing_dir[1] = '\0'; + } + if (access (containing_dir, W_OK)) + { + if (!quiet_flag) + fprintf (stderr, "%s: error: don't have write access to %s: %s\n", + pname, containing_dir, sys_errlist[errno]); + return -1; + } + + switch (dst_stat_buf.st_mode & S_IFMT) + { + case S_IFDIR: + if (access (d_path, R_OK) != 0) + { + if (!quiet_flag) + fprintf (stderr, "%s: error: don't have read permission for directory %s\n", + pname, d_path); + return -1; + } + if (access (d_path, X_OK) != 0) + { + if (!quiet_flag) + fprintf (stderr, + "%s: error: don't have search permission for directory %s\n", + pname, d_path); + return -1; + } + if (access (d_path, W_OK) != 0) + { + if (!quiet_flag) + fprintf (stderr, + "%s: error: don't have write permission for directory %s\n", + pname, d_path); + return -1; + } + if ((dirp = opendir (d_path)) == NULL) + { + if (!quiet_flag) + fprintf (stderr, + "%s: error: can't open directory %s for reading: %s\n", + pname, d_path, sys_errlist[errno]); + return -1; + } + for (;;) + { + struct dirent* dir_entry_p; + char* new_s_path; + char* new_d_path; + + if ((dir_entry_p = readdir (dirp)) == NULL) + break; + if (!strcmp (dir_entry_p->d_name, ".")) + continue; + if (!strcmp (dir_entry_p->d_name, "..")) + continue; + new_s_path = path_concat (s_path, dir_entry_p->d_name); + new_d_path = path_concat (d_path, dir_entry_p->d_name); + if (remove_item (new_s_path, new_d_path)) + { + closedir (dirp); + return -1; + } + free (new_s_path); + free (new_d_path); + } + closedir (dirp); + if (rmdir (d_path)) + { + if (!quiet_flag) + fprintf (stderr, "%s: error: can't delete existing directory %s: %s\n", + pname, d_path, sys_errlist[errno]); + return -1; + } + if (!quiet_flag) + fprintf (stderr, "%s: removed directory %s\n", + pname, d_path); + break; + + /* Note that symbolic links can be treated just like normal files + when the time comes for deleting them. Unlinking a symbolic link + just deletes the link and *not* the thing it points to. */ + + default: + if (unlink (d_path)) + { + if (!quiet_flag) + fprintf (stderr, "%s: error: can't delete existing file %s: %s\n", + pname, d_path, sys_errlist[errno]); + return -1; + } + if (!quiet_flag) + fprintf (stderr, "%s: removed file %s\n", + pname, d_path); + break; + } + return 0; +} + +#ifndef USG +static void +mk_symbolic_link (char *s_path, char *d_path) +{ + if (symlink (s_path, d_path)) + { + if (!quiet_flag) + fprintf (stderr, "%s: error: can't symlink %s to %s: %s\n", + pname, s_path, d_path, sys_errlist[errno]); + } + else + { + if (verbose_flag) + fprintf (stderr, "%s: created symlink %s -> %s\n", + pname, d_path, s_path); + } +} +#endif + +static void +mk_hard_link (char *s_path, char *d_path) +{ + if (link (s_path, d_path)) + { + if (!quiet_flag) + fprintf (stderr, "%s: error: can't link %s to %s: %s\n", + pname, s_path, d_path, sys_errlist[errno]); + } + else + { + if (verbose_flag) + fprintf (stderr, "%s: created hard link %s = %s\n", + pname, d_path, s_path); + } +} + +static void +copy_file (char *s_path, char *d_path) +{ + int input, output; + struct stat src_stat_buf; + + if (lstat (s_path, &src_stat_buf) == -1) + { + if (!quiet_flag) + { + fprintf (stderr, "%s: error: can't get status of %s: %s\n", + pname, s_path, sys_errlist[errno]); + fprintf (stderr, "%s: input entity %s will be ignored\n", + pname, s_path); + } + return; + } + + if ((input = open (s_path, O_RDONLY, 0)) == -1) + { + if (!quiet_flag) + { + fprintf (stderr, "%s: error: can't open input file %s: %s\n", + pname, d_path, sys_errlist[errno]); + fprintf (stderr, "%s: input file %s will be ignored\n", + pname, s_path); + } + return; + } + + if ((output = open (d_path, O_CREAT | O_WRONLY, src_stat_buf.st_mode & 07777)) == -1) + { + if (!quiet_flag) + { + fprintf (stderr, "%s: error: can't create output file %s: %s\n", + pname, d_path, sys_errlist[errno]); + fprintf (stderr, "%s: input file %s will be ignored\n", + pname, s_path); + } + return; + } + + for (;;) + { + int rlen, wlen; + char block_buf[BLKDEV_IOSIZE]; + + if ((rlen = read (input, block_buf, BLKDEV_IOSIZE)) == -1) + { + if (!quiet_flag) + { + fprintf (stderr, "%s: error: bad read from input file %s: %s\n", + pname, s_path, sys_errlist[errno]); + fprintf (stderr, "%s: input file %s was not fully copied\n", + pname, s_path); + } + break; + } + + if (rlen == 0) + break; + + if ((wlen = write (output, block_buf, rlen)) == -1 || wlen != rlen) + { + if (!quiet_flag) + { + fprintf (stderr, "%s: error: bad write to output file %s: %s\n", + pname, s_path, sys_errlist[errno]); + fprintf (stderr, "%s: input file %s not fully copied\n", + pname, s_path); + } + break; + } + } + + close (output); + close (input); + + fix_mode (src_stat_buf.st_mode & 07777, d_path); + + if (verbose_flag) + fprintf (stderr, "%s: created file copy %s = %s\n", + pname, d_path, s_path); +} + +static void +symlink_SCCS (char* s_path, char* d_path) +{ + struct stat dst_stat_buf; + char symlink_buf[MAXPATHLEN]; + int count; + + if (access (d_path, F_OK)) /* Does d_path exit? */ + { + if (errno != ENOENT) + { + if (!quiet_flag) + { + fprintf (stderr, "%s: error: can't check accessability of %s: %s\n", + pname, d_path, sys_errlist[errno]); + fprintf (stderr, "%s: input %s will be ignored\n", + pname, s_path); + } + return; + } + } + else /* d_path exists. What is it? */ + { + if (lstat (d_path, &dst_stat_buf) == -1) + { + if (!quiet_flag) + { + fprintf (stderr, "%s: error: unable to get status of %s: %s\n", + pname, d_path, sys_errlist[errno]); + fprintf (stderr, "%s: input %s will be ignored\n", + pname, s_path); + } + return; + } + + if (S_ISLNK(dst_stat_buf.st_mode)) /* d_path is a symbolic link */ + { + if ((count = readlink (d_path, symlink_buf, MAXPATHLEN)) == -1) + { + fprintf (stderr, "%s: error: can't read symlink %s: %s\n", + pname, d_path, sys_errlist[errno]); + fprintf (stderr, "%s: input file %s will be ignored\n", + pname, s_path); + return; + } + symlink_buf[count] = '\0'; + + if (!strcmp(s_path, symlink_buf)) /* symlink = s_path. Done */ + { + return; + } + else /* symlink != s_path */ + { + if (force_flag) + { + if (remove_item (s_path, d_path) != 0) + return; + } + else + { + if (!quiet_flag) + { + fprintf (stderr, "%s: error: Symbolic link %s already exists \ + but does not point to %s\n", + pname, d_path, s_path); + fprintf (stderr, "%s: input s %s will be ignored\n", + pname, s_path); + } + return; + } + } + } + else /* d_path is NOT a symbolic link */ + { + if (force_flag) + { + if (remove_item (s_path, d_path)) + return; + } + else + { + if (!quiet_flag) + { + fprintf (stderr, "%s: error: output already exists: %s\n", + pname, d_path); + fprintf (stderr, "%s: input %s will be ignored\n", + pname, s_path); + } + return; + } + } + } + + if (symlink (s_path, d_path)) + { + if (!quiet_flag) + fprintf (stderr, "%s: error: can't symlink %s to %s: %s\n", + pname, s_path, d_path, sys_errlist[errno]); + } + else + { + if (verbose_flag) + fprintf (stderr, "%s: created symlink %s -> %s\n", + pname, d_path, s_path); + } +} + +static void +clone_dir (char* s_path, char* d_path) +{ + DIR* dirp; + + if (access (s_path, R_OK) != 0) + { + if (!quiet_flag) + { + fprintf (stderr, + "%s: error: don't have read permission for input directory %s\n" +, + pname, s_path); + fprintf (stderr, "%s: input directory %s will be ignored\n", + pname, s_path); + } + return; + } + + if (access (s_path, X_OK) != 0) + { + if (!quiet_flag) + { + fprintf (stderr, + "%s: error: don't have search permission for input directory %s\n", + pname, s_path); + fprintf (stderr, "%s: input directory %s will be ignored\n", + pname, s_path); + } + return; + } + + if ((dirp = opendir (s_path)) == NULL) + { + if (!quiet_flag) + { + fprintf (stderr, "%s: error: can't open directory %s for reading: %s\n", + pname, s_path, sys_errlist[errno]); + fprintf (stderr, "%s: input directory %s will be ignored\n", + pname, s_path); + } + return; + } + + for (;;) + { + struct dirent* dir_entry_p; + char* new_s_path; + char* new_d_path; + char symlink_buf[MAXPATHLEN]; + int len; + + if ((dir_entry_p = readdir (dirp)) == NULL) + break; + if (!strcmp (dir_entry_p->d_name, ".")) + continue; + if (!strcmp (dir_entry_p->d_name, "..")) + continue; + + new_s_path = path_concat (s_path, dir_entry_p->d_name); + new_d_path = path_concat (d_path, dir_entry_p->d_name); + + if (sccs_flag && !strcmp (dir_entry_p->d_name, "SCCS")) + symlink_SCCS(new_s_path, new_d_path); + else + clone (new_s_path, new_d_path, 0); + + free (new_s_path); + free (new_d_path); + } + + closedir (dirp); +} + +static void +clone_symbolic_link (char* s_path,char* d_path) +{ + char symlink_buf[MAXPATHLEN]; + int count; + + if ((count = readlink (s_path, symlink_buf, MAXPATHLEN)) == -1) + { + fprintf (stderr, "%s: error: can't read symlink %s: %s\n", + pname, s_path, sys_errlist[errno]); + fprintf (stderr, "%s: input file %s will be ignored\n", + pname, s_path); + return; + } + symlink_buf[count] = '\0'; + + if (symlink_buf[0] == '/') /* symlink is absolute */ + { + if (in_original_tree (symlink_buf)) + { + if (!quiet_flag) + fprintf (stderr, + "%s: warning: absolute symlink points into source tree %s -> %s\n", + pname, s_path, symlink_buf); + } + } + else /* symlink is relative */ + { + char* src_root_relative = path_concat (s_path, symlink_buf); + int in_orig = in_original_tree (src_root_relative); + + free (src_root_relative); + if (!in_orig) + { + if (!quiet_flag) + fprintf (stderr, + "%s: warning: relative symlink points out of source tree %s -> %s\n", + pname, s_path, symlink_buf); + } + } + + mk_symbolic_link(symlink_buf, d_path); /* Make an identical symlink. */ +} + + +/* clone: clone the item designated by s_path as the new item d_path. */ + +#define IS_DIR(STAT_BUF) (((STAT_BUF).st_mode & S_IFMT) == S_IFDIR) + +static void +clone (char* s_path, char* d_path, int sroot_flag) +{ + struct stat src_stat_buf; + struct stat dst_stat_buf; + int dir_already_exists = 0; + char* intype = "file"; + + if (lstat (s_path, &src_stat_buf) == -1) + { + if (!quiet_flag) + { + fprintf (stderr, "%s: error: can't get status of %s: %s\n", + pname, s_path, sys_errlist[errno]); + fprintf (stderr, "%s: input entity %s will be ignored\n", + pname, s_path); + } + return; + } + if (sccs_flag && sroot_flag && S_ISLNK (src_stat_buf.st_mode)) + { + + /* If root of the source path is a symbolic link and + SCCS cloning is enabled, clone the target of the link */ + + if (stat(s_path, &src_stat_buf) == -1) + { + if (!quiet_flag) + { + fprintf (stderr, "%s: error: can't get status of %s: %s\n", + pname, s_path, sys_errlist[errno]); + fprintf (stderr, "%s: input entity %s will be ignored\n", + pname, s_path); + } + return; + } + } + if (IS_DIR (src_stat_buf)) + intype = "directory"; + if (access (d_path, 0)) + { + if (errno != ENOENT) + { + if (!quiet_flag) + { + fprintf (stderr, "%s: error: can't check accessability of %s: %s\n", + pname, d_path, sys_errlist[errno]); + fprintf (stderr, "%s: input %s %s will be ignored\n", + pname, intype, s_path); + } + return; + } + } + else + { + char* outtype = "file"; + + if (lstat (d_path, &dst_stat_buf) == -1) + { + if (!quiet_flag) + { + fprintf (stderr, "%s: error: unable to get status of %s: %s\n" +, + pname, d_path, sys_errlist[errno]); + fprintf (stderr, "%s: input %s %s will be ignored\n", + pname, intype, s_path); + } + return; + } + if (IS_DIR (dst_stat_buf)) + outtype = "directory"; + if (IS_DIR (src_stat_buf) && IS_DIR (dst_stat_buf)) + { + dir_already_exists = -1; + + /* Have to make sure that we have full access to the output + directory (at least temporarily). */ + + chmod (d_path, (dst_stat_buf.st_mode & 07777) | 0700); + if (access (d_path, R_OK | W_OK | X_OK) != 0) + { + if (!quiet_flag) + { + fprintf (stderr, + "%s: error: too few permissions for existing directory %s\n", + pname, d_path); + fprintf (stderr, "%s: input directory %s will be ignored\n", + pname, s_path); + } + return; + } + } + else + { + if (force_flag) + { + if (remove_item (s_path, d_path)) + return; + } + else + { + if (!quiet_flag) + { + fprintf (stderr, "%s: error: output %s already exists: %s\n", + pname, outtype, d_path); + fprintf (stderr, "%s: input %s %s will be ignored\n", + pname, intype, s_path); + } + return; + } + } + } + + switch (src_stat_buf.st_mode & S_IFMT) + { + case S_IFDIR: /* Clone a directory */ + + if (!dir_already_exists) + { + /* Don't let others sneak in. + Only we can write the new directory (for now). */ + + if (mkdir (d_path, 0700)) + { + if (!quiet_flag) + { + fprintf (stderr, "%s: error: can't create output directory %s: %s\n", + pname, d_path, sys_errlist[errno]); + fprintf (stderr, "%s: input directory %s will be ignored\n", + pname, s_path); + } + return; + } + if (verbose_flag) + fprintf (stderr, "%s: created new output directory: %s\n", + pname, d_path); + } + + clone_dir(s_path, d_path); + + /* By default, output directories which existed before this + program was executed are reset back to their original + permissions (when we are done adding things to them). For + output directories which are actually created by this program + however, these have their permissions set so that they are + essentially the same as the permissions for their corresponding + input directories, except that the owner is given full + permissions. */ + + if (dir_already_exists) + fix_mode (dst_stat_buf.st_mode & 07777, d_path); + else + fix_mode ((src_stat_buf.st_mode & 07777) | 0700, d_path); + break; + +#ifndef USG + case S_IFLNK: /* Clone a symbolic link */ + + if (!sccs_flag) + clone_symbolic_link (s_path, d_path); + break; +#endif + + default: /* Clone a normal file */ + + if (sccs_flag) + break; + +#ifndef USG + if (symlink_flag) + mk_symbolic_link(s_path, d_path); + else +#endif + if (copy_flag) + copy_file(s_path, d_path); + else + mk_hard_link(s_path, d_path); + + break; + } /* switch */ +} + +int +main (int argc, char *argv[]) +{ + char **argn; + + pname = (pname = strrchr (argv[0], '/')) ? pname+1 : argv[0]; + for (argn = argv+1; *argn; argn++) + { + if (**argn != '-') + { + if (!src_path) + src_path = *argn; + else if (!dst_path) + dst_path = *argn; + else + usage (); + } + else + { + switch (* ((*argn)+1)) + { + case 0: + fprintf (stderr, "%s: invalid option: -\n", pname); + errors = -1; + break; + + case 'q': + quiet_flag = -1; + break; + + case 'v': + verbose_flag = -1; + break; + + case 'f': + force_flag = -1; + break; + +#ifndef USG + case 'S': + sccs_flag = -1; + + if (copy_flag) + errors++; + break; +#endif + +#ifndef USG + case 's': + symlink_flag = -1; + if (copy_flag) + errors++; + break; +#endif + + case 'c': + copy_flag = -1; +#ifndef USG + if (symlink_flag) + errors++; + + if (sccs_flag) + errors++; +#endif + break; + + default: + fprintf (stderr, "%s: invalid option: -%c\n", + pname, *((*argn)+1)); + errors = -1; + } + } + } + if (errors || src_path == 0 || dst_path == 0) + usage (); +#if 0 // ndef USG + if (symlink_flag && *src_path != '/') + { + fprintf (stderr, "%s: error: source root pathname must be absolute when using -s\n", + pname); + exit (1); + } +#endif + if (access (src_path, 0) == -1) + { + fprintf (stderr, "%s: error: accessing source root entity %s: %s\n", + pname, src_path, sys_errlist[errno]); + exit (1); + } + umask (0); /* disable all masking */ + clone (src_path, dst_path, 1); + return 0; +} diff --git a/bin/clone.csh b/bin/clone.csh new file mode 100644 index 00000000000..1c14e912d64 --- /dev/null +++ b/bin/clone.csh @@ -0,0 +1,26 @@ +#!/bin/csh + +set src_root=`pwd` +set dst_root=`abspath $1` + +set subdirs=`find * -type d -print` + +mkdir $dst_root +set files=`find * \( -type d -prune \) -o -type f -print` + +if ($#files) then + ln $files $dst_root +endif + +if ($#subdirs) then + foreach subdir ($subdirs) + cd $src_root + mkdir $dst_root/$subdir + cd $src_root/$subdir + set files=`find * \( -type d -prune \) -o -type f -print` + if ($#files) then + ln $files $dst_root/$subdir + endif + end +endif +exit 0 diff --git a/bin/g++dep b/bin/g++dep new file mode 100755 index 00000000000..b149b7ff98d --- /dev/null +++ b/bin/g++dep @@ -0,0 +1,80 @@ +#! /bin/sh + +# This utility is a lightly editted version of the freed Berkeley +# script `mkdep'. The current script is intended to work for GNU G++. + +# Here is the original BSD header: +# @(#)mkdep.sh 1.7 (Berkeley) 10/13/87 +# + +PATH=/bin:/usr/bin:/usr/ucb:/usr/gnu:/usr/gnu/bin:/opt/gnu/bin:/pkg/gnu/bin:$PATH +export PATH + +if [ $# = 0 ] ; then + echo 'usage: g++dep [-p] [-f makefile] [flags] file ...' + exit 1 +fi + +MAKE=Makefile # default makefile name is "Makefile" +case $1 in + # -f allows you to select a makefile name + -f) + MAKE=$2 + shift; shift ;; + + # the -p flag produces "program: program.c" style dependencies + # so .o's don't get produced + -p) + SED='-e s;\.o;;' + shift ;; + # -r allows the use of relative pathnames... + -r) + REL="-e s;$WRAPPER_ROOT;\$(WRAPPER_ROOT);g" + shift ;; +esac + +if [ ! -w $MAKE ]; then + echo "g++dep: no writeable file \"$MAKE\"" + exit 1 +fi + +TMP=/tmp/g++dep$$ + +trap 'rm -f $TMP ; exit 1' 1 2 3 13 15 + +cp $MAKE ${MAKE}.bak + +sed -e '/DO NOT DELETE THIS LINE/,$d' < $MAKE > $TMP + +cat << _EOF_ >> $TMP +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +_EOF_ + +gcc -MM $* | /bin/sed -e "s; \./; ;g" $SED $REL | \ + awk ' { \ + if ($1 != prev) { \ + if (rec != "") \ + print rec; rec = $0; prev = $1; \ + } \ + else { \ + if (length(rec $2) > 78) { \ + print rec; rec = $0; \ + } else \ + rec = rec " " $2 \ + } \ + } \ + END { \ + print rec \ + } ' >> $TMP + +cat << _EOF_ >> $TMP + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +_EOF_ + +# copy to preserve permissions +cp $TMP $MAKE +rm -f ${MAKE}.bak $TMP +exit 0 diff --git a/bin/hiding.fmt b/bin/hiding.fmt new file mode 100644 index 00000000000..e77a719aee2 --- /dev/null +++ b/bin/hiding.fmt @@ -0,0 +1,20 @@ +# +# access control file for ADTs +# +# K. Dorn +# + +CSAMERGECXXHXX +off + +CSAHEADER +on + +PUBLIC +on + +PROTECTED +on + +PRIVATE +on diff --git a/bin/html-windex b/bin/html-windex new file mode 100755 index 00000000000..2a80ae85f6b --- /dev/null +++ b/bin/html-windex @@ -0,0 +1,33 @@ +#!/bin/sh +# +# This script generates automatically to its stdout a windex.html file; +# this file is useful just after running man2html. +# All the html man pages must be located under an html directory at the +# same level as the generated windex.html file. +# + + +WINDEX=$1 + +cat < +

ACE Wrappers Man Pages Index

+

+ This file has been generated from the windex file from the ACE package + and it contains a list of pointers to the man2html'ed man pages. +

+


+
    +EOF + +cat $WINDEX | \ + sed -e 's/ / /g' \ + -e 's%\(3\).*-%3\)%g' \ + -e 's/^[a-zA-Z_]*/&\.html">/g' \ + -e 's/\.PP/
    /g' \ + -e 's%^%
  • " diff --git a/bin/info2doc.awk b/bin/info2doc.awk new file mode 100755 index 00000000000..de2016e83fb --- /dev/null +++ b/bin/info2doc.awk @@ -0,0 +1,2181 @@ +# ============================================================================= +# +# = DESCRIPTION +# Awk script which performs the actual conversion from classinfo file +# to various types of documentation. +# +# = AUTHOR(S) +# Graham Dumpleton +# K.Dorn +# +# = COPYRIGHT +# Copyright 1991 OTC LIMITED +# Copyright 1994 DUMPLETON SOFTWARE CONSULTING PTY LIMITED +# +# ============================================================================= + +BEGIN { + # + # Set some defaults. + # + #device = "text" +# access["public"] = "on" +# access["protected"] = "on" +# access["private"] = "on" + access["public"] = publ + access["protected"] = prot + access["private"] = priv + + lower["CLASS"] = "class" + lower["STRUCT"] = "struct" + lower["UNION"] = "union" + lower["class"] = "class" + lower["struct"] = "struct" + lower["union"] = "union" + upper["public"] = "PUBLIC" + upper["protected"] = "PROTECTED" + upper["private"] = "PRIVATE" + + classfunc = "" + rettyp = "" + classname="" + classtitle="" + filedate="" + filename="" + filename1="" + origfile="" + author="" + classdescription="" + firsttime = "first" + nesting_level = 0 + +# csaprintheader=1 + + # + # Check that info file, class have been specified. + # + # if ( infile ~ /^$/ || class ~ /^$/ ) + # exit + + # + # Read in info file. + # + # FS="\n"; RS="" + # while ( getline < infile > 0 ) + # lines[++num] = $0 + + # + # Prepare for format file. + # + FS=" "; RS="\n" + + # + # Find some defaults in info file. + # + # findLibrary() + # findFilename() +} +# end of Begin section!!!!! + + +# +# +# +function csa_print_compilation_header_alt() +{ + if (csaprintheader == "on") + { + if ( length( firsttime ) > 3 ) + { + + csa_compilation_header=sprintf("\n/*[ Compilation unit "\ + "----------------------------------------------------------\n"\ + "\n"\ + " Component\ \ \ \ \ \ \ : CSA - OSC\n"\ + "\n"\ + " Name\ \ \ \ \ \ \ \ \ \ \ \ : %s.h\n"\ + "\n"\ + " Author : %s\n"\ + "\n"\ + " Language : C++\n"\ + "\n"\ + " Creation Date : %s\n"\ + "\n"\ + " Test State : %%Q%%\n"\ + "\n"\ + " Description : %s\n"\ + " %s\n"\ + "\n"\ + "\n"\ + " Copyright (C) Siemens AG 1995 All Rights Reserved\n"\ + "\n"\ + "--------------------------------------"\ + "---------------------------------------*/\n"\ + "/*] END */\n"\ + "#pragma ident \"%%Z%% %%M%% %%I%% (%%G%%), %%Y%% %%Q%%:"\ + " implementation file for class \n"\ + "%s\"\n"\ + "\n"\ + "#undef __STDC__\n"\ + "#undef __GNUG__\n"\ + "\n",filename1,author,filedate,classtitle,classdescription,classname); + printf("%s",csa_compilation_header); + firsttime = "" + } + } +} +# +# +# +function csa_print_compilation_header() +{ + if ((csaprintheader == "on" && merge != "on") || (merge == "on" && loop == "1")) + { + if ( length( firsttime ) > 3 ) + { + for ( i=0; i<=num; i++ ) + { + n = split( lines[i], line, "\n" ) + if (line[1] == "INCLUDE" && line[2] !~ /^.*\.\i/) + printf( "#include %s\n", line[2]) + } + + + csa_compilation_header=sprintf(vcohxx,filename1,author,filedate,classtitle,classdescription,classname); + printf("%s",csa_compilation_header); + firsttime = "" + } + } +} + +# +# +# +function csa_print_class_header_alt() +{ + if (csaprintheader == "on") + { + csa_class_header=sprintf("\n/*[ Class ---------------------"\ + "-------------------------------------------\n"\ + "\n"\ + " Name : %s\n"\ + "\n"\ + " Description : %s\n"\ + " %s\n"\ + "\n"\ + "--------------------------------------------"\ + "------------------------------*/\n\n",class,classtitle,classdescription) + + if ( device != "text" ) + print( ".nf\n" ) + printf("%s",csa_class_header); + } +} +# +# +# +function csa_print_class_header() +{ + if (csaprintheader == "on") + { + csa_class_header=sprintf(vclhxx,class,classtitle,classdescription) + + if ( device != "text" ) + print( ".nf\n" ) + printf("%s",csa_class_header); + } +} + +# +# +# +function csa_print_class_end() +{ + if (csaprintheader == "on") + { + csa_class_end=sprintf("\n/*] END Class */\n\n") + + if ( device != "text" ) + print( ".nf\n" ) + printf("%s",csa_class_end); + } +} + +# +# +# +function csa_collect_info() +{ + classdescription = "" + classtitle = "" + found = 0 + for ( i=0; i<=num; i++ ) + { + + n = split( lines[i], line, "\n" ) + + csa_get_filedate_and_name() + csa_get_class_name_and_title(n) + csa_get_library() + csa_get_author() + + + + if ( line[1] == "INFO" && + line[2] == "HDR" && + line[3] == "DESCRIPTION" && + line[4] == class ) + { + found = 1 + break + } + + } + if ( found == 1 ) + { + for ( i=5; i<=n; i++ ) + { + len = length(line[i]) + comm = substr(line[i],4,len) + classdescription = classdescription comm "\n " + } + } + + found = 0 + + csa_get_origfile_name() +} + +# +# +# +function csa_get_origfile_name() +{ + len=length(infile) + origfile=substr(infile,1,len-2) + origfile = origfile "h" +} + +# +# +# +function csa_get_author() +{ + if ( line[1] == "INFO" && + line[2] == "GLOBAL" && + line[3] == "AUTHOR" ) + { + len=length(line[4]) + author=substr(line[4],4,len) + } +} + +# +# +# +function csa_get_library() +{ + if ( line[1] == "INFO" && + line[2] == "GLOBAL" && + line[3] == "LIBRARY" ) + { + #library=line[4] + } +} + +# +# +# +function csa_get_class_name_and_title(n) +{ + if ( line[1] == "INFO" && + line[2] == "HDR" && + line[3] == "TITLE" && + line[4] == class ) + { + classname=line[4] +# classtitle=line[5] +# len = length(line[5]) +# classtitle = substr(line[5],4,len) + for ( j=5; j<=n; j++ ) + { + len = length(line[j]) + comm = substr(line[j],4,len) + classtitle = classtitle comm "\n " + } + } +} + +# +# +# +function csa_get_filedate_and_name() +{ + if ( line[1] == "CLASS2INFO" ) + { + filedate=line[2] + filename=line[3] + len=length(line[3]) + filename1=substr(line[3],1,(len-2)) + } +} + +# +# +# +function csa_get_() +{ +} + +# +# +# +function read_ci_file() +{ + while ( getline < infile > 0 ) + lines[++num] = $0 +} + +function read_fvclhxx_file() +{ + vclhxx1 = "\n" + while ( getline < fvclhxx > 0 ) + vclhxx1 = vclhxx1 $0 "\n" + vclhxx = vclhxx1 +} + +function read_fvcohxx_file() +{ + vcohxx1 = "\n" + while ( getline < fvcohxx > 0 ) + vcohxx1 = vcohxx1 $0 "\n" + vcohxx = vcohxx1 +} + +# +# currently not used because not necessary (in recursion properly handled!) +# +function read_ci_file_and_modify() +{ + while ( getline < infile > 0 ) + { + if ($1 ~ "^(CLASS|STRUCT|UNION)$" && $2 ~ "(::|<)") + { +#printf("\n----old=|%s|-----\n",$2) + n = split( $0, line, "\n" ) + len = length($2) + match( $2, "(::|<).*$") + $2 = substr( $2,RSTART+2,RLENGTH) +#printf("\n----new=|%s|-----\n",$2) + + line[1] = $1 "\n" + line[2] = $2 + new = "" + for (i=1; i<=(n+1) ;i++) + new = new line[i] + lines[++num] = new "\n" + } + else + lines[++num] = $0 "\n" + + } + +# for (i=1; i<=num ;i++) +# print lines[i] +} + +# +# Start next pass. +# +$1 == "start" { + + if ( pass == 0) + { + # + # Check that info file, class have been specified. + # + if ( infile ~ /^$/ || class ~ /^$/ ) + exit + + # + # Read in info file. + # + FS="\n"; RS="" + + read_ci_file() + FS=" "; RS="\n" + if (csaprintheader == "on") + { + read_fvclhxx_file() + read_fvcohxx_file() + } + # + # Prepare for format file. + # + FS=" "; RS="\n" + + # + # Find some defaults in info file. + # + findLibrary() + findFilename() + } + + pass++ +} + +# +# Sets the output device to use. +# +# $1 == "set" && $2 == "device" { +# device = $3 +# } + +# +# Prevents a section from being printed. +# +$1 == "hide" && $2 == "section" { + section = $3 + for ( i=4; i<=NF; i++ ) + section = " " section + sections[section] = "" +} + +# +# Prevents a contract from being printed. +# +# Note: a contract will not be displayed if it occurs in a part of the class +# which has been disabled. For instance, if anything occuring in the private +# section of a class is being hidden, the no contracts from that section will +# be displayed either. +# +$1 == "hide" && $2 == "contract" { + contract = $3 + for ( i=4; i<=NF; i++ ) + contract = " " contract + contracts[contract] = "" +} + +# +# Specification of whether a part of a class is hidden or not. +# +$1 == "set" && $2 in access { + access[$2] = $3 +} + +# +# Print a prelude. This should produce any stuff necessary to initialise +# the document. +# +pass == "2" && $1 == "print" && $2 == "prelude" { + "date" | getline date + split ( date, d, " " ) + date = d[2] " " d[3] ", " d[6] + if ( device == "text" ) + { + } + else if ( device == "troff" ) + { + print( ".\\\" troff -man %" ) + print( ".\\\"" ) + print( ".\\\" DO NOT EDIT" ) + print( ".\\\"" ) + print( ".\\\" This manual page is automatically generated by class2man." ) + print( ".\\\"" ) + print( ".ds sL " library ) + print( ".ds sV " date ) + print( ".ds sC " class ) + print( ".ds sS 3" ) + print( ".TH \"\\*(sC\" \"\\*(sS\" \"\\*(sV\" \"\\*(sL Library\" \"\\*(sL Reference Manual\"" ) + } + else if ( device == "mml" ) + { + print( "" ) + print( "" ) + print( "" ) + print( "" ) + print( "" ) + print( "" ) + } +} + +# +# Print out a title. +# The title should be generated from the class name and any information +# in the section labelled 'TITLE" which occurs in the hdr of a class. +# On pass 1 we simply note that we intend using the 'TITLE' section so +# that it doesn't get printed out as a seperate section. +# +pass == "1" && $1 == "print" && $2 == "title" { + sections["TITLE"] = "" +} + +# +# On pass 2 we actually print the title. +# Note: even if a 'TITLE' section is not found for the class, then the class +# name at least should be output. +# +pass == "2" && $1 == "print" && $2 == "title" { + found = 0 + for ( i=0; i<=num; i++ ) + { + n = split( lines[i], line, "\n" ) + if ( line[1] == "INFO" && + line[2] == "HDR" && + line[3] == "TITLE" && + line[4] == class ) + { + found = 1 + break + } + } + if ( device == "text" ) + { + if ( found == 1 ) + { + print( class " " ) + for ( i=5; i<=n; i++ ) + outputLine( line[i] ) + } + else + print( class ) + } + else if ( device == "troff" ) + { + print( ".PP" ) + print( ".SH \"NAME\"" ) + if ( found == 1 ) + { + print( class " \\- " ) + for ( i=5; i<=n; i++ ) + outputLine( line[i] ) + } + else + print( class ) + } + else if ( device == "mml" ) + { + print( "" ) + print( class ) + if ( found == 1 ) + { + print( "" ) + for ( i=5; i<=n; i++ ) + outputLine( line[i] ) + } + } +} + +# +# On pass 1 we actually store the class description for csa. +# +pass == "1" { + if (csaprintheader == "on") + csa_collect_info() +} + +# +# Print a synopsis. +# This should include a line indicating which header file needs to be included +# and a description of the members variables and functions in the class. +# A section of the class should not be output if access["section"] == "off". +# e.g.: Don't print private stuff if access["private"] == "off". +# +# +# das ist die standard ausgabe! (nur hier!) +# +pass == 2 && $1 == "print" && $2 == "synopsis" { + + + if (csaprintheader == "on") + csa_print_compilation_header() + + if ( device == "text" ) + { + print( "\ "SYNOPSIS"\ " ) + print( "\n" ) + } + else if ( device == "troff" ) + { + print( ".PP" ) + print( ".SH \"SYNOPSIS\"" ) + print( ".nf\n" ) + } + else if ( device == "mml" ) + { + print( "" ) + print( "") + print( "SYNOPSIS" ) + printf( "" ) + printf( "" ) + printf( "" ) + printf( "" ) + printf( "" ) + } + + # + # check for includes + # + if ( filename != "" && library != "C++" ) + { + if ( device == "text" ) + { + if ( merge != "on") + { +# printf( "\n#include <%s/%s>\n", library,filename) +# printf( "\n#include <%s/%s>\n", library,origfile) +# print( "\n" ) + } + else + { + if ( loop == "1") + { +# printf( "\n#include <%s/%s>\n", library,filename) +# printf( "\n#include <%s/%s>\n", library,origfile) +# print( "\n" ) + } + } + } + else if ( device == "troff" ) + { + print( "\\f(CO#include <" library "/" filename ">" ) + print( "" ) + } + else if ( device == "mml" ) + { + print( "#include \\<" library "/" filename "\\>" ) + print( "" ) + } + + if (csaprintheader == "on") + csa_print_class_header() + + } + + bases = "" + baseindex = 0 + numfields = 0 + + # + # start searching for loop for output 1 ADTs + # + for ( i=0; i<=num; i++ ) + { + numfields = split( lines[i], line, "\n" ) + if ( line[1] ~ /(CLASS|UNION|STRUCT)/ && line[2] == class ) + { + type = lower[line[1]] + baseindex = 3 + # + # + # break heisst, jetzt ist richtige klasse gefunden, die von aussen mitgegeben wurde!!!!!! + # + + break + } + else if ( \ + line[1] == "TEMPLATE" && \ + line[2] ~ /(class|union|struct)/ && \ + line[3] == class \ + ) + { + baseindex = 5 + type = "template" + break + } + } + + # + # end of searching for loop for output 1 ADTs + # ab hier function eingesetzt! + # + +#printf("\nvor parse_and_print_adt: class=%s nesting_level=%s",class,nesting_level); + class = parse_and_print_adt(class,class,class,baseindex,type) +#printf("\nafter parse_and_print_adt: class=%s nesting_level=%s",class,nesting_level); + + +# +# bis hier geht parse function +# + +#till end csa_print_class_end() + + if (csaprintheader == "on") + csa_print_class_end() + +} + +# +# Print copyright holders. This must break the line before each copyright +# holder. +# +# wird im moment nicht gerufen +# +pass == "2" && $1 == "print" && $2 == "copyright" { + for ( i=0; i<=num; i++ ) + { + n = split( lines[i], line, "\n" ) + if ( line[1] == "INFO" && + line[2] == "GLOBAL" && + line[3] == "COPYRIGHT" ) + { + if ( device == "text" ) + { + print( "COPYRIGHT" ) + } + else if ( device == "troff" ) + { + print( ".PP" ) + print( ".SH COPYRIGHT" ) + } + else if ( device == "mml" ) + { + print( "" ) + print( "" ) + print( "COPYRIGHT" ) + printf( "" ) + printf( "" ) + printf( "" ) + printf( "" ) + printf( "" ) + } + start = 4 + for ( k=start; k<=n; k++ ) + { + if ( k != start && line[k] ~ "[\t ]*Copyright" ) + { + if ( device == "text" ) + print( "\n" ) + else if ( device == "troff" ) + print( ".br" ) + else if ( device == "mml" ) + printf( "" ) + } + outputLine( line[k] ) + } + break + } + } +} + +# +# Print out any sections which have not been previously printed out and +# which are not hidden. +# +pass == "1" && $1 == "print" && $2 == "section" && $3 == "*" { + next +} + +pass == "2" && $1 == "print" && $2 == "section" && $3 == "*" { + for ( i=0; i<=num; i++ ) + { + n = split( lines[i], line, "\n" ) + if ( line[1] == "INFO" && + ( line[2] == "GLOBAL" || + ( line[2] == "HDR" && line[4] == class ) ) ) + { + if ( line[3] in sections ) + continue + else + { + section = line[3] + sections[section] = "" +#printf("\noutputSection() - 1 - called!!!!!!!!!!!!"); + outputSection() + } + } + } +} + +# +# Print out a section. +# On pass 1 only record the fact that this section will be printed. +# +pass == "1" && $1 == "print" && $2 == "section" { + section = $3 + for ( i=4; i<=NF; i++ ) + section = section " " $i + sections[section] = "" +} + +# +# Print out a section. +# On pass 2 actually print it out. +# +pass == "2" && $1 == "print" && $2 == "section" { + section = $3 + for ( i=4; i<=NF; i++ ) + section = section " " $i + found = 0 + for ( i=0; i<=num; i++ ) + { + n = split( lines[i], line, "\n" ) + if ( line[1] == "INFO" && + ( line[2] == "GLOBAL" || + ( line[2] == "HDR" && line[4] == class ) ) && + line[3] == section ) + { + found = 1 + break + } + } + if ( found == 1 ) + { +#printf("\noutputSection() - 2 - called!!!!!!!!!!!!"); + outputSection() + } +} + +# +# Print out any contracts which have not previously been printed, and +# which are not hidden. +# +# If there are no contracts in the class, then print out sections for the +# private, protected and public members; thats if they are not being hidden. +# +pass == "1" && $1 == "print" && $2 == "contract" && $3 == "\*" { + next +} + +pass == "2" && $1 == "print" && $2 == "contract" && $3 == "\*" { + for ( i=0; i<=num; i++ ) + { + n = split( lines[i], line, "\n" ) + + if ( line[1] == "INFO" && + line[2] == "BODY" && + line[4] == class ) + { + if ( line[3] in contracts ) + continue + else if ( access[line[5]] == "on" ) + { + contract = line[3] + contracts[contract] = "" + +#printf("\noutputContract() called!!!!!"); + outputContract() + } + } + } + i = 0 + for ( j in contracts ) + i++ + if ( i == 0 ) + { +#printf("\noutputClassSection() -2- called!!!!!!!\n"); + if ( access["public"] == "on" ) + outputClassSection( "public" ) + if ( access["protected"] == "on" ) + outputClassSection( "protected" ) + if ( access["private"] == "on" ) + outputClassSection( "private" ) + } +} + +# +# Print out a particular contract, regardless of whether it is hidden or +# not. +# On pass 1 we only note that the contract will be printed. +# +pass == "1" && $1 == "print" && $2 == "contract" { + contract = $3 + for ( i=4; i<=NF; i++ ) + contract = contract " " $i + contracts[contract] = "" +} + +pass == "2" && $1 == "print" && $2 == "contract" { + contract = $3 + for ( i=4; i<=NF; i++ ) + contract = contract " " $i + found = 0 + for ( i=0; i<=num; i++ ) + { + n = split( lines[i], line, "\n" ) + if ( line[1] == "INFO" && + line[2] == "BODY" && + line[4] == class && + line[3] == section ) + { + found = 1 + break + } + } + if ( found == 1 ) + { +#printf("\noutputContract() called!!!!!"); + outputContract() + } +} + +# +# Output a particular section of a class. +# This ignores whether that part is hidden. +# +pass == "2" && $1 == "print" && $3 in access { +#printf("\noutputClassSection() -1- called!!!!!!!\n"); + outputClassSection( $3 ) +} + +# +# Actually prints out a particular section of a class. +# +# +# wird nie gerufen +# +function outputClassSection( part ) +{ + start = 0 + for ( i=0; i<=num; i++ ) + { + n = split( lines[i], line, "\n" ) + if ( ( line[1] == "FUNC" || + line[1] == "MEMBER" || + line[1] == "TYPEDEF" || + line[1] == "FRIEND" ) && + line[2] == class && + line[3] == part ) + { + if ( start == 0 ) + { + start = 1 + if ( device == "text" ) + { + printf( "\n %s MEMBERS\n" ,upper[line[3]]) + } + else if ( device == "troff" ) + { + print( ".PP" ) + print( ".SH \"" upper[line[3]] " MEMBERS\"" ) + } + else if ( device == "mml" ) + { + print( "" ) + print( "" ) + print( upper[line[3]] " MEMBERS" ) + printf( "" ) + printf( "" ) + printf( "" ) + printf( "" ) + printf( "" ) + } + } + if ( device == "text" ) + { + print( "\n" ) + } + else if ( device == "troff" ) + { + print( ".nf" ) + } + else if ( device == "mml" ) + { + printf( "" ) + } + outputPrototype( line[4] ) + if ( device == "text" ) + { + } + else if ( device == "troff" ) + { + print( ".fi" ) + print( ".RS 0.25i" ) + } + else if ( device == "mml" ) + { + printf( "" ) + printf( "" ) + printf( "" ) + } + for ( l=5; l<=n; l++ ) + outputLine( line[l] ) + if ( device == "text" ) + { + print( "" ) + } + else if ( device == "troff" ) + { + print( ".RE" ) + print( "" ) + } + else if ( device == "mml" ) + { + printf( "" ) + printf( "" ) + } + } + } +} + +# +# Once a contract has been found, this prints it out. +# +# +# wird nie gerufen +# +function outputContract() { + if ( device == "text" ) + { + print( "\ " contract "\ " ) + } + else if ( device == "troff" ) + { + print( ".PP" ) + print( ".SH \"" contract "\"" ) + } + else if ( device == "mml" ) + { + print( "" ) + print( "" ) + print( contract ) + printf( "" ) + printf( "" ) + printf( "" ) + printf( "" ) + printf( "" ) + } + + for ( k=6; k<=n; k++ ) + outputLine( line[k] ) + + # print( "" ) + for ( k=i+1; k<=num; k++ ) + { + n = split( lines[k], line, "\n" ) + if ( ( line[1] == "INFO" && + line[2] == "BODY" && + line[4] == class ) || + ( line[1] == "END" && + line[2] == class ) || + ( line[1] == "ACCESS" && + line[2] == class ) ) + { + break + } + else + if ( ( line[1] == "FUNC" || + line[1] == "MEMBER" || + line[1] == "TYPEDEF" || + line[1] == "FRIEND" ) && + line[2] == class ) + { + if ( device == "text" ) + { + print( "\n" ) + } + else if ( device == "troff" ) + { + print( ".nf" ) + } + else if ( device == "mml" ) + { + printf( "" ) + } + outputPrototype( line[4] ) + if ( device == "text" ) + { + } + else if ( device == "troff" ) + { + print( ".fi" ) + print( ".RS 0.25i" ) + } + else if ( device == "mml" ) + { + printf( "" ) + printf( "" ) + printf( "" ) + } + for ( l=5; l<=n; l++ ) + outputLine( line[l] ) + if ( device == "text" ) + { + print( "" ) + } + else if ( device == "troff" ) + { + print( ".RE" ) + print( "" ) + } + else if ( device == "mml" ) + { + printf( "" ) + printf( "" ) + } + } + else if ( line[1] == "COMMENT" && + line[2] == "BODY" && + line[3] == class ) + { + for ( l=5; l<=n; l++ ) + outputLine( line[l] ) + # print( "" ) + } + } +} + +# +# Once a section has been found, this prints it out. +# +# +# wird nie gerufen +# +function outputSection() +{ + + if ( line[2] == "GLOBAL" ) + start = 4 + else + start = 5 + + if ( device == "text" ) + { + print( "\ " section "\ " ) + } + else if ( device == "troff" ) + { + print( ".PP" ) + print( ".SH \"" section "\"" ) + } + else if ( device == "mml" ) + { + print( "" ) + print( "" ) + print( section ) + if ( line[start] != "" ) + { + printf( "" ) + printf( "" ) + printf( "" ) + printf( "" ) + printf( "" ) + printf( "" ) + printf( "" ) + } + } + + blankLine = 0 + for ( k=start; k<=n; k++ ) + outputLine( line[k] ) +} + +# +# Removes comment delimiter from start of line. +# +function removeComment( line ) +{ + sub( "^// ?", "", line ) + return line +} + +# +# Output a line. This checks for various formatting requests and will +# appropriately expand them. +# +function outputLine( line ) +{ + line = removeComment( line ) + if ( inComment == 0 ) + { + if ( line ~ "^= BEGIN" ) + { + inCode = 1 + if ( device == "text" ) + { + print( "\n" ) + } + else if ( device == "troff" ) + { + print( ".RS 0.25i" ) + print( ".nf\n\\f(CO" ) + } + else if ( device == "mml" ) + { + printf( "" ) + printf( "" ) + printf( "" ) + printf( "" ) + printf( "" ) + } + } + else if ( line ~ "^= END" ) + { + inCode = -1 + if ( device == "text" ) + { + print( "\n" ) + } + else if ( device == "troff" ) + { + print( "\\fP\n.fi" ) + print( ".RE" ) + } + else if ( device == "mml" ) + { + printf( "" ) + printf( "" ) + printf( "" ) + printf( "") + } + } + else if ( line ~ "^= BEGIN" ) + inComment = 1 + else if ( line ~ "^= BEGIN" ) + { + if ( device == "text" ) + { + } + else if ( device == "troff" ) + print( ".RS 0.25i" ) + else if ( device == "mml" ) + { + printf( "" ) + printf( "" ) + } + } + else if ( line ~ "^= END" ) + { + if ( device == "text" ) + { + } + else if ( device == "troff" ) + print( ".RE" ) + else if ( device == "mml" ) + { + printf( "" ) + printf( "" ) + } + } + else if ( line ~ "^= BEGIN" ) + { + inNoFill = 1 + if ( device == "text" ) + { + } + else if ( device == "troff" ) + print( ".nf" ) + else if ( device == "mml" ) + printf( "" ) + } + else if ( line ~ "^= END" ) + { + inNoFill = 0 + if ( device == "text" ) + { + } + else if ( device == "troff" ) + print( ".fi" ) + else if ( device == "mml" ) + printf( "" ) + } + else + { + if ( inCode > 0 ) + { + if ( device == "mml" ) + { + gsub( " ", "\\ ", line ) + gsub( "<", "\\<", line ) + gsub( ">", "\\>", line ) + if ( inCode > 1 ) + line = "" line + } + print( line ) + inCode = inCode + 1 + } + else + { + gsub( "\\\\]>", "]\\fP", line ) + gsub( "\\\\}>", "]\\fP", line ) + gsub( "([^\\\\]|^)<\\[", "&<\\fB", line ) + gsub( "[^\\\\]\\]>", "&>\\fP", line ) + gsub( "<\\[<", "", line ) + gsub( "\\]>>", "", line ) + gsub( "([^\\\\]|^)<\{", "&<\\fI", line ) + gsub( "[^\\\\]}>", "&>\\fP", line ) + gsub( "<\{<", "", line ) + gsub( "}>>", "", line ) + gsub( "([^\\\\]|^)<", "&<\\f(CO", line ) + gsub( "[^\\\\]>", "&>\\fP", line ) + gsub( "<<", "", line ) + gsub( ">>", "", line ) + gsub( "\\\\<", "<", line ) + gsub( "\\\\>", ">", line ) + gsub( "\\\\", "\\\\", line ) + gsub( "\\\\fB", "fB", line ) + gsub( "\\\\fI", "fI", line ) + gsub( "\\\\fP", "fP", line ) + gsub( "\\\\f\\(CO", "f(CO", line ) + + if ( device == "mml" ) + { + if ( inNoFill > 0 ) + gsub( " ", "\\ ", line ) + + gsub( "<", "\\<", line ) + gsub( ">", "\\>", line ) + gsub( "\\\\fP", "", line ) + gsub( "\\\\fB", "", line ) + gsub( "\\\\fI", "", line ) + gsub( "\\\\f\\(CO", "", line ) + + if ( inNoFill > 0 ) + { + if ( inNoFill > 1 ) + line = "" line + inNoFill = inNoFill + 1 + } + } + + if ( line == "" ) + { + blankLine = 1 + } + else + { + if ( blankLine == 1 ) + { + if ( inCode == 0 ) + print( "" ) + blankLine = 0 + if ( inCode == -1 ) + inCode = 0 + } + print( line ) + } + } + } + } + else + { + if ( line ~ "^= END" ) + inComment = 0 + } +} + +# +# Searches for the 'LIBRARY' section and sets 'library' to the value found. +# +function findLibrary() +{ + for ( i=0; i<=num; i++ ) + { + split( lines[i], line, "\n" ) + if ( line[1] == "INFO" && + line[2] == "GLOBAL" && + line[3] == "LIBRARY" ) + { + len=length(line[4]) + libr = substr(line[4],4,len) + library = removeComment( libr ) + break + } + } + if ( library == "" ) + library = "C++" +} + +# +# Searches for the 'FILENAME' section and sets 'filename' to the value found. +# +function findFilename() +{ + for ( i=0; i<=num; i++ ) + { + split( lines[i], line, "\n" ) + if ( line[1] == "INFO" && + line[2] == "GLOBAL" && + ( line[3] == "FILENAME" || + line[3] == "RCSID" || + line[3] == "SCCSID" ) ) + { + filename = removeComment( line[4] ) + if ( line[3] == "RCSID" ) + { + sub( "^.*\\$Id:[\t ]*", "", filename ) + sub( ",v.*$", "", filename ) + } + else if ( line[3] == "SCCSID" ) + { + sub( "^.*@\\(#\\)", "", filename ) + sub( "[\t ]+.*$", "", filename ) + } + break + } + } +} + +# +# Outputs a prototype, wrapping it if required. +# +function outputPrototype( prototype ) +{ + sub( "[\t ]*$", "", prototype ) + if ( prototype !~ "^.*;$" ) + prototype = prototype ";" + + if ( device == "text" ) + width = 70 + else if ( device == "troff" ) + width = 70 + else if ( device == "mml" ) + width = 60 + + if ( length(prototype) > width ) + { + # multiline enums,functions have no spaces at the beginning, insert it! + if ( device == "mml" ) + { + gsub( ">", "\\>", prototype ) + gsub( "<", "\\<", prototype ) + } + if ( ( funcptr = match( prototype, "^[^(]*\\([^)]*\\)\\(" ) ) !~ "0" ) + match( prototype, "^[^(]*\\([^)]*\\)" ) + else + match( prototype, "^[^(]*\\(" ) + funcname = substr( prototype, RSTART, RLENGTH ) + if ( prototype ~ "^[^(]*\\(\\)[\t ]*\\(" ) + { + funcname = funcname ")(" + sub( "^[^(]*\\(\\)[\t ]*\\(", "", prototype ) + } + else + { + if ( funcptr ~ "0" ) + sub( "^[^(]*\\(", "", prototype ) + else + sub( "^[^(]*\\([^)]*\\)\\(", "", prototype ) + } + match( prototype, "\\)([\t ]*)?(=[\t ]*0|const[\t ]*(=[\t ]*0)?)?;[\t ]*" ) + functail = substr( prototype, RSTART, RLENGTH ) + sub( "\\)([\t ]*)?(=[\t ]*0|const[\t ]*(=[\t ]*0)?)?;.*$", "", prototype ) + sub( "\\($", "", funcname ) + match( funcname, "^[\t ]*" ) + space = substr( funcname, RSTART, RLENGTH ) + if (funcname != "") + { + # multiline enums or long typedefs have no funcname, so do not print it! + if ( device == "text" ) + { + printf( funcname ) + printf( "(\n" ) +#printf("\n---funcname=|%s|----\n",funcname); + } + else if ( device == "troff" ) + { + printf( "\\f(CO" funcname ) + printf( "(\n" ) + } + else if ( device = "mml" ) + { + gsub( " ", "\\ ", space ) + gsub( " ", "\\ ", funcname ) + printf( "%s(\n", funcname ) + } + } + narg = 0 + while ( match( prototype, "[^<>,#]*<[^<>]*>" ) ) + { + # collect the multiple line arguments + narg++ + arg = substr( prototype, RSTART, RLENGTH ) + sub( "[^<>,#]*<[^<>]*>", "#" narg, prototype ) + fargs["#" narg] = arg + # Need the following to stop resubstitution of the pattern matched + # back into the string. + gsub( "&", "\\\\&", fargs["#" narg] ) + } + numargs = split( prototype, args, "," ) +#------ + space = "" + for (z=1; z<=(nesting_level+1); z++) + space = space " " +# printf( "%s",outspace) +#------ + + for ( m=1; m<=numargs; m++ ) + { + while ( match( args[m], "#[0-9]+" ) ) + { + arg = substr( args[m], RSTART, RLENGTH ) + sub( arg, fargs[arg], args[m] ) + } + sub( "[\t ]*", "", args[m] ) + + # print one argument + +# printf( "%s %s", space, args[m] ) + printf( "%s%s", space, args[m] ) + if ( m == numargs ) + { + # print after the last argument + + if ( device == "text" ) + print( "" ) + else if ( device == "troff" ) + print( "" ) + else if ( device == "mml" ) + printf( "\n" ) + } + else + { + # print after each argument of a line + + if ( device == "text" ) + print( "," ) + else if ( device == "troff" ) + print( "," ) + else if ( device == "mml" ) + printf( ",\n" ) + } + } + # print after all arguments of a multiline are printed + + if ( device == "text" ) + print( space functail "\ " ) + else if ( device == "troff" ) + print( space functail "\\fP" ) + else if ( device == "mml" ) + print( space functail "" ) + + } + else # prototype < width + { + # not multiline enums,functions have spaces at the beginning already! + if ( device == "mml" ) + { + gsub( ">", "\\>", prototype ) + gsub( "<", "\\<", prototype ) + } + if ( device == "text" ) + print( prototype "\ " ) + else if ( device == "troff" ) + print( "\\f(CO" prototype "\\fP" ) + else if ( device == "mml" ) + { + gsub( " ", "\\ ", prototype ) + print( "" prototype "" ) + } + } +} + +#============================================================= +# neue rkursive parse function fuer nested ADTs +#============================================================= +function parse_and_print_adt (baseandsubclass, class, oldclass, baseindex, type) +{ + # 3.11.95 + bases = "" + + nesting_level++ + printf( "\n") +# printf("\nclass=%s oldclass=%s nesting_level=%s\n",class,oldclass,nesting_level); + if ( baseindex != 0 ) + { + for ( i=baseindex; i<=numfields; i++ ) + { + if ( bases == "" ) + bases = line[i] + else + bases = bases ", " line[i] + } + } + + outspace = "" + for (z=1; z", "\\>", line[4] ) + printf( "template%s\n",line[4] ) + } +# typestat = line[2] " " line[3] + typestat = line[2] " " class + + outspace = "" + for (z=1; z%s", typestat ) + } + else + { + # + # ADT != template + # + typestat = type " " class + if ( device == "mml" ) + printf( "" ) + printf( "%s", typestat ) + } + + if ( bases != "" ) + { + # + # analyse if ADT has base classes + # + typestat = typestat " : " + printf( " : " ) + if ( length(typestat) + length(bases) > 70 ) + { + print( "" ) + if ( device == "mml" ) + printf( "" ) + narg = 0 + while ( match( bases, "[^<>,# ]*<[^<>]*>" ) ) + { + narg++ + arg = substr( bases, RSTART, RLENGTH ) + sub( "[^<>,# ]*<[^<>]*>", "#" narg, bases ) + bargs["#" narg] = arg + # Need the following to stop resubstitution of the pattern matched + # back into the string. + gsub( "&", "\\\\&", bargs["#" narg] ) + } + numbases = split( bases, base, "," ) + for ( m=1; m<=numbases; m++ ) + { + while ( match( base[m], "#[0-9]+" ) ) + { + arg = substr( base[m], RSTART, RLENGTH ) + sub( arg, bargs[arg], base[m] ) + } + sub( "^[\t ]*", "", base[m] ) + if ( device == "mml" ) + { + gsub( "<", "\\<", base[m] ) + gsub( ">", "\\>", base[m] ) + } + if ( device == "text" ) + printf( " %s", base[m] ) + else if ( device == "troff" ) + printf( " %s", base[m] ) + else + printf( "\\ \\ %s", base[m] ) + if ( m == numbases ) + print( "" ) + else + { + print( "," ) + if ( device == "mml" ) + printf( "" ) + } + } + } + else + { + if ( device == "mml" ) + { + gsub( "<", "\\<", bases ) + gsub( ">", "\\>", bases ) + } + print( bases ) + } + } + else + { + # + # ADT has no base classes + # + printf( "\n" ) + } + +#till start if (csaprintheader == "on") csa_print_class_end() + + outspace = "" + for (z=1; z{") + if ( access["public"] == "on" ) + { + # + # collecting loop over the public lines of 1 ADT + # + start = 0 + for ( i=0; i<=num; i++ ) + { + split( lines[i], line, "\n" ) + + # + # 3.11.95 check outermost access + # + if ( line[1] == "ACCESS") + { + outeraccess = line[3] + #printf("\n----- outeraccess = |%s| --------\n",outeraccess) + } + + # + # start for nesting ADT + # + if ( line[1] == "CLASS" || line[1] == "STRUCT" || line[1] == "UNION" ) + { + # + # check for a normal nested ADT + # + if ( line[2] ~ "(::|<)" && lastaccess == "public" && outeraccess == "public") + { + if (line[2] ~ "::") + { + len = length(line[2]) + match( line[2], "(::|<).*$") + newclass = substr( line[2],RSTART+2,RLENGTH) + thisclass = substr( line[2],1,RSTART-1) + if (class == thisclass) + { + # + # hier is a nested class, struct, or union found!!!!!!! + # + + basesubclass = line[2] + #printf("\n----basesubclass=|%s|-----\n",basesubclass) + #printf("\n----thisclass=|%s|---------newclass=|%s|-----\n",thisclass,newclass) + #printf("\n----RECURSION--class=|%s|--line[1]=|%s|--line[2]=|%s|---\n", \ + #class,line[1],line[2]); + + nesttype = lower[line[1]] + nestbaseindex = 3 + #printf("\nvor parse_and_print_adt: class=%s nesting_level=%s",class,nesting_level); + #printf("\ni=%s num=%s line[1]=|%s| line[2]=|%s| line[3]=|%s|\n", \ + #i,num,line[1],line[2],line[3]); + save_i = i + class = parse_and_print_adt(basesubclass,newclass,thisclass,nestbaseindex,nesttype) + i = save_i + #printf("\nafter parse_and_print_adt: class=%s nesting_level=%s",class,nesting_level); + #printf("\ni=%s num=%s line[1]=|%s| line[2]=|%s| line[3]=|%s|\n", \ + #i,num,line[1],line[2],line[3]); + start = 1 + continue + } + } + } + } + else + { + # + # check for a TEMPLATE nested ADT + # + if ( line[1] == "TEMPLATE" && line[2] ~ /(class|union|struct)/ && lastaccess == "public" && outeraccess == "public") + { + len = length(line[3]) + match( line[3], "(::|<).*$") + newclass = substr( line[3],RSTART+2,RLENGTH) + thisclass = substr( line[3],1,RSTART-1) + if (class == thisclass) + { + # + # hier is a nested class, struct, or union found!!!!!!! + # + + basesubclass = line[3] + #printf("\n----basesubclass=|%s|-----\n",basesubclass) + #printf("\n----thisclass=|%s|---------newclass=|%s|-----\n",thisclass,newclass) + #printf("\n---RECURSION--class=|%s|--line[1]=|%s|--line[2]=|%s|--line[3]=|%s|---\n", \ + #class,line[1],line[2],line[3]); + + nesttype = "template" + nestbaseindex = 5 + #printf("\nvor parse_and_print_adt: class=%s nesting_level=%s",class,nesting_level); + #printf("\ni=%s num=%s line[1]=|%s| line[2]=|%s| line[3]=|%s|\n", \ + #i,num,line[1],line[2],line[3]); + save_i = i + class = parse_and_print_adt(basesubclass,newclass,thisclass,nestbaseindex,nesttype) + i = save_i + #printf("\nafter parse_and_print_adt: class=%s nesting_level=%s",class,nesting_level); + #printf("\ni=%s num=%s line[1]=|%s| line[2]=|%s| line[3]=|%s|\n", \ + #i,num,line[1],line[2],line[3]); + start = 1 + continue + } + } + } + # + # end for nesting ADT + # + # + # now print the protoypes of the public ADT + # + if ( ( line[1] == "MEMBER" || + line[1] == "FUNC" || + line[1] == "TYPEDEF" || + line[1] == "ENUM" || + line[1] == "FRIEND" ) && + line[2] == class && + line[3] == "public" ) + { + outspace = "" + for (z=1; z\\ \\ public:" ) + } + outspace = "" + for (z=1; z<=nesting_level; z++) + outspace = outspace " " + if ( device == "text" ) + { + outputPrototype( outspace line[4] ) + } + else if ( device == "troff" ) + outputPrototype( outspace line[4] ) + else + { + printf( "" ) + outputPrototype( outspace line[4] ) + } + } + } + } + if ( access["protected"] == "on" ) + { + # + # collecting loop over the protected lines of 1 ADT + # + start = 0 + for ( i=0; i<=num; i++ ) + { + split( lines[i], line, "\n" ) + + # + # 3.11.95 check outermost access + # + if ( line[1] == "ACCESS") + { + outeraccess = line[3] + #printf("\n----- outeraccess = |%s| --------\n",outeraccess) + } + + # + # start for nesting ADT + # + if ( line[1] == "CLASS" || line[1] == "STRUCT" || line[1] == "UNION" ) + { + # + # check for a normal nested ADT + # + if ( line[2] ~ "(::|<)" && lastaccess == "protected" && outeraccess == "protected") + { + if (line[2] ~ "::") + { + len = length(line[2]) + match( line[2], "(::|<).*$") + newclass = substr( line[2],RSTART+2,RLENGTH) + thisclass = substr( line[2],1,RSTART-1) + if (class == thisclass) + { + # + # hier is a nested class, struct, or union found!!!!!!! + # + + basesubclass = line[2] + #printf("\n----basesubclass=|%s|-----\n",basesubclass) + #printf("\n----thisclass=|%s|---------newclass=|%s|-----\n",thisclass,newclass) + #printf("\n----RECURSION--class=|%s|--line[1]=|%s|--line[2]=|%s|---\n", \ + #class,line[1],line[2]); + + nesttype = lower[line[1]] + nestbaseindex = 3 + #printf("\nvor parse_and_print_adt: class=%s nesting_level=%s",class,nesting_level); + #printf("\ni=%s num=%s line[1]=|%s| line[2]=|%s| line[3]=|%s|\n", \ + #i,num,line[1],line[2],line[3]); + save_i = i + class = parse_and_print_adt(basesubclass,newclass,thisclass,nestbaseindex,nesttype) + i = save_i + #printf("\nafter parse_and_print_adt: class=%s nesting_level=%s",class,nesting_level); + #printf("\ni=%s num=%s line[1]=|%s| line[2]=|%s| line[3]=|%s|\n", \ + #i,num,line[1],line[2],line[3]); + start = 1 + continue + } + } + } + } + else + { + # + # check for a TEMPLATE nested ADT + # + if ( line[1] == "TEMPLATE" && line[2] ~ /(class|union|struct)/ && lastaccess == "protected" && outeraccess == "protected") + { + len = length(line[3]) + match( line[3], "(::|<).*$") + newclass = substr( line[3],RSTART+2,RLENGTH) + thisclass = substr( line[3],1,RSTART-1) + if (class == thisclass) + { + # + # hier is a nested class, struct, or union found!!!!!!! + # + + basesubclass = line[3] + #printf("\n----basesubclass=|%s|-----\n",basesubclass) + #printf("\n----thisclass=|%s|---------newclass=|%s|-----\n",thisclass,newclass) + #printf("\n---RECURSION--class=|%s|--line[1]=|%s|--line[2]=|%s|--line[3]=|%s|---\n", \ + #class,line[1],line[2],line[3]); + + nesttype = "template" + nestbaseindex = 5 + #printf("\nvor parse_and_print_adt: class=%s nesting_level=%s",class,nesting_level); + #printf("\ni=%s num=%s line[1]=|%s| line[2]=|%s| line[3]=|%s|\n", \ + #i,num,line[1],line[2],line[3]); + save_i = i + class = parse_and_print_adt(basesubclass,newclass,thisclass,nestbaseindex,nesttype) + i = save_i + #printf("\nafter parse_and_print_adt: class=%s nesting_level=%s",class,nesting_level); + #printf("\ni=%s num=%s line[1]=|%s| line[2]=|%s| line[3]=|%s|\n", \ + #i,num,line[1],line[2],line[3]); + start = 1 + continue + } + } + } + # + # end for nesting ADT + # + # + # now print the protoypes of the public ADT + # + if ( ( line[1] == "MEMBER" || + line[1] == "FUNC" || + line[1] == "TYPEDEF" || + line[1] == "ENUM" || + line[1] == "FRIEND" ) && + line[2] == class && + line[3] == "protected" ) + { + outspace = "" + for (z=1; z\\ \\ protected:" ) + } + outspace = "" + for (z=1; z<=nesting_level; z++) + outspace = outspace " " + if ( device == "text" ) + outputPrototype( outspace line[4] ) + else if ( device == "troff" ) + outputPrototype( outspace line[4] ) + else + { + printf( "" ) + outputPrototype( outspace line[4] ) + } + } + } + } + if ( access["private"] == "on" ) + { + # + # collecting loop over the private lines of 1 ADT + # + start = 0 + for ( i=0; i<=num; i++ ) + { + split( lines[i], line, "\n" ) + + # + # 3.11.95 check outermost access + # + if ( line[1] == "ACCESS") + { + outeraccess = line[3] + #printf("\n----- outeraccess = |%s| --------\n",outeraccess) + } + + # + # start for nesting ADT + # + if ( line[1] == "CLASS" || line[1] == "STRUCT" || line[1] == "UNION" ) + { + # + # check for a normal nested ADT + # + if ( line[2] ~ "(::|<)" && lastaccess == "private" && outeraccess == "private") + { + if (line[2] ~ "::") + { + len = length(line[2]) + match( line[2], "(::|<).*$") + newclass = substr( line[2],RSTART+2,RLENGTH) + thisclass = substr( line[2],1,RSTART-1) + if (class == thisclass) + { + # + # hier is a nested class, struct, or union found!!!!!!! + # + + basesubclass = line[2] + #printf("\n----basesubclass=|%s|-----\n",basesubclass) + #printf("\n----thisclass=|%s|---------newclass=|%s|-----\n",thisclass,newclass) + #printf("\n----RECURSION--class=|%s|--line[1]=|%s|--line[2]=|%s|---\n", \ + #class,line[1],line[2]); + + nesttype = lower[line[1]] + nestbaseindex = 3 + #printf("\nvor parse_and_print_adt: class=%s nesting_level=%s",class,nesting_level); + #printf("\ni=%s num=%s line[1]=|%s| line[2]=|%s| line[3]=|%s|\n", \ + #i,num,line[1],line[2],line[3]); + save_i = i + class = parse_and_print_adt(basesubclass,newclass,thisclass,nestbaseindex,nesttype) + i = save_i + #printf("\nafter parse_and_print_adt: class=%s nesting_level=%s",class,nesting_level); + #printf("\ni=%s num=%s line[1]=|%s| line[2]=|%s| line[3]=|%s|\n", \ + #i,num,line[1],line[2],line[3]); + start = 1 + continue + } + } + } + } + else + { + # + # check for a TEMPLATE nested ADT + # + if ( line[1] == "TEMPLATE" && line[2] ~ /(class|union|struct)/ && lastaccess == "private" && outeraccess == "private") + { + len = length(line[3]) + match( line[3], "(::|<).*$") + newclass = substr( line[3],RSTART+2,RLENGTH) + thisclass = substr( line[3],1,RSTART-1) + if (class == thisclass) + { + # + # hier is a nested class, struct, or union found!!!!!!! + # + + basesubclass = line[3] + #printf("\n----basesubclass=|%s|-----\n",basesubclass) + #printf("\n----thisclass=|%s|---------newclass=|%s|-----\n",thisclass,newclass) + #printf("\n---RECURSION--class=|%s|--line[1]=|%s|--line[2]=|%s|--line[3]=|%s|---\n", \ + #class,line[1],line[2],line[3]); + + nesttype = "template" + nestbaseindex = 5 + #printf("\nvor parse_and_print_adt: class=%s nesting_level=%s",class,nesting_level); + #printf("\ni=%s num=%s line[1]=|%s| line[2]=|%s| line[3]=|%s|\n", \ + #i,num,line[1],line[2],line[3]); + save_i = i + class = parse_and_print_adt(basesubclass,newclass,thisclass,nestbaseindex,nesttype) + i = save_i + #printf("\nafter parse_and_print_adt: class=%s nesting_level=%s",class,nesting_level); + #printf("\ni=%s num=%s line[1]=|%s| line[2]=|%s| line[3]=|%s|\n", \ + #i,num,line[1],line[2],line[3]); + start = 1 + continue + } + } + } + # + # end for nesting ADT + # + # + # now print the protoypes of the public ADT + # + if ( ( line[1] == "MEMBER" || + line[1] == "FUNC" || + line[1] == "TYPEDEF" || + line[1] == "ENUM" || + line[1] == "FRIEND" ) && + line[2] == class && + line[3] == "private" ) + { + outspace = "" + for (z=1; z\\ \\ private:" ) + } + outspace = "" + for (z=1; z<=nesting_level; z++) + outspace = outspace " " + if ( device == "text" ) + outputPrototype( outspace line[4] ) + else if ( device == "troff" ) + outputPrototype( outspace line[4] ) + else + { + printf( "" ) + outputPrototype( outspace line[4] ) + } + } + } + } + outspace = "" + for (z=1; z};" ) + } + nesting_level-- + return oldclass +} diff --git a/bin/info2doc.fmt b/bin/info2doc.fmt new file mode 100644 index 00000000000..ef0b0331543 --- /dev/null +++ b/bin/info2doc.fmt @@ -0,0 +1,23 @@ +start +hide section FILENAME +hide section COPYRIGHT +print prelude +print title +print synopsis +print section CLASS TYPE +print section AUDIENCE +print section DESCRIPTION +print section EXAMPLE +print contract * +print section * +print section NOTES +print section PORTABILITY +print section SEE ALSO +print section LIBRARY +print section VERSION +print section DATE RELEASED +print section RCSID +print section SCCSID +print section AUTHOR(S) +print copyright +end diff --git a/bin/info2head b/bin/info2head new file mode 100755 index 00000000000..de8efa99c14 --- /dev/null +++ b/bin/info2head @@ -0,0 +1,166 @@ +#! /bin/sh +# ============================================================================= +# +# = DESCRIPTION +# Front end to awk script for generating manual pages from classinfo +# files. +# +# = AUTHOR(S) +# Graham Dumpleton +# K. Dorn +# +# = COPYRIGHT +# Copyright 1991 OTC LIMITED +# Copyright 1994 DUMPLETON SOFTWARE CONSULTING PTY LIMITED +# +# ============================================================================= + +OSE_HOST= + +OSE_RELEASE_NAME= +export OSE_RELEASE_NAME + +OSE_ROOT=${OSE_ROOT-$WRAPPER_ROOT} +export OSE_ROOT + +OSE_VERSION_ROOT=$OSE_ROOT +export OSE_VERSION_ROOT + +BINDIR="$OSE_VERSION_ROOT/$OSE_HOST/bin" +LIBDIR=${CLASSINFOLIBDIR-"$OSE_VERSION_ROOT/bin"} + +AWK="${AWK-nawk}" + + +if test "$AWK" = "nawk" +then + VARG="-v" +fi + +EXT="3" + +# +# Error. +# +ERROR() +{ + echo "`basename $0`: $1" >&2 + shift + while test $# != "0" + do + echo $1 >&2 + shift + done + exit 1 +} + +# +# Usage message. +# +USAGE() +{ + ERROR "Usage: `basename $0` file.ci" +} + +# +# Check usage. +# +if test $# != "1" -o "'basename $1 .ci'" = "$1" +then + USAGE +fi + +# +# Check for awk file etc. +# +INFO2DOC=$LIBDIR/info2doc.awk +MANFMT=$LIBDIR/info2head.fmt +HIDINGFMT=$LIBDIR/hiding.fmt + +if test ! -f $HIDINGFMT +then + ERROR "Can't find $HIDINGFMT" +fi + +if test ! -f $INFO2DOC +then + ERROR "Can't find $INFO2DOC" +fi + +if test ! -f $MANFMT +then + ERROR "Can't find $MANFMT" +fi + + + +ADTS=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^(CLASS|STRUCT|UNION)$" && $2 !~ "(::|<)" { + printf( "%s\n", $2 ) +} +$1 ~ "^TEMPLATE$" && $3 !~ "::" { + printf( "%s\n", $3 ) +}' $1` + + +VPUBL=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^PUBLIC$" { + if ( $2 ~ "on" ) + printf("%s","publ=on"); + else + printf("%s","publ="); +}' $HIDINGFMT` + +VPROT=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^PROTECTED$" { + if ( $2 ~ "on" ) + printf("%s","prot=on"); + else + printf("%s","prot="); +}' $HIDINGFMT` + +VPRIV=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^PRIVATE$" { + if ( $2 ~ "on" ) + printf("%s","priv=on"); + else + printf("%s","priv="); +}' $HIDINGFMT` + +echo " $VPUBL $VPROT $VPRIV " + + +# $VARG publ=on $VARG prot= $VARG priv= \ +# $VARG $VPUBL $VARG $VPROT $VARG $VPRIV \ +if test ! -z "$ADTS" +then + for ADT in $ADTS + do + echo "$ADT" + + echo "making $ADTS.hxx file ..." + $AWK -f $INFO2DOC \ + $VARG $VPUBL $VARG $VPROT $VARG $VPRIV \ + $VARG pass=0 $VARG device=text $VARG infile=$1 \ + $VARG class=$ADT \ + $MANFMT $MANFMT > $ADT.$EXT +# troff -a $ADT.$EXT > $ADT.hxx + cp $ADT.$EXT $ADT.hxx + echo "$ADTS.hxx file done!" +# echo "removing $ADTS.$EXT file ..." + \rm $ADT.$EXT +# echo "file $ADTS.$EXT file removed!" + done +fi diff --git a/bin/info2head.fmt b/bin/info2head.fmt new file mode 100644 index 00000000000..87eb1c8b1d0 --- /dev/null +++ b/bin/info2head.fmt @@ -0,0 +1,23 @@ +start +hide section FILENAME +hide section COPYRIGHT +hide prelude +hide title +print synopsis +hide section CLASS TYPE +hide section AUDIENCE +hide section DESCRIPTION +hide section EXAMPLE +hide contract * +hide section * +hide section NOTES +hide section PORTABILITY +hide section SEE ALSO +hide section LIBRARY +hide section VERSION +hide section DATE RELEASED +hide section RCSID +hide section SCCSID +hide section AUTHOR(S) +hide copyright +end diff --git a/bin/info2headsrc b/bin/info2headsrc new file mode 100755 index 00000000000..cc2c1f999dd --- /dev/null +++ b/bin/info2headsrc @@ -0,0 +1,326 @@ +#! /bin/sh +# ============================================================================= +# +# = DESCRIPTION +# Front end to awk script for generating .hxx and .hxx files +# from classinfo files. +# +# = AUTHOR(S) +# K. Dorn +# +# +# ============================================================================= + +OSE_HOST= + +OSE_RELEASE_NAME= +export OSE_RELEASE_NAME + +OSE_ROOT=${OSE_ROOT-$WRAPPER_ROOT} +export OSE_ROOT + +OSE_VERSION_ROOT=$OSE_ROOT +export OSE_VERSION_ROOT + +BINDIR="$OSE_VERSION_ROOT/$OSE_HOST/bin" +LIBDIR=${CLASSINFOLIBDIR-"$OSE_VERSION_ROOT/bin"} + +AWK="${AWK-nawk}" + + +if test "$AWK" = "nawk" +then + VARG="-v" +fi + +EXT="3" + +# +# Error. +# +ERROR() +{ + echo "`basename $0`: $1" >&2 + shift + while test $# != "0" + do + echo $1 >&2 + shift + done + exit 1 +} + +# +# Usage message. +# +USAGE() +{ + ERROR "Usage: `basename $0` file.ci" +} + +# +# Check usage. +# +if test $# != "1" -o "'basename $1 .ci'" = "$1" +then + USAGE +fi + + +# +# Check for awk file etc. +# +INFO2SRC=$BINDIR/info2src.awk +INFO2DOC=$LIBDIR/info2doc.awk +MANFMT=$LIBDIR/info2head.fmt +HIDINGFMT=$LIBDIR/hiding.fmt +VENDORFMT=$LIBDIR/vendor.fmt + +if test ! -f $VENDORFMT +then + ERROR "Can't find $VENDORFMT" +fi + +if test ! -f $HIDINGFMT +then + ERROR "Can't find $HIDINGFMT" +fi + +if test ! -f $INFO2DOC +then + ERROR "Can't find $INFO2DOC" +fi + +if test ! -f $MANFMT +then + ERROR "Can't find $MANFMT" +fi + +ADTS=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^(CLASS|STRUCT|UNION)$" && $2 !~ "(::|<)" { + printf( "%s\n", $2 ) +} +$1 ~ "^TEMPLATE$" && $3 !~ "::" { + printf( "%s\n", $3 ) +}' $1` + + + +VMERGE=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^CSAMERGECXXHXX$" { + if ( $2 ~ "on" ) + printf("%s","merge=on"); + else + printf("%s","merge="); +}' $HIDINGFMT` + +VCSA=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^CSAHEADER$" { + if ( $2 ~ "on" ) + printf("%s","csaprintheader=on"); + else + printf("%s","csaprintheader="); +}' $HIDINGFMT` + +VPUBL=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^PUBLIC$" { + if ( $2 ~ "on" ) + printf("%s","publ=on"); + else + printf("%s","publ="); +}' $HIDINGFMT` + +VPROT=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^PROTECTED$" { + if ( $2 ~ "on" ) + printf("%s","prot=on"); + else + printf("%s","prot="); +}' $HIDINGFMT` + +VPRIV=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^PRIVATE$" { + if ( $2 ~ "on" ) + printf("%s","priv=on"); + else + printf("%s","priv="); +}' $HIDINGFMT` + + + + +VCOCXX=`$AWK ' +BEGIN { + FS=""; RS="" +} +/VENDOR_COMPILATION_HEADER_CXX_START/, /VENDOR_COMPILATION_HEADER_CXX_END/ { +sub("^VENDOR_COMPILATION_HEADER_CXX_START\n","",$0) +sub("VENDOR_COMPILATION_HEADER_CXX_END$","",$0) + +gsub( / \\\" /, "999", $0 ) +gsub( "\"\\[\t ]*", "234", $0 ) +gsub( "234\\\n", "345", $0 ) +gsub( /234.\n/, "456", $0 ) +gsub( /456[\t ]*234/, "567", $0 ) +gsub( /567/, "", $0 ) +gsub( /234/, "", $0 ) +gsub( /345/, "", $0 ) +gsub( "999", "\"", $0 ) + +print $0 +}' $VENDORFMT` + + +VMECXX=`$AWK ' +BEGIN { + FS=""; RS="" +} +/VENDOR_METHOD_HEADER_CXX_START/, /VENDOR_METHOD_HEADER_CXX_END/ { +sub("^VENDOR_METHOD_HEADER_CXX_START\n","",$0) +sub("VENDOR_METHOD_HEADER_CXX_END$","",$0) + +gsub( / \\\" /, "999", $0 ) +gsub( "\"\\[\t ]*", "234", $0 ) +gsub( "234\\\n", "345", $0 ) +gsub( /234.\n/, "456", $0 ) +gsub( /456[\t ]*234/, "567", $0 ) +gsub( /567/, "", $0 ) +gsub( /234/, "", $0 ) +gsub( /345/, "", $0 ) +gsub( "999", "\"", $0 ) + +print $0 +}' $VENDORFMT` + +VCOHXX=`$AWK ' +BEGIN { + FS=""; RS="" +} +/VENDOR_COMPILATION_HEADER_HXX_START/, /VENDOR_COMPILATION_HEADER_HXX_END/ { +sub("^VENDOR_COMPILATION_HEADER_HXX_START\n","",$0) +sub("VENDOR_COMPILATION_HEADER_HXX_END$","",$0) + +gsub( / \\\" /, "999", $0 ) +gsub( "\"\\[\t ]*", "234", $0 ) +gsub( "234\\\n", "345", $0 ) +gsub( /234.\n/, "456", $0 ) +gsub( /456[\t ]*234/, "567", $0 ) +gsub( /567/, "", $0 ) +gsub( /234/, "", $0 ) +gsub( /345/, "", $0 ) +gsub( "999", "\"", $0 ) + +print $0 +}' $VENDORFMT` + + +VCLHXX=`$AWK ' +BEGIN { + FS=""; RS="" +} +/VENDOR_CLASS_HEADER_HXX_START/, /VENDOR_CLASS_HEADER_HXX_END/ { +sub("^VENDOR_CLASS_HEADER_HXX_START\n","",$0) +sub("VENDOR_CLASS_HEADER_HXX_END$","",$0) + +gsub( / \\\" /, "999", $0 ) +gsub( "\"\\[\t ]*", "234", $0 ) +gsub( "234\\\n", "345", $0 ) +gsub( /234.\n/, "456", $0 ) +gsub( /456[\t ]*234/, "567", $0 ) +gsub( /567/, "", $0 ) +gsub( /234/, "", $0 ) +gsub( /345/, "", $0 ) +gsub( "999", "\"", $0 ) + +print $0 +}' $VENDORFMT` + + +echo " $VCOCXX " > vcocxx.txt +echo " $VMECXX " > vmecxx.txt +echo " $VCOHXX " > vcohxx.txt +echo " $VCLHXX " > vclhxx.txt + + + +echo " $VPUBL $VPROT $VPRIV $VCSA $VMERGE" + +# +# get from *.ci file the classes that should separated +# and make the .hxx and .cxx files +# +if test ! -z "$ADTS" +then + LASTADT="" + LOPCNT=1 + BASEFILENAME=`basename $1` + HXXMERGEFILE=`echo $BASEFILENAME | sed -e 's/\..*$//'`.mhxx + CXXMERGEFILE=`echo $BASEFILENAME | sed -e 's/\..*$//'`.mcxx + rm -f $HXXMERGEFILE + rm -f $CXXMERGEFILE + for ADT in $ADTS + do + if test "$LASTADT" != "$ADT" + then + echo "loop = $LOPCNT" + echo "$ADT" + + echo "making $ADTS.hxx file ..." + $AWK -f $INFO2DOC \ + $VARG fvclhxx=vclhxx.txt \ + $VARG fvcohxx=vcohxx.txt \ + $VARG $VPUBL $VARG $VPROT $VARG $VPRIV $VARG $VCSA $VARG $VMERGE \ + $VARG pass=0 $VARG device=text $VARG infile=$1 \ + $VARG class=$ADT $VARG loop=$LOPCNT\ + $MANFMT $MANFMT > $ADT.hxx + echo "$ADTS.hxx file done!" + if test "$VMERGE" = "merge=on" + then + echo "merging $ADT.hxx into $HXXMERGEFILE" + cat $ADT.hxx >> $HXXMERGEFILE + fi + + echo "making $ADTS.cxx file ..." + $AWK -f $INFO2SRC \ + $VARG fvmecxx=vmecxx.txt \ + $VARG fvcocxx=vcocxx.txt \ + $VARG $VPUBL $VARG $VPROT $VARG $VPRIV $VARG $VCSA $VARG $VMERGE \ + $VARG infile=$1 $VARG classext=$ADT $VARG mode=single $VARG loop=$LOPCNT\ + $1 > $ADT.cxx + echo "$ADTS.cxx file done!" + if test "$VMERGE" = "merge=on" + then + echo "merging $ADT.cxx into $CXXMERGEFILE" + cat $ADT.cxx >> $CXXMERGEFILE + fi + + LOPCNT=`expr $LOPCNT + 1` + LASTADT=$ADT + fi + done +fi +# +# remove temporary vendor files +# +rm -f vcocxx.txt +rm -f vmecxx.txt +rm -f vcohxx.txt +rm -f vclhxx.txt diff --git a/bin/info2man b/bin/info2man new file mode 100755 index 00000000000..21d3746d6a9 --- /dev/null +++ b/bin/info2man @@ -0,0 +1,169 @@ +#! /bin/sh +# ============================================================================= +# +# = DESCRIPTION +# Front end to awk script for generating manual pages from classinfo +# files. +# +# = AUTHOR(S) +# Graham Dumpleton +# K. Dorn +# +# = COPYRIGHT +# Copyright 1991 OTC LIMITED +# Copyright 1994 DUMPLETON SOFTWARE CONSULTING PTY LIMITED +# +# ============================================================================= + +OSE_HOST= + +OSE_RELEASE_NAME= +export OSE_RELEASE_NAME + +OSE_ROOT=${OSE_ROOT-$WRAPPER_ROOT} +export OSE_ROOT + +OSE_VERSION_ROOT=$OSE_ROOT +export OSE_VERSION_ROOT + +BINDIR="$OSE_VERSION_ROOT/$OSE_HOST/bin" +LIBDIR=${CLASSINFOLIBDIR-"$OSE_VERSION_ROOT/bin"} + +AWK="${AWK-nawk}" + +if test "$AWK" = "nawk" +then + VARG="-v" +fi + +EXT="3" + +# +# Error. +# +ERROR() +{ + echo "`basename $0`: $1" >&2 + shift + while test $# != "0" + do + echo $1 >&2 + shift + done + exit 1 +} + +# +# Usage message. +# +USAGE() +{ + ERROR "Usage: `basename $0` file.ci" +} + +# +# Check usage. +# +if test $# != "1" -o "'basename $1 .ci'" = "$1" +then + USAGE +fi + +# +# Check for awk file etc. +# +INFO2MAN=$LIBDIR/info2doc.awk +MANFMT=$LIBDIR/info2doc.fmt +HIDINGFMT=$LIBDIR/hiding.fmt + +if test ! -f $HIDINGFMT +then + ERROR "Can't find $HIDINGFMT" +fi + +if test ! -f $INFO2MAN +then + ERROR "Can't find $INFO2MAN" +fi + +if test ! -f $MANFMT +then + ERROR "Can't find $MANFMT" +fi + + + + +ADTS=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^(CLASS|STRUCT|UNION)$" && $2 !~ "(::|<)" { + printf( "%s\n", $2 ) +} +$1 ~ "^TEMPLATE$" && $3 !~ "::" { + printf( "%s\n", $3 ) +}' $1` + + + +VCSA=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^CSAHEADER$" { + if ( $2 ~ "on" ) + printf("%s","csaprintheader=off"); + else + printf("%s","csaprintheader=off"); +}' $HIDINGFMT` + +VPUBL=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^PUBLIC$" { + if ( $2 ~ "on" ) + printf("%s","publ=on"); + else + printf("%s","publ="); +}' $HIDINGFMT` + +VPROT=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^PROTECTED$" { + if ( $2 ~ "on" ) + printf("%s","prot=on"); + else + printf("%s","prot="); +}' $HIDINGFMT` + +VPRIV=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^PRIVATE$" { + if ( $2 ~ "on" ) + printf("%s","priv=on"); + else + printf("%s","priv="); +}' $HIDINGFMT` + +echo " $VPUBL $VPROT $VPRIV $VCSA " + + + +if test ! -z "$ADTS" +then + for ADT in $ADTS + do + echo "$ADT" + + $AWK -f $INFO2MAN \ + $VARG $VPUBL $VARG $VPROT $VARG $VPRIV $VARG $VCSA \ + $VARG pass=0 $VARG device=troff $VARG infile=$1 \ + $VARG class=$ADT $MANFMT $MANFMT > $ADT.$EXT + done +fi diff --git a/bin/info2mml b/bin/info2mml new file mode 100755 index 00000000000..21257927f42 --- /dev/null +++ b/bin/info2mml @@ -0,0 +1,166 @@ +#! /bin/sh +# ============================================================================= +# +# = DESCRIPTION +# Front end to awk script for generating Frame mml from classinfo +# files. +# +# = AUTHOR(S) +# Graham Dumpleton +# K. Dorn +# +# = COPYRIGHT +# Copyright 1991 OTC LIMITED +# Copyright 1994 DUMPLETON SOFTWARE CONSULTING PTY LIMITED +# +# ============================================================================= + +OSE_HOST= + +OSE_RELEASE_NAME= +export OSE_RELEASE_NAME + +OSE_ROOT=${OSE_ROOT-$WRAPPER_ROOT} +export OSE_ROOT + +OSE_VERSION_ROOT=$OSE_ROOT/$OSE_RELEASE_NAME +export OSE_VERSION_ROOT + +BINDIR="$OSE_VERSION_ROOT/$OSE_HOST/bin" +LIBDIR=${CLASSINFOLIBDIR-"$OSE_VERSION_ROOT/bin"} + +AWK="${AWK-nawk}" + +if test "$AWK" = "nawk" +then + VARG="-v" +fi + +EXT="mml" + +# +# Error. +# +ERROR() +{ + echo "`basename $0`: $1" >&2 + shift + while test $# != "0" + do + echo $1 >&2 + shift + done + exit 1 +} + +# +# Usage message. +# +USAGE() +{ + ERROR "Usage: `basename $0` file.ci" +} + +# +# Check usage. +# +if test $# != "1" -o "'basename $1 .ci'" = "$1" +then + USAGE +fi + +# +# Check for awk file etc. +# +INFO2MAN=$LIBDIR/info2doc.awk +HIDINGFMT=$LIBDIR/hiding.fmt +MANFMT=$LIBDIR/info2doc.fmt + + +if test ! -f $HIDINGFMT +then + ERROR "Can't find $HIDINGFMT" +fi + +if test ! -f $INFO2MAN +then + ERROR "Can't find $INFO2MAN" +fi + +if test ! -f $MANFMT +then + ERROR "Can't find $MANFMT" +fi + +ADTS=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^(CLASS|STRUCT|UNION)$" && $2 !~ "(::|<)" { + printf( "%s\n", $2 ) +} +$1 ~ "^TEMPLATE$" && $3 !~ "::" { + printf( "%s\n", $3 ) +}' $1` + + +VCSA=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^CSAHEADER$" { + if ( $2 ~ "on" ) + printf("%s","csaprintheader=off"); + else + printf("%s","csaprintheader=off"); +}' $HIDINGFMT` + +VPUBL=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^PUBLIC$" { + if ( $2 ~ "on" ) + printf("%s","publ=on"); + else + printf("%s","publ="); +}' $HIDINGFMT` + +VPROT=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^PROTECTED$" { + if ( $2 ~ "on" ) + printf("%s","prot=on"); + else + printf("%s","prot="); +}' $HIDINGFMT` + +VPRIV=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^PRIVATE$" { + if ( $2 ~ "on" ) + printf("%s","priv=on"); + else + printf("%s","priv="); +}' $HIDINGFMT` + +echo " $VPUBL $VPROT $VPRIV $VCSA " + + + +if test ! -z "$ADTS" +then + for ADT in $ADTS + do + echo "$ADT" + + $AWK -f $INFO2MAN \ + $VARG $VPUBL $VARG $VPROT $VARG $VPRIV $VARG $VCSA \ + $VARG pass=0 $VARG device=mml $VARG infile=$1 \ + $VARG class=$ADT $MANFMT $MANFMT > $ADT.$EXT + done +fi diff --git a/bin/info2src b/bin/info2src new file mode 100755 index 00000000000..e8e3847faf7 --- /dev/null +++ b/bin/info2src @@ -0,0 +1,133 @@ +#! /bin/sh +# ============================================================================= +# +# = DESCRIPTION +# Script to combine class2info and info2src. +# +# = AUTHOR(S) +# Graham Dumpleton +# K. Dorn +# +# = COPYRIGHT +# Copyright 1991 OTC LIMITED +# +# ============================================================================= + +OSE_HOST= + +OSE_RELEASE_NAME= +export OSE_RELEASE_NAME + +OSE_ROOT=${OSE_ROOT-$WRAPPER_ROOT} +export OSE_ROOT + +OSE_VERSION_ROOT=$OSE_ROOT/$OSE_RELEASE_NAME +export OSE_VERSION_ROOT + +BINDIR="$OSE_VERSION_ROOT/$OSE_HOST/bin" +LIBDIR=${CLASSINFOLIBDIR-"$OSE_VERSION_ROOT/bin"} + +AWK="nawk" + +# +# Error. +# +ERROR() +{ + echo "`basename $0`: $1" >&2 + shift + while test $# != "0" + do + echo $1 >&2 + shift + done + exit 1 +} + +# +# Usage message. +# +USAGE() +{ + ERROR "Usage: `basename $0` file.ci" +} + +if test $# != "1" -o "'basename $1 .ci'" = "$1" +then + USAGE +fi + +# +# Check for awk file. +# +INFO2SRC=$BINDIR/info2src.awk +HIDINGFMT=$LIBDIR/hiding.fmt + +file=`basename $1` +base="`echo $file | sed -e 's/\..*$//'`" + +if test ! -f $INFO2SRC +then + ERROR "Can't find $INFO2SRC" +fi + +if test ! -f $HIDINGFMT +then + ERROR "Can't find $HIDINGFMT" +fi + + +VCSA=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^CSAHEADER$" { + if ( $2 ~ "on" ) + printf("%s","csaprintheader=on"); + else + printf("%s","csaprintheader="); +}' $HIDINGFMT` + +VPUBL=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^PUBLIC$" { + if ( $2 ~ "on" ) + printf("%s","publ=on"); + else + printf("%s","publ="); +}' $HIDINGFMT` + +VPROT=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^PROTECTED$" { + if ( $2 ~ "on" ) + printf("%s","prot=on"); + else + printf("%s","prot="); +}' $HIDINGFMT` + +VPRIV=`$AWK ' +BEGIN { + FS="\n"; RS="" +} +$1 ~ "^PRIVATE$" { + if ( $2 ~ "on" ) + printf("%s","priv=on"); + else + printf("%s","priv="); +}' $HIDINGFMT` + +echo " $VPUBL $VPROT $VPRIV $VCSA " + + +# $VARG publ=on $VARG prot=on $VARG priv=on \ +echo "making $base.cxx file ..." +$AWK -f $INFO2SRC \ + $VARG $VPUBL $VARG $VPROT $VARG $VPRIV $VARG $VCSA \ + $VARG infile=$1 $VARG classext= $VARG mode=multiple \ + $1 > $base.cxx +echo "$base.cxx file done!" diff --git a/bin/info2src.awk b/bin/info2src.awk new file mode 100755 index 00000000000..1a8b19ae964 --- /dev/null +++ b/bin/info2src.awk @@ -0,0 +1,630 @@ +# ============================================================================= +# +# = DESCRIPTION +# Awk script to convert classinfo description file to src stubs. +# +# = AUTHOR(S) +# Graham Dumpleton +# K. Dorn +# +# = COPYRIGHT +# Copyright 1991 OTC LIMITED +# +# ============================================================================= + +BEGIN { +# separator = "/* ------------------------------"\ +# "------------------------------------------- */" + separator = "" + csa_method_trailer=sprintf("\n/*] END Method */\n\n") + FS="\n"; RS="" + firsttime = "first" + templ="" + blank=" " + classfunc = "" + rettyp = "" + classname="" + classtitle="" + filedate="" + filename="" + filename1="" + author="" + classdescription="" + methoddescription="" + +# csaprintheader=1 + +# accpubl = "off" +# accprot = "off" +# accpriv = "off" +} +# +# variable von awk sind nicht in begin zuweisbar! +# +{ + accmergecxxhxx = merge + accloop = loop + accpubl = publ + accprot = prot + accpriv = priv +#printf("\nmerge=%s loop=%s csaprintheader=%s firsttime=%s\n",merge,loop,csaprintheader,firsttime); +} + +function csa_print_compilation_header_alt() +{ + if ( length( firsttime ) > 3 ) + { + + csa_compilation_header=sprintf("\n/*[ Compilation unit "\ + "----------------------------------------------------------\n"\ + "\n"\ + " Component : CSA - OSC\n"\ + "\n"\ + " Name : %s.[Ci]\n"\ + "\n"\ + " Author : %s\n"\ + "\n"\ + " Language : C++\n"\ + "\n"\ + " Creation Date : %s\n"\ + "\n"\ + " Test State : %%Q%%\n"\ + "\n"\ + " Description : %s\n"\ + "\n"\ + "\n"\ + " Copyright (C) Siemens AG 1995 All Rights Reserved\n"\ + "\n"\ + "--------------------------------------"\ + "---------------------------------------*/\n"\ + "/*] END */\n"\ + "#pragma ident \"%%Z%% %%M%% %%I%% (%%G%%), %%Y%% %%Q%%:"\ + " implementation file for class \n"\ + "%s\"\n"\ + "\n"\ + "#undef __STDC__\n"\ + "#undef __GNUG__\n"\ + "\n",filename1,author,filedate,classdescription,names[$2]); + printf("%s",csa_compilation_header); + firsttime = "" + } +} + +function csa_print_compilation_header() +{ + if ((csaprintheader == "on" && merge != "on") || (merge == "on" && loop == "1")) + { + if ( length( firsttime ) > 3 ) + { + FS=" "; RS="\n" + read_fvmecxx_file() + read_fvcocxx_file() + FS="\n"; RS="" + + #csa_compilation_header=sprintf(vcocxx,filename1,author,filedate,classdescription,names[$2]); +csa_compilation_header=sprintf(vcocxx,filename1,author,filedate,classdescription,classname); + printf("%s",csa_compilation_header); + firsttime = "" + } + } + else if (csaprintheader == "on" && merge == "on" && loop != "1" && length( firsttime ) > 3) + { + FS=" "; RS="\n" + read_fvmecxx_file() + read_fvcocxx_file() + FS="\n"; RS="" + firsttime = "" + } +} + +function csa_print_method_header_alt() +{ + prrettyp = "" + if (rettyp != "") + prrettyp=sprintf("type = %s",rettyp); + else + prrettyp=sprintf("-"); + + csa_method_header=sprintf("\n/*[ Method ---------------------"\ + "-------------------------------------------\n"\ + "\n"\ + " Name : %s\n"\ + "\n"\ + " Description : %s\n"\ + "\n"\ + " Return : %s\n"\ + "\n"\ + "--------------------------------------------"\ + "------------------------------*/\n\n",classfunc,methoddescription,prrettyp) + printf("%s",csa_method_header); +} + +function csa_print_method_header() +{ + if (csaprintheader == "on") + { + prrettyp = "" + if (rettyp != "") + prrettyp=sprintf("type = %s",rettyp); + else + prrettyp=sprintf("-"); + + csa_method_header=sprintf(vmecxx,classfunc,methoddescription,prrettyp) + printf("%s",csa_method_header); + } +} + +function csa_print_method_trailer() +{ + if (csaprintheader == "on") + { + csa_method_trailer=sprintf("/*] END Method */\n") + printf("\n%s\n",csa_method_trailer); + } +} + +function csa_get_method_description() +{ + n = split( $0, line, "\n" ) + methoddescription="" + for ( i=5; i<=n; i++ ) + { + len = length(line[i]) + comm = substr(line[i],4,len) + methoddescription = methoddescription comm "\n " + } +} + + +function read_fvmecxx_file() +{ + vmecxx1 = "\n" + while ( getline < fvmecxx > 0 ) + vmecxx1 = vmecxx1 $0 "\n" + vmecxx = vmecxx1 +} + +function read_fvcocxx_file() +{ + vcocxx1 = "\n" + while ( getline < fvcocxx > 0 ) + vcocxx1 = vcocxx1 $0 "\n" + vcocxx = vcocxx1 +} + + +# +# hier laueft er durch mit allen zeilen +# + +$1 ~ /CLASS2INFO/ { + filedate=$2 + filename=$3 + len=length($3) + filename1=substr($3,1,(len-2)) +} + +$1 ~ /INFO/ && $2 ~ /GLOBAL/ && $3 ~ /LIBRARY/ { + library=$4 + len=length(library) + library=substr(library,4,len) + if ( merge != "on") + printf( "#include <%s/%s>\n", library, filename ) + else + if ( loop == "1") + printf( "#include <%s/%s>\n", library, filename ) +} + +$1 ~ /INFO/ && $2 ~ /GLOBAL/ && $3 ~ /AUTHOR/ { + l=length($4) + author=substr($4,4,l) +} + +$1 ~ /INFO/ && $2 ~ /HDR/ && $3 ~ /TITLE/ { + classname=$4 + classtitle=$5 +} + +$1 ~ /INFO/ && $2 ~ /HDR/ && $3 ~ /DESCRIPTION/ { + n = split( $0, line, "\n" ) + classdescription="" + for ( i=5; i<=n; i++ ) + { + len = length(line[i]) + comm = substr(line[i],4,len) + classdescription = classdescription comm "\n " + } +# if (csaprintheader == "on") +# csa_print_compilation_header() +} + +$1 ~ /INCLUDE/ { + if ( merge != "on") + printf( "#include %s\n", $2) +# else +# if ( loop == "1") +# printf( "#include %s\n", $2) +} + +# +# neu mit nested classes +# +$1 ~ /(CLASS|STRUCT|UNION)/ { + nestedclass = "" + nested = "" + templnested = "" + containerclass = "" + if ( $2 ~ "(::|<)" ) + { + len = length($2) + match( $2, "(::|<).*$") + newclass = substr( $2,RSTART+2,RLENGTH) + thisclass = substr( $2,1,RSTART-1) + if (thisclass == classext) + { + nestedclass = newclass + nested = "on" + containerclass = thisclass + class = newclass $3 # 23.10.95 + } + else + nestedclass = "" + } + else + { + names[$2] = $2 + } +} + +# +# neu mit nested classes +# +$1 ~ /TEMPLATE/ { + templnestedclass = "" + nested = "" + templnested = "" + if ( $2 ~ /(class|union|struct)/ && $3 ~ "(::|<)" ) + { + len = length($3) + match( $3, "(::|<).*$") + templnewclass = substr( $3,RSTART+2,RLENGTH) + templthisclass = substr( $3,1,RSTART-1) + if (templthisclass == classext) + { + templnestedclass = templnewclass + nestedtempl = $4 +#printf("\n------nestedtempl=%s----\n",nestedtempl); + class = templnewclass $4 + nestedtemplclass = templnewclass $4 + nested = "on" + templnested = "on" + containerclass = templthisclass + } + else + templnestedclass = "" + } + else + { + class = $3 $4 + templclass = $3 $4 + args[$3] = $4 + templ=$4 + # This needs extra work. + # + # macht aus: folgendes: + # + + sub( "<[\t ]*(class)[\t ]+", "<", class ) + sub( ",[\t ]*(class)[\t ]+", ",", class ) + + names[$3] = class + } +} + +# +# neu nested classes, achtung: nur level1 moeglich, da keine rekursion! +# +$1 ~ /END/ && $2 == class{ + nested= "" + templnested= "" +} + +# +# alt ohne nested classes +# +#$1 ~ /(CLASS|STRUCT|UNION)/ { +# names[$2] = $2 +#} + +# +# alt ohne nested classes +# +#$1 ~ /TEMPLATE/ { +# class = $3 $4 +# templclass = $3 $4 +# args[$3] = $4 +# templ=$4 +# # This needs extra work. +# +# macht aus: folgendes: +# +# +# sub( "<[\t ]*(class)[\t ]+", "<", class ) +# sub( ",[\t ]*(class)[\t ]+", ",", class ) + +# names[$3] = class +#} + + +$1 ~ /FUNC/ { + prototype = $4 + class = $2 + hiding = $3 + if ( (((hiding == "private") && (accpriv == "on") ) || ((hiding == "public") && (accpubl == "on") ) || ((hiding == "protected") && (accprot == "on") )) && ((mode != "single") || ((mode == "single") && ((classext == class) || (class == nestedclass) || (class == templnestedclass))) )) + { +# printf("\nclassext=%s\n",classext); +# printf("\nclass =%s\n",class); +# printf("\nhiding=%s\n",hiding); + csa_print_compilation_header() + # Filter out inline functions. + flinline=0 + if ( prototype ~ /^[\t ]*inline[\t ]+/ ) + { + flinline=1 +#printf("\n######inline####\n"); +# next + sub( "^[\t ]*inline[\t ]+", "", prototype ) + } + # Filter out pure virtual functions: wenn prototype "= 0 ;" enthaelt! + flpurevirt=0 + if ( prototype ~ /[\t ]*=[\t ]*0[\t ]*;[\t ]*$/ ) + { + flpurevirt=1 + next + } + # Strip out unwanted bits "static oder virtual". + flstatic=0 + if ( prototype ~ /^[\t ]*static[\t ]+/ ) + { + flstatic=1 + } + flvirtual=0 + if ( prototype ~ /^[\t ]*virtual[\t ]+/ ) + { + flvirtual=1 + } + sub( "^[\t ]*(static|virtual)[\t ]+", "", prototype ) +# suchstring ersetzen src/zielstring + # Strip out unwanted bits "; + # blank und tab" am ende der methode. + sub( ";[\t ]*$", "", prototype ) + # Strip out unwanted bits : 1. default werte der methode aus class def und comma. +# gsub( "[\t ]*\\(=[^(=][^,=]*,", ",", prototype ) +# gsub( "[\t ]*\\(=[^(=][^,=]*\\)", ")", prototype ) + +#neu + if ( prototype !~ /[\t \&\*]*operator[^a-zA-Z0-9]+/ ) + { +#neu + # Strip out unwanted bits : 1. default werte der methode aus class def und comma, aber nicht bei + # operator funs , wegen deren "=" ! + gsub( "[\t ]*=[^(=][^,=]*,", ",", prototype ) + gsub( "[\t ]*=[^(=][^,=]*\\)", ")", prototype ) +#neu + } +#neu + +#printf("\nprototype=|%s|\n",prototype); + + # Put in class name. + floperator=0 + if ( prototype ~ /[\t \&\*]*operator[^a-zA-Z0-9]+/ ) + { + # + # operator funcs + # + floperator=1 +#printf("\noperatorfunc|%s|\n",prototype); + match( prototype, "[^\t \&\*]*operator" ) + typoper = substr( prototype, 1,RSTART-1) +#printf("\ntypoper=|%s|\n",typoper); + wholelen=length(prototype) + restoper = substr( prototype, RSTART, wholelen) +#printf("\nrestoper=|%s|\n",restoper); + len=length(restoper) + restoper1 = substr( restoper, 9, len ) + match( restoper1, "[^\t ].*$" ) # trimstring fuer anf des feldes + restoper2 = substr( restoper1, RSTART, RLENGTH ) +#printf("\nrestoper2=|%s|\n",restoper2); + len=length(restoper2) # pvar++ + restoper3 = substr( restoper2,2, len ) +#printf("\nrestoper3=|%s|\n",restoper3); + match( restoper3, "\\(.*$" ) # gebe naechsten string der + # mit ( anfaengt bis zum ende + decl = substr( restoper3, RSTART, RLENGTH ) +#printf("\nparas=|%s| s=%d l=%d\n",decl,RSTART,RLENGTH); + parstart=index(restoper,decl) + restoperfun=substr(restoper,1,parstart-1) +#printf("\nrestoperfun=|%s|\n",restoperfun); + +#neu + # Strip out unwanted bits : 1. default werte der methode aus class def und comma. + gsub( "[\t ]*=[^(=][^,=]*,", ",", decl ) + gsub( "[\t ]*=[^(=][^,=]*\\)", ")", decl ) + restoper=restoperfun decl +#printf("\nneu restoper=|%s|\n",restoper); +#neu + + +if (nested == "on" ) + prototype=typoper containerclass "::" class "::" restoper +else + prototype=typoper class "::" restoper +#printf("\nprototype=|%s|\n",prototype); + +if (nested == "on" ) + classfunc = containerclass "::" class "::" restoperfun +else + classfunc = class "::" restoperfun +#printf("\nclassfunc=|%s|\n",classfunc); + rettyp = typoper +#printf("\nrettyp=|%s|\n",rettyp); + funcname = classfunc +#printf("\n7|%s|\n",funcname); + } + else + { + # + # other functions + # + match( prototype, "[^\t ]*\\(.*$" ) + decl = substr( prototype, RSTART, RLENGTH ) + +#-----neu start, damit 0-n blanks zwischen "func-name" und "(" stehen koennen! + match( decl, "\\(.*$" ) + decl = substr( decl, RSTART, RLENGTH ) + parstart=index(prototype,decl) + typfuncn=substr(prototype,1,parstart-1) + sub( "[\t ]*$", "", typfuncn ) + prototype = "" + prototype = typfuncn " " decl +#printf("\nprototypeneu=|%s|\n",prototype); +#printf("\ntypfuncnneu=|%s|\n",typfuncn); +#printf("\ndeclneu=|%s|\n",decl); + + + match( prototype, "[^\t ]*\\(.*$" ) + decl = substr( prototype, RSTART, RLENGTH ) +#-----neu end + +#printf("\ndecl=|%s|\n",decl); + parstart=index(prototype,decl) + typfuncn=substr(prototype,1,parstart-1) + + nitems=split(typfuncn,typfuncitems,"[\t \&\*]") + sub( "[\t ]*$", "", typfuncn ) + funcn = typfuncitems[nitems-1] + funstart=index(typfuncn,funcn) + typ=substr(typfuncn,1,funstart-1) +#printf("\ntypfuncn=|%s|\n",typfuncn); +#printf("\nfuncn=|%s|\n",funcn); +#printf("\ntyp=|%s|\n",typ); +if (nested == "on" ) + sub( "^", typ containerclass "::" class "::" funcn, decl ) +else + sub( "^", typ class "::" funcn, decl ) + prototype=decl +#printf("\nprototype=|%s|\n",prototype); + classfunc = "" +if (nested == "on" ) + sub( "^", containerclass "::" class "::" funcn, classfunc ) +else + sub( "^", class "::" funcn, classfunc ) +#printf("\nclassfunc=|%s|\n",classfunc); + rettyp = "" + sub( "^", typ, rettyp ) +#printf("\nrettyp=|%s|\n",rettyp); +#printf("\n6|%s|\n",prototype); + match( prototype, "^[^(]*\\(" ) + funcname = substr( prototype, RSTART, RLENGTH ) +#printf("\n7|%s|\n",funcname); + } + + # Output it. + + if (firsttime == "") + { + csa_get_method_description() +# if (csaprintheader == "on") + csa_print_method_header() + + if ( length(prototype) > 75 ) + { + match( prototype, "^[^(]*\\(" ) + funcname = substr( prototype, RSTART, RLENGTH ) + if ( prototype ~ "^[^(]*\\(\\)[\t ]*\\(" ) + { + funcname = funcname ")(" + sub( "^[^(]*\\(\\)[\t ]*\\(", "", prototype ) + } + else + sub( "^[^(]*\\(", "", prototype ) + + if ( templclass ~ "<" && templnested == "" && nested == "") + { + printf( "template%s\n", templ) + } + if ( templnested == "on") + { + printf( "template%s\n", nestedtempl ) + } + printf( "%s\n", funcname ) + + match( prototype, "\\)([\t ]*const)?[\t ]*$" ) + functail = substr( prototype, RSTART, RLENGTH ) + sub( "\\)([\t ]* const)?[\t ]*$", "", prototype ) + narg = 0 + while ( match( prototype, "[^<>,#]*<[^<>]*>" ) ) + { + narg++ + arg = substr( prototype, RSTART, RLENGTH ) + sub( "[^<>,#]*<[^<>]*>", "#" narg, prototype ) + fargs["#" narg] = arg + # Need the following to stop resubstitution of the pattern matched + # back into the string. + gsub( "&", "\\\\&", fargs["#" narg] ) + } + numargs = split( prototype, args, "," ) + for ( m=1; m<=numargs; m++ ) + { + while ( match( args[m], "#[0-9]+" ) ) + { + arg = substr( args[m], RSTART, RLENGTH ) + sub( arg, fargs[arg], args[m] ) + } + sub( "[\t ]*", "", args[m] ) + printf( " %s", args[m] ) + if ( m == numargs ) + { + print( "" ) + } + else + print( "," ) + } + if (flinline == 1) + printf("/* inline */\n"); +# printf( "%s\n%s{\n}\n\n%s\n", functail,csa_method_trailer, separator ) + printf( "%s\n", functail) +# csa_print_method_trailer() +# printf( "{\n}\n\n%s\n", separator ) + } + else + { + if (flinline == 1) + printf("/* inline */\n"); + + if ( templclass ~ "<" && templnested == "" && nested == "") + { + printf( "template%s\n", templ ) + } + if ( templnested == "on") + { + printf( "template%s\n", nestedtempl ) + } +# printf( "%s\n%s{\n}\n\n%s\n", prototype,csa_method_trailer, separator ) + printf( "%s\n", prototype) +# csa_print_method_trailer() +# printf( "{\n}\n\n%s\n", separator ) + } + csa_print_method_trailer() + if (rettyp != "" && rettyp != "void " && rettyp != "void") + printf( "{\n\treturn((%s)0);\n}\n\n%s\n",rettyp, separator ) + else + printf( "{\n}\n\n%s\n", separator ) + + } + # end of firsttime + } + # end of if +} +#end of FUNC diff --git a/bin/man2html b/bin/man2html new file mode 100755 index 00000000000..7211bdc60bb --- /dev/null +++ b/bin/man2html @@ -0,0 +1,88 @@ +#!/bin/sh + +OSE_HOST= + +OSE_RELEASE_NAME= +export OSE_RELEASE_NAME + +OSE_ROOT=${OSE_ROOT-$WRAPPER_ROOT} +export OSE_ROOT + +OSE_VERSION_ROOT=$OSE_ROOT +export OSE_VERSION_ROOT + +BINDIR="$OSE_VERSION_ROOT/$OSE_HOST/bin" +LIBDIR=${CLASSINFOLIBDIR-"$OSE_VERSION_ROOT/bin"} + +# +# Error. +# +ERROR() +{ + echo "`basename $0`: $1" >&2 + shift + while test $# != "0" + do + echo $1 >&2 + shift + done + exit 1 +} + +# +# Usage message. +# +USAGE() +{ + ERROR "Usage: `basename $0` files" +} + +# +# Check usage. +# +if test "$#" = "0" +then + USAGE +fi + +while test "$#" != "0" +do + INPUT=$1 + BASENAME=`basename $INPUT | sed -e 's/\(.*\)\.[^.]*$/\1/'` + OUTPUT=${BASENAME}.html + + if test -f ${INPUT} + then + echo ${BASENAME} + cat ${INPUT} | + sed -e 's/\\-/-/g' \ + -e 's/\\ / /g' \ + -e 's/\\[0&]/ /g' \ + -e 's/&/\&/g' \ + -e 's//\>/g' \ + -e 's/\\|//g' \ + -e 's/\\e/\\/g' | + /bin/nawk -f ${LIBDIR}/man2html1.awk | + sed -e 's^\\fB\([^\\]*\)\\fR^\1^g' \ + -e 's^\\f(CO\(.[^\\]*\)\\fR^\1^g' \ + -e 's^\\fI\(.[^\\]*\)\\fR^\1^g' \ + -e 's^\\fB^^g' \ + -e 's^\\f(CO^^g' \ + -e 's^\\fI^^g' \ + -e 's^\\f[RP]^^g' \ + -e 's/^.[LP]P/

    /' \ + -e 's/^.br/
    /' \ + -e 's/^\.DS.*/

    /' \
    +	    -e 's$^\.DE.*$
    $' \ + -e 's/^\.nf */
    /' \
    +	    -e 's$^\.fi *$
    $' \ + -e 's$^\.BE *$
    $' \ + -e 's/^\.RS.*/
      /' \ + -e 's$^\.RE.*$
    $' \ + -e 's^\.SH *"*\([^"]*\)"*^

    \1

    ^' \ + -e '/^\.[a-zA-Z]*.*/d' | + /bin/nawk -f ${LIBDIR}/man2html2.awk > ${OUTPUT} + fi + shift +done diff --git a/bin/man2html1.awk b/bin/man2html1.awk new file mode 100644 index 00000000000..a780ab70c9f --- /dev/null +++ b/bin/man2html1.awk @@ -0,0 +1,139 @@ +#!/bin/nawk + + +# defining macros - eat them +/^\.de.*/ { + getline + while ( $0 !~ "^\.\.$" ) + { + getline + } + getline + } + +# eat [nt]roff comments +$0 ~ /['.][\/\\]"/ || $1 == "'" { next } + +# remove sidebar macros +$1 == ".VS" || $1 == ".VE" || $1 == ".AS" { next } + + +# handle first .SH as special case - .SH NAME +/^.SH *NAME */ { + getline + while ( $0 ~ /\.[a-zA-Z].*/ ) # eat dot-cmd following title + { + getline + } + print "" $0 "" + print "

    " $0 "

    \n" + next + +#-e 's/^.SH *NAME */{N;s#.*\n\(.*\)#

    \1

    #;}' \ + } + + +# Convert .IP Paragraphs upto next .cmd to hanging indents +# using
    pairs without intervening
  • + +/^\.IP */ { + if ( inIP > 0 ) + { + print "" + } + inIP = 1 + startIP = 1 + print "
    " + match($0, /".*"/ ) + if ( RSTART > 0 ) + { + arg = substr( $0, RSTART+1, RLENGTH-2) + + print "
    " arg + } + else if ( length( $2 ) > 0 ) + { + print "
    " $2 + } + next + } + +$0 ~ /^\.[a-zA-Z]*/ && inIP > 0 { + inIP = 0 + print "
    " + } + +# Convert +# .TP +# Line1 +# line 2 - n +# .Any +# +# to +#
    +#
    Line1 +#
    lines 2 - n +#
    + +/^\.TP */ { + if ( inTP > 0 ) + { + print "
    " + } + inTP = 1 + print "
    " + next + } + +inTP == 1 && $1 !~ /\.[a-zA-Z]*/ { + print "
    " $0 + inTP = 2 + next + } + +inTP == 2 && $1 !~ /\.[a-zA-Z]*/{ + print "" # Belt and suspenders + print "
    " $0 + inTP = 3 + next + } + +$0 ~ /^\.[a-zA-Z]*/ && inTP > 0 { + inTP = 0 + print "
    " + } + + + +$1 == ".AP" { + $1="" + print "
    " + print "
    " $2 "\t\t" $3 "\t\t("$4")" + inTP = 2 + next + } + +# make a blank line +$1 == ".sp" { + print "
    " + next # print "
    " + } + + +$1 == ".ta" { next } + +# just pass everything else on + + { + if ( startIP > 0 ) + { + print "
    " $0 + startIP = 0 + } + else + { + print $0 + } + } + + diff --git a/bin/man2html2.awk b/bin/man2html2.awk new file mode 100644 index 00000000000..31c4cece3b9 --- /dev/null +++ b/bin/man2html2.awk @@ -0,0 +1,18 @@ +#!/bin/nawk + +$0 ~ "

    SEE ALSO

    " { + print $0 + getline + while ( $0 !~ "^

    $" && $0 !~ "^[ \t]*$" ) { + gsub("OTC[_a-zA-Z0-9]*_[_a-zA-Z0-9]*","&",$0) + gsub("OUX[_a-zA-Z0-9]*_[_a-zA-Z0-9]*","&",$0) + gsub("OTK[_a-zA-Z0-9]*_[_a-zA-Z0-9]*","&",$0) + print $0 + if ( getline <= 0 ) + $0 = "" + } + if ( $0 !~ "^[ \t]*$" ) + print $0 +} + +{ print $0 } diff --git a/bin/rename-ace.pl b/bin/rename-ace.pl new file mode 100755 index 00000000000..c785370f779 --- /dev/null +++ b/bin/rename-ace.pl @@ -0,0 +1,175 @@ +#!/pkg/gnu/bin/perl -pi +s/\bAcceptor\b/ACE_Acceptor/g; +s/\bAddr\b/ACE_Addr/g; +s/\bArgument_Vector\b/ACE_ARGV/g; +s/\bAtomic_Op\b/ACE_Atomic_Op/g; +s/\bCORBA_Handler\b/ACE_CORBA_Handler/g; +s/\bCondition\b/ACE_Condition/g; +s/\bConnector\b/ACE_Connector/g; +s/\bControl_Block\b/ACE_Control_Block/g; +s/\bControl_Mode\b/ACE_Control_Mode/g; +s/\bData_Block\b/ACE_Data_Block/g; +s/\bDummy_Node\b/ACE_Dummy_Node/g; +s/\bDynamic_Node\b/ACE_Dynamic_Node/g; +s/\bElapsed_Time\b/ACE_Elapsed_Time/g; +s/\bEvent_Handler\b/ACE_Event_Handler/g; +s/\bEvent_Handler_T\b/ACE_Event_Handler_T/g; +s/\bFIFO\b/ACE_FIFO/g; +s/\bFIFO_Recv\b/ACE_FIFO_Recv/g; +s/\bFIFO_Recv_Msg\b/ACE_FIFO_Recv_Msg/g; +s/\bFIFO_Send\b/ACE_FIFO_Send/g; +s/\bFIFO_Send_Msg\b/ACE_FIFO_Send_Msg/g; +s/\bFunction_Node\b/ACE_Function_Node/g; +s/\bGet_Opt\b/ACE_Get_Opt/g; +s/\bGuard\b/ACE_Guard/g; +s/\bHANDLE\b/ACE_HANDLE/g; +s/\bHandle_Set_Iterator\b/ACE_Handle_Set_Iterator/g; +s/\bHandle_Set\b/ACE_Handle_Set/g; +s/\bHigh_Res_Timer\b/ACE_High_Res_Timer/g; +s/\bINET_Addr\b/ACE_INET_Addr/g; +s/\bIO_Cntl_Cmds\b/ACE_IO_Cntl_Cmds/g; +s/\bIO_Cntl_Msg\b/ACE_IO_Cntl_Msg/g; +s/\bIO_Vector\b/ACE_IO_Vector/g; +s/\bIPC_SAP\b/ACE_IPC_SAP/g; +s/\bLSOCK\b/ACE_LSOCK/g; +s/\bLSOCK_Acceptor\b/ACE_LSOCK_Acceptor/g; +s/\bLSOCK_Aceeptor\b/ACE_LSOCK_Aceeptor/g; +s/\bLSOCK_CODgram\b/ACE_LSOCK_CODgram/g; +s/\bLSOCK_Connector\b/ACE_LSOCK_Connector/g; +s/\bLSOCK_Dgram\b/ACE_LSOCK_Dgram/g; +s/\bLSOCK_Stream\b/ACE_LSOCK_Stream/g; +s/\bLocal_Memory_Pool\b/ACE_Local_Memory_Pool/g; +s/\bLocation_Node\b/ACE_Location_Node/g; +s/\bLog_Msg\b/ACE_Log_Msg/g; +s/\bLog_Priority\b/ACE_Log_Priority/g; +s/\bLog_Record\b/ACE_Log_Record/g; +s/\bMalloc\b/ACE_Malloc/g; +s/\bMalloc_Align\b/ACE_Malloc_Align/g; +s/\bMalloc_Header\b/ACE_Malloc_Header/g; +s/\bMalloc_Stats\b/ACE_Malloc_Stats/g; +s/\bMap_Entry\b/ACE_Map_Entry/g; +s/\bMap_Iterator\b/ACE_Map_Iterator/g; +s/\bMap_Manager\b/ACE_Map_Manager/g; +s/\bMem_Map\b/ACE_Mem_Map/g; +s/\bMMAP_Memory_Pool\b/ACE_MMAP_Memory_Pool/g; +s/\bMT_SYNCH\b/ACE_MT_SYNCH/g; +s/\bMemory_Pool\b/ACE_Memory_Pool/g; +s/\bMessage_Block\b/ACE_Message_Block/g; +s/\bMessage_Queue\b/ACE_Message_Queue/g; +s/\bMessage_Type\b/ACE_Message_Type/g; +s/\bModule\b/ACE_Module/g; +s/\bModule_Link\b/ACE_Module_Link/g; +s/\bModule_Type\b/ACE_Module_Type/g; +s/\bMultiplexor\b/ACE_Multiplexor/g; +s/\bMutex\b/ACE_Mutex/g; +s/\bNull_Condition\b/ACE_Null_Condition/g; +s/\bNull_Mutex\b/ACE_Null_Mutex/g; +s/\bNULL_SYNCH\b/ACE_NULL_SYNCH/g; +s/\bObchunk\b/ACE_Obchunk/g; +s/\bObject_Node\b/ACE_Object_Node/g; +s/\bObstack\b/ACE_Obstack/g; +s/\bOneshot_Acceptor\b/ACE_Oneshot_Acceptor/g; +s/\bParse_Node\b/ACE_Parse_Node/g; +s/\bProcess_Mutex\b/ACE_Process_Mutex/g; +s/\bProfile_Timer\b/ACE_Profile_Timer/g; +s/\bQ_Entry\b/ACE_Q_Entry/g; +s/\bQueue\b/ACE_Queue/g; +s/\bRW_Mutex\b/ACE_RW_Mutex/g; +s/\bRaw_Data_Block\b/ACE_Raw_Data_Block/g; +s/\bReactor\b/ACE_Reactor/g; +s/\bReactor_Mask\b/ACE_Reactor_Mask/g; +s/\bReactor_Token\b/ACE_Reactor_Token/g; +s/\bRead_Guard\b/ACE_Read_Guard/g; +s/\bRecursive_Lock\b/ACE_Recursive_Lock/g; +s/\bRemove_Node\b/ACE_Remove_Node/g; +s/\bRequest_Queue\b/ACE_Request_Queue/g; +s/\bResume_Node\b/ACE_Resume_Node/g; +s/\bSOCK\b/ACE_SOCK/g; +s/\bSOCK_Acceptor\b/ACE_SOCK_Acceptor/g; +s/\bSOCK_CODgram\b/ACE_SOCK_CODgram/g; +s/\bSOCK_Connector\b/ACE_SOCK_Connector/g; +s/\bSOCK_DGRAM\b/ACE_SOCK_DGRAM/g; +s/\bSOCK_Dgram\b/ACE_SOCK_Dgram/g; +s/\bSOCK_Dgram_Bcast\b/ACE_SOCK_Dgram_Bcast/g; +s/\bSOCK_Dgram_Mcast\b/ACE_SOCK_Dgram_Mcast/g; +s/\bSOCK_IO\b/ACE_SOCK_IO/g; +s/\bSOCK_Stream\b/ACE_SOCK_Stream/g; +s/\bSPIPE\b/ACE_SPIPE/g; +s/\bSPIPE_Acceptor\b/ACE_SPIPE_Acceptor/g; +s/\bSPIPE_Addr\b/ACE_SPIPE_Addr/g; +s/\bSPIPE_Connector\b/ACE_SPIPE_Connector/g; +s/\bSPIPE_IO\b/ACE_SPIPE_Stream/g; +s/\bSPIPE_Msg\b/ACE_SPIPE_Msg/g; +s/\bSString\b/ACE_SString/g; +s/\bSV_Message\b/ACE_SV_Message/g; +s/\bSV_Message_Queue\b/ACE_SV_Message_Queue/g; +s/\bSV_Semaphore\b/ACE_SV_Semaphore/g; +s/\bSV_Semaphore_Complex\b/ACE_SV_Semaphore_Complex/g; +s/\bSV_Semaphore_Simple\b/ACE_SV_Semaphore_Simple/g; +s/\bSV_Shared_Memory\b/ACE_SV_Shared_Memory/g; +s/\bSemaphore\b/ACE_Semaphore/g; +s/\bService_Config\b/ACE_Service_Config/g; +s/\bService_Manager\b/ACE_Service_Manager/g; +s/\bService_Object\b/ACE_Service_Object/g; +s/\bService_Object_Type\b/ACE_Service_Object_Type/g; +s/\bService_Record\b/ACE_Service_Record/g; +s/\bService_Repository\b/ACE_Service_Repository/g; +s/\bService_Repository_Iterator\b/ACE_Service_Repository_Iterator/g; +s/\bService_Type\b/ACE_Service_Type/g; +s/\bShared_Malloc\b/ACE_Shared_Malloc/g; +s/\bShared_Malloc_MM\b/ACE_Shared_Malloc_MM/g; +s/\bShared_Malloc_SV\b/ACE_Shared_Malloc_SV/g; +s/\bShared_Memory\b/ACE_Shared_Memory/g; +s/\bShared_Memory_Pool\b/ACE_Shared_Memory_Pool/g; +s/\bShared_Object\b/ACE_Shared_Object/g; +s/\bSig_Action\b/ACE_Sig_Action/g; +s/\bSig_Handler\b/ACE_Sig_Handler/g; +s/\bSig_Set\b/ACE_Sig_Set/g; +s/\bSignalHandler\b/ACE_SignalHandler/g; +s/\bSignalHandlerV\b/ACE_SignalHandlerV/g; +s/\bSignal_Guard\b/ACE_Signal_Guard/g; +s/\bSignal_Handler\b/ACE_Signal_Handler/g; +s/\bStatic_Node\b/ACE_Static_Node/g; +s/\bStr_Buf\b/ACE_Str_Buf/g; +s/\bStream\b/ACE_Stream/g; +s/\bStream_Head\b/ACE_Stream_Head/g; +s/\bStream_Iterator\b/ACE_Stream_Iterator/g; +s/\bStream_Modules\b/ACE_Stream_Modules/g; +s/\bStream_Node\b/ACE_Stream_Node/g; +s/\bStream_Tail\b/ACE_Stream_Tail/g; +s/\bSTREAM_Type\b/ACE_STREAM_Type/g; +s/\bSuspend_Node\b/ACE_Suspend_Node/g; +s/\bSvc_Handler\b/ACE_Svc_Handler/g; +s/\bSvc_Manager\b/ACE_Svc_Manager/g; +s/\bSvc_Tuple\b/ACE_Svc_Tuple/g; +s/\bSynch\b/ACE_Synch/g; +s/\bSynch_Options\b/ACE_Synch_Options/g; +s/\bTHR_FUNC\b/ACE_THR_FUNC/g; +s/\bTLI\b/ACE_TLI/g; +s/\bTLI_Acceptor\b/ACE_TLI_Acceptor/g; +s/\bTLI_Connector\b/ACE_TLI_Connector/g; +s/\bTLI_Stream\b/ACE_TLI_Stream/g; +s/\bTask\b/ACE_Task/g; +s/\bThread\b/ACE_Thread/g; +s/\bThread_Control\b/ACE_Thread_Control/g; +s/\bThread_Manager\b/ACE_Thread_Manager/g; +s/\bThread_Mutex\b/ACE_Thread_Mutex/g; +s/\bThread_Spawn\b/ACE_Thread_Spawn/g; +s/\bThread_Specific\b/ACE_Thread_Specific/g; +s/\bThru_Task\b/ACE_Thru_Task/g; +s/\bTime_Value\b/ACE_Time_Value/g; +s/\bTimer_Handle\b/ACE_Timer_Handle/g; +s/\bTimer_Queue\b/ACE_Timer_Queue/g; +s/\bToken\b/ACE_Token/g; +s/\bTrace\b/ACE_Trace/g; +s/\bTry_Guard\b/ACE_Try_Guard/g; +s/\bTyped_SV_Message\b/ACE_Typed_SV_Message/g; +s/\bTyped_SV_Message_Queue\b/ACE_Typed_SV_Message_Queue/g; +s/\bUNIX_Addr\b/ACE_UNIX_Addr/g; +s/\bUPIPE\b/ACE_UPIPE/g; +s/\bUPIPE_Addr\b/ACE_UPIPE_Addr/g; +s/\bUPIPE_Stream\b/ACE_UPIPE_Stream/g; +s/\bUPIPE_Acceptor\b/ACE_UPIPE_Acceptor/g; +s/\bUPIPE_Connector\b/ACE_UPIPE_Connector/g; +s/\bWrite_Guard\b/ACE_Write_Guard/g; +s@ace/ACE_@ace/@g; diff --git a/bin/vendor.fmt b/bin/vendor.fmt new file mode 100755 index 00000000000..a780d430fec --- /dev/null +++ b/bin/vendor.fmt @@ -0,0 +1,101 @@ +# +# vendor description header control file for ADTs +# please insert your company name in the field +# +# K. Dorn +# + +VENDOR_COMPILATION_HEADER_CXX_START +"\n/*[ Compilation unit "\ + "----------------------------------------------------------\n"\ + "\n"\ + " Component : CSA - OSC\n"\ + "\n"\ + " Name : %s.[Ci]\n"\ + "\n"\ + " Author : %s\n"\ + "\n"\ + " Language : C++\n"\ + "\n"\ + " Creation Date : %s\n"\ + "\n"\ + " Test State : %%Q%%\n"\ + "\n"\ + " Description : %s\n"\ + "\n"\ + "\n"\ + " Copyright (C) 1995 All Rights Reserved\n"\ + "\n"\ + "--------------------------------------"\ + "---------------------------------------*/\n"\ + "/*] END */\n"\ + "#pragma ident \" %%Z%% %%M%% %%I%% (%%G%%), %%Y%% %%Q%%:"\ + " implementation file for class "\ + "%s \" \n "\ + "\n"\ + "\n" +VENDOR_COMPILATION_HEADER_CXX_END + + +VENDOR_METHOD_HEADER_CXX_START +"\n/*[ Method ---------------------"\ + "-------------------------------------------\n"\ + "\n"\ + " Name : %s\n"\ + "\n"\ + " Description : %s\n"\ + "\n"\ + " Return : %s\n"\ + "\n"\ + "--------------------------------------------"\ + "------------------------------*/\n\n" +VENDOR_METHOD_HEADER_CXX_END + + +VENDOR_COMPILATION_HEADER_HXX_START +"\n/*[ Compilation unit "\ + "----------------------------------------------------------\n"\ + "\n"\ + " Component : CSA - OSC\n"\ + "\n"\ + " Name : %s.h\n"\ + "\n"\ + " Author : %s\n"\ + "\n"\ + " Language : C++\n"\ + "\n"\ + " Creation Date : %s\n"\ + "\n"\ + " Test State : %%Q%%\n"\ + "\n"\ + " Description : %s\n"\ + "\n %s\n"\ + "\n"\ + "\n"\ + " Copyright (C) 1995 All Rights Reserved\n"\ + "\n"\ + "--------------------------------------"\ + "---------------------------------------*/\n"\ + "/*] END */\n"\ + "#pragma ident \" %%Z%% %%M%% %%I%% (%%G%%), %%Y%% %%Q%%:"\ + " implementation file for class "\ + "%s \" \n "\ + "\n"\ + "\n" +VENDOR_COMPILATION_HEADER_HXX_END + +VENDOR_CLASS_HEADER_HXX_START +"\n/*[ Class ---------------------"\ + "-------------------------------------------\n"\ + "\n"\ + " Name : %s\n"\ + "\n"\ + " Description : %s\n"\ + "\n %s\n"\ + "\n"\ + "--------------------------------------------"\ + "------------------------------*/\n\n" +VENDOR_CLASS_HEADER_HXX_END + + + diff --git a/examples/ASX/CCM_App/CCM_App.cpp b/examples/ASX/CCM_App/CCM_App.cpp new file mode 100644 index 00000000000..218b3037be2 --- /dev/null +++ b/examples/ASX/CCM_App/CCM_App.cpp @@ -0,0 +1,123 @@ +#define ACE_BUILD_SVC_DLL +// @(#)CCM_App.cpp 1.1 10/18/96 + +#include "ace/Stream.h" +#include "ace/Task.h" +#include "ace/Module.h" + +typedef ACE_Task MT_Task; +typedef ACE_Stream MT_Stream; +typedef ACE_Module MT_Module; + +class ACE_Svc_Export Test_Task : public MT_Task +{ +public: + virtual int open (void *); + virtual int close (u_long); + virtual int put (ACE_Message_Block *, ACE_Time_Value * = 0); + virtual int svc (void); + virtual int info (char **, size_t) const; + virtual int init (int, char *[]); + virtual int fini (void); + virtual int suspend (void); + virtual int resume (void); +}; + +int +Test_Task::open (void *) +{ + ACE_DEBUG ((LM_DEBUG, "opening %s\n", this->name () ? this->name () : "task")); + return 0; +} + +int +Test_Task::close (u_long) +{ + ACE_DEBUG ((LM_DEBUG, "closing %s\n", this->name () ? this->name () : "task")); + return 0; +} + +int +Test_Task::suspend (void) +{ + ACE_DEBUG ((LM_DEBUG, "suspending in %s\n", this->name () ? this->name () : "task")); + return 0; +} + +int +Test_Task::resume (void) +{ + ACE_DEBUG ((LM_DEBUG, "resuming in %s\n", this->name () ? this->name () : "task")); + return 0; +} + +int +Test_Task::put (ACE_Message_Block *, ACE_Time_Value *) +{ + return 0; +} + +int +Test_Task::svc (void) +{ + return 0; +} + +int +Test_Task::info (char **, size_t) const +{ + return 0; +} + +int +Test_Task::init (int, char *[]) +{ + ACE_DEBUG ((LM_DEBUG, "initializing %s\n", this->name () ? this->name () : "task")); + + return 0; +} + +int +Test_Task::fini (void) +{ + ACE_DEBUG ((LM_DEBUG, "finalizing %s\n", this->name () ? this->name () : "task")); + return 0; +} + +// Dynamically linked functions used to control configuration. + +extern "C" ACE_Svc_Export MT_Stream *make_stream (void); +extern "C" ACE_Svc_Export MT_Module *make_da (void); +extern "C" ACE_Svc_Export MT_Module *make_ea (void); +extern "C" ACE_Svc_Export MT_Module *make_mr (void); +extern "C" ACE_Svc_Export ACE_Service_Object *make_task (void); + +ACE_Service_Object * +make_task (void) +{ + return new Test_Task; +} + +MT_Stream * +make_stream (void) +{ + return new MT_Stream; +} + +MT_Module * +make_da (void) +{ + return new MT_Module ("Device_Adapter", new Test_Task, new Test_Task); +} + +MT_Module * +make_ea (void) +{ + return new MT_Module ("Event_Analyzer", new Test_Task, new Test_Task); +} + +MT_Module * +make_mr (void) +{ + return new MT_Module ("Multicast_Router", new Test_Task, new Test_Task); +} diff --git a/examples/ASX/CCM_App/Makefile b/examples/ASX/CCM_App/Makefile new file mode 100644 index 00000000000..3902aef1235 --- /dev/null +++ b/examples/ASX/CCM_App/Makefile @@ -0,0 +1,176 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for CCM tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = SC_Client \ + SC_Server + +LSRC = $(addsuffix .cpp,$(BIN)) \ + CCM_App.cpp + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VSHLIB) $(SHLIBA) $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/SC_Client.o .shobj/SC_Client.so: SC_Client.cpp +.obj/SC_Server.o .shobj/SC_Server.so: SC_Server.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h +.obj/CCM_App.o .shobj/CCM_App.so: CCM_App.cpp \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/ASX/CCM_App/SC_Client.cpp b/examples/ASX/CCM_App/SC_Client.cpp new file mode 100644 index 00000000000..498ff89ba9b --- /dev/null +++ b/examples/ASX/CCM_App/SC_Client.cpp @@ -0,0 +1,9 @@ +// Pretty simple, eh? ;-) +// @(#)SC_Client.cpp 1.1 10/18/96 + + +int +main (int, char *[]) +{ + return 0; +} diff --git a/examples/ASX/CCM_App/SC_Server.cpp b/examples/ASX/CCM_App/SC_Server.cpp new file mode 100644 index 00000000000..49a11179dcd --- /dev/null +++ b/examples/ASX/CCM_App/SC_Server.cpp @@ -0,0 +1,63 @@ +// Simple driver program for the server. +// @(#)SC_Server.cpp 1.1 10/18/96 + + +#include "ace/Service_Config.h" +#include "ace/Synch.h" +#include "ace/Signal.h" + +class Event_Handler : public ACE_Event_Handler +{ +public: + virtual int handle_input (ACE_HANDLE handle); + virtual int handle_close (ACE_HANDLE, + ACE_Reactor_Mask); +}; + +int +Event_Handler::handle_input (ACE_HANDLE handle) +{ + char buf[BUFSIZ]; + + ssize_t n = ACE_OS::read (handle, buf, sizeof buf); + + if (n == -1) + return -1; + else if (ACE_OS::write (ACE_STDOUT, buf, n) != n) + return -1; + else + return 0; +} + +int +Event_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + ACE_DEBUG ((LM_DEBUG, "closing Event_Handler\n")); + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config loggerd; + Event_Handler handler; + ACE_Sig_Adapter shutdown_handler ((ACE_Sig_Handler_Ex) ACE_Service_Config::end_reactor_event_loop); + + if (ACE::register_stdin_handler (&handler, + ACE_Service_Config::reactor (), + ACE_Service_Config::thr_mgr ()) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "register_stdin_handler")); + + if (loggerd.open (argc, argv) == -1 && errno != ENOENT) + ACE_ERROR ((LM_ERROR, "%p\n%a", "open", 1)); + + else if (ACE_Service_Config::reactor ()->register_handler + (SIGINT, &shutdown_handler) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "register_handler", 1)); + + // Perform logging service until we receive SIGINT. + + loggerd.run_reactor_event_loop (); + + return 0; +} diff --git a/examples/ASX/CCM_App/svc.conf b/examples/ASX/CCM_App/svc.conf new file mode 100644 index 00000000000..4737cc6312e --- /dev/null +++ b/examples/ASX/CCM_App/svc.conf @@ -0,0 +1,21 @@ +static ACE_Service_Manager "-d -p 3911" + +dynamic My_Task Service_Object *.shobj/CCM_App.so:make_task() "-p 3000" + +stream dynamic CCM_App STREAM *.shobj/CCM_App.so:make_stream() active +{ + dynamic Device_Adapter Module *.shobj/CCM_App.so:make_da() + dynamic Event_Analyzer Module *.shobj/CCM_App.so:make_ea() + dynamic Multicast_Router Module *.shobj/CCM_App.so:make_mr() "-p 3001" +} + +stream CCM_App +{ + remove Device_Adapter + remove Event_Analyzer + remove Multicast_Router +} + +remove CCM_App +remove My_Task + diff --git a/examples/ASX/Event_Server/Event_Server/Consumer_Router.cpp b/examples/ASX/Event_Server/Event_Server/Consumer_Router.cpp new file mode 100644 index 00000000000..aad0adf313e --- /dev/null +++ b/examples/ASX/Event_Server/Event_Server/Consumer_Router.cpp @@ -0,0 +1,132 @@ +#include "ace/Log_Msg.h" +// @(#)Consumer_Router.cpp 1.1 10/18/96 + +#include "Consumer_Router.h" +#include "Options.h" + +#if defined (ACE_HAS_THREADS) + +typedef Acceptor_Factory CONSUMER_FACTORY; + +int +Consumer_Handler::open (void *a) +{ + CONSUMER_FACTORY *af = (CONSUMER_FACTORY *) a; + this->router_task_ = af->router (); + return this->Peer_Handler::open (a); +} + +Consumer_Handler::Consumer_Handler (ACE_Thread_Manager *tm) + : Peer_Handler (tm) +{ +} + +// Create a new handler that will interact with a consumer and point +// its ROUTER_TASK_ data member to the CONSUMER_ROUTER. + +Consumer_Router::Consumer_Router (ACE_Thread_Manager *tm) + : CONSUMER_ROUTER (tm) +{ +} + +// Initialize the Router. + +int +Consumer_Router::open (void *) +{ + assert (this->is_reader ()); + + char *argv[4]; + + argv[0] = (char *) this->name (); + argv[1] = "-p"; + argv[2] = options.consumer_port (); + argv[3] = 0; + + if (this->init (2, &argv[1]) == -1) + return -1; + + // Make this an active object. + return this->activate (options.t_flags ()); +} + +int +Consumer_Router::close (u_long) +{ + assert (this->is_reader ()); + ACE_DEBUG ((LM_DEBUG, "(%t) closing Consumer_Router\n")); + this->peer_map_.close (); + + // Inform the thread to shut down. + this->msg_queue ()->deactivate (); + return 0; +} + +// Handle incoming messages in a separate thread. + +int +Consumer_Router::svc (void) +{ + ACE_Thread_Control tc (this->thr_mgr ()); + ACE_Message_Block *mb = 0; + + assert (this->is_reader ()); + + ACE_DEBUG ((LM_DEBUG, "(%t) starting svc in Consumer_Router\n")); + + while (this->getq (mb) >= 0) + { + ACE_DEBUG ((LM_DEBUG, "Consumer_Router is routing via send_peers\n")); + if (this->send_peers (mb) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "(%t) send_peers failed in Consumer_Router\n"), + -1); + } + ACE_DEBUG ((LM_DEBUG, "(%t) stopping svc in Consumer_Router\n")); + return 0; + // Note the implicit ACE_OS::thr_exit() via destructor. +} + +// Send a MESSAGE_BLOCK to the supplier(s). + +int +Consumer_Router::put (ACE_Message_Block *mb, ACE_Time_Value *) +{ + assert (this->is_reader ()); + + if (mb->msg_type () == ACE_Message_Block::MB_IOCTL) + { + this->control (mb); + return this->put_next (mb); + } + else + // Queue up the message, which will be processed by + // Consumer_Router::svc(). + return this->putq (mb); +} + +// Return information about the Client_Router ACE_Module. + +int +Consumer_Router::info (char **strp, size_t length) const +{ + char buf[BUFSIZ]; + ACE_INET_Addr addr; + const char *mod_name = this->name (); + ACE_SOCK_Acceptor &sa = this->acceptor_->acceptor (); + + if (sa.get_local_addr (addr) == -1) + return -1; + + ACE_OS::sprintf (buf, "%s\t %d/%s %s", + mod_name, addr.get_port_number (), "tcp", + "# consumer router\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (mod_name)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, mod_name, length); + return ACE_OS::strlen (mod_name); +} + +#endif /* ACE_HAS_THREADS */ diff --git a/examples/ASX/Event_Server/Event_Server/Consumer_Router.h b/examples/ASX/Event_Server/Event_Server/Consumer_Router.h new file mode 100644 index 00000000000..efc5acf9e3d --- /dev/null +++ b/examples/ASX/Event_Server/Event_Server/Consumer_Router.h @@ -0,0 +1,46 @@ +/* -*- C++ -*- */ +// @(#)Consumer_Router.h 1.1 10/18/96 + +/* The interface between one or more consumers and an Event Server ACE_Stream */ + +#if !defined (_CONSUMER_ROUTER_H) +#define _CONSUMER_ROUTER_H + +#include "ace/Thread_Manager.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/UPIPE_Acceptor.h" +#include "ace/Svc_Handler.h" +#include "Peer_Router.h" + +#if defined (ACE_HAS_THREADS) + +class Consumer_Handler; /* Forward declaration... */ + +typedef ACE_HANDLE CONSUMER_KEY; + +typedef Peer_Router CONSUMER_ROUTER; + +class Consumer_Handler : public Peer_Handler +{ +public: + Consumer_Handler (ACE_Thread_Manager *tm = 0); + virtual int open (void *); +}; + +class Consumer_Router : public CONSUMER_ROUTER +{ +public: + Consumer_Router (ACE_Thread_Manager *thr_manager); + +protected: + /* ACE_Task hooks. */ + virtual int open (void *a = 0); + virtual int close (u_long flags = 0); + virtual int put (ACE_Message_Block *msg, ACE_Time_Value * = 0); + virtual int svc (void); + + /* Dynamic linking hooks */ + virtual int info (char **info_string, size_t length) const; +}; +#endif /* ACE_HAS_THREADS */ +#endif /* _CONSUMER_ROUTER_H */ diff --git a/examples/ASX/Event_Server/Event_Server/Event_Analyzer.cpp b/examples/ASX/Event_Server/Event_Server/Event_Analyzer.cpp new file mode 100644 index 00000000000..977e5c4af9d --- /dev/null +++ b/examples/ASX/Event_Server/Event_Server/Event_Analyzer.cpp @@ -0,0 +1,68 @@ +#include "Event_Analyzer.h" +// @(#)Event_Analyzer.cpp 1.1 10/18/96 + + +#if defined (ACE_HAS_THREADS) + +int +Event_Analyzer::open (void *) +{ + return 0; +} + +int +Event_Analyzer::close (u_long) +{ + return 0; +} + +int +Event_Analyzer::control (ACE_Message_Block *mb) +{ + ACE_IO_Cntl_Msg *ioc = (ACE_IO_Cntl_Msg *) mb->rd_ptr (); + ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds cmd; + + switch (cmd = ioc->cmd ()) + { + case ACE_IO_Cntl_Msg::SET_LWM: + case ACE_IO_Cntl_Msg::SET_HWM: + this->water_marks (cmd, *(size_t *) mb->cont ()->rd_ptr ()); + break; + } + return 0; +} + +int +Event_Analyzer::put (ACE_Message_Block *mb, ACE_Time_Value *) +{ + if (mb->msg_type () == ACE_Message_Block::MB_IOCTL) + this->control (mb); + + return this->put_next (mb); +} + +int +Event_Analyzer::init (int, char *[]) +{ + return 0; +} + +int +Event_Analyzer::fini (void) +{ + return 0; +} + +int +Event_Analyzer::info (char **strp, size_t length) const +{ + const char *mod_name = this->name (); + + if (*strp == 0 && (*strp = ACE_OS::strdup (mod_name)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, mod_name, length); + return ACE_OS::strlen (mod_name); +} + +#endif /* ACE_HAS_THREADS */ diff --git a/examples/ASX/Event_Server/Event_Server/Event_Analyzer.h b/examples/ASX/Event_Server/Event_Server/Event_Analyzer.h new file mode 100644 index 00000000000..9d38611e7aa --- /dev/null +++ b/examples/ASX/Event_Server/Event_Server/Event_Analyzer.h @@ -0,0 +1,34 @@ +/* -*- C++ -*- */ +// @(#)Event_Analyzer.h 1.1 10/18/96 + +/* Signal router */ + +#if !defined (_EVENT_ANALYZER_H) +#define _EVENT_ANALYZER_H + +#include "ace/Stream.h" +#include "ace/Module.h" +#include "ace/Task.h" +#include "ace/Synch.h" + +#if defined (ACE_HAS_THREADS) + +class Event_Analyzer : public ACE_Task +{ +public: + virtual int open (void *a = 0); + virtual int close (u_long flags = 0); + virtual int put (ACE_Message_Block *msg, ACE_Time_Value * = 0); + virtual int svc (void) { return 0; } + + /* Dynamic linking hooks */ + virtual int init (int argc, char *argv[]); + virtual int fini (void); + virtual int info (char **info_string, size_t length) const; + +private: + virtual int control (ACE_Message_Block *); +}; + +#endif /* ACE_HAS_THREADS */ +#endif /* _EVENT_ANALYZER_H */ diff --git a/examples/ASX/Event_Server/Event_Server/Makefile b/examples/ASX/Event_Server/Event_Server/Makefile new file mode 100644 index 00000000000..947f50c5d7a --- /dev/null +++ b/examples/ASX/Event_Server/Event_Server/Makefile @@ -0,0 +1,433 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Event Server test +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = event_server + +FILES = Options \ + Supplier_Router \ + Event_Analyzer \ + Consumer_Router \ + Peer_Router + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(addsuffix .o,$(FILES)) +SHOBJ = $(addsuffix .so,$(FILES)) + +LDLIBS = $(addprefix .shobj/,$(SHOBJ)) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/Options.o .shobj/Options.so: Options.cpp \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + Options.i +.obj/Supplier_Router.o .shobj/Supplier_Router.so: Supplier_Router.cpp Supplier_Router.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + Peer_Router.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/Acceptor.cpp \ + Peer_Router.cpp \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + Options.i +.obj/Event_Analyzer.o .shobj/Event_Analyzer.so: Event_Analyzer.cpp Event_Analyzer.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i +.obj/Consumer_Router.o .shobj/Consumer_Router.so: Consumer_Router.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + Consumer_Router.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/UPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Acceptor.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + Peer_Router.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/Acceptor.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + Peer_Router.cpp \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + Options.i +.obj/Peer_Router.o .shobj/Peer_Router.so: Peer_Router.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + Options.i Peer_Router.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/Acceptor.cpp \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + Peer_Router.cpp + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/ASX/Event_Server/Event_Server/Options.cpp b/examples/ASX/Event_Server/Event_Server/Options.cpp new file mode 100644 index 00000000000..41658639a77 --- /dev/null +++ b/examples/ASX/Event_Server/Event_Server/Options.cpp @@ -0,0 +1,186 @@ +#include "ace/Get_Opt.h" +// @(#)Options.cpp 1.1 10/18/96 + +#include "ace/Synch.h" +#include "ace/Thread.h" +#include "ace/Log_Msg.h" +#include "Options.h" + +#if defined (ACE_HAS_THREADS) + +Options::Options (void) + : debugging_ (0), + verbosity_ (0), + low_water_mark_ (1024), + high_water_mark_ (8 * 1024), + message_size_ (128), + thr_count_ (4), + initial_queue_length_ (0), + iterations_ (100000), + consumer_port_ ("-p " ACE_ITOA (10000)), + supplier_port_ ("-p " ACE_ITOA (10001)), + t_flags_ (THR_DETACHED) +{ +} + +Options::~Options (void) +{ +} + +void Options::print_results (void) +{ +#if !defined (ACE_WIN32) + ACE_Profile_Timer::ACE_Elapsed_Time et; + ACE_Profile_Timer::Rusage rusage; + + this->itimer_.elapsed_time (et); + this->itimer_.get_rusage (rusage); + + if (options.verbose ()) + { +#if defined (ACE_HAS_PRUSAGE_T) + ACE_OS::printf ("final concurrency hint = %d\n", ACE_Thread::getconcurrency ()); + ACE_OS::printf ("%8d = lwpid\n" + "%8d = lwp count\n" + "%8d = minor page faults\n" + "%8d = major page faults\n" + "%8d = input blocks\n" + "%8d = output blocks\n" + "%8d = messages sent\n" + "%8d = messages received\n" + "%8d = signals received\n" + "%8ds, %dms = wait-cpu (latency) time\n" + "%8ds, %dms = user lock wait sleep time\n" + "%8ds, %dms = all other sleep time\n" + "%8d = voluntary context switches\n" + "%8d = involuntary context switches\n" + "%8d = system calls\n" + "%8d = chars read/written\n", + rusage.pr_lwpid, + rusage.pr_count, + rusage.pr_minf, + rusage.pr_majf, + rusage.pr_inblk, + rusage.pr_oublk, + rusage.pr_msnd, + rusage.pr_mrcv, + rusage.pr_sigs, + rusage.pr_wtime.tv_sec, rusage.pr_wtime.tv_nsec / 1000000, + rusage.pr_ltime.tv_sec, rusage.pr_ltime.tv_nsec / 1000000, + rusage.pr_slptime.tv_sec, rusage.pr_slptime.tv_nsec / 1000000, + rusage.pr_vctx, + rusage.pr_ictx, + rusage.pr_sysc, + rusage.pr_ioch); +#else + /* Someone needs to write the corresponding dump for rusage... */ +#endif /* ACE_HAS_PRUSAGE_T */ + } + + ACE_OS::printf ("---------------------\n" + "real time = %.3f\n" + "user time = %.3f\n" + "system time = %.3f\n" + "---------------------\n", + et.real_time, et.user_time, et.system_time); +#endif /* ACE_WIN32 */ +} + +/* Manages the options */ +Options options; + +void +Options::parse_args (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0]); + + ACE_Get_Opt get_opt (argc, argv, "c:bdH:i:L:l:M:ns:t:T:v"); + int c; + + while ((c = get_opt ()) != -1) + switch (c) + { + case 'b': + this->t_flags (THR_BOUND); + break; + case 'c': + this->consumer_port (get_opt.optarg); + break; + case 'd': + this->debugging_ = 1; + break; + case 'H': + this->high_water_mark (ACE_OS::atoi (get_opt.optarg)); + break; + case 'i': + this->iterations (ACE_OS::atoi (get_opt.optarg)); + break; + case 'L': + this->low_water_mark (ACE_OS::atoi (get_opt.optarg)); + break; + case 'l': + this->initial_queue_length (ACE_OS::atoi (get_opt.optarg)); + break; + case 'M': + this->message_size (ACE_OS::atoi (get_opt.optarg)); + break; + case 'n': + this->t_flags (THR_NEW_LWP); + break; + case 's': + this->supplier_port (get_opt.optarg); + break; + case 'T': + if (ACE_OS::strcasecmp (get_opt.optarg, "ON") == 0) + ACE_Trace::start_tracing (); + else if (ACE_OS::strcasecmp (get_opt.optarg, "OFF") == 0) + ACE_Trace::stop_tracing (); + break; + case 't': + this->thr_count (ACE_OS::atoi (get_opt.optarg)); + break; + case 'v': + this->verbosity_ = 1; + break; + default: + ::fprintf (stderr, "%s\n" + "\t[-b] (THR_BOUND)\n" + "\t[-c consumer port]\n" + "\t[-d] (enable debugging)\n" + "\t[-H high water mark]\n" + "\t[-i number of test iterations]\n" + "\t[-L low water mark]\n" + "\t[-M] message size \n" + "\t[-n] (THR_NEW_LWP)\n" + "\t[-q max queue size]\n" + "\t[-s supplier port]\n" + "\t[-t number of threads]\n" + "\t[-v] (verbose) \n", + argv[0]); + ::exit (1); + /* NOTREACHED */ + break; + } + + if (this->verbose ()) + ACE_OS::printf ("%8d = initial concurrency hint\n" + "%8d = total iterations\n" + "%8d = thread count\n" + "%8d = low water mark\n" + "%8d = high water mark\n" + "%8d = message_size\n" + "%8d = initial queue length\n" + "%8d = THR_BOUND\n" + "%8d = THR_NEW_LWP\n", + ACE_Thread::getconcurrency (), + this->iterations (), + this->thr_count (), + this->low_water_mark (), + this->high_water_mark (), + this->message_size (), + this->initial_queue_length (), + (this->t_flags () & THR_BOUND) != 0, + (this->t_flags () & THR_NEW_LWP) != 0); +} + +#endif /* ACE_HAS_THREADS */ diff --git a/examples/ASX/Event_Server/Event_Server/Options.h b/examples/ASX/Event_Server/Event_Server/Options.h new file mode 100644 index 00000000000..054f0d834f6 --- /dev/null +++ b/examples/ASX/Event_Server/Event_Server/Options.h @@ -0,0 +1,75 @@ +/* -*- C++ -*- */ +// @(#)Options.h 1.1 10/18/96 + +/* Option manager for Event Server */ + +#if !defined (DEVICE_OPTIONS_H) +#define DEVICE_OPTIONS_H + +#include "ace/OS.h" +#include "ace/Profile_Timer.h" + +#if defined (ACE_HAS_THREADS) + +class Options +{ +public: + Options (void); + ~Options (void); + void parse_args (int argc, char *argv[]); + + void stop_timer (void); + void start_timer (void); + + void thr_count (size_t count); + size_t thr_count (void); + + void initial_queue_length (size_t length); + size_t initial_queue_length (void); + + void high_water_mark (size_t size); + size_t high_water_mark (void); + + void low_water_mark (size_t size); + size_t low_water_mark (void); + + void message_size (size_t size); + size_t message_size (void); + + void iterations (size_t n); + size_t iterations (void); + + void t_flags (long flag); + long t_flags (void); + + void supplier_port (char *port); + char *supplier_port (void); + + void consumer_port (char *port); + char *consumer_port (void); + + int debug (void); + int verbose (void); + + void print_results (void); + +private: + ACE_Profile_Timer itimer_; /* Time the process */ + size_t thr_count_; /* Number of threads to spawn */ + long t_flags_; /* Flags to thr_create() */ + size_t high_water_mark_; /* ACE_Task high water mark */ + size_t low_water_mark_; /* ACE_Task low water mark */ + size_t message_size_; /* Size of a message */ + size_t initial_queue_length_; /* Initial number of items in the queue */ + size_t iterations_; /* Number of iterations to run the test program */ + int debugging_; /* Extra debugging info */ + int verbosity_; /* Extra verbose messages */ + char *consumer_port_; /* Port that the Consumer_Router is using */ + char *supplier_port_; /* Port that the Supplier_Router is using */ +}; + +extern Options options; + +#include "Options.i" +#endif /* ACE_HAS_THREADS */ +#endif /* DEVICE_OPTIONS_H */ diff --git a/examples/ASX/Event_Server/Event_Server/Options.i b/examples/ASX/Event_Server/Event_Server/Options.i new file mode 100644 index 00000000000..c538b94b46a --- /dev/null +++ b/examples/ASX/Event_Server/Event_Server/Options.i @@ -0,0 +1,137 @@ +/* -*- C++ -*- */ +// @(#)Options.i 1.1 10/18/96 + +/* Option manager for ustreams */ + +inline void +Options::supplier_port (char *port) +{ + this->supplier_port_ = port; +} + +inline char * +Options::supplier_port (void) +{ + return this->supplier_port_; +} + +inline void +Options::consumer_port (char *port) +{ + this->consumer_port_ = port; +} + +inline char * +Options::consumer_port (void) +{ + return this->consumer_port_; +} + +inline void +Options::start_timer (void) +{ + this->itimer_.start (); +} + +inline void +Options::stop_timer (void) +{ + this->itimer_.stop (); +} + +inline void +Options::thr_count (size_t count) +{ + this->thr_count_ = count; +} + +inline size_t +Options::thr_count (void) +{ + return this->thr_count_; +} + +inline void +Options::initial_queue_length (size_t length) +{ + this->initial_queue_length_ = length; +} + +inline size_t +Options::initial_queue_length (void) +{ + return this->initial_queue_length_; +} + +inline void +Options::high_water_mark (size_t size) +{ + this->high_water_mark_ = size; +} + +inline size_t +Options::high_water_mark (void) +{ + return this->high_water_mark_; +} + +inline void +Options::low_water_mark (size_t size) +{ + this->low_water_mark_ = size; +} + +inline size_t +Options::low_water_mark (void) +{ + return this->low_water_mark_; +} + +inline void +Options::message_size (size_t size) +{ + this->message_size_ = size; +} + +inline size_t +Options::message_size (void) +{ + return this->message_size_; +} + +inline void +Options::iterations (size_t n) +{ + this->iterations_ = n; +} + +inline size_t +Options::iterations (void) +{ + return this->iterations_; +} + +inline void +Options::t_flags (long flag) +{ + this->t_flags_ |= flag; +} + +inline long +Options::t_flags (void) +{ + return this->t_flags_; +} + +inline int +Options::debug (void) +{ + return this->debugging_; +} + +inline int +Options::verbose (void) +{ + return this->verbosity_; +} + diff --git a/examples/ASX/Event_Server/Event_Server/Peer_Router.cpp b/examples/ASX/Event_Server/Event_Server/Peer_Router.cpp new file mode 100644 index 00000000000..f0a77ed7103 --- /dev/null +++ b/examples/ASX/Event_Server/Event_Server/Peer_Router.cpp @@ -0,0 +1,279 @@ +#if !defined (_PEER_ROUTER_C) +// @(#)Peer_Router.cpp 1.1 10/18/96 + +#define _PEER_ROUTER_C + +#include "ace/Service_Config.h" +#include "ace/Get_Opt.h" +#include "ace/Log_Msg.h" +#include "Options.h" +#include "Peer_Router.h" + +#if defined (ACE_HAS_THREADS) + +// Define some short-hand macros to deal with verbose templates +// names... + +#define PH PEER_HANDLER +#define PA PEER_ACCEPTOR +#define PAD PEER_ADDR +#define PK PEER_KEY +#define PM PEER_MAP + +template int +Acceptor_Factory::init (int argc, char *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, "dp:", 0); + ACE_INET_Addr addr; + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'p': + addr.set (ACE_OS::atoi (get_opt.optarg)); + break; + case 'd': + break; + default: + break; + } + + if (this->open (addr, ACE_Service_Config::reactor ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + return 0; +} + +template +Acceptor_Factory::Acceptor_Factory (Peer_Router *pr) + : pr_ (pr) +{ +} + +template Peer_Router * +Acceptor_Factory::router (void) +{ + return this->pr_; +} + +template +Peer_Handler::Peer_Handler (ACE_Thread_Manager *tm) + : inherited (tm) +{ +} + +template int +Peer_Handler::svc (void) +{ +#if 0 + ACE_Thread_Control thread_control (tm); + // Just a try !! we're just reading from our Message_Queue + ACE_Message_Block *db, *hb; + int n; + + // Do an endless loop + for (;;) + { + db = new Message_Block (BUFSIZ); + hb = new Message_Block (sizeof (KEY), Message_Block::MB_PROTO, db); + + if ((n = this->peer_.recv (db->rd_ptr (), db->size ())) == -1) + LM_ERROR_RETURN ((LOG_ERROR, "%p", "recv failed"), -1); + else if (n == 0) // Client has closed down the connection. + { + if (this->router_task_->unbind_peer (this->get_handle ()) == -1) + LM_ERROR_RETURN ((LOG_ERROR, "%p", "unbind failed"), -1); + LM_DEBUG ((LOG_DEBUG, "(%t) shutting down \n")); + return -1; // We do not need to be deregistered by reactor + // as we were not registered at all + } + else + // Transform incoming buffer into a Message and pass + // downstream. + { + db->wr_ptr (n); + *(long *) hb->rd_ptr () = this->get_handle (); // Structure assignment. + hb->wr_ptr (sizeof (long)); + + if (this->router_task_->reply (hb) == -1) + { + cout << "Peer_Handler.svc : router_task->reply failed" << endl ; + return -1; + } + } + } + return 0; +#else + return -1; +#endif +} + +template int +Peer_Handler::put (ACE_Message_Block *mb, ACE_Time_Value *) +{ + return this->peer ().send_n (mb->rd_ptr (), mb->length ()); +} + +// Create a new handler and point its ROUTER_TASK_ data member to the +// corresponding router. Note that this router is extracted out of +// the Acceptor_Factory * that is passed in via the +// ACE_Acceptor::handle_input() method. + +template int +Peer_Handler::open (void *a) +{ + char buf[BUFSIZ], *p = buf; + + if (this->router_task_->info (&p, sizeof buf) != -1) + ACE_DEBUG ((LM_DEBUG, "(%t) creating handler for %s, fd = %d, this = %d\n", + buf, this->get_handle (), a)); + else + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "info"), -1); +#if 0 + if (this->activate (options.t_flags ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "activation of thread failed"), -1); +#endif + ACE_DEBUG ((LM_DEBUG, + "Peer_Handler::open registering with Reactor for handle_input\n")); + + if (ACE_Service_Config::reactor ()->register_handler + (this, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "register_handler"), -1); + else if (this->router_task_->bind_peer (this->get_handle (), this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "bind_peer"), -1); + else if (this->peer ().disable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "disable non-blocking I/O"), -1); + return 0; +} + +// Receive a message from a supplier. + +template int +Peer_Handler::handle_input (ACE_HANDLE h) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) input arrived on sd %d\n", h)); + + ACE_Message_Block *db = new ACE_Message_Block (BUFSIZ); + ACE_Message_Block *hb = new ACE_Message_Block (sizeof (KEY), + ACE_Message_Block::MB_PROTO, db); + int n; + + if ((n = this->peer ().recv (db->rd_ptr (), db->size ())) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p", "recv failed"), -1); + else if (n == 0) // Client has closed down the connection. + { + if (this->router_task_->unbind_peer (this->get_handle ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p", "unbind failed"), -1); + ACE_DEBUG ((LM_DEBUG, "(%t) shutting down %d\n", h)); + return -1; // Instruct the ACE_Reactor to deregister us by returning -1. + } + else // Transform incoming buffer into a Message and pass downstream. + { + db->wr_ptr (n); + *(ACE_HANDLE *) hb->rd_ptr () = this->get_handle (); // structure assignment. + hb->wr_ptr (sizeof (ACE_HANDLE)); + return this->router_task_->reply (hb) == -1 ? -1 : 0; + } +} + +template +Peer_Router::Peer_Router (ACE_Thread_Manager *tm) + : ACE_Task (tm) +{ +} + +template int +Peer_Router::send_peers (ACE_Message_Block *mb) +{ + PEER_ITERATOR map_iter = this->peer_map_; + int bytes = 0; + int iterations = 0; + ACE_Message_Block *data_block = mb->cont (); + + for (ACE_Map_Entry *ss = 0; + map_iter.next (ss) != 0; + map_iter.advance ()) + { + if (options.debug ()) + ACE_DEBUG ((LM_DEBUG, "(%t) sending to peer via sd %d\n", ss->ext_id_)); + + iterations++; + bytes += ss->int_id_->put (data_block); + } + + delete mb; + return bytes == 0 ? 0 : bytes / iterations; +} + +template +Peer_Router::~Peer_Router (void) +{ +} + +template ACE_INLINE int +Peer_Router::fini (void) +{ + delete this->acceptor_; + return 0; +} + +template ACE_INLINE int +Peer_Router::control (ACE_Message_Block *mb) +{ + ACE_IO_Cntl_Msg *ioc = (ACE_IO_Cntl_Msg *) mb->rd_ptr (); + ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds command; + + switch (command = ioc->cmd ()) + { + case ACE_IO_Cntl_Msg::SET_LWM: + case ACE_IO_Cntl_Msg::SET_HWM: + this->water_marks (command, *(size_t *) mb->cont ()->rd_ptr ()); + break; + default: + return -1; + } + return 0; +} + +template ACE_INLINE int +Peer_Router::unbind_peer (PK key) +{ + return this->peer_map_.unbind (key); +} + +template ACE_INLINE int +Peer_Router::bind_peer (PK key, Peer_Handler, PK> *ph) +{ + PH *peer_handler = (PH *) ph; + return this->peer_map_.bind (key, peer_handler); +} + +template ACE_INLINE int +Peer_Router::init (int argc, char *argv[]) +{ + this->acceptor_ = new ACCEPTOR (this); + + if (this->acceptor_->init (argc, argv) == -1 + || this->peer_map_.open () == -1) + return -1; + else + { + ACE_INET_Addr addr; + ACE_SOCK_Acceptor &acceptor = this->acceptor_->acceptor(); + + if (acceptor.get_local_addr (addr) != -1) + ACE_DEBUG ((LM_DEBUG, "(%t) initializing %s, port = %d, fd = %d, this = %u\n", + this->name (), addr.get_port_number (), + acceptor.get_handle (), this)); + else + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "get_local_addr"), -1); + } + return 0; +} + +#undef PH +#undef PA +#undef PAD +#undef PK +#undef PM +#endif /* ACE_HAS_THREADS */ +#endif /* _PEER_ROUTER_C */ diff --git a/examples/ASX/Event_Server/Event_Server/Peer_Router.h b/examples/ASX/Event_Server/Event_Server/Peer_Router.h new file mode 100644 index 00000000000..5df444a985a --- /dev/null +++ b/examples/ASX/Event_Server/Event_Server/Peer_Router.h @@ -0,0 +1,121 @@ +/* -*- C++ -*- */ +// @(#)Peer_Router.h 1.1 10/18/96 + + +#if !defined (_PEER_ROUTER_H) +#define _PEER_ROUTER_H + +#include "ace/Acceptor.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/Thread_Manager.h" +#include "ace/Map_Manager.h" + +#if defined (ACE_HAS_THREADS) + +// Forward declaration. +template +class Peer_Router; + +template +class Acceptor_Factory : public ACE_Acceptor + // = TITLE + // Creates , which route events between peers. +{ +public: + Acceptor_Factory (Peer_Router *pr); + Peer_Router *router (void); + + int init (int argc, char *argv[]); + // Initialize the acceptor when it's linked dynamically. + +private: + Peer_Router *pr_; +}; + +template +class Peer_Handler : public ACE_Svc_Handler + // = TITLE + // Receive input from a Peer. +{ +public: + Peer_Handler (ACE_Thread_Manager * = 0); + + virtual int open (void * = 0); + // Called by the ACE_Acceptor::handle_input() to activate this object. + + virtual int handle_input (ACE_HANDLE); + // Receive input from the peer. + + virtual int put (ACE_Message_Block *, ACE_Time_Value *tv = 0); + // Send output to a peer. + +protected: + typedef ACE_Svc_Handler inherited; + + ROUTER *router_task_; + // Pointer to write task. + +private: + virtual int svc (void); + // Don't need this method here... +}; + +template +class Peer_Router : public ACE_Task + // = TITLE + // This abstract base class provides mechanisms for routing + // messages to/from a ACE_Stream from/to one or more peers (which + // are typically running on remote hosts). + // + // = DESCRIPTION + // A subclass of Peer_Router overrides the open(), close(), and + // put() methods in order to specialize the behavior of the router + // to meet application-specific requirements. +{ +public: + // = Initialization and termination methods. + Peer_Router (ACE_Thread_Manager * = 0); + ~Peer_Router (void); + + typedef Peer_Handler, PEER_KEY> HANDLER; + + virtual int unbind_peer (PEER_KEY); + // Remove a PEER_HANDLER from the PEER_MAP. + + virtual int bind_peer (PEER_KEY, HANDLER *); + // Add a PEER_HANDLER to the PEER_MAP + + int send_peers (ACE_Message_Block *mb); + // Send the message block to the peer(s). + +protected: + virtual int control (ACE_Message_Block *); + // Handle control messages arriving from adjacent Modules. + + // = Useful typedefs + typedef ACE_Map_Manager PEER_MAP; + typedef ACE_Map_Iterator PEER_ITERATOR; + + PEER_MAP peer_map_; + // Map used to keep track of active peers. + + // = Dynamic linking initialization hooks inherited from ACE_Task + virtual int init (int argc, char *argv[]); + virtual int fini (void); + + typedef Acceptor_Factory ACCEPTOR; + + ACCEPTOR *acceptor_; + // Factory for accepting new PEER_HANDLERs. + +private: + // = Prevent copies and pass-by-value. + Peer_Router (const Peer_Router &) {} + void operator= (const Peer_Router &) {} +}; + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "Peer_Router.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ +#endif /* ACE_HAS_THREADS */ +#endif /* _PEER_ROUTER_H */ diff --git a/examples/ASX/Event_Server/Event_Server/Supplier_Router.cpp b/examples/ASX/Event_Server/Event_Server/Supplier_Router.cpp new file mode 100644 index 00000000000..6d18dce66fa --- /dev/null +++ b/examples/ASX/Event_Server/Event_Server/Supplier_Router.cpp @@ -0,0 +1,134 @@ +#include "Supplier_Router.h" +// @(#)Supplier_Router.cpp 1.1 10/18/96 + +#include "Options.h" + +#if defined (ACE_HAS_THREADS) + +typedef Acceptor_Factory SUPPLIER_FACTORY; + +int +Supplier_Handler::open (void *a) +{ + SUPPLIER_FACTORY *af = (SUPPLIER_FACTORY *) a; + this->router_task_ = af->router (); + return this->Peer_Handler::open (a); +} + +Supplier_Handler::Supplier_Handler (ACE_Thread_Manager *tm) + : Peer_Handler (tm) +{ +} + +// Create a new router and associate it with the REACTOR parameter. + +Supplier_Router::Supplier_Router (ACE_Thread_Manager *tm) + : SUPPLIER_ROUTER (tm) +{ +} + +// Handle incoming messages in a separate thread. + +int +Supplier_Router::svc (void) +{ + assert (this->is_writer ()); + + ACE_Thread_Control tc (this->thr_mgr ()); + ACE_Message_Block *mb = 0; + + ACE_DEBUG ((LM_DEBUG, "(%t) starting svc in Supplier_Router\n")); + + while (this->getq (mb) >= 0) + { + ACE_DEBUG ((LM_DEBUG, "Supplier_Router is routing via send_peers\n")); + if (this->send_peers (mb) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "(%t) send_peers failed in Supplier_Router\n"), + -1); + } + + ACE_DEBUG ((LM_DEBUG, "(%t) stopping svc in Supplier_Router\n")); + return 0; + // Note the implicit ACE_OS::thr_exit() via ACE_Thread_Control's + // destructor. +} + +// Initialize the Router. + +int +Supplier_Router::open (void *) +{ + assert (this->is_writer ()); + + char *argv[4]; + + argv[0] = (char *) this->name (); + argv[1] = "-p"; + argv[2] = options.supplier_port (); + argv[3] = 0; + + if (this->init (2, &argv[1]) == -1) + return -1; + + // Make this an active object. + return this->activate (options.t_flags ()); +} + +// Close down the router. + +int +Supplier_Router::close (u_long) +{ + assert (this->is_writer ()); + ACE_DEBUG ((LM_DEBUG, "(%t) closing Supplier_Router\n")); + this->peer_map_.close (); + + // Inform the thread to shut down. + this->msg_queue ()->deactivate (); + return 0; +} + +// Send a MESSAGE_BLOCK to the supplier(s). + +int +Supplier_Router::put (ACE_Message_Block *mb, ACE_Time_Value *) +{ + assert (this->is_writer ()); + + if (mb->msg_type () == ACE_Message_Block::MB_IOCTL) + { + this->control (mb); + return this->put_next (mb); + } + else + // Queue up the message, which will be processed by + // Supplier_Router::svc(). + return this->putq (mb); +} + +// Return information about the Supplier_Router ACE_Module. + +int +Supplier_Router::info (char **strp, size_t length) const +{ + char buf[BUFSIZ]; + ACE_INET_Addr addr; + const char *mod_name = this->name (); + ACE_SOCK_Acceptor &sa = this->acceptor_->acceptor (); + + if (sa.get_local_addr (addr) == -1) + return -1; + + ACE_OS::sprintf (buf, "%s\t %d/%s %s", + mod_name, addr.get_port_number (), "tcp", + "# supplier router\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (mod_name)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, mod_name, length); + return ACE_OS::strlen (mod_name); +} + +#endif /* ACE_HAS_THREADS */ diff --git a/examples/ASX/Event_Server/Event_Server/Supplier_Router.h b/examples/ASX/Event_Server/Event_Server/Supplier_Router.h new file mode 100644 index 00000000000..766e08c01e3 --- /dev/null +++ b/examples/ASX/Event_Server/Event_Server/Supplier_Router.h @@ -0,0 +1,51 @@ +/* -*- C++ -*- */ +// @(#)Supplier_Router.h 1.1 10/18/96 + +/* The interface between a supplier and an Event Service ACE_Stream */ + +#if !defined (_SUPPLIER_ROUTER_H) +#define _SUPPLIER_ROUTER_H + +#include "ace/INET_Addr.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/Map_Manager.h" +#include "ace/Svc_Handler.h" +#include "Peer_Router.h" + +#if defined (ACE_HAS_THREADS) + +/* Forward declaration */ +class Supplier_Handler; + +/* Type of search key for SUPPLIER_MAP */ +typedef ACE_HANDLE SUPPLIER_KEY; + +/* Instantiated type for routing messages to suppliers */ + +typedef Peer_Router SUPPLIER_ROUTER; + +class Supplier_Handler : public Peer_Handler +{ +public: + Supplier_Handler (ACE_Thread_Manager *tm = 0); + virtual int open (void *); +}; + +class Supplier_Router : public SUPPLIER_ROUTER +{ +public: + Supplier_Router (ACE_Thread_Manager *); + +protected: + /* ACE_Task hooks. */ + virtual int open (void *a = 0); + virtual int close (u_long flags = 0); + virtual int put (ACE_Message_Block *msg, ACE_Time_Value * = 0); + virtual int svc (void); + + /* Dynamic linking hooks inherited from Peer_Router */ + virtual int info (char **info_string, size_t length) const; +}; + +#endif /* ACE_HAS_THREADS */ +#endif /* _SUPPLIER_ROUTER_H */ diff --git a/examples/ASX/Event_Server/Event_Server/event_server.cpp b/examples/ASX/Event_Server/Event_Server/event_server.cpp new file mode 100644 index 00000000000..e54bb845d84 --- /dev/null +++ b/examples/ASX/Event_Server/Event_Server/event_server.cpp @@ -0,0 +1,125 @@ +// Test the event server. +// @(#)event_server.cpp 1.1 10/18/96 + +#include "ace/Log_Msg.h" +#include "ace/Stream.h" +#include "ace/Service_Config.h" +#include "Options.h" +#include "Consumer_Router.h" +#include "Event_Analyzer.h" +#include "Supplier_Router.h" + +#if defined (ACE_HAS_THREADS) + +typedef ACE_Stream MT_Stream; +typedef ACE_Module MT_Module; + +// Handle SIGINT and terminate the entire application. + +class Quit_Handler : public ACE_Sig_Adapter +{ +public: + Quit_Handler (void); + virtual int handle_input (ACE_HANDLE fd); +}; + +Quit_Handler::Quit_Handler (void) + : ACE_Sig_Adapter (ACE_Sig_Handler_Ex (ACE_Service_Config::end_reactor_event_loop)) +{ + // Register to trap input from the user. + if (ACE::register_stdin_handler (this, + ACE_Service_Config::reactor (), + ACE_Service_Config::thr_mgr ()) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "register_stdin_handler")); + // Register to trap the SIGINT signal. + else if (ACE_Service_Config::reactor ()->register_handler + (SIGINT, this) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "register_handler")); +} + +int +Quit_Handler::handle_input (ACE_HANDLE) +{ + options.stop_timer (); + ACE_DEBUG ((LM_INFO, "(%t) closing down the test\n")); + options.print_results (); + + ACE_Service_Config::end_reactor_event_loop (); + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config daemon; + + options.parse_args (argc, argv); + + { + // Primary ACE_Stream for EVENT_SERVER application. + MT_Stream event_server; + + // Enable graceful shutdowns... + Quit_Handler quit_handler; + + // Create the Supplier Router module. + + MT_Module *sr = new MT_Module ("Supplier_Router", + new Supplier_Router (ACE_Service_Config::thr_mgr ())); + + // Create the Event Analyzer module. + + MT_Module *ea = new MT_Module ("Event_Analyzer", + new Event_Analyzer, + new Event_Analyzer); + + // Create the Consumer Router module. + + MT_Module *cr = new MT_Module ("Consumer_Router", + 0, // 0 triggers the creation of a ACE_Thru_Task... + new Consumer_Router (ACE_Service_Config::thr_mgr ())); + + // Push the Modules onto the event_server stream. + + if (event_server.push (sr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push (Supplier_Router)"), -1); + + if (event_server.push (ea) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push (Event_Analyzer)"), -1); + + if (event_server.push (cr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push (Consumer_Router)"), -1); + + // Set the high and low water marks appropriately. + + int wm = options.low_water_mark (); + + if (event_server.control (ACE_IO_Cntl_Msg::SET_LWM, &wm) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "push (setting low watermark)"), -1); + + wm = options.high_water_mark (); + if (event_server.control (ACE_IO_Cntl_Msg::SET_HWM, &wm) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "push (setting high watermark)"), -1); + + options.start_timer (); + + // Perform the main event loop waiting for the user to type ^C or to + // enter a line on the ACE_STDIN. + + daemon.run_reactor_event_loop (); + // The destructor of event_server will close down the stream and + // call the close() hooks on all the ACE_Tasks. + } + + // Wait for the threads to exit. + ACE_Service_Config::thr_mgr ()->wait (); + ACE_DEBUG ((LM_DEBUG, "exiting main\n")); + return 0; +} +#else +int +main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "test not defined for this platform\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/ASX/Event_Server/Makefile b/examples/ASX/Event_Server/Makefile new file mode 100644 index 00000000000..6c8d3f443f5 --- /dev/null +++ b/examples/ASX/Event_Server/Makefile @@ -0,0 +1,23 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Event Server tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +DIRS = Event_Server \ + Transceiver + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + diff --git a/examples/ASX/Event_Server/README b/examples/ASX/Event_Server/README new file mode 100644 index 00000000000..f97e767cdd8 --- /dev/null +++ b/examples/ASX/Event_Server/README @@ -0,0 +1,38 @@ +The subdirectory illustrates a number of the ACE ASX framework +features using an ACE_Stream application called the Event Server. The +Event Server works as follows: + +1. When the ./Event_Server/event_server executable is run it + creates two SOCK_Acceptors, which listen for and accept + incoming connections from consumers and suppliers. + +2. The ./Event_Server/Transceiver/transceiver application may be + started multiple times. Each call should be either: + + % transceiver -p XYZ -h hostname + + or + + % transceiver -p ABC -h hostname + + where XYZ and ABC are the consumer port and supplier port, + respectively, on the event server and "hostname" is the name of the + machine the event_server is running. I typically open up multiple + windows. + +3. Once the consumer(s) and supplier(s) are connected, you can type + data from any supplier windows. This data will be routed + through the Modules/Tasks in an event_server's Stream and + be forwarded to the consumer(s). + +4. When you want to shut down the tranceivers or event server + just type ^C (which generates a SIGINT). + +What makes this example particularly interesting is that +once you've got the hang of this basic architecture, you can +"push" new filtering Modules onto the event_server Stream + and modify the application's behavior. + +For more information on the design and use of the ACE ASX framework +please see http://www.cs.wustl.edu/~schmidt/C++-USENIX-94.ps.gz and +http://www.cs.wustl.edu/~schmidt/DSEJ-94.ps.gz diff --git a/examples/ASX/Event_Server/Transceiver/Makefile b/examples/ASX/Event_Server/Transceiver/Makefile new file mode 100644 index 00000000000..7fb95dc617d --- /dev/null +++ b/examples/ASX/Event_Server/Transceiver/Makefile @@ -0,0 +1,135 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the transceiver portion of the Event Server test +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = transceiver + +LSRC = $(addsuffix .cpp,$(BIN)) + +LDLIBS = + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +INSTALL = + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/transceiver.o .shobj/transceiver.so: transceiver.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Connector.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Connector.i \ + $(WRAPPER_ROOT)/ace/Connector.cpp \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/ASX/Event_Server/Transceiver/transceiver.cpp b/examples/ASX/Event_Server/Transceiver/transceiver.cpp new file mode 100644 index 00000000000..7321e02dd9c --- /dev/null +++ b/examples/ASX/Event_Server/Transceiver/transceiver.cpp @@ -0,0 +1,187 @@ +// Test program for the event transceiver. This program can play the +// @(#)transceiver.cpp 1.1 10/18/96 + +// role of either Consumer or Supplier. You can terminate this +// program by typing ^C.... + +#include "ace/Log_Msg.h" +#include "ace/Service_Config.h" +#include "ace/Connector.h" +#include "ace/SOCK_Connector.h" +#include "ace/Get_Opt.h" + +#if defined (ACE_HAS_THREADS) + +class Event_Transceiver : public ACE_Svc_Handler + // = TITLE + // Generate and receives messages from the event server. + // + // = DESCRIPTION + // This class is both a consumer and supplier of events, i.e., + // it is a ``transceiver.'' +{ +public: + Event_Transceiver (void); + + // = Svc_Handler hook called by the . + virtual int open (void *); + // Initialize the transceiver when we are connected. + + // = Demultplexing hooks from the . + virtual int handle_input (ACE_HANDLE); + // Receive data from STDIN or socket. + + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + // Close down via SIGINT. + +private: + int receiver (void); + // Reads data from socket and writes to ACE_STDOUT. + + int forwarder (void); + // Writes data from ACE_STDIN to socket. +}; + +// Close down via SIGINT. + +int +Event_Transceiver::handle_signal (int signum, + siginfo_t *, + ucontext_t *) +{ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) received signal %S\n", signum)); + + ACE_Service_Config::end_reactor_event_loop (); + return 0; +} + +Event_Transceiver::Event_Transceiver (void) +{ + ACE_Sig_Set sig_set; + + sig_set.sig_add (SIGINT); + sig_set.sig_add (SIGQUIT); + + if (ACE_Service_Config::reactor ()->register_handler + (sig_set, this) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "register_handler")); +} + +int +Event_Transceiver::open (void *) +{ + if (ACE_Service_Config::reactor ()->register_handler + (this->peer ().get_handle (), + this, + ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "register_handler"), -1); + else if (ACE::register_stdin_handler (this, + ACE_Service_Config::reactor (), + ACE_Service_Config::thr_mgr ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "register_stdin_handler"), -1); + return 0; +} + +int +Event_Transceiver::handle_input (ACE_HANDLE handle) +{ + if (handle == ACE_STDIN) + return this->forwarder (); + else + return this->receiver (); +} + + +int +Event_Transceiver::forwarder (void) +{ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) entering transceiver forwarder\n")); + + char buf[BUFSIZ]; + ssize_t n = ACE_OS::read (ACE_STDIN, buf, sizeof buf); + int result = 0; + + if (n <= 0 || this->peer ().send_n (buf, n) != n) + result = -1; + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) leaving transceiver forwarder\n")); + return result; +} + +int +Event_Transceiver::receiver (void) +{ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) entering transceiver receiver\n")); + + char buf[BUFSIZ]; + + ssize_t n = this->peer ().recv (buf, sizeof buf); + int result = 0; + + if (n <= 0 || ACE_OS::write (ACE_STDOUT, buf, n) != n) + result = -1; + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) leaving transceiver receiver\n")); + return result; +} + +// Port number of event server. +static u_short port_number; + +// Name of event server. +static char *host_name; + +// Handle the command-line arguments. + +static void +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, "h:p:"); + + port_number = ACE_DEFAULT_SERVER_PORT; + host_name = ACE_DEFAULT_SERVER_HOST; + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'h': + host_name = get_opt.optarg; + break; + case 'p': + port_number = ACE_OS::atoi (get_opt.optarg); + break; + default: + ACE_ERROR ((LM_ERROR, + "usage: %n [-p portnum] [-h host_name]\n%a", 1)); + /* NOTREACHED */ + break; + } +} + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config daemon (argv[0]); + + parse_args (argc, argv); + + // Establish the connection. + ACE_Connector connector; + Event_Transceiver transceiver; + + if (connector.connect (&transceiver, ACE_INET_Addr (port_number, host_name)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", host_name), 1); + + // Run event loop until either the event server shuts down or we get + // a SIGINT. + ACE_Service_Config::run_reactor_event_loop (); + return 0; +} +#else +int +main (void) +{ + ACE_ERROR ((LM_ERROR, "test not defined for this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/ASX/Makefile b/examples/ASX/Makefile new file mode 100644 index 00000000000..38b94b51626 --- /dev/null +++ b/examples/ASX/Makefile @@ -0,0 +1,25 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the ASX test directory +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +DIRS = CCM_App \ + Event_Server \ + Message_Queue \ + UPIPE_Event_Server + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + diff --git a/examples/ASX/Message_Queue/Makefile b/examples/ASX/Message_Queue/Makefile new file mode 100644 index 00000000000..77e32813526 --- /dev/null +++ b/examples/ASX/Message_Queue/Makefile @@ -0,0 +1,218 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for Message_Queue tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = buffer_stream \ + bounded_buffer \ + priority_buffer + +LSRC = $(addsuffix .cpp,$(BIN)) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/buffer_stream.o .shobj/buffer_stream.so: buffer_stream.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i +.obj/bounded_buffer.o .shobj/bounded_buffer.so: bounded_buffer.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h +.obj/priority_buffer.o .shobj/priority_buffer.so: priority_buffer.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Read_Buffer.h \ + $(WRAPPER_ROOT)/ace/Read_Buffer.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/ASX/Message_Queue/bounded_buffer.cpp b/examples/ASX/Message_Queue/bounded_buffer.cpp new file mode 100644 index 00000000000..ec5abd1d7e1 --- /dev/null +++ b/examples/ASX/Message_Queue/bounded_buffer.cpp @@ -0,0 +1,130 @@ +// This short program copies stdin to stdout via the use of an ASX +// @(#)bounded_buffer.cpp 1.1 10/18/96 + +// Message_Queue. It illustrates an implementation of the classic +// "bounded buffer" program. + +#include "ace/Log_Msg.h" +#include "ace/Message_Queue.h" +#include "ace/Thread_Manager.h" + +#if defined (ACE_HAS_THREADS) + +// Global thread manager. +static ACE_Thread_Manager thr_mgr; + +// Message list. +static ACE_Message_Queue msg_queue; + +// The producer reads data from the stdin stream, creates a message, +// and then queues the message in the message list, where it is +// removed by the consumer thread. A 0-sized message is enqueued when +// there is no more data to read. The consumer uses this as a flag to +// know when to exit. + +static void * +producer (ACE_Message_Queue *msg_queue) +{ + // Insert thread into thr_mgr. + ACE_Thread_Control thread_control (&thr_mgr); + + // Keep reading stdin, until we reach EOF. + + for (int n; ; ) + { + // Allocate a new message. + ACE_Message_Block *mb = new ACE_Message_Block (BUFSIZ); + + n = ACE_OS::read (ACE_STDIN, mb->rd_ptr (), mb->size ()); + + if (n <= 0) + { + // Send a shutdown message to the other thread and exit. + mb->length (0); + if (msg_queue->enqueue_tail (mb) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "put_next")); + break; + } + + // Send the message to the other thread. + else + { + mb->msg_priority (n); + mb->wr_ptr (n); + if (msg_queue->enqueue_tail (mb) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "put_next")); + } + } + + // The destructor of ACE_Thread_Control removes the exiting thread + // from the thr_mgr automatically. + return 0; +} + +// The consumer dequeues a message from the ACE_Message_Queue, writes +// the message to the stderr stream, and deletes the message. The +// producer sends a 0-sized message to inform the consumer to stop +// reading and exit. + +static void *consumer (ACE_Message_Queue *msg_queue) +{ + // Insert thread into thr_mgr. + ACE_Thread_Control thread_control (&thr_mgr); + int result = 0; + + // Keep looping, reading a message out of the queue, until we timeout + // or get a message with a length == 0, which signals us to quit. + + for (;;) + { + ACE_Message_Block *mb; + + ACE_Time_Value timeout (ACE_OS::time (0) + 4, 0); // Wait for upto 4 seconds + + result = msg_queue->dequeue_head (mb, &timeout); + + if (result == -1) + break; + + int length = mb->length (); + + if (length > 0) + ACE_OS::write (ACE_STDOUT, mb->rd_ptr (), length); + + delete mb; + + if (length == 0) + break; + } + + if (result == -1 && errno == EWOULDBLOCK) + ACE_ERROR ((LM_ERROR, "(%t) %p\n%a", "timed out waiting for message", 1)); + + // The destructor of ACE_Thread_Control removes the exiting thread + // from the thr_mgr automatically. + return 0; +} + +/* Spawn off two threads that copy stdin to stdout. */ + +int main (int, char *[]) +{ + if (thr_mgr.spawn (ACE_THR_FUNC (producer), (void *) &msg_queue, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), 1); + else if (thr_mgr.spawn (ACE_THR_FUNC (consumer), (void *) &msg_queue, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), 1); + + // Wait for producer and consumer threads to exit. + thr_mgr.wait (); + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/ASX/Message_Queue/buffer_stream.cpp b/examples/ASX/Message_Queue/buffer_stream.cpp new file mode 100644 index 00000000000..0cc96cd16c5 --- /dev/null +++ b/examples/ASX/Message_Queue/buffer_stream.cpp @@ -0,0 +1,215 @@ +// This short program copies stdin to stdout via the use of an ASX +// @(#)buffer_stream.cpp 1.1 10/18/96 + +// STREAM. It illustrates an implementation of the classic "bounded +// buffer" program using an ASX STREAM containing two Modules. Each +// ACE_Module contains two Tasks. Each ACE_Task contains a +// ACE_Message_Queue and a pointer to a ACE_Thread_Manager. Note how +// the use of these reusable components reduces the reliance on global +// variables, as compared with the bounded_buffer.C example. + +#include "ace/Log_Msg.h" +#include "ace/Synch.h" +#include "ace/Service_Config.h" +#include "ace/Stream.h" +#include "ace/Module.h" +#include "ace/Task.h" + +#if defined (ACE_HAS_THREADS) + +typedef ACE_Stream MT_Stream; +typedef ACE_Module MT_Module; +typedef ACE_Task MT_Task; + +class Common_Task : public MT_Task + // = TITLE + // Methods that are common to the producer and consumer. +{ +public: + Common_Task (void) {} + // ACE_Task hooks + virtual int open (void * = 0); + virtual int close (u_long = 0); + virtual int put (ACE_Message_Block *, ACE_Time_Value * = 0) { return 0; } + + // ACE_Service_Object hooks + virtual int init (int, char **) { return 0; } + virtual int fini (void) { return 0; } + virtual int info (char **, size_t) const { return 0; } +}; + +// Define the Producer interface. + +class Producer : public Common_Task +{ +public: + Producer (void) {} + + // Read data from stdin and pass to consumer. + virtual int svc (void); +}; + +class Consumer : public Common_Task + // = TITLE + // Define the Consumer interface. +{ +public: + Consumer (void) {} + + // Enqueue the message on the ACE_Message_Queue for subsequent + // handling in the svc() method. + virtual int put (ACE_Message_Block *mb, ACE_Time_Value *tv = 0); + + // Receive message from producer and print to stdout. + virtual int svc (void); + +private: + + ACE_Time_Value timeout_; +}; + +// Spawn off a new thread. + +int +Common_Task::open (void *) +{ + if (this->activate (THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), -1); + return 0; +} + +int +Common_Task::close (u_long exit_status) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) thread is exiting with status %d in module %s\n", + exit_status, this->name ())); + + // Can do anything here that is required when a thread exits, e.g., + // storing thread-specific information in some other storage + // location, etc. + return 0; +} + +// The Consumer reads data from the stdin stream, creates a message, +// and then queues the message in the message list, where it is +// removed by the consumer thread. A 0-sized message is enqueued when +// there is no more data to read. The consumer uses this as a flag to +// know when to exit. + +int +Producer::svc (void) +{ + // Keep reading stdin, until we reach EOF. + + for (int n; ; ) + { + // Allocate a new message. + ACE_Message_Block *mb = new ACE_Message_Block (BUFSIZ); + + n = ACE_OS::read (ACE_STDIN, mb->rd_ptr (), mb->size ()); + + if (n <= 0) + { + // Send a shutdown message to the other thread and exit. + mb->length (0); + + if (this->put_next (mb) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "put_next")); + break; + } + + // Send the message to the other thread. + else + { + mb->wr_ptr (n); + + if (this->put_next (mb) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "put_next")); + } + } + + return 0; +} + +// Simply enqueue the Message_Block into the end of the queue. + +int +Consumer::put (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + return this->putq (mb, tv); +} + +// The consumer dequeues a message from the ACE_Message_Queue, writes +// the message to the stderr stream, and deletes the message. The +// Consumer sends a 0-sized message to inform the consumer to stop +// reading and exit. + +int +Consumer::svc (void) +{ + int result = 0; + + // Keep looping, reading a message out of the queue, until we + // timeout or get a message with a length == 0, which signals us to + // quit. + + for (;;) + { + ACE_Message_Block *mb; + + this->timeout_.sec (ACE_OS::time (0) + 4); // Wait for upto 4 seconds + + result = this->getq (mb, &this->timeout_); + + if (result == -1) + break; + + int length = mb->length (); + + if (length > 0) + ACE_OS::write (ACE_STDOUT, mb->rd_ptr (), length); + + delete mb; + + if (length == 0) + break; + } + + if (result == -1 && errno == EWOULDBLOCK) + ACE_ERROR ((LM_ERROR, "(%t) %p\n%a", "timed out waiting for message", 1)); + return 0; +} + +// Main driver function. + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config daemon (argv[0]); + + // Control hierachically-related active objects + MT_Stream stream; + MT_Module *pm = new MT_Module ("Consumer", new Consumer); + MT_Module *cm = new MT_Module ("Producer", new Producer); + + // Create Producer and Consumer Modules and push them onto the + // STREAM. All processing is performed in the STREAM. + + if (stream.push (pm) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push"), 1); + else if (stream.push (cm) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push"), 1); + + // Barrier synchronization: wait for the threads to exit, then exit + // ourselves. + ACE_Service_Config::thr_mgr ()->wait (); + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/ASX/Message_Queue/priority_buffer.cpp b/examples/ASX/Message_Queue/priority_buffer.cpp new file mode 100644 index 00000000000..ef59d76b355 --- /dev/null +++ b/examples/ASX/Message_Queue/priority_buffer.cpp @@ -0,0 +1,139 @@ +// This short program prints the contents of stdin to stdout sorted by +// @(#)priority_buffer.cpp 1.1 10/18/96 + +// the length of each line via the use of an ASX Message_Queue. It +// illustrates how priorities can be used for ACE Message_Queues. + +#include "ace/Log_Msg.h" +#include "ace/Message_Queue.h" +#include "ace/Read_Buffer.h" +#include "ace/Thread_Manager.h" +#include "ace/Service_Config.h" + +#if defined (ACE_HAS_THREADS) + +// Global thread manager. +static ACE_Thread_Manager thr_mgr; + +// Make the queue be capable of being *very* large. +static const long max_queue = LONG_MAX; + +// Message queue. +static ACE_Message_Queue msg_queue (max_queue); + +// The consumer dequeues a message from the ACE_Message_Queue, writes +// the message to the stderr stream, and deletes the message. The +// producer sends a 0-sized message to inform the consumer to stop +// reading and exit. + +static void * +consumer (ACE_Message_Queue *msg_queue) +{ + // Keep looping, reading a message out of the queue, until we + // timeout or get a message with a length == 0, which signals us to + // quit. + + for (;;) + { + ACE_Message_Block *mb; + + if (msg_queue->dequeue_head (mb) == -1) + break; + + int length = mb->length (); + + if (length > 0) + ACE_OS::puts (mb->rd_ptr ()); + + // Free up the buffer memory and the Message_Block. + ACE_Service_Config::allocator ()->free (mb->rd_ptr ()); + delete mb; + + if (length == 0) + break; + } + + return 0; +} + +// The producer reads data from the stdin stream, creates a message, +// and then queues the message in the message list, where it is +// removed by the consumer thread. A 0-sized message is enqueued when +// there is no more data to read. The consumer uses this as a flag to +// know when to exit. + +static void * +producer (ACE_Message_Queue *msg_queue) +{ + // Insert thread into thr_mgr. + ACE_Thread_Control thread_control (&thr_mgr); + + ACE_Read_Buffer rb (ACE_STDIN); + + // Keep reading stdin, until we reach EOF. + + for (int n; ; ) + { + // Allocate a new buffer. + char *buffer = rb.read ('\n'); + + if (buffer == 0) + { + // Send a 0-sized shutdown message to the other thread and + // exit. + if (msg_queue->enqueue_tail (new ACE_Message_Block ((size_t) 0)) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "put_next")); + break; + } + + // Enqueue the message in priority order. + else + { + // Allocate a new message, but have it "borrow" its memory + // from the buffer. + ACE_Message_Block *mb = new ACE_Message_Block (rb.size (), + ACE_Message_Block::MB_DATA, + 0, + buffer); + mb->msg_priority (rb.size ()); + mb->wr_ptr (rb.size ()); + + ACE_DEBUG ((LM_DEBUG, "enqueueing message of size %d\n", + mb->msg_priority ())); + // Enqueue in priority order. + if (msg_queue->enqueue (mb) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "put_next")); + } + } + + // Now read all the items out in priority order (i.e., ordered by + // the size of the lines!). + consumer (msg_queue); + + // The destructor of ACE_Thread_Control removes the exiting thread + // from the thr_mgr automatically. + return 0; +} + +// Spawn off one thread that copies stdin to stdout in order of the +// size of each line. + +int +main (int, char *[]) +{ + if (thr_mgr.spawn (ACE_THR_FUNC (producer), (void *) &msg_queue, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), 1); + + // Wait for producer and consumer threads to exit. + thr_mgr.wait (); + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/ASX/UPIPE_Event_Server/Consumer_Router.cpp b/examples/ASX/UPIPE_Event_Server/Consumer_Router.cpp new file mode 100644 index 00000000000..e679de5390e --- /dev/null +++ b/examples/ASX/UPIPE_Event_Server/Consumer_Router.cpp @@ -0,0 +1,126 @@ +#include "Consumer_Router.h" +// @(#)Consumer_Router.cpp 1.1 10/18/96 + +#include "Options.h" + +#if defined (ACE_HAS_THREADS) + +typedef Acceptor_Factory CONSUMER_FACTORY; + +int +Consumer_Handler::open (void *a) +{ + CONSUMER_FACTORY *af = (CONSUMER_FACTORY *) a; + this->router_task_ = af->router (); + return this->Peer_Handler::open (a); +} + +Consumer_Handler::Consumer_Handler (ACE_Thread_Manager *tm) + : Peer_Handler (tm) +{ +} + +// Create a new handler that will interact with a consumer and point +// its ROUTER_TASK_ data member to the CONSUMER_ROUTER. + +Consumer_Router::Consumer_Router (ACE_Thread_Manager *tm) + : CONSUMER_ROUTER (tm) +{ +} + +// Initialize the Router.. + +int +Consumer_Router::open (void *) +{ + ACE_ASSERT (this->is_reader ()); + char *argv[3]; + + argv[0] = (char *) this->name (); + argv[1] = options.consumer_file (); + argv[2] = 0; + + if (this->init (1, &argv[1]) == -1) + return -1; + + // Make this an active object. +// return this->activate (options.t_flags ()); +} + +int +Consumer_Router::close (u_long) +{ + ACE_ASSERT (this->is_reader ()); + this->peer_map_.close (); + this->msg_queue ()->deactivate(); + return 0; +} + + +// Handle incoming messages in a separate thread.. + +int +Consumer_Router::svc (void) +{ + ACE_Thread_Control tc (this->thr_mgr ()); + ACE_Message_Block *mb = 0; + + ACE_ASSERT (this->is_reader ()); + + if (options.debug ()) + ACE_DEBUG ((LM_DEBUG, "(%t) starting svc in %s\n", this->name ())); + + while (this->getq (mb) > 0) + { + if (this->put_next (mb) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) put_next failed in %s\n", this->name ()), -1); + + } + return 0; + // Note the implicit ACE_OS::thr_exit() via destructor. +} + +// Send a MESSAGE_BLOCK to the supplier(s).. + +int +Consumer_Router::put (ACE_Message_Block *mb, ACE_Time_Value *) +{ + ACE_ASSERT (this->is_reader ()); + + if (mb->msg_type () == ACE_Message_Block::MB_IOCTL) + { + this->control (mb); + return this->put_next (mb); + } + else +{ +//printf("consumer-Router is routing : send_peers\n"); + return this->send_peers (mb); +} +} + +// Return information about the Client_Router ACE_Module.. + +int +Consumer_Router::info (char **strp, size_t length) const +{ + char buf[BUFSIZ]; + ACE_UPIPE_Addr addr; + const char *mod_name = this->name (); + ACE_UPIPE_Acceptor &sa = (ACE_UPIPE_Acceptor &) *this->acceptor_; + + if (sa.get_local_addr (addr) == -1) + return -1; + + ACE_OS::sprintf (buf, "%s\t /%s %s", + mod_name, "upipe", + "# consumer router\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (mod_name)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, mod_name, length); + return ACE_OS::strlen (mod_name); +} + +#endif /* ACE_HAS_THREADS */ diff --git a/examples/ASX/UPIPE_Event_Server/Consumer_Router.h b/examples/ASX/UPIPE_Event_Server/Consumer_Router.h new file mode 100644 index 00000000000..66d3f28ba07 --- /dev/null +++ b/examples/ASX/UPIPE_Event_Server/Consumer_Router.h @@ -0,0 +1,48 @@ +/* -*- C++ -*- */ +// @(#)Consumer_Router.h 1.1 10/18/96 + +// The interface between one or more consumers and an Event Server +// ACE_Stream. + +#if !defined (_CONSUMER_ROUTER_H) +#define _CONSUMER_ROUTER_H + +#include "ace/Thread_Manager.h" +#include "ace/UPIPE_Acceptor.h" +#include "ace/UPIPE_Addr.h" +#include "ace/Svc_Handler.h" +#include "Peer_Router.h" + +#if defined (ACE_HAS_THREADS) + +class Consumer_Handler; // Forward declaration.... + +typedef long CONSUMER_KEY; + +typedef Peer_Router CONSUMER_ROUTER; + +class Consumer_Handler + : public Peer_Handler +{ +public: + Consumer_Handler (ACE_Thread_Manager *tm = 0); + virtual int open (void *); +}; + +class Consumer_Router : public CONSUMER_ROUTER +{ +public: + Consumer_Router (ACE_Thread_Manager *thr_manager); + +protected: + // ACE_Task hooks.. + virtual int open (void *a = 0); + virtual int close (u_long flags = 0); + virtual int put (ACE_Message_Block *msg, ACE_Time_Value * = 0); + virtual int svc (void); + + // Dynamic linking hooks. + virtual int info (char **info_string, size_t length) const; +}; +#endif /* ACE_HAS_THREADS */ +#endif /* _CONSUMER_ROUTER_H */ diff --git a/examples/ASX/UPIPE_Event_Server/Event_Analyzer.cpp b/examples/ASX/UPIPE_Event_Server/Event_Analyzer.cpp new file mode 100644 index 00000000000..977e5c4af9d --- /dev/null +++ b/examples/ASX/UPIPE_Event_Server/Event_Analyzer.cpp @@ -0,0 +1,68 @@ +#include "Event_Analyzer.h" +// @(#)Event_Analyzer.cpp 1.1 10/18/96 + + +#if defined (ACE_HAS_THREADS) + +int +Event_Analyzer::open (void *) +{ + return 0; +} + +int +Event_Analyzer::close (u_long) +{ + return 0; +} + +int +Event_Analyzer::control (ACE_Message_Block *mb) +{ + ACE_IO_Cntl_Msg *ioc = (ACE_IO_Cntl_Msg *) mb->rd_ptr (); + ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds cmd; + + switch (cmd = ioc->cmd ()) + { + case ACE_IO_Cntl_Msg::SET_LWM: + case ACE_IO_Cntl_Msg::SET_HWM: + this->water_marks (cmd, *(size_t *) mb->cont ()->rd_ptr ()); + break; + } + return 0; +} + +int +Event_Analyzer::put (ACE_Message_Block *mb, ACE_Time_Value *) +{ + if (mb->msg_type () == ACE_Message_Block::MB_IOCTL) + this->control (mb); + + return this->put_next (mb); +} + +int +Event_Analyzer::init (int, char *[]) +{ + return 0; +} + +int +Event_Analyzer::fini (void) +{ + return 0; +} + +int +Event_Analyzer::info (char **strp, size_t length) const +{ + const char *mod_name = this->name (); + + if (*strp == 0 && (*strp = ACE_OS::strdup (mod_name)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, mod_name, length); + return ACE_OS::strlen (mod_name); +} + +#endif /* ACE_HAS_THREADS */ diff --git a/examples/ASX/UPIPE_Event_Server/Event_Analyzer.h b/examples/ASX/UPIPE_Event_Server/Event_Analyzer.h new file mode 100644 index 00000000000..30053d5f45d --- /dev/null +++ b/examples/ASX/UPIPE_Event_Server/Event_Analyzer.h @@ -0,0 +1,34 @@ +/* -*- C++ -*- */ +// @(#)Event_Analyzer.h 1.1 10/18/96 + +// Signal router. + +#if !defined (_EVENT_ANALYZER_H) +#define _EVENT_ANALYZER_H + +#include "ace/Stream.h" +#include "ace/Module.h" +#include "ace/Task.h" +#include "ace/Synch.h" + +#if defined (ACE_HAS_THREADS) + +class Event_Analyzer : public ACE_Task +{ +public: + virtual int open (void *a = 0); + virtual int close (u_long flags = 0); + virtual int put (ACE_Message_Block *msg, ACE_Time_Value * = 0); + virtual int svc (void) { return 0; } + + // Dynamic linking hooks. + virtual int init (int argc, char *argv[]); + virtual int fini (void); + virtual int info (char **info_string, size_t length) const; + +private: + virtual int control (ACE_Message_Block *); +}; + +#endif /* ACE_HAS_THREADS */ +#endif /* _EVENT_ANALYZER_H */ diff --git a/examples/ASX/UPIPE_Event_Server/Makefile b/examples/ASX/UPIPE_Event_Server/Makefile new file mode 100644 index 00000000000..bb0cdc00ed4 --- /dev/null +++ b/examples/ASX/UPIPE_Event_Server/Makefile @@ -0,0 +1,455 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Event Server test +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = event_server + +FILES = Options \ + Supplier_Router \ + Event_Analyzer \ + Consumer_Router \ + Peer_Router + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(addsuffix .o,$(FILES)) +SHOBJ = $(addsuffix .so,$(FILES)) + +LDLIBS = $(addprefix .shobj/,$(SHOBJ)) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/Options.o .shobj/Options.so: Options.cpp \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + Options.i +.obj/Supplier_Router.o .shobj/Supplier_Router.so: Supplier_Router.cpp Supplier_Router.h \ + $(WRAPPER_ROOT)/ace/UPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/UPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Acceptor.i \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + Peer_Router.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/Acceptor.cpp \ + Peer_Router.cpp \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + Options.i +.obj/Event_Analyzer.o .shobj/Event_Analyzer.so: Event_Analyzer.cpp Event_Analyzer.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i +.obj/Consumer_Router.o .shobj/Consumer_Router.so: Consumer_Router.cpp Consumer_Router.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/UPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Acceptor.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + Peer_Router.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/Acceptor.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + Peer_Router.cpp \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + Options.i +.obj/Peer_Router.o .shobj/Peer_Router.so: Peer_Router.cpp \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + Peer_Router.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/Acceptor.cpp \ + $(WRAPPER_ROOT)/ace/UPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/UPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Acceptor.i \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + Peer_Router.cpp Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + Options.i + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/ASX/UPIPE_Event_Server/Options.cpp b/examples/ASX/UPIPE_Event_Server/Options.cpp new file mode 100644 index 00000000000..2a334d7ff2a --- /dev/null +++ b/examples/ASX/UPIPE_Event_Server/Options.cpp @@ -0,0 +1,191 @@ +#include "ace/Get_Opt.h" +// @(#)Options.cpp 1.1 10/18/96 + +#include "ace/Synch.h" +#include "ace/Log_Msg.h" +#include "Options.h" + +#if defined (ACE_HAS_THREADS) + +Options::Options (void) + : debugging_ (0), + verbosity_ (0), + low_water_mark_ (1024), + high_water_mark_ (8 * 1024), + message_size_ (128), + thr_count_ (4), + initial_queue_length_ (0), + iterations_ (100000), + consumer_port_ ("-p 10000"), + supplier_port_ ("-p 10001"), + consumer_file_ ("-f/tmp/conupipe"), + supplier_file_ ("-f/tmp/supupipe"), + t_flags_ (THR_DETACHED) +{ +} + +Options::~Options (void) +{ +} + +void Options::print_results (void) +{ + ACE_Profile_Timer::ACE_Elapsed_Time et; + this->itimer_.elapsed_time (et); + +#if defined (ACE_HAS_PRUSAGE_T) + prusage_t rusage; + this->itimer_.get_rusage (rusage); + + if (options.verbose ()) + { + ACE_OS::printf ("final concurrency hint = %d\n", ACE_OS::thr_getconcurrency ()); + ACE_OS::printf ("%8d = lwpid\n" + "%8d = lwp count\n" + "%8d = minor page faults\n" + "%8d = major page faults\n" + "%8d = input blocks\n" + "%8d = output blocks\n" + "%8d = messages sent\n" + "%8d = messages received\n" + "%8d = signals received\n" + "%8ds, %dms = wait-cpu (latency) time\n" + "%8ds, %dms = user lock wait sleep time\n" + "%8ds, %dms = all other sleep time\n" + "%8d = voluntary context switches\n" + "%8d = involuntary context switches\n" + "%8d = system calls\n" + "%8d = chars read/written\n", + rusage.pr_lwpid, + rusage.pr_count, + rusage.pr_minf, + rusage.pr_majf, + rusage.pr_inblk, + rusage.pr_oublk, + rusage.pr_msnd, + rusage.pr_mrcv, + rusage.pr_sigs, + rusage.pr_wtime.tv_sec, rusage.pr_wtime.tv_nsec / 1000000, + rusage.pr_ltime.tv_sec, rusage.pr_ltime.tv_nsec / 1000000, + rusage.pr_slptime.tv_sec, rusage.pr_slptime.tv_nsec / 1000000, + rusage.pr_vctx, + rusage.pr_ictx, + rusage.pr_sysc, + rusage.pr_ioch); + } +#endif /* ACE_HAS_PRUSAGE_T */ + + ACE_OS::printf ("---------------------\n" + "real time = %.3f\n" + "user time = %.3f\n" + "system time = %.3f\n" + "---------------------\n", + et.real_time, et.user_time, et.system_time); +} + +// Manages the options. +Options options; + +void +Options::parse_args (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0]); + + ACE_Get_Opt getopt (argc, argv, "C:c:bdH:i:L:l:M:nS:s:t:T:v"); + int c; + + while ((c = getopt ()) != -1) + switch (c) + { + case 'b': + this->t_flags (THR_BOUND); + break; + case 'C': + this->consumer_file (getopt.optarg); + break; + case 'c': + this->consumer_port (getopt.optarg); + break; + case 'd': + this->debugging_ = 1; + break; + case 'H': + this->high_water_mark (ACE_OS::atoi (getopt.optarg)); + break; + case 'i': + this->iterations (ACE_OS::atoi (getopt.optarg)); + break; + case 'L': + this->low_water_mark (ACE_OS::atoi (getopt.optarg)); + break; + case 'l': + this->initial_queue_length (ACE_OS::atoi (getopt.optarg)); + break; + case 'M': + this->message_size (ACE_OS::atoi (getopt.optarg)); + break; + case 'n': + this->t_flags (THR_NEW_LWP); + break; + case 'S': + this->supplier_file (getopt.optarg); + break; + case 's': + this->supplier_port (getopt.optarg); + break; + case 'T': + if (ACE_OS::strcasecmp (getopt.optarg, "ON") == 0) + ACE_Trace::start_tracing (); + else if (ACE_OS::strcasecmp (getopt.optarg, "OFF") == 0) + ACE_Trace::stop_tracing (); + break; + case 't': + this->thr_count (ACE_OS::atoi (getopt.optarg)); + break; + case 'v': + this->verbosity_ = 1; + break; + default: + ::fprintf (stderr, "%s\n" + "\t[-b] (THR_BOUND)\n" + "\t[-C consumer file]\n" + "\t[-c consumer port]\n" + "\t[-d] (enable debugging)\n" + "\t[-H high water mark]\n" + "\t[-i number of test iterations]\n" + "\t[-L low water mark]\n" + "\t[-M] message size \n" + "\t[-n] (THR_NEW_LWP)\n" + "\t[-q max queue size]\n" + "\t[-S supplier file]\n" + "\t[-s supplier port]\n" + "\t[-t number of threads]\n" + "\t[-v] (verbose) \n", + argv[0]); + ::exit (1); + /* NOTREACHED */ + break; + } + + if (this->verbose ()) + ACE_OS::printf ("%8d = initial concurrency hint\n" + "%8d = total iterations\n" + "%8d = thread count\n" + "%8d = low water mark\n" + "%8d = high water mark\n" + "%8d = message_size\n" + "%8d = initial queue length\n" + "%8d = THR_BOUND\n" + "%8d = THR_NEW_LWP\n", + ACE_OS::thr_getconcurrency (), + this->iterations (), + this->thr_count (), + this->low_water_mark (), + this->high_water_mark (), + this->message_size (), + this->initial_queue_length (), + (this->t_flags () & THR_BOUND) != 0, + (this->t_flags () & THR_NEW_LWP) != 0); +} + +#endif /* ACE_HAS_THREADS */ diff --git a/examples/ASX/UPIPE_Event_Server/Options.h b/examples/ASX/UPIPE_Event_Server/Options.h new file mode 100644 index 00000000000..bd73eae2bae --- /dev/null +++ b/examples/ASX/UPIPE_Event_Server/Options.h @@ -0,0 +1,83 @@ +/* -*- C++ -*- */ +// @(#)Options.h 1.1 10/18/96 + +// Option manager for Event Server. + +#if !defined (DEVICE_OPTIONS_H) +#define DEVICE_OPTIONS_H + +#include "ace/OS.h" +#include "ace/Profile_Timer.h" + +#if defined (ACE_HAS_THREADS) + +class Options +{ +public: + Options (void); + ~Options (void); + void parse_args (int argc, char *argv[]); + + void stop_timer (void); + void start_timer (void); + + void thr_count (size_t count); + size_t thr_count (void); + + void initial_queue_length (size_t length); + size_t initial_queue_length (void); + + void high_water_mark (size_t size); + size_t high_water_mark (void); + + void low_water_mark (size_t size); + size_t low_water_mark (void); + + void message_size (size_t size); + size_t message_size (void); + + void iterations (size_t n); + size_t iterations (void); + + void t_flags (long flag); + long t_flags (void); + + void supplier_port (char *port); + char *supplier_port (void); + + void consumer_port (char *port); + char *consumer_port (void); + + void supplier_file (char *file); + char *supplier_file (void); + + void consumer_file (char *file); + char *consumer_file (void); + + int debug (void); + int verbose (void); + + void print_results (void); + +private: + ACE_Profile_Timer itimer_; // Time the process. + size_t thr_count_; // Number of threads to spawn. + long t_flags_; // Flags to thr_create(). + size_t high_water_mark_; // ACE_Task high water mark. + size_t low_water_mark_; // ACE_Task low water mark. + size_t message_size_; // Size of a message. + size_t initial_queue_length_; // Initial number of items in the queue. + size_t iterations_; // Number of iterations to run the test program. + int debugging_; // Extra debugging info. + int verbosity_; // Extra verbose messages. + char *consumer_port_; // Port that the Consumer_Router is using. + char *supplier_port_; // Port that the Supplier_Router is using. + char *consumer_file_; // file that the Consumer_Router is using. + char *supplier_file_; // file that the Supplier_Router is using. +}; + +extern Options options; + +#include "Options.i" +#endif /* ACE_HAS_THREADS */ +#endif /* DEVICE_OPTIONS_H */ diff --git a/examples/ASX/UPIPE_Event_Server/Options.i b/examples/ASX/UPIPE_Event_Server/Options.i new file mode 100644 index 00000000000..226e46b1548 --- /dev/null +++ b/examples/ASX/UPIPE_Event_Server/Options.i @@ -0,0 +1,161 @@ +/* -*- C++ -*- */ +// @(#)Options.i 1.1 10/18/96 + +// Option manager for ustreams. + +inline void +Options::supplier_port (char *port) +{ + this->supplier_port_ = port; +} + +inline char * +Options::supplier_port (void) +{ + return this->supplier_port_; +} + +inline void +Options::supplier_file (char *file) +{ + this->supplier_file_ = file; +} + +inline char * +Options::supplier_file (void) +{ + return this->supplier_file_; +} + +inline void +Options::consumer_file (char *file) +{ + this->consumer_file_ = file; +} + +inline char * +Options::consumer_file (void) +{ + return this->consumer_file_; +} + +inline void +Options::consumer_port (char *port) +{ + this->consumer_port_ = port; +} + +inline char * +Options::consumer_port (void) +{ + return this->consumer_port_; +} + +inline void +Options::start_timer (void) +{ + this->itimer_.start (); +} + +inline void +Options::stop_timer (void) +{ + this->itimer_.stop (); +} + +inline void +Options::thr_count (size_t count) +{ + this->thr_count_ = count; +} + +inline size_t +Options::thr_count (void) +{ + return this->thr_count_; +} + +inline void +Options::initial_queue_length (size_t length) +{ + this->initial_queue_length_ = length; +} + +inline size_t +Options::initial_queue_length (void) +{ + return this->initial_queue_length_; +} + +inline void +Options::high_water_mark (size_t size) +{ + this->high_water_mark_ = size; +} + +inline size_t +Options::high_water_mark (void) +{ + return this->high_water_mark_; +} + +inline void +Options::low_water_mark (size_t size) +{ + this->low_water_mark_ = size; +} + +inline size_t +Options::low_water_mark (void) +{ + return this->low_water_mark_; +} + +inline void +Options::message_size (size_t size) +{ + this->message_size_ = size; +} + +inline size_t +Options::message_size (void) +{ + return this->message_size_; +} + +inline void +Options::iterations (size_t n) +{ + this->iterations_ = n; +} + +inline size_t +Options::iterations (void) +{ + return this->iterations_; +} + +inline void +Options::t_flags (long flag) +{ + this->t_flags_ |= flag; +} + +inline long +Options::t_flags (void) +{ + return this->t_flags_; +} + +inline int +Options::debug (void) +{ + return this->debugging_; +} + +inline int +Options::verbose (void) +{ + return this->verbosity_; +} + diff --git a/examples/ASX/UPIPE_Event_Server/Peer_Router.cpp b/examples/ASX/UPIPE_Event_Server/Peer_Router.cpp new file mode 100644 index 00000000000..6aba899f4ea --- /dev/null +++ b/examples/ASX/UPIPE_Event_Server/Peer_Router.cpp @@ -0,0 +1,273 @@ +#if !defined (_PEER_ROUTER_C) +// @(#)Peer_Router.cpp 1.1 10/18/96 + +#define _PEER_ROUTER_C + +#include "ace/Get_Opt.h" +#include "ace/Service_Config.h" +#include "ace/Log_Msg.h" +#include "Peer_Router.h" +#include "Options.h" + +#if defined (ACE_HAS_THREADS) + +// Define some short-hand macros to deal with long templates +// names... + +#define PH PEER_HANDLER +#define PA PEER_ACCEPTOR +#define PAD PEER_ADDR +#define PK PEER_KEY +#define PM PEER_MAP + +template int +Acceptor_Factory::init (int argc, char *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, "df:", 0); + ACE_UPIPE_Addr addr; + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'f': + addr.set (get_opt.optarg); + break; + case 'd': + break; + default: + break; + } + + if (this->open (addr, ACE_Service_Config::reactor ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + return 0; +} + +template +Acceptor_Factory::Acceptor_Factory (Peer_Router *pr) + : pr_ (pr) +{ +} + +template Peer_Router * +Acceptor_Factory::router (void) +{ + return this->pr_; +} + +template +Peer_Handler::Peer_Handler (ACE_Thread_Manager *tm) + : ACE_Svc_Handler (tm) +{ +} + +template int +Peer_Handler::svc (void) +{ + ACE_Thread_Control thread_control (tm); + // just a try !! + // we're just reading from our ACE_Message_Queue + ACE_Message_Block *db, *hb; + int n; + // do an endless loop + for (;;) + { + db = new ACE_Message_Block (BUFSIZ); + hb = new ACE_Message_Block (sizeof (KEY), ACE_Message_Block::MB_PROTO, db); + + if ((n = this->peer ().recv (db->rd_ptr (), db->size ())) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p", "recv failed"), -1); + else if (n == 0) // Client has closed down the connection. + { + + if (this->router_task_->unbind_peer (this->get_handle ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p", "unbind failed"), -1); + ACE_DEBUG ((LM_DEBUG, "(%t) shutting down \n")); + return -1; // We do not need to be deregistered by reactor + // as we were not registered at all + } + else // Transform incoming buffer into a Message and pass downstream. + { + db->wr_ptr (n); + *(long *) hb->rd_ptr () = this->get_handle (); // structure assignment. + hb->wr_ptr (sizeof (long)); + if (this->router_task_->reply (hb) == -1) + { + cout << "Peer_Handler.svc : router_task->reply failed" << endl ; + return -1; + } + + // return this->router_task_->reply (hb) == -1 ? -1 : 0; + } + } + return 0; +} + +template int +Peer_Handler::put (ACE_Message_Block *mb, ACE_Time_Value *) +{ + return this->peer ().send_n (mb->rd_ptr (), mb->length ()); +} + +// Create a new handler and point its ROUTER_TASK_ data member to the +// corresponding router. Note that this router is extracted out of +// the Acceptor_Factory * that is passed in via the +// ACE_Acceptor::handle_input() method. + +template int +Peer_Handler::open (void *a) +{ + char buf[BUFSIZ], *p = buf; + + if (this->router_task_->info (&p, sizeof buf) != -1) + ACE_DEBUG ((LM_DEBUG, "(%t) creating handler for %s, fd = %d, this = %d\n", + buf, this->get_handle (), a)); + else + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "info"), -1); + + if ( this->activate (options.t_flags ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "activation of thread failed"), -1); + else if (this->router_task_->bind_peer (this->get_handle (), this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "bind_peer"), -1); + return 0; +} + +// Receive a message from a supplier.. + +template int +Peer_Handler::handle_input (ACE_HANDLE h) +{ + + ACE_DEBUG ((LM_DEBUG, "(%t) input arrived on sd %d\n", h)); +// ACE_Service_Config::reactor ()->remove_handler(h, +// ACE_Event_Handler::RWE_MASK +// |ACE_Event_Handler::DONT_CALL); +// this method should be called only if the peer shuts down +// so we deactivate our ACE_Message_Queue to awake our svc thread + + return 0; + +#if 0 + ACE_Message_Block *db = new ACE_Message_Block (BUFSIZ); + ACE_Message_Block *hb = new ACE_Message_Block (sizeof (KEY), ACE_Message_Block::MB_PROTO, db); + int n; + + if ((n = this->peer ().recv (db->rd_ptr (), db->size ())) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p", "recv failed"), -1); + else if (n == 0) // Client has closed down the connection. + { + if (this->router_task_->unbind_peer (this->get_handle ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p", "unbind failed"), -1); + ACE_DEBUG ((LM_DEBUG, "(%t) shutting down %d\n", h)); + return -1; // Instruct the ACE_Reactor to deregister us by returning -1. + } + else // Transform incoming buffer into a Message and pass downstream. + { + db->wr_ptr (n); + *(long *) hb->rd_ptr () = this->get_handle (); // structure assignment. + hb->wr_ptr (sizeof (long)); + return this->router_task_->reply (hb) == -1 ? -1 : 0; + } +#endif +} + +template +Peer_Router::Peer_Router (ACE_Thread_Manager *tm) + : ACE_Task (tm) +{ +} + +template int +Peer_Router::send_peers (ACE_Message_Block *mb) +{ + ACE_Map_Iterator map_iter = this->peer_map_; + int bytes = 0; + int iterations = 0; + ACE_Message_Block *data_block = mb->cont (); + for (ACE_Map_Entry *ss = 0; + map_iter.next (ss) != 0; + map_iter.advance ()) + { + if (options.debug ()) + ACE_DEBUG ((LM_DEBUG, "(%t) sending to peer via sd %d\n", ss->ext_id_)); + + iterations++; + bytes += ss->int_id_->put (data_block); + } + + delete mb; + return bytes == 0 ? 0 : bytes / iterations; +} + +template +Peer_Router::~Peer_Router (void) +{ +} + +template ACE_INLINE int +Peer_Router::fini (void) +{ + delete this->acceptor_; + return 0; +} + +template ACE_INLINE int +Peer_Router::control (ACE_Message_Block *mb) +{ + ACE_IO_Cntl_Msg *ioc = (ACE_IO_Cntl_Msg *) mb->rd_ptr (); + ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds command; + + switch (command = ioc->cmd ()) + { + case ACE_IO_Cntl_Msg::SET_LWM: + case ACE_IO_Cntl_Msg::SET_HWM: + this->water_marks (command, *(size_t *) mb->cont ()->rd_ptr ()); + break; + default: + return -1; + } + return 0; +} + +template ACE_INLINE int +Peer_Router::unbind_peer (PK key) +{ + return this->peer_map_.unbind (key); +} + +template ACE_INLINE int +Peer_Router::bind_peer (PK key, Peer_Handler, PK> *ph) +{ + PH *peer_handler = (PH *) ph; + return this->peer_map_.bind (key, peer_handler); +} + +template ACE_INLINE int +Peer_Router::init (int argc, char *argv[]) +{ + this->acceptor_ = new Acceptor_Factory (this); + + if (this->acceptor_->init (argc, argv) == -1 + || this->peer_map_.open () == -1) + return -1; + else + { + ACE_UPIPE_Addr addr; + ACE_UPIPE_Acceptor &pa = this->acceptor_->acceptor (); + + if (pa.get_local_addr (addr) != -1) + ACE_DEBUG ((LM_DEBUG, "(%t) initializing %s, file = %s, fd = %d, this = %u\n", + this->name (), addr.get_path_name (), pa.get_handle (), this)); + else + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "get_local_addr"), -1); + } + return 0; +} + +#undef PH +#undef PA +#undef PAD +#undef PK +#undef PM +#endif /* ACE_HAS_THREADS */ +#endif /* _PEER_ROUTER_C */ diff --git a/examples/ASX/UPIPE_Event_Server/Peer_Router.h b/examples/ASX/UPIPE_Event_Server/Peer_Router.h new file mode 100644 index 00000000000..b344497d4b1 --- /dev/null +++ b/examples/ASX/UPIPE_Event_Server/Peer_Router.h @@ -0,0 +1,116 @@ +/* -*- C++ -*- */ +// @(#)Peer_Router.h 1.1 10/18/96 + +// The interface between one or more peers and a stream. A peer +// typically runs remotely on another machine. + +#if !defined (_PEER_ROUTER_H) +#define _PEER_ROUTER_H + +#include "ace/Acceptor.h" +#include "ace/Svc_Handler.h" +#include "ace/UPIPE_Acceptor.h" +#include "ace/UPIPE_Addr.h" +#include "ace/Thread_Manager.h" +#include "ace/Map_Manager.h" + +#if defined (ACE_HAS_THREADS) + +// Forward declaration. +template +class Peer_Router; + +template +class Acceptor_Factory : public ACE_Acceptor +{ +public: + Acceptor_Factory (Peer_Router *pr); + Peer_Router *router (void); + + int init (int argc, char *argv[]); + // Initialize the acceptor when it's linked dynamically. + +private: + Peer_Router *pr_; +}; + +// Receive input from a Peer.. +template +class Peer_Handler : public ACE_Svc_Handler +{ +public: + Peer_Handler (ACE_Thread_Manager * = 0); + + virtual int open (void * = 0); + // Called by the ACE_Acceptor::handle_input() to activate this object. + + virtual int handle_input (ACE_HANDLE); + // Receive input from the peer.. + + virtual int put (ACE_Message_Block *, ACE_Time_Value *tv = 0); + // Send output to a peer. + +protected: + ROUTER *router_task_; + // Pointer to write task.. + +private: + // Don't need this method here... + virtual int svc (void); +}; + +// This abstract base class provides mechanisms for routing messages +// to/from a ACE_Stream from/to one or more peers (which are typically +// running on remote hosts). A subclass of Peer_Router overrides the +// open(), close(), and put() methods in order to specialize the +// behavior of the router to meet application-specific requirements. + +template +class Peer_Router : public ACE_Task +{ +public: + Peer_Router (ACE_Thread_Manager * = 0); + ~Peer_Router (void); + + typedef Peer_Handler, PEER_KEY> HANDLER; + + // Remove a PEER_HANDLER from the PEER_MAP. + virtual int unbind_peer (PEER_KEY); + + // Add a PEER_HANDLER to the PEER_MAP. + virtual int bind_peer (PEER_KEY, HANDLER *); + + // Send the message block to the peer(s).. + int send_peers (ACE_Message_Block *mb); + +protected: +// Handle control messages arriving from adjacent Modules. + virtual int control (ACE_Message_Block *); + + // Map used to keep track of active peers. + ACE_Map_Manager peer_map_; + + // Dynamic linking initialization hooks inherited from ACE_Task. + virtual int init (int argc, char *argv[]); + virtual int fini (void); + + // Factory for accepting new PEER_HANDLERs. + Acceptor_Factory *acceptor_; + +private: +// Prevent copies and pass-by-value. + Peer_Router (const Peer_Router &); + void operator= (const Peer_Router &); +}; + +#if defined (__ACE_INLINE__) +#define ACE_INLINE inline +#else +#define ACE_INLINE +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "Peer_Router.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ +#endif /* ACE_HAS_THREADS */ +#endif /* _PEER_ROUTER_H */ diff --git a/examples/ASX/UPIPE_Event_Server/Supplier_Router.cpp b/examples/ASX/UPIPE_Event_Server/Supplier_Router.cpp new file mode 100644 index 00000000000..414fc5c9ccf --- /dev/null +++ b/examples/ASX/UPIPE_Event_Server/Supplier_Router.cpp @@ -0,0 +1,126 @@ +#include "Supplier_Router.h" +// @(#)Supplier_Router.cpp 1.1 10/18/96 + +#include "Options.h" + +#if defined (ACE_HAS_THREADS) + +typedef Acceptor_Factory SUPPLIER_FACTORY; + +int +Supplier_Handler::open (void *a) +{ + SUPPLIER_FACTORY *af = (SUPPLIER_FACTORY *) a; + this->router_task_ = af->router (); + return this->Peer_Handler::open (a); +} + +Supplier_Handler::Supplier_Handler (ACE_Thread_Manager *tm) + : Peer_Handler (tm) +{ +} + +// Create a new router and associate it with the REACTOR parameter.. + +Supplier_Router::Supplier_Router (ACE_Thread_Manager *tm) + : SUPPLIER_ROUTER (tm) +{ +} + +// Handle incoming messages in a separate thread.. + +int +Supplier_Router::svc (void) +{ + ACE_ASSERT (this->is_writer ()); + + ACE_Thread_Control tc (this->thr_mgr ()); + ACE_Message_Block *message_block = 0; + + if (options.debug ()) + ACE_DEBUG ((LM_DEBUG, "(%t) starting svc in %s\n", this->name ())); + + while (this->getq (message_block) > 0) + { + if (this->put_next (message_block) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) put_next failed in %s\n", this->name ()), -1); + } + + return 0; + // Note the implicit ACE_OS::thr_exit() via ACE_Thread_Control's destructor. +} + +// Initialize the Router.. + +int +Supplier_Router::open (void *) +{ + ACE_ASSERT (this->is_writer ()); + + char *argv[3]; + + argv[0] = (char *) this->name (); + argv[1] = options.supplier_file (); + argv[2] = 0; + + if (this->init (1, &argv[1]) == -1) + return -1; + // Make this an active object. Return this->activate + // (options.t_flags ()); +} + +// Close down the router.. + +int +Supplier_Router::close (u_long) +{ + ACE_ASSERT (this->is_writer ()); + this->peer_map_.close (); + this->msg_queue ()->deactivate(); + return 0; +} + +// Send a MESSAGE_BLOCK to the supplier(s).. + +int +Supplier_Router::put (ACE_Message_Block *mb, ACE_Time_Value *) +{ + ACE_ASSERT (this->is_writer ()); + + if (mb->msg_type () == ACE_Message_Block::MB_IOCTL) + { + this->control (mb); + return this->put_next (mb); + } + else + { +//printf("supplier-Router is routing: send_peers\n"); + return this->send_peers (mb); + } +} + +// Return information about the Supplier_Router ACE_Module.. + +int +Supplier_Router::info (char **strp, size_t length) const +{ + char buf[BUFSIZ]; + ACE_UPIPE_Addr addr; + const char *mod_name = this->name (); + ACE_UPIPE_Acceptor &sa = (ACE_UPIPE_Acceptor &) *this->acceptor_; + + if (sa.get_local_addr (addr) == -1) + return -1; + + ACE_OS::sprintf (buf, "%s\t %s/ %s", + mod_name, "upipe", + "# supplier router\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (mod_name)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, mod_name, length); + return ACE_OS::strlen (mod_name); +} + +#endif /* ACE_HAS_THREADS */ diff --git a/examples/ASX/UPIPE_Event_Server/Supplier_Router.h b/examples/ASX/UPIPE_Event_Server/Supplier_Router.h new file mode 100644 index 00000000000..bb304042586 --- /dev/null +++ b/examples/ASX/UPIPE_Event_Server/Supplier_Router.h @@ -0,0 +1,52 @@ +/* -*- C++ -*- */ +// @(#)Supplier_Router.h 1.1 10/18/96 + +// The interface between a supplier and an Event Service ACE_Stream. + +#if !defined (_SUPPLIER_ROUTER_H) +#define _SUPPLIER_ROUTER_H + +#include "ace/UPIPE_Addr.h" +#include "ace/UPIPE_Acceptor.h" +#include "ace/Map_Manager.h" +#include "ace/Svc_Handler.h" +#include "Peer_Router.h" + +#if defined (ACE_HAS_THREADS) + +// Forward declaration. +class Supplier_Handler; + +// Type of search key for SUPPLIER_MAP. +typedef long SUPPLIER_KEY; + +// Instantiated type for routing messages to suppliers. + +typedef Peer_Router SUPPLIER_ROUTER; + +class Supplier_Handler + : public Peer_Handler +{ +public: + Supplier_Handler (ACE_Thread_Manager *tm = 0); + virtual int open (void *); +}; + +class Supplier_Router : public SUPPLIER_ROUTER +{ +public: + Supplier_Router (ACE_Thread_Manager *); + +protected: + // ACE_Task hooks.. + virtual int open (void *a = 0); + virtual int close (u_long flags = 0); + virtual int put (ACE_Message_Block *msg, ACE_Time_Value * = 0); + virtual int svc (void); + + // Dynamic linking hooks inherited from Peer_Router. + virtual int info (char **info_string, size_t length) const; +}; + +#endif /* ACE_HAS_THREADS */ +#endif /* _SUPPLIER_ROUTER_H */ diff --git a/examples/ASX/UPIPE_Event_Server/event_server.cpp b/examples/ASX/UPIPE_Event_Server/event_server.cpp new file mode 100644 index 00000000000..bdafdb23de7 --- /dev/null +++ b/examples/ASX/UPIPE_Event_Server/event_server.cpp @@ -0,0 +1,252 @@ +// Test the event server. +// @(#)event_server.cpp 1.1 10/18/96 + +#include "ace/Log_Msg.h" +#include "ace/Stream.h" +#include "ace/Service_Config.h" +#include "Options.h" +#include "Consumer_Router.h" +#include "Event_Analyzer.h" +#include "Supplier_Router.h" +#include "ace/UPIPE_Acceptor.h" +#include "ace/UPIPE_Connector.h" + +#if defined (ACE_HAS_THREADS) + +typedef ACE_Stream MT_Stream; +typedef ACE_Module MT_Module; + +// Handle SIGINT and terminate the entire application. + +class Quit_Handler : public ACE_Sig_Adapter +{ +public: + Quit_Handler (void); + virtual int handle_input (ACE_HANDLE fd); +}; + +Quit_Handler::Quit_Handler (void) + : ACE_Sig_Adapter (ACE_Sig_Handler_Ex (ACE_Service_Config::end_reactor_event_loop)) +{ + // Register to trap input from the user. + if (ACE::register_stdin_handler (this, + ACE_Service_Config::reactor (), + ACE_Service_Config::thr_mgr ()) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "register_stdin_handler")); + // Register to trap the SIGINT signal. + else if (ACE_Service_Config::reactor ()->register_handler + (SIGINT, this) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "register_handler")); +} + +int +Quit_Handler::handle_input (ACE_HANDLE) +{ + options.stop_timer (); + ACE_DEBUG ((LM_INFO, " (%t) closing down the test\n")); + options.print_results (); + + ACE_Service_Config::end_reactor_event_loop (); + return 0; +} + +static void * +consumer (void *) +{ + ACE_UPIPE_Stream c_stream; + ACE_UPIPE_Addr c_addr ("/tmp/conupipe"); + + int iter = options.iterations (); + int verb = options.verbose (); + int msiz = options.message_size (); + int secs, par1, par2, i; + time_t currsec; + + if (verb) + cout << "consumer starting connect" << endl; + + ACE_UPIPE_Connector con; + + if (con.connect (c_stream, c_addr) == -1) + ACE_DEBUG ((LM_INFO, " (%t) connect failed\n")); + else + cout << "consumer :we're connected" << endl; + + char buf[BUFSIZ]; + int n; + ACE_Message_Block *mb_p; + + int done = 0; + int cnt = 0; + ACE_OS::time (&currsec); + + par1= (time_t) currsec; + + while (done == 0 + && ((n = c_stream.recv (mb_p)) != -1)) + if (mb_p->length () > 1) + { + cnt++; + if (verb) + cout << " consumer received message !!!!!! " + << mb_p->rd_ptr () << endl; + } + else + { + if (verb) + cout << "consumer got last mb" + << (char) * (mb_p->rd_ptr ()) << endl; + c_stream.close (); + done = 1; + } + + ACE_OS::time (&currsec); + par2 = (time_t) currsec; + + secs = par2 - par1; + + if (secs <= 0) + secs=1; + + cout << "consumer got " << cnt << " messages of size " << msiz + << "within " << secs << " seconds" << endl; + + ACE_OS::sleep (2); + cout << "consumer terminating " << endl; + return 0; +} + +static void * +supplier (void *dummy) +{ + ACE_UPIPE_Stream s_stream; + ACE_UPIPE_Addr serv_addr ("/tmp/supupipe"); + ACE_UPIPE_Connector con; + + int iter = options.iterations (); + int verb = options.verbose (); + int msiz = options.message_size (); + cout << "supplier starting connect" << endl; + + if (con.connect (s_stream, serv_addr) == -1) + ACE_DEBUG ((LM_INFO, " (%t) connect failed\n")); + + cout << "supplier : we're connected" << endl; + int n; + n = 0; + ACE_Message_Block * mb_p; + + while (n < iter) + { + mb_p = new ACE_Message_Block (msiz); + strcpy (mb_p->rd_ptr (), (char *) dummy); + mb_p->length (msiz); + if (verb) + cout << "supplier sending 1 message_block" << endl; + if (s_stream.send (mb_p) == -1) + { + cout << "supplier send failed" << endl; + return (void *) -1; + } + n++; + } + + mb_p = new ACE_Message_Block (10); + mb_p->length (1); + *mb_p->rd_ptr () = 'g'; + + cout << "supplier sending last message_block" << endl; + + if (s_stream.send (mb_p) == -1) + { + cout << "supplier send last mb failed" << endl; + return (void *) -1; + } + mb_p = new ACE_Message_Block (10); + mb_p->length (0); + + if (verb) + cout << "supplier sending very last message_block" << endl; + + if (s_stream.send (mb_p) == -1) + { + cout << "supplier send very last mb failed" << endl; + return (void *) -1; + } + + ACE_OS::sleep (2); + cout << "supplier terminating" << endl; + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config daemon; + + options.parse_args (argc, argv); + options.start_timer (); + + // Primary ACE_Stream for EVENT_SERVER application. + MT_Stream event_server; + + // Enable graceful shutdowns.... + Quit_Handler quit_handler; + + // Create the modules.. + + MT_Module *sr = new MT_Module ("Supplier_Router", + new Supplier_Router (ACE_Service_Config::thr_mgr ())); + MT_Module *ea = new MT_Module ("Event_Analyzer", + new Event_Analyzer, + new Event_Analyzer); + MT_Module *cr = new MT_Module ("Consumer_Router", + 0, // 0 triggers the creation of a ACE_Thru_Task... + new Consumer_Router (ACE_Service_Config::thr_mgr ())); + + // Push the modules onto the event_server stream. + + if (event_server.push (sr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push (Supplier_Router)"), -1); + + if (event_server.push (ea) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push (Event_Analyzer)"), -1); + + if (event_server.push (cr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push (Consumer_Router)"), -1); + + // Set the high and low water marks appropriately. + + int wm = options.low_water_mark (); + + if (event_server.control (ACE_IO_Cntl_Msg::SET_LWM, &wm) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "push (setting low watermark)"), -1); + + wm = options.high_water_mark (); + if (event_server.control (ACE_IO_Cntl_Msg::SET_HWM, &wm) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "push (setting high watermark)"), -1); + + // spawn the two threads. + + if (ACE_Service_Config::thr_mgr ()->spawn (ACE_THR_FUNC (consumer), (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), 1); + + else if (ACE_Service_Config::thr_mgr ()->spawn (ACE_THR_FUNC (supplier), (void *) "hello", + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), 1); + + // Perform the main event loop waiting for the user to type ^C or to + // enter a line on the ACE_STDIN. + + daemon.run_reactor_event_loop (); + + ACE_DEBUG ((LM_DEBUG, "main exiting\n")); +} +#else +int +main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "test not defined for this platform\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/CORBA/Makefile b/examples/CORBA/Makefile new file mode 100644 index 00000000000..5ca20af9257 --- /dev/null +++ b/examples/CORBA/Makefile @@ -0,0 +1,65 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the ACE_MT_CORBA_Handler tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +SRC = Test_i.cpp client.cpp server.cpp + +SVR_OBJS = TestS.o Test_i.o server.o +CLT_OBJS = TestC.o client.o + +LDLIBS = + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Orbix related macros and target settings. +#---------------------------------------------------------------------------- + +ORBIX_BINDIR = $(ORBIX_ROOT)/bin +ORBIX_LIBDIR = $(ORBIX_ROOT)/lib +ORBIX_INCDIR = $(ORBIX_ROOT)/include + +CPPFLAGS += -DEXCEPTIONS -I$(ORBIX_INCDIR) -DWANT_ORBIX_FDS +LDFLAGS += -L$(ORBIX_LIBDIR) -R $(ORBIX_LIBDIR) + +IDLFLAGS = -s S.cpp -c C.cpp -B + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +all: client server + +client: $(addprefix $(VDIR),$(CLT_OBJS)) + $(LINK.cc) -o client $(addprefix $(VDIR),$(CLT_OBJS)) $(LDFLAGS) -lITsrvmt $(VLDLIBS) + +server: $(addprefix $(VDIR),$(SVR_OBJS)) + $(LINK.cc) -o server $(addprefix $(VDIR),$(SVR_OBJS)) $(LDFLAGS) -lITsrvmt $(VLDLIBS) + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + + + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/CORBA/Test.idl b/examples/CORBA/Test.idl new file mode 100644 index 00000000000..33e8adce847 --- /dev/null +++ b/examples/CORBA/Test.idl @@ -0,0 +1,6 @@ +interface Test +// @(#)Test.idl 1.1 10/18/96 + +{ + void method (in long input1); +}; diff --git a/examples/CORBA/Test_i.cpp b/examples/CORBA/Test_i.cpp new file mode 100644 index 00000000000..2f7c4301470 --- /dev/null +++ b/examples/CORBA/Test_i.cpp @@ -0,0 +1,10 @@ +#include "Test_i.h" +// @(#)Test_i.cpp 1.1 10/18/96 + + +void +Test_i::method (long input, + ACE_CORBA_1 (Environment) &) +{ + ACE_DEBUG ((LM_DEBUG, "received a number %d\n", input)); +} diff --git a/examples/CORBA/Test_i.h b/examples/CORBA/Test_i.h new file mode 100644 index 00000000000..1e8b8c471bd --- /dev/null +++ b/examples/CORBA/Test_i.h @@ -0,0 +1,14 @@ +/* -*- C++ -*- */ +// @(#)Test_i.h 1.1 10/18/96 + +#include "ace/Log_Msg.h" +#include "Test.hh" + +class Test_i +{ +public: + virtual void method (long input, + ACE_CORBA_1 (Environment) &IT_env = ACE_CORBA_1 (default_environment)); +}; + +DEF_TIE_Test (Test_i) diff --git a/examples/CORBA/client.cpp b/examples/CORBA/client.cpp new file mode 100644 index 00000000000..8538bcc2eda --- /dev/null +++ b/examples/CORBA/client.cpp @@ -0,0 +1,26 @@ +#include "ace/Log_Msg.h" +// @(#)client.cpp 1.1 10/18/96 + +#include "Test.hh" + +int +main (int argc, char *argv[]) +{ + char *host = argc == 2 ? argv[1] : ACE_DEFAULT_SERVER_HOST; + + Test_var my_test; + + TRY { + my_test = Test::_bind ("", host, IT_X); + my_test->method (5); + } CATCHANY { + cerr << IT_X << endl; + return -1; + } ENDTRY; + + ACE_DEBUG ((LM_DEBUG, "everything works!\n")); + + // Memory for my_test is automatically released by destructor of + // smart pointer. + return 0; +} diff --git a/examples/CORBA/server.cpp b/examples/CORBA/server.cpp new file mode 100644 index 00000000000..89cccefcee8 --- /dev/null +++ b/examples/CORBA/server.cpp @@ -0,0 +1,37 @@ +#include "ace/Service_Config.h" +// @(#)server.cpp 1.1 10/18/96 + +#include "ace/CORBA_Handler.h" +#include "Test_i.h" + +#if defined (ACE_HAS_ORBIX) + +#if defined (ACE_HAS_MT_ORBIX) +typedef ACE_MT_CORBA_Handler CORBA_HANDLER; +#else +typedef ACE_ST_CORBA_Handler CORBA_HANDLER; +#endif /* ACE_HAS_MT_ORBIX */ + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config daemon; + + char pwd[BUFSIZ]; + char app[BUFSIZ]; + + ACE_OS::getcwd (pwd, sizeof pwd); + ACE_OS::sprintf (app, "%s/%s", pwd, argv[0]); + + if (CORBA_HANDLER::instance ()->activate_service (Test_IMPL, 0, app) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "Could not activate services for supplier\n"), -1); + + TIE_Test (Test_i) test (new Test_i); + + for (;;) + if (CORBA_HANDLER::instance ()->reactor ()->handle_events () == -1) + break; + + return 0; +} +#endif /* ACE_HAS_ORBIX */ diff --git a/examples/Connection/Makefile b/examples/Connection/Makefile new file mode 100644 index 00000000000..96c53892d51 --- /dev/null +++ b/examples/Connection/Makefile @@ -0,0 +1,26 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Connection tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +INFO = README + +DIRS = blocking \ + misc \ + non_blocking + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + diff --git a/examples/Connection/blocking/Makefile b/examples/Connection/blocking/Makefile new file mode 100644 index 00000000000..4240e569478 --- /dev/null +++ b/examples/Connection/blocking/Makefile @@ -0,0 +1,414 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Connection pattern tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +LIB = libSPIPE.a +SHLIB = libSPIPE.so + +BIN = test_spipe_connector \ + test_spipe_acceptor + +SRC = $(addsuffix .cpp,$(BIN)) +OBJ = $(SRC:%.cpp=$(VDIR)%.o) + +LSRC = SPIPE-connector.cpp \ + SPIPE-acceptor.cpp + +LDLIBS = -lSPIPE +LIBS = -lACE + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VLIB) $(VSHLIB) $(SHLIBA) $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +LDFLAGS += -L./ + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/SPIPE-connector.o .shobj/SPIPE-connector.so: SPIPE-connector.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Connector.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Connector.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + SPIPE-connector.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Connector.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Connector.i \ + $(WRAPPER_ROOT)/ace/Connector.cpp +.obj/SPIPE-acceptor.o .shobj/SPIPE-acceptor.so: SPIPE-acceptor.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + SPIPE-acceptor.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/Acceptor.cpp +.obj/test_spipe_connector.o .shobj/test_spipe_connector.so: test_spipe_connector.cpp \ + $(WRAPPER_ROOT)/ace/SPIPE_Connector.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Connector.i \ + SPIPE-connector.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Connector.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Connector.i \ + $(WRAPPER_ROOT)/ace/Connector.cpp +.obj/test_spipe_acceptor.o .shobj/test_spipe_acceptor.so: test_spipe_acceptor.cpp \ + $(WRAPPER_ROOT)/ace/SPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + SPIPE-acceptor.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/Acceptor.cpp + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/Connection/blocking/README b/examples/Connection/blocking/README new file mode 100644 index 00000000000..c7763e3ed04 --- /dev/null +++ b/examples/Connection/blocking/README @@ -0,0 +1,36 @@ +Presently, this directory contains only one example application for +SPIPEs. The test source code is contained in SPIPE-acceptor.h and +SPIPE-connector.h. + +The SPIPE-acceptor example illustrates how named pipes are used on NT. +Once the server establishes a connection to a single client, it spawns +a thread pool to handle incoming requests via the proactor event loop. +That is, a separate thread from the pool is used to process each +message sent by a client. The size of the thread pool can be +specified by command-line arguments. This example leverages the +queueing performed by the NT kernel to trivially implement a thread +pool architecture. + +test_spipe_acceptor has the following command-line arguments: + +test_spipe_acceptor -t + + specifies the size of the thread-pool running in the +proactor event loop. + +Here's how to run the tests: + +% test_spipe_acceptor -t 1000000 +starting up daemon test_sock_acceptor +Opening acepipe +hello + +% test_spipe_connector +starting up daemon test_sock_connector +Opening acepipe +activating 5 + +please enter input..: hello + +There are a number of other options that you can provide. Please see +the source code for details. diff --git a/examples/Connection/blocking/SPIPE-acceptor.cpp b/examples/Connection/blocking/SPIPE-acceptor.cpp new file mode 100644 index 00000000000..471ae4db8f4 --- /dev/null +++ b/examples/Connection/blocking/SPIPE-acceptor.cpp @@ -0,0 +1,179 @@ +#if !defined (SPIPE_ACCEPTOR_C) +// @(#)SPIPE-acceptor.cpp 1.1 10/18/96 + +#define SPIPE_ACCEPTOR_C + +#include "ace/Log_Msg.h" +#include "ace/SPIPE_Addr.h" +#include "ace/Time_Value.h" +#include "ace/SPIPE_Acceptor.h" +#include "ace/Get_Opt.h" +#include "SPIPE-acceptor.h" + +Svc_Handler::Svc_Handler (void) +{ +} + +Svc_Handler::~Svc_Handler (void) +{ +} + +int +Svc_Handler::open (void *) +{ + ACE_DEBUG ((LM_DEBUG, "client connected on handle %d\n", + this->peer ().get_handle ())); + return ACE_Service_Config::proactor ()->initiate + (this, ACE_Event_Handler::READ_MASK); +} + +ACE_Message_Block * +Svc_Handler::get_message (void) +{ + // An extra byte for null termination. + ACE_Message_Block *message = + new ACE_Message_Block (BUFSIZ + 1); + message->size (BUFSIZ); + return message; +} + +int +Svc_Handler::handle_input_complete (ACE_Message_Block *msg, + long bytes_transfered) +{ + if (bytes_transfered > 0) + { + msg->base ()[msg->length ()] = '\0'; + // Print out the message received from the server. + ACE_DEBUG ((LM_DEBUG, "(%t) message size %d.\n", msg->length ())); + ACE_DEBUG ((LM_DEBUG, "%s", msg->rd_ptr ())); + + return 1; // Reinvoke a recv() operation. + } + else + return -1; // Close down. +} + +IPC_Server::IPC_Server (void) + : n_threads_ (1), + rendezvous_ ("acepipe"), + done_handler_ (ACE_Sig_Handler_Ex (ACE_Service_Config::end_proactor_event_loop)) +{ +} + +IPC_Server::~IPC_Server (void) +{ +} + +int +IPC_Server::init (int argc, char *argv[]) +{ + if (this->parse_args (argc, argv) == -1) + return -1; + + ACE_DEBUG ((LM_DEBUG, "Opening %s\n", rendezvous_)); + + // Initialize named pipe listener. + if (this->open (ACE_SPIPE_Addr (rendezvous_)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), 1); + + // Register to receive shutdowns. + else if (ACE_Service_Config::reactor ()->register_handler + (SIGINT, &this->done_handler_) == -1) + return -1; + else + return 0; +} + +int +IPC_Server::fini (void) +{ + return 0; +} + +int +IPC_Server::parse_args (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0]); + + ACE_Get_Opt get_opt (argc, argv, "ut:r:"); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'r': + rendezvous_ = get_opt.optarg; + break; + case 't': + n_threads_ = ACE_OS::atoi (get_opt.optarg); + ACE_DEBUG ((LM_DEBUG, "%s == %d.\n", + get_opt.optarg, + n_threads_)); + ACE_Service_Config::proactor (2*n_threads_); + // This is a lame way to tell the proactor how many threads + // we'll be using. + break; + case 'u': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %n -t \n" + "-r \n"), -1); + break; + } + } + + return 0; +} + +static void * +run_reactor_event_loop (void *) +{ + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + ACE_DEBUG ((LM_DEBUG, "(%t) worker thread starting\n")); + + ACE_Service_Config::run_proactor_event_loop (); + return 0; +} + +int +IPC_Server::svc (void) +{ + // Performs the iterative server activities. + while (ACE_Service_Config::reactor_event_loop_done () == 0) + { + Svc_Handler sh; + + // Create a new SH endpoint, which performs all processing in + // its open() method (note no automatic restart if errno == + // EINTR). + if (this->accept (&sh, 0) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "accept"), 1); + // SH's destructor closes the stream implicitly but the + // listening endpoint stays open. + else + { + // Run single-threaded. + if (n_threads_ <= 1) + run_reactor_event_loop (0); + else + { + // Run thread pool. + if (ACE_Service_Config::thr_mgr ()->spawn_n (n_threads_, + run_reactor_event_loop, + 0, THR_NEW_LWP) + == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn_n"), 1); + + ACE_Service_Config::thr_mgr ()->wait (); + } + + ACE_DEBUG ((LM_DEBUG, "(%t) main thread exiting.\n")); + } + } + + /* NOTREACHED */ + return 0; +} + +#endif /* SPIPE_ACCEPTOR_C */ diff --git a/examples/Connection/blocking/SPIPE-acceptor.h b/examples/Connection/blocking/SPIPE-acceptor.h new file mode 100644 index 00000000000..42d0e106ede --- /dev/null +++ b/examples/Connection/blocking/SPIPE-acceptor.h @@ -0,0 +1,63 @@ +/* -*- C++ -*- */ +// @(#)SPIPE-acceptor.h 1.1 10/18/96 + +#if !defined (SP_ACCEPTOR_H) +#define SP_ACCEPTOR_H + +#include "ace/Svc_Handler.h" +#include "ace/Acceptor.h" +#include "ace/SPIPE_Stream.h" +#include "ace/SPIPE_Acceptor.h" + +// This is the class that does the work once the ACE_Oneshot_Acceptor +// has accepted a connection. + +class Svc_Handler : public ACE_Svc_Handler +{ +public: + Svc_Handler (void); + ~Svc_Handler (void); + + virtual int open (void *); + + virtual ACE_Message_Block *get_message (void); + + virtual int handle_input_complete (ACE_Message_Block *msg, + long bytes_transfered); + // Handle data from the client. + +private: +}; + +class IPC_Server : public ACE_Oneshot_Acceptor +{ +public: + IPC_Server (void); + ~IPC_Server (void); + + // = Dynamic linking hooks. + virtual int init (int argc, char *argv[]); + // Initialize the network server. + + virtual int fini (void); + // Close down the server. + + virtual int svc (void); + // Run the interative service. + +private: + int parse_args (int argc, char *argv[]); + // Parse command-line arguments. + + int n_threads_; + // Size of thread pool to use. + + const char *rendezvous_; + // Meeting place for pipe. + + ACE_Sig_Adapter done_handler_; + // Keeps track of when we shut down due to receipt of the SIGINT + // signal. +}; + +#endif /* SP_ACCEPTOR_H */ diff --git a/examples/Connection/blocking/SPIPE-connector.cpp b/examples/Connection/blocking/SPIPE-connector.cpp new file mode 100644 index 00000000000..584c16cd9f2 --- /dev/null +++ b/examples/Connection/blocking/SPIPE-connector.cpp @@ -0,0 +1,182 @@ +#if !defined (SPIPE_CONNECTOR_C) +// @(#)SPIPE-connector.cpp 1.1 10/18/96 + +#define SPIPE_CONNECTOR_C + +#include "ace/Log_Msg.h" +#include "ace/SPIPE_Addr.h" +#include "ace/SPIPE_Connector.h" +#include "ace/Get_Opt.h" +#include "SPIPE-connector.h" + +Peer_Handler::Peer_Handler (int iterations) + : iterations_ (iterations) +{ +} + +Peer_Handler::~Peer_Handler () +{ +} + +int +Peer_Handler::open (void *) +{ + ACE_DEBUG ((LM_DEBUG, "activating %d\n", this->get_handle ())); + + // If iterations_ has not been set, read from stdin. + if (iterations_ == 0) + { + this->display_menu (); + if (ACE::register_stdin_handler (this, + ACE_Service_Config::reactor (), + ACE_Service_Config::thr_mgr ()) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "register_stdin_handler")); + } + else // If iterations_ has been set, send iterations_ buffers. + { + char *buffer = + "Oh give me a home\n" + "Where the buffalo roam,\n" + "And the deer and the antelope play.\n" + "Where seldom is heard\n" + "A discouraging word,\n" + "And the skies are not cloudy all day.\n"; + int length = ACE_OS::strlen (buffer); + + while (iterations_-- > 0 + && this->peer ().send_n (buffer, length) == length) + continue; + + return this->peer ().close (); + } +} + +int +Peer_Handler::handle_input (ACE_HANDLE) +{ + char buf[BUFSIZ]; + + ssize_t n = ACE_OS::read (ACE_STDIN, buf, sizeof buf); + + if (n > 0) + if (this->peer ().send (buf, n) != n) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "write failed"), -1); + else if (n == 0) /* Explicitly close the connection. */ + { + if (this->peer ().close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), 1); + return -1; + } + else + this->display_menu (); + return 0; +} + +int +Peer_Handler::handle_close (ACE_HANDLE handle, + ACE_Reactor_Mask mask) +{ + ACE_DEBUG ((LM_DEBUG, "Shutting down\n")); + return 0; +} + +ACE_HANDLE +Peer_Handler::get_handle (void) const +{ + return this->peer ().get_handle (); +} + +void +Peer_Handler::display_menu (void) +{ + ACE_DEBUG ((LM_DEBUG, "\nplease enter input..: ")); +} + +IPC_Client::IPC_Client (void) + : rendezvous_ ("acepipe"), + iterations_ (0), + done_handler_ (ACE_Sig_Handler_Ex (ACE_Service_Config::end_proactor_event_loop)) +{ +} + +IPC_Client::~IPC_Client (void) +{ +} + +// Dynamic linking hooks. + +int +IPC_Client::init (int argc, char *argv[]) +{ + if (this->parse_args (argc, argv) == -1) + return -1; + // Handle signals through the ACE_Reactor. + else if (ACE_Service_Config::reactor ()->register_handler + (SIGINT, &this->done_handler_) == -1) + return -1; + + ACE_DEBUG ((LM_DEBUG, "Opening %s\n", rendezvous_)); + + // Connect to the peer, reusing the local addr if necessary. + if (this->connect (new Peer_Handler (iterations_), + ACE_SPIPE_Addr (rendezvous_), + ACE_Synch_Options::defaults, + *((ACE_SPIPE_Addr *) &ACE_Addr::sap_any), + 0, + O_RDWR | FILE_FLAG_OVERLAPPED, + 0) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "connect"), -1); + + return 0; +} + +int +IPC_Client::fini (void) +{ + return 0; +} + +int +IPC_Client::svc (void) +{ + ACE_Service_Config::run_reactor_event_loop (); + return 0; +} + +int +IPC_Client::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + return 0; +} + +int +IPC_Client::parse_args (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0]); + + ACE_Get_Opt get_opt (argc, argv, "ui:r:"); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'r': + rendezvous_ = get_opt.optarg; + break; + case 'i': + iterations_ = ACE_OS::atoi (get_opt.optarg); + break; + case 'u': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %n -i \n" + "-r \n"), -1); + break; + } + } + + return 0; +} + + +#endif /* SPIPE_CONNECTOR */ diff --git a/examples/Connection/blocking/SPIPE-connector.h b/examples/Connection/blocking/SPIPE-connector.h new file mode 100644 index 00000000000..81525f0a0eb --- /dev/null +++ b/examples/Connection/blocking/SPIPE-connector.h @@ -0,0 +1,75 @@ +/* -*- C++ -*- */ +// @(#)SPIPE-connector.h 1.1 10/18/96 + +#if !defined (SP_CONNECTOR_H) +#define SP_CONNECTOR_H + +#include "ace/Svc_Handler.h" +#include "ace/SPIPE_Stream.h" +#include "ace/Connector.h" +#include "ace/SPIPE_Connector.h" + +class Peer_Handler : public ACE_Svc_Handler +{ +public: + // = Initialization + + Peer_Handler (int iterations); + // is the number of buffers to send. If + // == 0, then read from stdin. + + ~Peer_Handler (void); + + virtual int open (void * = 0); + // Activate the handler when connection is established. + + // = Demultiplexing hooks. + virtual int handle_input (ACE_HANDLE); + virtual int handle_close (ACE_HANDLE handle = ACE_INVALID_HANDLE, + ACE_Reactor_Mask mask = ACE_Event_Handler::RWE_MASK); + + virtual ACE_HANDLE get_handle (void) const; + +private: + void display_menu (void); + + int iterations_; + // No. of buffers to send. +}; + +class IPC_Client : public ACE_Connector +{ +public: + // Initialization + IPC_Client (void); + ~IPC_Client (void); + + // = Dynamic linking hooks. + virtual int init (int argc, char *argv[]); + // Initialize the IPC client. + + virtual int fini (void); + // Destroy the IPC client. + + virtual int svc (void); + // Run the svc. + + virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask); + // Report connection errors. + +private: + int parse_args (int argc, char *argv[]); + // Parse command-line arguments. + + int iterations_; + // Number of times to send a buffer. + + const char *rendezvous_; + // Meeting place for pipe. + + ACE_Sig_Adapter done_handler_; + // Keeps track of when we shut down due to receipt of the SIGINT + // signal. +}; + +#endif /* SP_CONNECTOR_H */ diff --git a/examples/Connection/blocking/test_spipe_acceptor.cpp b/examples/Connection/blocking/test_spipe_acceptor.cpp new file mode 100644 index 00000000000..2ef842022f8 --- /dev/null +++ b/examples/Connection/blocking/test_spipe_acceptor.cpp @@ -0,0 +1,22 @@ +// ACE_SPIPE Server. +// @(#)test_spipe_acceptor.cpp 1.1 10/18/96 + + +#include "ace/SPIPE_Acceptor.h" +#include "ace/SPIPE_Addr.h" +#include "SPIPE-acceptor.h" + +int +main (int argc, char *argv[]) +{ + // Perform Service_Config initializations + ACE_Service_Config daemon (argv[0]); + + IPC_Server acceptor; + + if (acceptor.init (argc, argv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "init"), -1); + + return acceptor.svc (); +} + diff --git a/examples/Connection/blocking/test_spipe_connector.cpp b/examples/Connection/blocking/test_spipe_connector.cpp new file mode 100644 index 00000000000..2dbc1b7d5e0 --- /dev/null +++ b/examples/Connection/blocking/test_spipe_connector.cpp @@ -0,0 +1,22 @@ +// ACE_SPIPE Client. +// @(#)test_spipe_connector.cpp 1.1 10/18/96 + + +#include "ace/SPIPE_Connector.h" +#include "ace/SPIPE_Addr.h" +#include "SPIPE-connector.h" + +int +main (int argc, char *argv[]) +{ + // Perform Service_Config initializations + ACE_Service_Config daemon (argv[0]); + + IPC_Client peer_connector; + + if (peer_connector.init (argc, argv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "init"), -1); + + return peer_connector.svc (); +} + diff --git a/examples/Connection/misc/Makefile b/examples/Connection/misc/Makefile new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/Connection/misc/test_upipe.cpp b/examples/Connection/misc/test_upipe.cpp new file mode 100644 index 00000000000..84e10fae03e --- /dev/null +++ b/examples/Connection/misc/test_upipe.cpp @@ -0,0 +1,176 @@ +// This short program illustrates in implementation of the classic +// @(#)test_upipe.cpp 1.1 10/18/96 + +// "bounded buffer" program using ACE_UPIPEs. This program also shows +// how the ACE_Connector and ACE_Acceptor patterns work when used with +// ACE_UPIPEs. + +// Enable tracing +#include "ace/Log_Msg.h" +#include "ace/Acceptor.h" +#include "ace/Connector.h" +#include "ace/UPIPE_Acceptor.h" +#include "ace/UPIPE_Connector.h" +#include "ace/UPIPE_Addr.h" + +#if defined (ACE_HAS_THREADS) + +typedef ACE_Svc_Handler SVC_HANDLER; + +class Server_Service : public SVC_HANDLER + // = TITLE + // Defines the interface for a service that recvs data from its + // client and writes the data to its stdout. +{ +public: + Server_Service (ACE_Thread_Manager * = 0) {} + virtual int open (void *) + { + ACE_TRACE ("Server_Service::open"); + return 0; + } + + virtual int svc (void) + { + ACE_TRACE ("Server_Service::svc"); + + char buf[BUFSIZ]; + ssize_t n; + + while ((n = this->peer ().recv (buf, sizeof buf)) > 0) + ::write (1, buf, n); + + return 0; + } +}; + +class Server : public ACE_Strategy_Acceptor + // = TITLE + // Defines the interface for a factory that accepts connections + // and creates/activates Server_Service objects. +{ +public: + Server (ACE_Thread_Manager *thr_mgr, + ACE_Reactor *reactor) + : reactor_ (reactor), + thr_mgr_ (thr_mgr) + { + ACE_TRACE ("Server::Server"); + } + + virtual int init (int argc, char *argv[]) + { + ACE_TRACE ("Server::init"); + const char *l_addr = argc > 1 ? argv[1] : ACE_DEFAULT_RENDEZVOUS; + + ACE_UPIPE_Addr local_addr (l_addr); + + if (this->thr_strategy_.open (this->thr_mgr_, THR_DETACHED | THR_NEW_LWP) == -1) + return -1; + else if (this->open (local_addr, this->reactor_, + 0, 0, &this->thr_strategy_) == -1) + return -1; + + // Give server a chance to register the STREAM pipe. + ACE_OS::sleep (ACE_Time_Value (4)); + return 0; + } + +private: + ACE_Reactor *reactor_; + // Our instance of the reactor. + + ACE_Thread_Manager *thr_mgr_; + // Our instance of a thread manager. + + ACE_Thread_Strategy thr_strategy_; + // Our concurrency strategy. +}; + +class Client_Service : public SVC_HANDLER + // = TITLE + // Defines the interface for a service that recvs data from its + // stdin and forward the data to its server. +{ +public: + Client_Service (ACE_Thread_Manager *thr_mgr) + : SVC_HANDLER (thr_mgr) + { + ACE_TRACE ("Client_Service::Client_Service"); + } + + virtual int open (void *) + { + ACE_TRACE ("Client_Service::open"); + return this->activate (THR_DETACHED | THR_NEW_LWP); + } + + virtual int svc (void) + { + ACE_TRACE ("Client_Service::svc"); + char buf[BUFSIZ]; + ssize_t n; + + while ((n = ACE_OS::read (ACE_STDIN, buf, sizeof buf)) > 0) + this->peer ().send (buf, sizeof buf); + + this->peer ().close (); + return 0; + } +}; + +class Client : public ACE_Connector + // = TITLE + // Defines the interface for a factory that connects + // a Client_Service with a Server. +{ +public: + Client (ACE_Thread_Manager *thr_mgr) + : thr_mgr_ (thr_mgr) + { + ACE_TRACE ("Client::Client"); + } + + virtual int init (int argc, char *argv[]) + { + ACE_TRACE ("Client::init"); + + char *r_addr = argc > 1 ? argv[1] : ACE_DEFAULT_RENDEZVOUS; + + ACE_UPIPE_Addr remote_addr (r_addr); + + return this->connect (new Client_Service (this->thr_mgr_), remote_addr); + } + +private: + ACE_Thread_Manager *thr_mgr_; +}; + +//---------------------------------------- + +int main (int argc, char *argv[]) +{ + ACE_Service_Config svc_conf; + ACE_Thread_Manager thr_mgr; + + Client peer_connector (&thr_mgr); + Server peer_acceptor (&thr_mgr, ACE_Service_Config::reactor ()); + + // Establish the connection between Acceptor and Connector. + + if (peer_acceptor.init (argc, argv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "init"), -1); + else if (peer_connector.init (argc, argv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "init"), -1); + + // Wait for threads to exit. + thr_mgr.wait (); + return 0; +} +#else +int +main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "your platform does not support threads\n"), 1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/Connection/non_blocking/CPP-acceptor.cpp b/examples/Connection/non_blocking/CPP-acceptor.cpp new file mode 100644 index 00000000000..378fe347eb8 --- /dev/null +++ b/examples/Connection/non_blocking/CPP-acceptor.cpp @@ -0,0 +1,172 @@ +#if !defined (CPP_ACCEPTOR_C) +// @(#)CPP-acceptor.cpp 1.1 10/18/96 + +#define CPP_ACCEPTOR_C + +#include "ace/Log_Msg.h" +#include "ace/Service_Config.h" +#include "CPP-acceptor.h" + +#define PR_ST_1 ACE_PEER_STREAM_1 +#define PR_ST_2 ACE_PEER_STREAM_2 +#define PR_AC_1 ACE_PEER_ACCEPTOR_1 +#define PR_AC_2 ACE_PEER_ACCEPTOR_2 +#define PR_AD ACE_PEER_ACCEPTOR_ADDR +#define SH SVC_HANDLER + +template +Svc_Handler::Svc_Handler (ACE_Reactor *r) + : SVC_HANDLER (0, 0, r) +{ +} + +template int +Svc_Handler::close (u_long) +{ + ACE_DEBUG ((LM_DEBUG, "calling Svc_Handler close\n")); + + // Free up the handle. + this->peer ().close (); + return 0; +} + +template int +Svc_Handler::open (void *) +{ + PR_AD client_addr; + char buf[BUFSIZ]; + + if (this->peer ().get_remote_addr (client_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "get_remote_addr"), -1); + else if (client_addr.addr_to_string (buf, sizeof buf) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "addr_to_string"), -1); + else + ACE_DEBUG ((LM_DEBUG, "client addr %s on handle %d\n", + buf, this->peer ().get_handle ())); + + // Process the connection immediately since we are an interative + // server. + return this->handle_input (); +} + +// Receive and process the data from the client. + +template int +Svc_Handler::handle_input (ACE_HANDLE) +{ + char buf[BUFSIZ]; + + // Read data from client (terminate on error). + + cerr << "in handle_input" << endl; + for (int r_bytes; (r_bytes = this->peer ().recv (buf, sizeof buf)) > 0; ) + if (ACE_OS::write (ACE_STDOUT, buf, r_bytes) != r_bytes) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ACE::send_n"), -1); + + // Send back ack. + if (this->peer ().send_n ("", 1) != 1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send_n"), -1); + return 0; +} + +template int +Svc_Handler::handle_timeout (const ACE_Time_Value &, + const void *) +{ + ACE_DEBUG ((LM_DEBUG, "%p\n", "handle_timeout")); + return 0; +} + +template int +IPC_Server::init (int argc, char *argv[]) +{ + const char *local_addr = argc > 1 ? argv[1] : ACE_DEFAULT_SERVER_PORT_STR; + ACE_Time_Value timeout (argc > 2 ? ACE_OS::atoi (argv[2]) : ACE_DEFAULT_TIMEOUT); + int use_reactor = argc > 3 ? ACE_Synch_Options::USE_REACTOR : 0; + + this->options_.set (ACE_Synch_Options::USE_TIMEOUT | use_reactor, timeout); + + if (this->server_addr_.set (local_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "set"), -1); + // Call down to the ACCEPTOR's open() method to do the initialization. + if (this->inherited::open (this->server_addr_, + use_reactor ? ACE_Service_Config::reactor () : 0) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + + // Handle SIGINT signal through the ACE_Reactor. + else if (ACE_Service_Config::reactor ()->register_handler + (SIGINT, &this->done_handler_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "register_handler"), -1); + + // Handle SIGPIPE signal through the ACE_Reactor. + else if (ACE_Service_Config::reactor ()->register_handler + (SIGPIPE, &this->done_handler_) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "register_handler")); + else + return 0; +} + +template +IPC_Server::IPC_Server (void) + : done_handler_ (ACE_Sig_Handler_Ex (ACE_Service_Config::end_reactor_event_loop)) +{ +} + +template int +IPC_Server::fini (void) +{ + return 0; +} + +template +IPC_Server::~IPC_Server (void) +{ +} + +// Run the interative service. + +template int +IPC_Server::svc (void) +{ + char buf[BUFSIZ]; + + if (this->server_addr_.addr_to_string (buf, sizeof buf) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "addr_to_string"), -1); + else + ACE_DEBUG ((LM_DEBUG, "starting server addr %s on handle %d\n", + buf, this->get_handle ())); + + // Performs the iterative server activities. + + while (ACE_Service_Config::reactor_event_loop_done () == 0) + { + SH sh (this->reactor ()); + + // Create a new SH endpoint, which performs all processing in + // its open() method (note no automatic restart if errno == + // EINTR). + + if (this->accept (&sh, 0, this->options_, 0) == -1) + { + if (errno == EWOULDBLOCK && this->reactor ()) + this->reactor ()->handle_events (); + else + ACE_ERROR ((LM_ERROR, "%p on handle %d\n", + "accept", this->acceptor ().get_handle ())); + } + + // SH's destructor closes the stream implicitly but the + // listening endpoint stays open. + } + + /* NOTREACHED */ + return 0; +} + +#undef PR_ST_1 +#undef PR_ST_2 +#undef PR_AC_1 +#undef PR_AC_2 +#undef PR_AD +#undef SH +#endif /* CPP_ACCEPTOR_C */ diff --git a/examples/Connection/non_blocking/CPP-acceptor.h b/examples/Connection/non_blocking/CPP-acceptor.h new file mode 100644 index 00000000000..75f01ad9bf2 --- /dev/null +++ b/examples/Connection/non_blocking/CPP-acceptor.h @@ -0,0 +1,70 @@ +/* -*- C++ -*- */ +// @(#)CPP-acceptor.h 1.1 10/18/96 + +#if !defined (CPP_ACCEPTOR_H) +#define CPP_ACCEPTOR_H + +#include "ace/Acceptor.h" + +// This is the class that does the work once the ACE_Oneshot_Acceptor +// has accepted a connection. + +template +class Svc_Handler : public ACE_Svc_Handler +{ +public: + // = Initialization method. + Svc_Handler (ACE_Reactor *r); + + virtual int open (void *); + // Perform the work of the SVC_HANDLER. + + virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE); + // Handle data from the client. + + virtual int close (u_long); + // Called if ACE_Svc_Handler is closed down unexpectedly. + + virtual int handle_timeout (const ACE_Time_Value &, const void *arg); + // Handles acceptor timeouts. + +private: + typedef ACE_Svc_Handler SVC_HANDLER; +}; + +template +class IPC_Server : public ACE_Oneshot_Acceptor +{ +public: + // = Initialization and termination. + IPC_Server (void); + ~IPC_Server (void); + + // = Dynamic linking hooks. + virtual int init (int argc, char *argv[]); + // Initialize the network server. + + virtual int fini (void); + // Close down the server. + + virtual int svc (void); + // Run the interative service. + +private: + typedef ACE_Oneshot_Acceptor inherited; + + PEER_ADDR server_addr_; + // Address of this server. + + ACE_Synch_Options options_; + // Options that this server is using. + + ACE_Sig_Adapter done_handler_; + // Keeps track of when we shut down due to receipt of the SIGINT + // signal. +}; + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "CPP-acceptor.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ +#endif /* CPP_ACCEPTOR_H */ diff --git a/examples/Connection/non_blocking/CPP-connector.cpp b/examples/Connection/non_blocking/CPP-connector.cpp new file mode 100644 index 00000000000..c77a36f248c --- /dev/null +++ b/examples/Connection/non_blocking/CPP-connector.cpp @@ -0,0 +1,219 @@ +#if !defined (CPP_CONNECTOR_C) +// @(#)CPP-connector.cpp 1.1 10/18/96 + +#define CPP_CONNECTOR_C + +#include "ace/Log_Msg.h" +#include "CPP-connector.h" + +#define PR_ST_1 ACE_PEER_STREAM_1 +#define PR_ST_2 ACE_PEER_STREAM_2 +#define PR_CO_1 ACE_PEER_CONNECTOR_1 +#define PR_CO_2 ACE_PEER_CONNECTOR_2 +#define PR_AD ACE_PEER_CONNECTOR_ADDR +#define SH SVC_HANDLER + +template +Peer_Handler::Peer_Handler (ACE_Reactor *r) + : action_ (&Peer_Handler::idle) +{ + this->reactor (r); +} + +template int +Peer_Handler::open (void *) +{ + ACE_DEBUG ((LM_DEBUG, "activating %d\n", this->get_handle ())); + this->action_ = &Peer_Handler::connected; + + if (this->reactor ()) + this->reactor ()->register_handler (this, ACE_Event_Handler::WRITE_MASK); + else + { + while (this->connected () != -1) + continue; + + this->handle_close (0, ACE_Event_Handler::READ_MASK); + } + return 0; +} + +template ACE_HANDLE +Peer_Handler::get_handle (void) const +{ + return this->peer ().get_handle (); +} + +template int +Peer_Handler::disconnecting (void) +{ + char buf[BUFSIZ]; + int n; + + if ((n = this->peer ().recv (buf, sizeof buf)) > 0) + ACE_OS::write (ACE_STDOUT, buf, n); + this->action_ = &Peer_Handler::idle; + return -1; +} + +template int +Peer_Handler::idle (void) +{ + ACE_DEBUG ((LM_DEBUG, "idle!\n")); + return 0; +} + +template int +Peer_Handler::connected (void) +{ + char buf[BUFSIZ]; + int n; + + ACE_DEBUG ((LM_DEBUG, "please enter input..: ")); + + if ((n = ACE_OS::read (ACE_STDIN, buf, sizeof buf)) > 0 + && this->peer ().send_n (buf, n) != n) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "write failed"), -1); + else if (n == 0) /* Explicitly close the connection. */ + { + if (this->peer ().close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), 1); + this->action_ = &Peer_Handler::disconnecting; + return -1; + } + else + return 0; +} + +template int +Peer_Handler::stdio (void) +{ + char buf[BUFSIZ]; + int n; + + ACE_DEBUG ((LM_DEBUG, "stdio!\n")); + + ACE_DEBUG ((LM_DEBUG, "please enter input..: ")); + + if ((n = ACE_OS::read (ACE_STDIN, buf, sizeof buf)) > 0) + { + ACE_OS::write (ACE_STDOUT, buf, n); + return 0; + } + else + return -1; +} + +template int +Peer_Handler::handle_output (ACE_HANDLE) +{ + ACE_DEBUG ((LM_DEBUG, "in handle_output\n")); + + return (this->*action_) (); +} + +template int +Peer_Handler::handle_input (ACE_HANDLE) +{ + ACE_DEBUG ((LM_DEBUG, "in handle_input\n")); + + return (this->*action_) (); +} + +template int +Peer_Handler::handle_close (ACE_HANDLE, + ACE_Reactor_Mask mask) +{ + ACE_DEBUG ((LM_DEBUG, "closing down (%d)\n", mask)); + if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK)) + { + this->action_ = &Peer_Handler::stdio; + this->peer ().close (); + ACE_OS::rewind (stdin); + return this->reactor () && this->reactor ()->register_handler + (ACE_STDIN, this, ACE_Event_Handler::READ_MASK); + } + else if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK)) + delete this; + return 0; + +} + +template int +IPC_Client::svc (void) +{ + if (this->reactor ()) + ACE_Service_Config::run_reactor_event_loop (); + + return 0; +} + +template int +IPC_Client::fini (void) +{ + return 0; +} + +template +IPC_Client::IPC_Client (void) + : done_handler_ (ACE_Sig_Handler_Ex (ACE_Service_Config::end_reactor_event_loop)) +{ +} + +template int +IPC_Client::init (int argc, char *argv[]) +{ + // Call down to the CONNECTOR's open() method to do the initialization. + this->inherited::open (ACE_Service_Config::reactor ()); + + char *r_addr = argc > 1 ? argv[1] : + ACE_SERVER_ADDRESS (ACE_DEFAULT_SERVER_HOST, ACE_DEFAULT_SERVER_PORT_STR); + ACE_Time_Value timeout (argc > 2 ? ACE_OS::atoi (argv[2]) : ACE_DEFAULT_TIMEOUT); + char *l_addr = argc > 3 ? argv[3] : ACE_DEFAULT_LOCAL_PORT_STR; + + // Handle signals through the ACE_Reactor. + if (ACE_Service_Config::reactor ()->register_handler + (SIGINT, &this->done_handler_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "register_handler"), -1); + + PR_AD remote_addr (r_addr); + PR_AD local_addr (l_addr); + + this->options_.set (ACE_Synch_Options::USE_REACTOR, timeout); + + // Connect to the peer, reusing the local addr if necessary. + if (this->connect (new SH (this->reactor ()), remote_addr, + this->options_, local_addr, 1) == -1 + && errno != EWOULDBLOCK) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "connect"), -1); + return 0; +} + +template +IPC_Client::~IPC_Client (void) +{ +} + +template int +IPC_Client::handle_close (ACE_HANDLE h, + ACE_Reactor_Mask) +{ + if (h >= 0) + ACE_ERROR ((LM_ERROR, "%p on %d\n", "connection failed", h)); + else // We are closing down the connector. + { + ACE_DEBUG ((LM_DEBUG, "closing down IPC_Client\n")); + this->inherited::handle_close (); + } + + ACE_Service_Config::end_reactor_event_loop (); + return 0; +} + +#undef PR_ST_1 +#undef PR_ST_2 +#undef PR_CO_1 +#undef PR_CO_2 +#undef PR_AD +#undef SH +#endif /* CPP_CONNECTOR_C */ diff --git a/examples/Connection/non_blocking/CPP-connector.h b/examples/Connection/non_blocking/CPP-connector.h new file mode 100644 index 00000000000..021fbb85661 --- /dev/null +++ b/examples/Connection/non_blocking/CPP-connector.h @@ -0,0 +1,77 @@ +/* -*- C++ -*- */ +// @(#)CPP-connector.h 1.1 10/18/96 + +#if !defined (CPP_CONNECTOR_H) +#define CPP_CONNECTOR_H + +#include "ace/Service_Config.h" +#include "ace/Connector.h" + +template +class Peer_Handler : public ACE_Svc_Handler +{ +public: + Peer_Handler (ACE_Reactor *r); + + virtual int open (void * = 0); + // Activate the handler when connection is established. + + // = Demultiplexing hooks. + virtual int handle_output (ACE_HANDLE); + virtual int handle_input (ACE_HANDLE); + virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask mask); + + virtual ACE_HANDLE get_handle (void) const; + +protected: + // = These methods implement the State pattern. + int idle (void); + int connected (void); + int disconnecting (void); + int stdio (void); + + int (Peer_Handler::*action_) (void); + // Keeps track of which state we are in. + +private: + // = Disallow these methods... + virtual int put (ACE_Message_Block *, ACE_Time_Value *) { return 0; } + virtual int svc (void) { return 0; } +}; + +template +class IPC_Client : public ACE_Connector +{ +public: + // = Initialization and termination methods. + IPC_Client (void); + ~IPC_Client (void); + + // = Dynamic linking hooks. + virtual int init (int argc, char *argv[]); + // Initialize the IPC client. + + virtual int fini (void); + // Destroy the IPC client. + + virtual int svc (void); + // Run the svc. + + virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask); + // Report connection errors. + +private: + typedef ACE_Connector inherited; + + ACE_Synch_Options options_; + // Options for the active connection factory. + + ACE_Sig_Adapter done_handler_; + // Keeps track of when we shut down due to receipt of the SIGINT + // signal. +}; + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "CPP-connector.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ +#endif /* CPP_CONNECTOR_H */ diff --git a/examples/Connection/non_blocking/Makefile b/examples/Connection/non_blocking/Makefile new file mode 100644 index 00000000000..3098b81802c --- /dev/null +++ b/examples/Connection/non_blocking/Makefile @@ -0,0 +1,756 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Connection pattern tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +LIB = libConn.a +SHLIB = libConn.so + +BIN = test_sock_connector \ + test_sock_acceptor \ + test_tli_connector \ + test_tli_acceptor \ + test_spipe_connector \ + test_spipe_acceptor + +SRC = $(addsuffix .cpp,$(BIN)) +OBJ = $(SRC:%.cpp=$(VDIR)%.o) + +LSRC = CPP-connector.cpp \ + CPP-acceptor.cpp + +LDLIBS = -lConn +LIBS = -lACE + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VLIB) $(VSHLIB) $(SHLIBA) $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +LDFLAGS += -L./ + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/CPP-connector.o .shobj/CPP-connector.so: CPP-connector.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + CPP-connector.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Connector.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Connector.i \ + $(WRAPPER_ROOT)/ace/Connector.cpp \ + CPP-connector.cpp +.obj/CPP-acceptor.o .shobj/CPP-acceptor.so: CPP-acceptor.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + CPP-acceptor.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/Acceptor.cpp \ + CPP-acceptor.cpp +.obj/test_sock_connector.o .shobj/test_sock_connector.so: test_sock_connector.cpp \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + CPP-connector.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Connector.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Connector.i \ + $(WRAPPER_ROOT)/ace/Connector.cpp \ + CPP-connector.cpp +.obj/test_sock_acceptor.o .shobj/test_sock_acceptor.so: test_sock_acceptor.cpp \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + CPP-acceptor.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/Acceptor.cpp \ + CPP-acceptor.cpp +.obj/test_tli_connector.o .shobj/test_tli_connector.so: test_tli_connector.cpp \ + $(WRAPPER_ROOT)/ace/TLI_Connector.h \ + $(WRAPPER_ROOT)/ace/TLI_Stream.h \ + $(WRAPPER_ROOT)/ace/TLI.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/TLI.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/TLI_Stream.i \ + $(WRAPPER_ROOT)/ace/TLI_Connector.i \ + CPP-connector.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Connector.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Connector.i \ + $(WRAPPER_ROOT)/ace/Connector.cpp \ + CPP-connector.cpp +.obj/test_tli_acceptor.o .shobj/test_tli_acceptor.so: test_tli_acceptor.cpp \ + $(WRAPPER_ROOT)/ace/TLI_Acceptor.h \ + $(WRAPPER_ROOT)/ace/TLI.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/TLI.i \ + $(WRAPPER_ROOT)/ace/TLI_Stream.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/TLI_Stream.i \ + $(WRAPPER_ROOT)/ace/TLI_Acceptor.i \ + CPP-acceptor.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/Acceptor.cpp \ + CPP-acceptor.cpp +.obj/test_spipe_connector.o .shobj/test_spipe_connector.so: test_spipe_connector.cpp \ + $(WRAPPER_ROOT)/ace/SPIPE_Connector.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Connector.i \ + CPP-connector.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Connector.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.cpp \ + $(WRAPPER_ROOT)/ace/Map_Manager.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Connector.i \ + $(WRAPPER_ROOT)/ace/Connector.cpp \ + CPP-connector.cpp +.obj/test_spipe_acceptor.o .shobj/test_spipe_acceptor.so: test_spipe_acceptor.cpp \ + $(WRAPPER_ROOT)/ace/SPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + CPP-acceptor.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/Acceptor.cpp \ + CPP-acceptor.cpp + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/Connection/non_blocking/README b/examples/Connection/non_blocking/README new file mode 100644 index 00000000000..78fb023b99e --- /dev/null +++ b/examples/Connection/non_blocking/README @@ -0,0 +1,24 @@ +This code illustrates how to write a single set of source code (for a +client and server) and then parameterize in the desired IPC mechanism. +In this case, the IPC mechanisms include sockets, TLI, and STREAM +pipes. The single set of source code is located in CPP-acceptor.cpp +(which is the server) and CPP-connector.cpp (which is the non-blocking +client). + +Here's how I typically run these tests: + +% test_sock_acceptor localhost:10005 & +starting up daemon ./test_sock_acceptor +starting server addr 127.0.0.1:10007 on handle 5 +client addr 127.0.0.1:10003 on handle 6 +hello + +% test_sock_connector localhost:10005 +starting up daemon ./test_sock_connector +activating 5 +in handle_output +please enter input..: hello +in handle_output + +There are a number of other options that you can provide. Please see +the source code for details. diff --git a/examples/Connection/non_blocking/test_sock_acceptor.cpp b/examples/Connection/non_blocking/test_sock_acceptor.cpp new file mode 100644 index 00000000000..c723f292aa7 --- /dev/null +++ b/examples/Connection/non_blocking/test_sock_acceptor.cpp @@ -0,0 +1,25 @@ +// ACE_SOCK Server. +// @(#)test_sock_acceptor.cpp 1.1 10/18/96 + + +#include "ace/SOCK_Acceptor.h" +#include "ace/INET_Addr.h" +#include "CPP-acceptor.h" + +typedef Svc_Handler SVC_HANDLER; +typedef IPC_Server IPC_SERVER; + +int +main (int argc, char *argv[]) +{ + // Perform Service_Config initializations + ACE_Service_Config daemon (argv[0]); + + IPC_SERVER acceptor; + + if (acceptor.init (argc, argv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "init"), -1); + + return acceptor.svc (); +} + diff --git a/examples/Connection/non_blocking/test_sock_connector.cpp b/examples/Connection/non_blocking/test_sock_connector.cpp new file mode 100644 index 00000000000..5cfbef12f77 --- /dev/null +++ b/examples/Connection/non_blocking/test_sock_connector.cpp @@ -0,0 +1,25 @@ +// ACE_SOCK Client. +// @(#)test_sock_connector.cpp 1.1 10/18/96 + + +#include "ace/SOCK_Connector.h" +#include "ace/INET_Addr.h" +#include "CPP-connector.h" + +typedef Peer_Handler PEER_HANDLER; +typedef IPC_Client IPC_CLIENT; + +int +main (int argc, char *argv[]) +{ + // Perform Service_Config initializations + ACE_Service_Config daemon (argv[0]); + + IPC_CLIENT peer_connector; + + if (peer_connector.init (argc, argv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "init"), -1); + + return peer_connector.svc (); +} + diff --git a/examples/Connection/non_blocking/test_spipe_acceptor.cpp b/examples/Connection/non_blocking/test_spipe_acceptor.cpp new file mode 100644 index 00000000000..a65658634e2 --- /dev/null +++ b/examples/Connection/non_blocking/test_spipe_acceptor.cpp @@ -0,0 +1,25 @@ +// ACE_SPIPE Server. +// @(#)test_spipe_acceptor.cpp 1.1 10/18/96 + + +#include "ace/SPIPE_Acceptor.h" +#include "ace/SPIPE_Addr.h" +#include "CPP-acceptor.h" + +typedef Svc_Handler SVC_HANDLER; +typedef IPC_Server IPC_SERVER; + +int +main (int argc, char *argv[]) +{ + // Perform Service_Config initializations + ACE_Service_Config daemon (argv[0]); + + IPC_SERVER acceptor; + + if (acceptor.init (argc, argv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "init"), -1); + + return acceptor.svc (); +} + diff --git a/examples/Connection/non_blocking/test_spipe_connector.cpp b/examples/Connection/non_blocking/test_spipe_connector.cpp new file mode 100644 index 00000000000..ad5b4b3cb1e --- /dev/null +++ b/examples/Connection/non_blocking/test_spipe_connector.cpp @@ -0,0 +1,25 @@ +// ACE_SPIPE Client. +// @(#)test_spipe_connector.cpp 1.1 10/18/96 + + +#include "ace/SPIPE_Connector.h" +#include "ace/SPIPE_Addr.h" +#include "CPP-connector.h" + +typedef Peer_Handler PEER_HANDLER; +typedef IPC_Client IPC_CLIENT; + +int +main (int argc, char *argv[]) +{ + // Perform Service_Config initializations + ACE_Service_Config daemon (argv[0]); + + IPC_CLIENT peer_connector; + + if (peer_connector.init (argc, argv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "init"), -1); + + return peer_connector.svc (); +} + diff --git a/examples/Connection/non_blocking/test_tli_acceptor.cpp b/examples/Connection/non_blocking/test_tli_acceptor.cpp new file mode 100644 index 00000000000..dccb6305573 --- /dev/null +++ b/examples/Connection/non_blocking/test_tli_acceptor.cpp @@ -0,0 +1,33 @@ +// ACE_TLI Server. +// @(#)test_tli_acceptor.cpp 1.1 10/18/96 + + +#include "ace/TLI_Acceptor.h" +#include "ace/INET_Addr.h" +#include "CPP-acceptor.h" + +#if defined (ACE_HAS_TLI) +typedef Svc_Handler SVC_HANDLER; +typedef IPC_Server IPC_SERVER; + +int +main (int argc, char *argv[]) +{ + // Perform Service_Config initializations + ACE_Service_Config daemon (argv[0]); + + IPC_SERVER acceptor; + + if (acceptor.init (argc, argv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "init"), -1); + + return acceptor.svc (); +} +#else +int +main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "your platform does not support TLI\n"), 1); +} +#endif /* ACE_HAS_TLI */ + diff --git a/examples/Connection/non_blocking/test_tli_connector.cpp b/examples/Connection/non_blocking/test_tli_connector.cpp new file mode 100644 index 00000000000..e3409efca3a --- /dev/null +++ b/examples/Connection/non_blocking/test_tli_connector.cpp @@ -0,0 +1,33 @@ +// ACE_TLI Client. +// @(#)test_tli_connector.cpp 1.1 10/18/96 + + +#include "ace/TLI_Connector.h" +#include "ace/INET_Addr.h" +#include "CPP-connector.h" + +#if defined (ACE_HAS_TLI) + +typedef Peer_Handler PEER_HANDLER; +typedef IPC_Client IPC_CLIENT; + +int +main (int argc, char *argv[]) +{ + // Perform Service_Config initializations + ACE_Service_Config daemon (argv[0]); + + IPC_CLIENT peer_connector; + + if (peer_connector.init (argc, argv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "init"), -1); + + return peer_connector.svc (); +} +#else +int +main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "your platform does not support TLI\n"), 1); +} +#endif /* ACE_HAS_TLI */ diff --git a/examples/IPC_SAP/DEV_SAP/Makefile b/examples/IPC_SAP/DEV_SAP/Makefile new file mode 100644 index 00000000000..d596bd3d53c --- /dev/null +++ b/examples/IPC_SAP/DEV_SAP/Makefile @@ -0,0 +1,22 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the DEV_SAP test directory +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +DIRS = reader \ + writer + +#---------------------------------------------------------------------------- +# macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU diff --git a/examples/IPC_SAP/DEV_SAP/README b/examples/IPC_SAP/DEV_SAP/README new file mode 100644 index 00000000000..8e47d8c5cec --- /dev/null +++ b/examples/IPC_SAP/DEV_SAP/README @@ -0,0 +1,23 @@ +This directory contains a test example for the DEV_SAP +class category. It implements a class TTY_IO that is +derived from ACE_DEV_IO and adds a control method +with specific features for a serial line connection +(e.g. /dev/ttya and /dev/ttyb on UNIX systems). + +The reader/reader executable initializes its +device-special file (given as command-line parameter), +reads characters from it (until it recognizes character 'q') +ands sends the characters read to stdout. + +The writer/writer executable also initializes its +device-special file (given as command-line parameter), +reads characters from stdin (until'q') and sends them +to the device. + +To run the tests I connect /dev/ttya and /dev/ttyb (with a +zero modem cable) and start the reader with "reader /dev/ttya" +and the writer (in a different window) with "writer /dev/ttyb". + +Characters typed in the writer window should now appear as output +in the reader window. Note that characters are buffered till EOL. + diff --git a/examples/IPC_SAP/DEV_SAP/reader/Makefile b/examples/IPC_SAP/DEV_SAP/reader/Makefile new file mode 100644 index 00000000000..12373f002d5 --- /dev/null +++ b/examples/IPC_SAP/DEV_SAP/reader/Makefile @@ -0,0 +1,71 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the simple DEV reader test file +# for serial devices +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = reader + +SRC = $(addsuffix .cpp,$(BIN)) +OBJ = $(SRC:%.cpp=$(VDIR)%.o) + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(addsuffix .o,$(FILES)) +SHOBJ = $(addsuffix .so,$(FILES)) + +LIBS = -lACE + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/reader.o .shobj/reader.so: reader.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/DEV_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/DEV_Connector.h \ + $(WRAPPER_ROOT)/ace/DEV_IO.h \ + $(WRAPPER_ROOT)/ace/DEV.h \ + $(WRAPPER_ROOT)/ace/IO_SAP.h \ + $(WRAPPER_ROOT)/ace/IO_SAP.i \ + $(WRAPPER_ROOT)/ace/DEV.i \ + $(WRAPPER_ROOT)/ace/DEV_IO.i \ + $(WRAPPER_ROOT)/ace/DEV_Connector.i \ + $(WRAPPER_ROOT)/ace/TTY_IO.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/IPC_SAP/DEV_SAP/reader/reader.cpp b/examples/IPC_SAP/DEV_SAP/reader/reader.cpp new file mode 100644 index 00000000000..e4ac8f03123 --- /dev/null +++ b/examples/IPC_SAP/DEV_SAP/reader/reader.cpp @@ -0,0 +1,49 @@ +#include "ace/Log_Msg.h" +// @(#)reader.cpp 1.1 10/18/96 + +#include "ace/OS.h" +#include "ace/DEV_Addr.h" +#include "ace/DEV_Connector.h" +#include "ace/DEV_IO.h" +#include "ace/TTY_IO.h" + +int +main (int argc, char *argv[]) +{ + if (argc < 2) + ACE_ERROR_RETURN ((LM_ERROR, "usage: %s device-filename\n", argv[0]), 1); + + ACE_TTY_IO read_dev; + ACE_DEV_Connector con; + + if (con.connect (read_dev, ACE_DEV_Addr (argv[1])) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", argv[1]), 1); + + ACE_TTY_IO::Serial_Params myparams; + myparams.baudrate = 9600; + myparams.parityenb = 1; + myparams.paritymode = "EVEN"; + myparams.databits = 8; + myparams.stopbits = 1; + myparams.readtimeoutmsec = 10000; + myparams.ctsenb = 0; + myparams.rcvenb = 1; + + int ret = read_dev.control (ACE_TTY_IO::SETPARAMS, &myparams); + + if (ret == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p control\n", argv[1]), 1); + + // Read till character 'q'. + for (char readback = 'x'; readback != 'q'; ) + { + ssize_t bytes_read = read_dev.recv_n ((void *) &readback, 1); + + if (bytes_read == 1) + ACE_DEBUG ((LM_DEBUG, "read: %c\n", readback)); + else if (bytes_read == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p recv\n", argv[1]), 1); + } + + return 0; +} diff --git a/examples/IPC_SAP/DEV_SAP/writer/Makefile b/examples/IPC_SAP/DEV_SAP/writer/Makefile new file mode 100644 index 00000000000..dfa8198f829 --- /dev/null +++ b/examples/IPC_SAP/DEV_SAP/writer/Makefile @@ -0,0 +1,71 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the simple DEV writer test file +# for serial devices +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = writer + +SRC = $(addsuffix .cpp,$(BIN)) +OBJ = $(SRC:%.cpp=$(VDIR)%.o) + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(addsuffix .o,$(FILES)) +SHOBJ = $(addsuffix .so,$(FILES)) + +LIBS = -lACE + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/writer.o .shobj/writer.so: writer.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/DEV_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/DEV_Connector.h \ + $(WRAPPER_ROOT)/ace/DEV_IO.h \ + $(WRAPPER_ROOT)/ace/DEV.h \ + $(WRAPPER_ROOT)/ace/IO_SAP.h \ + $(WRAPPER_ROOT)/ace/IO_SAP.i \ + $(WRAPPER_ROOT)/ace/DEV.i \ + $(WRAPPER_ROOT)/ace/DEV_IO.i \ + $(WRAPPER_ROOT)/ace/DEV_Connector.i \ + $(WRAPPER_ROOT)/ace/TTY_IO.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/IPC_SAP/DEV_SAP/writer/writer.cpp b/examples/IPC_SAP/DEV_SAP/writer/writer.cpp new file mode 100644 index 00000000000..97bd26dd1f6 --- /dev/null +++ b/examples/IPC_SAP/DEV_SAP/writer/writer.cpp @@ -0,0 +1,54 @@ +#include "ace/Log_Msg.h" +// @(#)writer.cpp 1.1 10/18/96 + +#include "ace/DEV_Connector.h" +#include "ace/TTY_IO.h" + +int +main (int argc, char *argv[]) +{ + if (argc < 2) + ACE_ERROR_RETURN ((LM_ERROR, "usage: %s device-filename\n", argv[0]), 1); + + ACE_TTY_IO write_dev; + + ACE_DEV_Connector con; + + if (con.connect (write_dev, ACE_DEV_Addr (argv[1])) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", argv[1]), 1); + + ACE_TTY_IO::Serial_Params myparams; + myparams.baudrate = 9600; + myparams.parityenb = 1; + myparams.paritymode = "EVEN"; + myparams.databits = 8; + myparams.stopbits = 1; + myparams.readtimeoutmsec = 200; + myparams.ctsenb = 0; + myparams.rcvenb = 1; + + int ret = write_dev.control (ACE_TTY_IO::SETPARAMS, &myparams); + + if (ret == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "control"), 1); + + ACE_DEBUG ((LM_DEBUG, "enter character to send, q terminates :\n")); + + for (char writeto = 'x'; + ACE_OS::read (ACE_STDIN, &writeto, 1) != -1; + ) + { + ssize_t bytes_written = write_dev.send_n ((void *)&writeto, 1); + + if (bytes_written != 1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), 1); + + if (writeto == 'q') + break; + } + + if (write_dev.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), 1); + + return 0; +} diff --git a/examples/IPC_SAP/FIFO_SAP/FIFO-Msg-client.cpp b/examples/IPC_SAP/FIFO_SAP/FIFO-Msg-client.cpp new file mode 100644 index 00000000000..21fcc849de4 --- /dev/null +++ b/examples/IPC_SAP/FIFO_SAP/FIFO-Msg-client.cpp @@ -0,0 +1,36 @@ +#include "ace/FIFO_Send_Msg.h" +// @(#)FIFO-Msg-client.cpp 1.1 10/18/96 + + +#if defined (ACE_HAS_STREAM_PIPES) + +int +main (int, char *[]) +{ + ACE_FIFO_Send_Msg client (ACE_DEFAULT_RENDEZVOUS); + + char buf[BUFSIZ]; + ACE_Str_Buf msg (buf); + + ACE_OS::srand (unsigned (ACE_OS::time (0))); + + while (ACE_OS::fgets (buf, sizeof buf, stdin) != 0) + { + msg.len = strlen (buf) + 1; + if (client.send (ACE_OS::rand () % 11, &msg) == -1) + ::perror ("send"); + } + + if (client.close () == -1) + ACE_OS::perror ("close"), ACE_OS::exit (1); + + return 0; +} +#else +#include +int main (void) +{ + ACE_OS::fprintf (stderr, "This feature is not supported\n"); + return 0; +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/examples/IPC_SAP/FIFO_SAP/FIFO-Msg-server.cpp b/examples/IPC_SAP/FIFO_SAP/FIFO-Msg-server.cpp new file mode 100644 index 00000000000..f5d50040f81 --- /dev/null +++ b/examples/IPC_SAP/FIFO_SAP/FIFO-Msg-server.cpp @@ -0,0 +1,40 @@ +#include "ace/FIFO_Recv_Msg.h" +// @(#)FIFO-Msg-server.cpp 1.1 10/18/96 + + +#if defined (ACE_HAS_STREAM_PIPES) + +int +main (int, char *[]) +{ + ACE_OS::unlink (ACE_DEFAULT_RENDEZVOUS); + ACE_FIFO_Recv_Msg server (ACE_DEFAULT_RENDEZVOUS); + char buf[BUFSIZ]; + ACE_Str_Buf msg (buf, 0, sizeof buf); + int flags = MSG_ANY; + int band = 0; + int n; + + while ((n = server.recv (&band, &msg, (ACE_Str_Buf *) 0, &flags)) >= 0) + { + if (msg.len == 0) + break; + else + printf ("%4d (%4d): %*s", msg.len, band, msg.len, msg.buf); + flags = MSG_ANY; + band = 0; + } + + if (n == -1) + ACE_OS::perror ("recv"), ACE_OS::exit (1); + + return 0; +} +#else +#include +int main (void) +{ + ACE_OS::fprintf (stderr, "This feature is not supported\n"); + return 0; +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/examples/IPC_SAP/FIFO_SAP/FIFO-client.cpp b/examples/IPC_SAP/FIFO_SAP/FIFO-client.cpp new file mode 100644 index 00000000000..231c7ebac7e --- /dev/null +++ b/examples/IPC_SAP/FIFO_SAP/FIFO-client.cpp @@ -0,0 +1,24 @@ +#include "ace/Log_Msg.h" +// @(#)FIFO-client.cpp 1.1 10/18/96 + +#include "ace/FIFO_Send.h" + +int +main (int, char *[]) +{ + ACE_FIFO_Send client (ACE_DEFAULT_RENDEZVOUS); + char buf[BUFSIZ]; + + while (ACE_OS::fgets (buf, sizeof buf, stdin) != 0) + { + size_t n = ACE_OS::strlen (buf); + + if (client.send (buf, n) != n) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), 1); + } + + if (client.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), 1); + + return 0; +} diff --git a/examples/IPC_SAP/FIFO_SAP/FIFO-server.cpp b/examples/IPC_SAP/FIFO_SAP/FIFO-server.cpp new file mode 100644 index 00000000000..9140b9681fa --- /dev/null +++ b/examples/IPC_SAP/FIFO_SAP/FIFO-server.cpp @@ -0,0 +1,25 @@ +#include "ace/Log_Msg.h" +// @(#)FIFO-server.cpp 1.1 10/18/96 + +#include "ace/FIFO_Recv.h" + +int +main (int, char *[]) +{ + ACE_OS::unlink (ACE_DEFAULT_RENDEZVOUS); + ACE_FIFO_Recv server (ACE_DEFAULT_RENDEZVOUS); + char buf[BUFSIZ]; + int n; + + while ((n = server.recv (buf, sizeof buf)) > 0) + { + ACE_OS::printf ("%4d: ", n); + ACE_OS::fflush (stdout); + ACE_OS::write (ACE_STDOUT, buf, n); + } + + if (n == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv"), 1); + + return 0; +} diff --git a/examples/IPC_SAP/FIFO_SAP/FIFO-test.cpp b/examples/IPC_SAP/FIFO_SAP/FIFO-test.cpp new file mode 100644 index 00000000000..f191f2abe6e --- /dev/null +++ b/examples/IPC_SAP/FIFO_SAP/FIFO-test.cpp @@ -0,0 +1,92 @@ +/* Purpose: This program uses ACE_FIFO wrappers to perform interprocess +// @(#)FIFO-test.cpp 1.1 10/18/96 + + communication between a parent process and a child process. + The parents reads from an input file and writes it into the fifo. + The child reads from the ACE_FIFO and executes the more command. */ + +#include "ace/Log_Msg.h" +#include "ace/FIFO_Recv.h" +#include "ace/FIFO_Send.h" + +#define PERMS 0666 +#define EXEC_NAME "more" +#define EXEC_COMMAND_ARG "more" + +const char *FIFO_NAME = "/tmp/fifo"; + +int +do_child (ACE_FIFO_Recv &fifo_reader) +{ + /* Set child's stdin to read from the fifo */ + if (ACE_OS::close (0) == -1 || ACE_OS::dup (fifo_reader.get_handle ()) == -1) + return -1; + + char *argv[2]; + argv[0] = EXEC_COMMAND_ARG; + argv[1] = 0; + + if (ACE_OS::execvp (EXEC_NAME, argv) == -1) + return -1; +} + +int +do_parent (const char fifo_name[], char input_filename[]) +{ + int inputfd; + ACE_FIFO_Send fifo_sender (fifo_name, O_WRONLY | O_CREAT); + int len; + char buf[BUFSIZ]; + + if (fifo_sender.get_handle () == ACE_INVALID_HANDLE) + return -1; + + if ((inputfd = ACE_OS::open (input_filename, O_RDONLY)) == -1) + return -1; + + /* Read from input file and write into input end of the fifo */ + + while ((len = ACE_OS::read (inputfd, buf, sizeof buf)) > 0) + if (fifo_sender.send (buf, len) != len) + return -1; + + if (len == -1) + return -1; + + if (fifo_sender.remove () == -1) + return -1; + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0]); + + if (argc != 2) + ACE_ERROR ((LM_ERROR, "usage: %n input-file\n%a", 1)); + + ACE_FIFO_Recv fifo_reader (FIFO_NAME, O_RDONLY | O_CREAT, PERMS, 0); + + if (fifo_reader.get_handle () == ACE_INVALID_HANDLE) + return -1; + + pid_t child_pid; + + switch (child_pid = ACE_OS::fork ()) + { + case -1: + ACE_ERROR ((LM_ERROR, "%n: %p\n%a", "fork", 1)); + case 0: + if (do_child (fifo_reader) == -1) + ACE_ERROR ((LM_ERROR, "%n: %p\n%a", "do_child", 1)); + default: + if (do_parent (FIFO_NAME, argv[1]) == -1) + ACE_ERROR ((LM_ERROR, "%n: %p\n%a", "do_parent", 1)); + + if (ACE_OS::waitpid (child_pid, (int *) 0, 0) == -1) /* wait for child to ACE_OS::exit */ + ACE_ERROR ((LM_ERROR, "%n: %p\n%a", "waitpid", 1)); + } + + return 0; +} diff --git a/examples/IPC_SAP/FIFO_SAP/Makefile b/examples/IPC_SAP/FIFO_SAP/Makefile new file mode 100644 index 00000000000..9ee2b323493 --- /dev/null +++ b/examples/IPC_SAP/FIFO_SAP/Makefile @@ -0,0 +1,132 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for simple FIFO test +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = FIFO-Msg-client \ + FIFO-Msg-server \ + FIFO-client \ + FIFO-server \ + FIFO-test + +LSRC = $(addsuffix .cpp,$(BIN)) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/FIFO-Msg-client.o .shobj/FIFO-Msg-client.so: FIFO-Msg-client.cpp \ + $(WRAPPER_ROOT)/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/ace/FIFO.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/ace/FIFO_Send_Msg.i +.obj/FIFO-Msg-server.o .shobj/FIFO-Msg-server.so: FIFO-Msg-server.cpp \ + $(WRAPPER_ROOT)/ace/FIFO_Recv_Msg.h \ + $(WRAPPER_ROOT)/ace/FIFO_Recv.h \ + $(WRAPPER_ROOT)/ace/FIFO.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/FIFO_Recv.i \ + $(WRAPPER_ROOT)/ace/FIFO_Recv_Msg.i +.obj/FIFO-client.o .shobj/FIFO-client.so: FIFO-client.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/ace/FIFO.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/FIFO_Send.i +.obj/FIFO-server.o .shobj/FIFO-server.so: FIFO-server.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/FIFO_Recv.h \ + $(WRAPPER_ROOT)/ace/FIFO.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/FIFO_Recv.i +.obj/FIFO-test.o .shobj/FIFO-test.so: FIFO-test.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/FIFO_Recv.h \ + $(WRAPPER_ROOT)/ace/FIFO.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/FIFO_Recv.i \ + $(WRAPPER_ROOT)/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/ace/FIFO_Send.i + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/IPC_SAP/FILE_SAP/Makefile b/examples/IPC_SAP/FILE_SAP/Makefile new file mode 100644 index 00000000000..cf0a6764be7 --- /dev/null +++ b/examples/IPC_SAP/FILE_SAP/Makefile @@ -0,0 +1,62 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the simple file test +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = client + +LSRC = $(addsuffix .cpp,$(BIN)) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/client.o .shobj/client.so: client.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/FILE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/FILE_Connector.h \ + $(WRAPPER_ROOT)/ace/FILE_IO.h \ + $(WRAPPER_ROOT)/ace/FILE.h \ + $(WRAPPER_ROOT)/ace/IO_SAP.h \ + $(WRAPPER_ROOT)/ace/IO_SAP.i \ + $(WRAPPER_ROOT)/ace/FILE.i \ + $(WRAPPER_ROOT)/ace/FILE_IO.i \ + $(WRAPPER_ROOT)/ace/FILE_Connector.i + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/IPC_SAP/FILE_SAP/client.cpp b/examples/IPC_SAP/FILE_SAP/client.cpp new file mode 100644 index 00000000000..ba8edaf4827 --- /dev/null +++ b/examples/IPC_SAP/FILE_SAP/client.cpp @@ -0,0 +1,57 @@ +#include "ace/OS.h" +// @(#)client.cpp 1.1 10/18/96 + +#include "ace/Log_Msg.h" +#include "ace/FILE_Addr.h" +#include "ace/FILE_Connector.h" +#include "ace/FILE_IO.h" + +int +main (int argc, char *argv[]) +{ + if (argc < 2) + ACE_ERROR_RETURN ((LM_ERROR, "usage: %s filename string\n", argv[0]), 1); + + char *readback = new char[::strlen (argv[1]) + 1]; + + ACE_FILE_Info fileinfo; + ACE_FILE_IO cli_file; + ACE_FILE_Connector con; + + if (con.connect (cli_file, ACE_FILE_Addr (argv[1]), + 0, ACE_Addr::sap_any, 0, + O_RDWR|O_APPEND|O_CREAT, 0666) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n to %s", "connect", argv[1]), -1); + + size_t len = ACE_OS::strlen (argv[2]) + 1; + + if (cli_file.send (argv[2], len) != len) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), 1); + + if (cli_file.get_info (&fileinfo) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "get_info"), 1); + else + cout << "fileinfo : mode = " << (fileinfo.mode_ & 777) + << "\nno of links = " << fileinfo.nlink_ + << "\nsize = " << fileinfo.size_ << endl; + + off_t fpos = cli_file.position (); + + if (fpos == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "position"), 1); + else + cout << "current filepointer is at " << fpos << endl; + + if (cli_file.position (0, SEEK_SET) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "position"), 1); + + if (cli_file.recv (readback, len) != len) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv"), 1); + + cout << "read back :" << readback << endl; + + if (cli_file.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), 1); + + return 0; +} diff --git a/examples/IPC_SAP/FILE_SAP/testfile b/examples/IPC_SAP/FILE_SAP/testfile new file mode 100644 index 00000000000..e7cbb71a0d5 --- /dev/null +++ b/examples/IPC_SAP/FILE_SAP/testfile @@ -0,0 +1 @@ +testfile \ No newline at end of file diff --git a/examples/IPC_SAP/Makefile b/examples/IPC_SAP/Makefile new file mode 100644 index 00000000000..8414b8c6201 --- /dev/null +++ b/examples/IPC_SAP/Makefile @@ -0,0 +1,27 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the IPC_SAP test directory +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +DIRS = DEV_SAP \ + FIFO_SAP \ + FILE_SAP \ + SOCK_SAP \ + SPIPE_SAP \ + TLI_SAP \ + UPIPE_SAP + +#---------------------------------------------------------------------------- +# macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU diff --git a/examples/IPC_SAP/SOCK_SAP/C-inclient.cpp b/examples/IPC_SAP/SOCK_SAP/C-inclient.cpp new file mode 100644 index 00000000000..1555e3b8059 --- /dev/null +++ b/examples/IPC_SAP/SOCK_SAP/C-inclient.cpp @@ -0,0 +1,60 @@ +#include "ace/OS.h" +// @(#)C-inclient.cpp 1.1 10/18/96 + + +/* BSD socket client */ + +int +main (int argc, char *argv[]) +{ + // Initialize WinSock DLL on Win32... + ACE_OS::socket_init (ACE_WSOCK_VERSION); + + struct sockaddr_in saddr; + struct hostent *hp; + char *host = argc > 1 ? argv[1] : ACE_DEFAULT_SERVER_HOST; + u_short port_num = + htons (argc > 2 ? atoi (argv[2]) : ACE_DEFAULT_SERVER_PORT); + char buf[BUFSIZ]; + ACE_HANDLE s_handle; + int w_bytes; + int r_bytes; + int n; + + /* Create a local endpoint of communication */ + if ((s_handle = ACE_OS::socket (PF_INET, SOCK_STREAM, 0)) == ACE_INVALID_HANDLE) + ACE_OS::perror ("socket"), ACE_OS::exit (1); + + /* Determine IP address of the server */ + if ((hp = ACE_OS::gethostbyname (host)) == 0) + ACE_OS::perror ("gethostbyname"), ACE_OS::exit (1); + + /* Set up the address information to contact the server */ + ACE_OS::memset ((void *) &saddr, 0, sizeof saddr); + saddr.sin_family = AF_INET; + saddr.sin_port = port_num; + ACE_OS::memcpy (&saddr.sin_addr, hp->h_addr, hp->h_length); + + /* Establish connection with remote server */ + if (ACE_OS::connect (s_handle, (struct sockaddr *) &saddr, + sizeof saddr) == -1) + ACE_OS::perror ("connect"), ACE_OS::exit (1); + + /* Send data to server (correctly handles + "incomplete writes" due to flow control) */ + + while ((r_bytes = ACE_OS::read (ACE_STDIN, buf, sizeof buf)) > 0) + for (w_bytes = 0; w_bytes < r_bytes; w_bytes += n) + if ((n = ACE_OS::send (s_handle, buf + w_bytes, + r_bytes - w_bytes)) < 0) + ACE_OS::perror ("write"), ACE_OS::exit (1); + + if (ACE_OS::recv (s_handle, buf, 1) == 1) + ACE_OS::write (ACE_STDOUT, buf, 1); + + /* Explicitly close the connection */ + if (ACE_OS::closesocket (s_handle) == -1) + ACE_OS::perror ("close"), ACE_OS::exit (1); + + return 0; +} diff --git a/examples/IPC_SAP/SOCK_SAP/C-inserver.cpp b/examples/IPC_SAP/SOCK_SAP/C-inserver.cpp new file mode 100644 index 00000000000..1d35f654a45 --- /dev/null +++ b/examples/IPC_SAP/SOCK_SAP/C-inserver.cpp @@ -0,0 +1,84 @@ +#include "ace/OS.h" +// @(#)C-inserver.cpp 1.1 10/18/96 + + +/* BSD socket server. */ + +int main (int argc, char *argv[]) +{ + // Initialize WinSock DLL on Win32... + ACE_OS::socket_init (ACE_WSOCK_VERSION); + + u_short port_num = + htons (argc > 1 ? ACE_OS::atoi (argv[1]) : ACE_DEFAULT_SERVER_PORT); + struct sockaddr_in saddr; + ACE_HANDLE s_handle, n_handle; + + /* Create a local endpoint of communication */ + if ((s_handle = ACE_OS::socket (PF_INET, SOCK_STREAM, 0)) == ACE_INVALID_HANDLE) + ACE_OS::perror ("socket"), ACE_OS::exit (1); + + /* Set up the address information to become a server */ + ACE_OS::memset ((void *) &saddr, 0, sizeof saddr); + saddr.sin_family = AF_INET; + saddr.sin_port = port_num; + saddr.sin_addr.s_addr = INADDR_ANY; + + /* Associate address with endpoint */ + if (ACE_OS::bind (s_handle, (struct sockaddr *) &saddr, + sizeof saddr) == -1) + ACE_OS::perror ("bind"), ACE_OS::exit (1); + + /* Make endpoint listen for service requests */ + if (ACE_OS::listen (s_handle, 5) == -1) + ACE_OS::perror ("listen"), ACE_OS::exit (1); + + /* Performs the iterative server activities */ + + for (;;) + { + char buf[BUFSIZ]; + int r_bytes; + struct sockaddr_in cli_addr; + int cli_addr_len = sizeof cli_addr; + struct hostent *hp; + + /* Create a new endpoint of communication */ + do + n_handle = ACE_OS::accept (s_handle, (struct sockaddr *) + &cli_addr, &cli_addr_len); + while (n_handle == ACE_INVALID_HANDLE && errno == EINTR); + + if (n_handle == ACE_INVALID_HANDLE) + { + ACE_OS::perror ("accept"); + continue; + } + + int addr_len = sizeof cli_addr.sin_addr.s_addr; + hp = ACE_OS::gethostbyaddr ((char *) &cli_addr.sin_addr, + addr_len, AF_INET); + + if (hp != 0) + ACE_OS::printf ("client %s\n", hp->h_name), ACE_OS::fflush (stdout); + else + ACE_OS::perror ("gethostbyaddr"); + + /* Read data from client (terminate on error) */ + + while ((r_bytes = ACE_OS::recv (n_handle, buf, sizeof buf)) > 0) + if (ACE_OS::write (ACE_STDOUT, buf, r_bytes) != r_bytes) + ACE_OS::perror ("write"), ACE_OS::exit (1); + + if (ACE_OS::send (n_handle, "", 1) != 1) + ::perror ("write"), ACE_OS::exit (1); + + /* Close the new endpoint + (listening endpoint remains open) */ + if (ACE_OS::closesocket (n_handle) == -1) + ACE_OS::perror ("close"), ACE_OS::exit (1); + ACE_OS::exit (0); + } + /* NOTREACHED */ + return 0; +} diff --git a/examples/IPC_SAP/SOCK_SAP/CPP-inclient.cpp b/examples/IPC_SAP/SOCK_SAP/CPP-inclient.cpp new file mode 100644 index 00000000000..249d345fb38 --- /dev/null +++ b/examples/IPC_SAP/SOCK_SAP/CPP-inclient.cpp @@ -0,0 +1,73 @@ +// This tests the non-blocking features of the ACE_SOCK_Connector class. +// @(#)CPP-inclient.cpp 1.1 10/18/96 + + +#include "ace/Log_Msg.h" +#include "ace/SOCK_Connector.h" +#include "ace/INET_Addr.h" + +// ACE SOCK_SAP client. + +int main (int argc, char *argv[]) +{ + char *host = argc > 1 ? argv[1] : ACE_DEFAULT_SERVER_HOST; + u_short r_port = argc > 2 ? ACE_OS::atoi (argv[2]) : ACE_DEFAULT_SERVER_PORT; + int timeout = argc > 3 ? ACE_OS::atoi (argv[3]) : ACE_DEFAULT_TIMEOUT; + u_short l_port = argc > 4 ? ACE_OS::atoi (argv[4]) : ACE_DEFAULT_LOCAL_PORT; + char buf[BUFSIZ]; + + ACE_SOCK_Stream cli_stream; + ACE_INET_Addr remote_addr (r_port, host); + ACE_INET_Addr local_addr (l_port); + + ACE_DEBUG ((LM_DEBUG, "starting non-blocking connect\n")); + // Initiate timed, non-blocking connection with server. + ACE_SOCK_Connector con; + + // Attempt a non-blocking connect to the server, reusing the local + // addr if necessary. + if (con.connect (cli_stream, remote_addr, + (ACE_Time_Value *) &ACE_Time_Value::zero, + local_addr, 1) == -1) + { + if (errno != EWOULDBLOCK) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "connection failed"), 1); + + ACE_DEBUG ((LM_DEBUG, "starting timed connect\n")); + + // Check if non-blocking connection is in progress, + // and wait up to timeout seconds for it to complete. + ACE_Time_Value tv (timeout); + + if (con.complete (cli_stream, &remote_addr, &tv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "connection failed"), 1); + else + ACE_DEBUG ((LM_DEBUG, "connected to %s\n", remote_addr.get_host_name ())); + } + + if (cli_stream.disable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "disable"), 1); + + // Send data to server (correctly handles "incomplete writes"). + + for (ssize_t r_bytes; + (r_bytes = ACE_OS::read (ACE_STDIN, buf, sizeof buf)) > 0; ) + if (ACE_OS::strcmp (buf, "quit\n") == 0) + break; + else if (cli_stream.send_n (buf, r_bytes) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send_n"), 1); + + // Explicitly close the writer-side of the connection. + if (cli_stream.close_writer () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close_writer"), 1); + + // Wait for handshake with server. + if (cli_stream.recv_n (buf, 1) != 1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv_n"), 1); + + // Close the connection completely. + if (cli_stream.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), 1); + + return 0; +} diff --git a/examples/IPC_SAP/SOCK_SAP/CPP-inserver-poll.cpp b/examples/IPC_SAP/SOCK_SAP/CPP-inserver-poll.cpp new file mode 100644 index 00000000000..ccd164be11a --- /dev/null +++ b/examples/IPC_SAP/SOCK_SAP/CPP-inserver-poll.cpp @@ -0,0 +1,101 @@ +// IPC_SAP/poll server, which illustrates how to integrate the ACE +// @(#)CPP-inserver-poll.cpp 1.1 10/18/96 + +// socket wrappers with the SVR4 poll() system call to create a +// single-threaded concurrent server. + +#include "ace/SOCK_Acceptor.h" +#include "ace/SOCK_Stream.h" +#include "ace/INET_Addr.h" + +#if defined (ACE_HAS_SVR4_POLL) + +// Maximum per-process open I/O descriptors. +const int MAX_FDS = 200; + +int +main (void) +{ + // Create a server end-point. + ACE_INET_Addr addr (ACE_DEFAULT_SERVER_PORT); + ACE_SOCK_Acceptor peer_acceptor (addr); + ACE_SOCK_Stream new_stream; + ACE_HANDLE s_handle = peer_acceptor.get_handle (); + struct pollfd poll_array[MAX_FDS]; + + for (int i = 0; i < MAX_FDS; i++) + { + poll_array[i].fd = ACE::INVALID_HANDLE; + poll_array[i].events = POLLIN; + } + + poll_array[0].fd = s_handle; + + for (int n_handles = 1;;) + { + // Wait for client I/O events (handle interrupts). + while (ACE_OS::poll (poll_array, n_handles) == -1 + && errno == EINTR) + continue; + + // Handle pending logging messages first (s_handle + 1 is + // guaranteed to be lowest client descriptor). + + for (i = 1; i < n_handles; i++) + { + if (poll_array[i].revents & POLLIN) + { + char buf[BUFSIZ]; + int n; + // recv will not block in this case! + if ((n = ACE_OS::recv (poll_array[i].fd, buf, sizeof buf, 0)) == -1) + ACE_OS::perror ("read failed"); + else if (n == 0) + { + // Handle client connection shutdown. + if (ACE_OS::close (poll_array[i].fd) == -1) + ACE_OS::perror ("close"); + poll_array[i].fd = poll_array[--n_handles].fd; + + // Send handshake back to client to unblock it. + if (ACE_OS::send (poll_array[i].fd, "", 1) != 1) + ACE_ERROR ((LM_ERROR, "%p\n", "send_n")); + } + else + ACE_OS::printf ("%*s", n, buf), fflush (stdout); + } + ACE_OS::fflush (stdout); + } + if (poll_array[0].revents & POLLIN) + { + ACE_INET_Addr client; + ACE_Time_Value nonblock (0, 0); + + // Handle all pending connection requests (note use of + // "polling" feature that doesn't block). + + while (ACE_OS::poll (poll_array, 1, nonblock) > 0) + if (peer_acceptor.accept (new_stream, &client) == -1) + ACE_OS::perror ("accept"); + else + { + const char *s = client.get_host_name (); + + ACE_ASSERT (s != 0); + ACE_OS::printf ("client %s\n", s); + ACE_OS::fflush (stdout); + poll_array[n_handles++].fd = new_stream.get_handle (); + } + } + } + /* NOTREACHED */ + return 0; +} +#else +#include +int main (void) +{ + ACE_OS::fprintf (stderr, "This feature is not supported\n"); + return 0; +} +#endif /* ACE_HAS_SVR4_POLL */ diff --git a/examples/IPC_SAP/SOCK_SAP/CPP-inserver.cpp b/examples/IPC_SAP/SOCK_SAP/CPP-inserver.cpp new file mode 100644 index 00000000000..fefeb39fdeb --- /dev/null +++ b/examples/IPC_SAP/SOCK_SAP/CPP-inserver.cpp @@ -0,0 +1,136 @@ +// This example tests the non-blocking features of the +// @(#)CPP-inserver.cpp 1.1 10/18/96 + +// ACE_SOCK_Acceptor and ACE_SOCK_Stream classes. + +#include "ace/Log_Msg.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/SOCK_Stream.h" +#include "ace/INET_Addr.h" +#include "ace/Handle_Set.h" + +// ACE SOCK_SAP server. + +int +main (int argc, char *argv[]) +{ + u_short port = argc > 1 + ? ACE_OS::atoi (argv[1]) + : ACE_DEFAULT_SERVER_PORT; + ACE_Time_Value timeout (argc > 2 + ? ACE_OS::atoi (argv[2]) + : ACE_DEFAULT_TIMEOUT); + + ACE_SOCK_Acceptor peer_acceptor; + + // Create a server address. + ACE_INET_Addr server_addr (port); + + // Create a server, reuse the address. + if (peer_acceptor.open (server_addr, 1) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), 1); + // Set the peer acceptor into non-blocking mode. + else if (peer_acceptor.enable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "enable"), 1); + else if (peer_acceptor.get_local_addr (server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "get_local_addr"), 1); + + ACE_DEBUG ((LM_DEBUG, "starting server at port %d\n", + server_addr.get_port_number ())); + + // Keep these objects out here to prevent excessive constructor + // calls within the loop. + ACE_SOCK_Stream new_stream; + ACE_INET_Addr cli_addr; + ACE_Handle_Set handle_set; + + // Performs the iterative server activities. + + for (;;) + { + char buf[BUFSIZ]; + + handle_set.reset (); + handle_set.set_bit (peer_acceptor.get_handle ()); + + int result = ACE_OS::select (int (peer_acceptor.get_handle ()) + 1, + handle_set, + 0, 0, &timeout); + if (result == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "select"), -1); + else if (result == 0) + ACE_DEBUG ((LM_DEBUG, "select timed out\n")); + else + { + // Create a new ACE_SOCK_Stream endpoint (note automatic restart + // if errno == EINTR). + + while ((result = peer_acceptor.accept (new_stream, &cli_addr)) != -1) + { + ACE_DEBUG ((LM_DEBUG, "client %s connected from %d\n", + cli_addr.get_host_name (), cli_addr.get_port_number ())); + + // Enable non-blocking I/O. + if (new_stream.enable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "enable"), -1); + + handle_set.reset (); + handle_set.set_bit (new_stream.get_handle ()); + + // Read data from client (terminate on error). + + for (ssize_t r_bytes;;) + { + if (ACE_OS::select (int (new_stream.get_handle ()) + 1, + handle_set, + 0, 0, 0) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "select"), -1); + + for (;;) + { + r_bytes = new_stream.recv (buf, sizeof buf); + + if (r_bytes <= 0) + break; + else if (ACE::write_n (ACE_STDOUT, buf, r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE::send_n")); + } + + if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, + "reached end of input, connection closed by client\n")); + + // Send handshake back to client to unblock it. + if (new_stream.send_n ("", 1) != 1) + ACE_ERROR ((LM_ERROR, "%p\n", "send_n")); + break; + } + else if (r_bytes == -1) + { + if (errno == EWOULDBLOCK) + ACE_DEBUG ((LM_DEBUG, + "no input available, going back to reading\n")); + else + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv"), -1); + } + } + + // Close new endpoint (listening endpoint stays open). + if (new_stream.close () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "close")); + } + + if (result == -1) + { + if (errno == EWOULDBLOCK) + ACE_DEBUG ((LM_DEBUG, + "no connections available, going back to accepting\n")); + else + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ACE::write"), -1); + } + } + } + /* NOTREACHED */ + return 0; +} diff --git a/examples/IPC_SAP/SOCK_SAP/CPP-unclient.cpp b/examples/IPC_SAP/SOCK_SAP/CPP-unclient.cpp new file mode 100644 index 00000000000..abd3ad87a50 --- /dev/null +++ b/examples/IPC_SAP/SOCK_SAP/CPP-unclient.cpp @@ -0,0 +1,50 @@ +/* ACE_LSOCK Client */ +// @(#)CPP-unclient.cpp 1.1 10/18/96 + + +#include "ace/Log_Msg.h" +#include "ace/LSOCK_Connector.h" +#include "ace/UNIX_Addr.h" + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +int +main (int argc, char *argv[]) +{ + char *rendezvous = argc > 1 ? argv[1] : ACE_DEFAULT_RENDEZVOUS; + char buf[BUFSIZ]; + + ACE_LSOCK_Stream cli_stream; + ACE_LSOCK_Connector con; + + /* Establish the connection with server */ + if (con.connect (cli_stream, ACE_UNIX_Addr (rendezvous)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "connect"), 1); + + /* Send data to server (correctly handles "incomplete writes") */ + + for (int r_bytes; (r_bytes = ACE_OS::read (ACE_STDIN, buf, sizeof buf)) > 0; ) + if (cli_stream.send_n (buf, r_bytes) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send_n"), 1); + + /* Explicitly close the writer-side of the connection. */ + if (cli_stream.close_writer () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close_writer"), 1); + + /* Wait for handshake with server. */ + if (cli_stream.recv_n (buf, 1) != 1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv_n"), 1); + + /* Close the connection completely. */ + if (cli_stream.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), 1); + + return 0; +} +#else +int main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "this platform does not support UNIX-domain sockets\n"), -1); +} +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ diff --git a/examples/IPC_SAP/SOCK_SAP/CPP-unserver.cpp b/examples/IPC_SAP/SOCK_SAP/CPP-unserver.cpp new file mode 100644 index 00000000000..d1455090e76 --- /dev/null +++ b/examples/IPC_SAP/SOCK_SAP/CPP-unserver.cpp @@ -0,0 +1,78 @@ +/* ACE_LSOCK Server */ +// @(#)CPP-unserver.cpp 1.1 10/18/96 + + +#include "ace/Log_Msg.h" +#include "ace/LSOCK_Acceptor.h" +#include "ace/LSOCK_Stream.h" +#include "ace/UNIX_Addr.h" + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +int +main (int argc, char *argv[]) +{ + char *rendezvous = argc > 1 ? argv[1] : ACE_DEFAULT_RENDEZVOUS; + + /* Create a server address. */ + ACE_UNIX_Addr server_addr (rendezvous); + + ACE_LSOCK_Acceptor peer_acceptor; + + /* Create a server */ + + if (peer_acceptor.open (server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), 1); + + /* Keep these guys out here to prevent excessive constructor + calls... */ + ACE_LSOCK_Stream new_stream; + ACE_UNIX_Addr cli_addr; + + ACE_DEBUG ((LM_DEBUG, "starting server %s\n", + server_addr.get_path_name ())); + + /* Performs the iterative server activities */ + + for (;;) + { + char buf[BUFSIZ]; + ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT); + + /* Create a new ACE_SOCK_Stream endpoint (note + automatic restart if errno == EINTR) */ + + if (peer_acceptor.accept (new_stream, &cli_addr, &timeout) == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "accept")); + continue; + } + + ACE_DEBUG ((LM_DEBUG, "client %s\n", + cli_addr.get_path_name ())); + + /* Read data from client (terminate on error) */ + + for (int r_bytes; + (r_bytes = new_stream.recv (buf, sizeof buf)) > 0; ) + if (ACE_OS::write (ACE_STDOUT, buf, r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE::send_n")); + + if (new_stream.send_n ("", 1) != 1) + ACE_ERROR ((LM_ERROR, "%p\n", "send_n")); + + /* Close new endpoint (listening endpoint stays open) */ + if (new_stream.close () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "close")); + } + + /* NOTREACHED */ + return 0; +} +#else +int main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "this platform does not support UNIX-domain sockets\n"), -1); +} +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ diff --git a/examples/IPC_SAP/SOCK_SAP/FD-unclient.cpp b/examples/IPC_SAP/SOCK_SAP/FD-unclient.cpp new file mode 100644 index 00000000000..ed026d9e53c --- /dev/null +++ b/examples/IPC_SAP/SOCK_SAP/FD-unclient.cpp @@ -0,0 +1,51 @@ +#include "ace/LSOCK_Connector.h" +// @(#)FD-unclient.cpp 1.1 10/18/96 + +#include "ace/UNIX_Addr.h" + +#if defined (ACE_HAS_MSG) && !defined (ACE_HAS_UNIX_DOMAIN_SOCKETS) +// ACE_LSOCK Client. + +int +main (int argc, char *argv[]) +{ + char *file_name = argc > 1 ? argv[1] : "./local_data"; + char *send_str = argc > 2 ? argv[2] : "hello world"; + char *rendezvous = argc > 3 ? argv[3] : ACE_DEFAULT_RENDEZVOUS; + int fd; + int n; + char buf[BUFSIZ]; + + ACE_LSOCK_Stream cli_stream; + ACE_UNIX_Addr addr (rendezvous); + + /* Establish the connection with server */ + ACE_LSOCK_Connector connector; + + if (connector.connect (cli_stream, addr) == -1) + ACE_OS::perror ("connect"), ACE_OS::exit (1); + + if ((fd = ACE_OS::open (file_name, O_RDONLY)) == -1) + ACE_OS::perror ("open"), ACE_OS::exit (1); + + /* Send data to server (correctly handles incomplete writes) */ + if (cli_stream.send_handle (fd) == -1) + ACE_OS::perror ("send"), ACE_OS::exit (1); + + if ((n = cli_stream.recv_n (buf, sizeof buf)) == -1) + ACE_OS::perror ("recv"), ACE_OS::exit (1); + else + ACE_OS::write (ACE_STDOUT, buf, n); + + /* Explicitly close the connection */ + if (cli_stream.close () == -1) + ACE_OS::perror ("close"), ACE_OS::exit (1); + + return 0; +} +#else +int main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "your platform must support sendmsg/recvmsg to run this test\n"), -1); +} +#endif /* ACE_HAS_MSG */ diff --git a/examples/IPC_SAP/SOCK_SAP/FD-unserver.cpp b/examples/IPC_SAP/SOCK_SAP/FD-unserver.cpp new file mode 100644 index 00000000000..4d988ba9253 --- /dev/null +++ b/examples/IPC_SAP/SOCK_SAP/FD-unserver.cpp @@ -0,0 +1,60 @@ +#include "ace/LSOCK_Acceptor.h" +// @(#)FD-unserver.cpp 1.1 10/18/96 + +#include "ace/LSOCK_Stream.h" +#include "ace/UNIX_Addr.h" + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +/* ACE_SOCK Server */ + +int +main (int argc, char *argv[]) +{ + char *rendezvous = argc > 1 ? argv[1] : ACE_DEFAULT_RENDEZVOUS; + /* Create a server */ + ACE_OS::unlink (rendezvous); + ACE_UNIX_Addr addr (rendezvous); + ACE_LSOCK_Acceptor peer_acceptor (addr); + ACE_LSOCK_Stream new_stream; + + /* Performs the iterative server activities */ + + for (;;) + { + char buf[BUFSIZ]; + int fd; + + /* Create a new ACE_SOCK_Stream endpoint */ + if (peer_acceptor.accept (new_stream) == -1) + ACE_OS::perror ("accept"); + + /* Read data from client (correctly handles incomplete reads due to flow control) */ + + if (new_stream.recv_handle (fd) == -1) + ::perror ("recv_handle"), ACE_OS::exit (1); + + ACE_OS::puts ("----------------------------------------"); + + for (int n; (n = ACE_OS::read (fd, buf, sizeof buf)) > 0; ) + ::write (1, buf, n); + + ACE_OS::puts ("----------------------------------------"); + + if (new_stream.send ("yow", 3) == -1) + ::perror ("send"), ACE_OS::exit (1); + + /* Close new endpoint (listening endpoint stays open) */ + if (new_stream.close () == -1) + ACE_OS::perror ("close"); + } + /* NOTREACHED */ + return 0; +} +#else +int +main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "your platform doesn't not support UNIX domain sockets\n"), -1); +} +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ diff --git a/examples/IPC_SAP/SOCK_SAP/Makefile b/examples/IPC_SAP/SOCK_SAP/Makefile new file mode 100644 index 00000000000..604ff0da614 --- /dev/null +++ b/examples/IPC_SAP/SOCK_SAP/Makefile @@ -0,0 +1,246 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for IPC_SAP test +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +INFO = README + +BIN = CPP-inclient \ + CPP-unclient \ + CPP-inserver \ + CPP-inserver-poll \ + CPP-unserver \ + FD-unclient \ + FD-unserver \ + C-inclient \ + C-inserver + +LSRC = $(addsuffix .cpp,$(BIN)) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/CPP-inclient.o .shobj/CPP-inclient.so: CPP-inclient.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i +.obj/CPP-unclient.o .shobj/CPP-unclient.so: CPP-unclient.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/LSOCK.h \ + $(WRAPPER_ROOT)/ace/LSOCK.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/UNIX_Addr.h \ + $(WRAPPER_ROOT)/ace/LSOCK_Connector.i +.obj/CPP-inserver.o .shobj/CPP-inserver.so: CPP-inserver.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Handle_Set.h +.obj/CPP-inserver-poll.o .shobj/CPP-inserver-poll.so: CPP-inserver-poll.cpp \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i +.obj/CPP-unserver.o .shobj/CPP-unserver.so: CPP-unserver.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/UNIX_Addr.h \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/LSOCK.h \ + $(WRAPPER_ROOT)/ace/LSOCK.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.i +.obj/FD-unclient.o .shobj/FD-unclient.so: FD-unclient.cpp \ + $(WRAPPER_ROOT)/ace/LSOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/LSOCK.h \ + $(WRAPPER_ROOT)/ace/LSOCK.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/UNIX_Addr.h \ + $(WRAPPER_ROOT)/ace/LSOCK_Connector.i +.obj/FD-unserver.o .shobj/FD-unserver.so: FD-unserver.cpp \ + $(WRAPPER_ROOT)/ace/LSOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/UNIX_Addr.h \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/LSOCK.h \ + $(WRAPPER_ROOT)/ace/LSOCK.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.i +.obj/C-inclient.o .shobj/C-inclient.so: C-inclient.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h +.obj/C-inserver.o .shobj/C-inserver.so: C-inserver.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/IPC_SAP/SOCK_SAP/README b/examples/IPC_SAP/SOCK_SAP/README new file mode 100644 index 00000000000..3155575ddb1 --- /dev/null +++ b/examples/IPC_SAP/SOCK_SAP/README @@ -0,0 +1,35 @@ +This directory contains groups of client and server test programs that +exercise the various C++ wrappers for sockets. In general, the test +programs do more or less the same thing -- they transfer data from +client to the server. Unless noted differently, the server is +implemented as an "iterative server," i.e., it only deals with one +client at a time. The following describes each set of tests in more +detail: + + . C-inclient.cpp/C-inserver.cpp -- This is basically a C code + implementation that opens a connection to the server and + sends all the data from the stdin using Internet domain + sockets (i.e., TCP). + + . CPP-inclient.cpp/CPP-server.cpp -- This test is basically + a C++ wrapper version of the preceeding "C" test using + Internet domain sockets (i.e., TCP). + + . CPP-unclient.cpp/CPP-unserver.cpp -- This test is basically + a C++ wrapper version of the preceeding "C++" test using + UNIX domain sockets. + + . FD-unclient.cpp/FD-inclient.cpp -- This test illustrates + how to pass file descriptors between two processes on the + same machine using the ACE C++ wrappers for UNIX domain + sockets. + + . CPP-inserver-poll.cpp -- This test illustrates how to + write single-threaded concurrent servers using UNIX SVR4 + poll(). You can run this test using the CPP-inclient.cpp + program as the client. + +For examples of the ACE SOCK_{Dgram,CODgram} and +SOCK_Dgram_{Mcast,Bcast} wrappers, please take a look in the +./examples/Reactor/{Dgram,Multicast,Ntalker} directories. + diff --git a/examples/IPC_SAP/SOCK_SAP/local_data b/examples/IPC_SAP/SOCK_SAP/local_data new file mode 100644 index 00000000000..c0119859a28 --- /dev/null +++ b/examples/IPC_SAP/SOCK_SAP/local_data @@ -0,0 +1 @@ +I am Iron man! diff --git a/examples/IPC_SAP/SPIPE_SAP/Makefile b/examples/IPC_SAP/SPIPE_SAP/Makefile new file mode 100644 index 00000000000..10d79cb2a7a --- /dev/null +++ b/examples/IPC_SAP/SPIPE_SAP/Makefile @@ -0,0 +1,218 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the simple STREAM pipe client/server test file +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = client \ + server \ + consumer_msg \ + consumer_read \ + producer_msg \ + producer_read \ + NPClient \ + NPServer + +LSRC = $(addsuffix .cpp,$(BIN)) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/client.o .shobj/client.so: client.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Connector.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Connector.i \ + shared.h +.obj/server.o .shobj/server.so: server.cpp \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + shared.h +.obj/consumer_msg.o .shobj/consumer_msg.so: consumer_msg.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + shared.h +.obj/consumer_read.o .shobj/consumer_read.so: consumer_read.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + shared.h +.obj/producer_msg.o .shobj/producer_msg.so: producer_msg.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Connector.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Connector.i \ + shared.h +.obj/producer_read.o .shobj/producer_read.so: producer_read.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Connector.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Connector.i \ + shared.h +.obj/NPClient.o .shobj/NPClient.so: NPClient.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Connector.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Connector.i +.obj/NPServer.o .shobj/NPServer.so: NPServer.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/IPC_SAP/SPIPE_SAP/NPClient.cpp b/examples/IPC_SAP/SPIPE_SAP/NPClient.cpp new file mode 100644 index 00000000000..552d462367b --- /dev/null +++ b/examples/IPC_SAP/SPIPE_SAP/NPClient.cpp @@ -0,0 +1,46 @@ +#include "ace/Log_Msg.h" +// @(#)NPClient.cpp 1.1 10/18/96 + +#include "ace/SPIPE_Addr.h" +#include "ace/SPIPE_Connector.h" + +#if defined (ACE_WIN32) +#define MAKE_PIPE_NAME(X) \\\\.\\pipe\\#X +#else +#define MAKE_PIPE_NAME(X) X +#endif + +const int DEFAULT_SIZE = 8; +const int DEFAULT_COUNT = 10000; + +int +main (int argc, char *argv[]) +{ + int size = argc > 1 ? atoi (argv[1]) : DEFAULT_SIZE; + int iterations = argc > 2 ? atoi (argv[2]) : DEFAULT_COUNT; + char *buf = new char[size]; + + //char *pipe_name = ACE_DEFAULT_RENDEZVOUS; + char *pipe_name = "acepipe"; + char *rendezvous; + rendezvous = MAKE_PIPE_NAME (pipe_name); + + ACE_SPIPE_Stream cli_stream; + ACE_SPIPE_Connector con; + int i; + + if (con.connect (cli_stream, ACE_SPIPE_Addr (rendezvous)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", rendezvous), -1); + + ACE_OS::strcpy (buf, "hello"); + size = ACE_OS::strlen (buf) + 1; + + for (i = 0; i < iterations; i++) + if (cli_stream.send (buf, size) != size) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "putmsg"), -1); + + if (cli_stream.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), -1); + + return 0; +} diff --git a/examples/IPC_SAP/SPIPE_SAP/NPServer.cpp b/examples/IPC_SAP/SPIPE_SAP/NPServer.cpp new file mode 100644 index 00000000000..eb4be9451a7 --- /dev/null +++ b/examples/IPC_SAP/SPIPE_SAP/NPServer.cpp @@ -0,0 +1,54 @@ +#include "ace/Log_Msg.h" +// @(#)NPServer.cpp 1.1 10/18/96 + +#include "ace/SPIPE_Addr.h" +#include "ace/Time_Value.h" +#include "ace/SPIPE_Acceptor.h" + +#if defined (ACE_WIN32) +#define MAKE_PIPE_NAME(X) \\\\.\\pipe\\#X +#else +#define MAKE_PIPE_NAME(X) X +#endif + +int +main (int argc, char *argv[]) +{ + ACE_SPIPE_Acceptor acceptor; + ACE_SPIPE_Stream new_stream; + char buf[BUFSIZ]; + int n; + // char *pipe_name = ACE_DEFAULT_RENDEZVOUS; + char *pipe_name = "acepipe"; + + char *rendezvous; + rendezvous = MAKE_PIPE_NAME (pipe_name); + + /* Initialize named pipe listener */ + + if (acceptor.open (ACE_SPIPE_Addr (rendezvous)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), 1); + + for (;;) + { + ACE_DEBUG ((LM_DEBUG, "waiting for connection\n")); + + /* Accept a client connection */ + if (acceptor.accept (new_stream, 0) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "accept"), 1); + + ACE_DEBUG ((LM_DEBUG, "Accepted connection\n")); + + while ((n = new_stream.recv (buf, sizeof buf)) > 0) + { + cerr << buf << endl; + ACE_OS::write (ACE_STDOUT, buf, n); + } + if (n == -1) + { + ACE_DEBUG ((LM_DEBUG, "End of connection. Closing handle\n")); + new_stream.close (); + } + } + return 0; +} diff --git a/examples/IPC_SAP/SPIPE_SAP/client.cpp b/examples/IPC_SAP/SPIPE_SAP/client.cpp new file mode 100644 index 00000000000..8c0b6e0a074 --- /dev/null +++ b/examples/IPC_SAP/SPIPE_SAP/client.cpp @@ -0,0 +1,42 @@ +#include "ace/Log_Msg.h" +// @(#)client.cpp 1.1 10/18/96 + +#include "ace/SPIPE_Addr.h" +#include "ace/SPIPE_Connector.h" +#include "shared.h" + +#if defined (ACE_HAS_STREAM_PIPES) + +int +main (int argc, char *argv[]) +{ + if (argc < 2) + ACE_ERROR_RETURN ((LM_ERROR, "usage: %s string [rendezvous]\n", argv[0]), 1); + + if (argc > 2) + rendezvous = argv[2]; + + ACE_SPIPE_Stream cli_stream; + ACE_SPIPE_Connector con; + + if (con.connect (cli_stream, ACE_SPIPE_Addr (rendezvous)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", rendezvous), 1); + + size_t len = ACE_OS::strlen (argv[1]) + 1; + + if (cli_stream.send (argv[1], len) != len) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), 1); + + if (cli_stream.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), 1); + + return 0; +} +#else +#include +int main (void) +{ + ACE_OS::fprintf (stderr, "This feature is not supported\n"); + return 0; +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/examples/IPC_SAP/SPIPE_SAP/consumer_msg.cpp b/examples/IPC_SAP/SPIPE_SAP/consumer_msg.cpp new file mode 100644 index 00000000000..ad96c04677b --- /dev/null +++ b/examples/IPC_SAP/SPIPE_SAP/consumer_msg.cpp @@ -0,0 +1,53 @@ +#include "ace/Log_Msg.h" +// @(#)consumer_msg.cpp 1.1 10/18/96 + +#include "ace/SPIPE_Addr.h" +#include "ace/SPIPE_Acceptor.h" +#include "ace/Time_Value.h" +#include "shared.h" + +#if defined (ACE_HAS_STREAM_PIPES) + +int +main (int argc, char *argv[]) +{ + ACE_SPIPE_Acceptor peer_acceptor; + ACE_SPIPE_Stream new_stream; + char buf[BUFSIZ]; + ACE_Str_Buf buffer (buf, 0, sizeof buf); + int flags = 0; + + if (argc > 1) + rendezvous = argv[1]; + + ACE_OS::unlink (rendezvous); + ACE_OS::fdetach (rendezvous); + + ACE_SPIPE_Addr addr (rendezvous); + ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT); + + if (peer_acceptor.open (addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), 1); + + ACE_DEBUG ((LM_DEBUG, "waiting for connection\n")); + + if (peer_acceptor.accept (new_stream, 0, &timeout) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "accept"), 1); + + ACE_DEBUG ((LM_DEBUG, "accepted\n")); + + while (new_stream.recv ((ACE_Str_Buf *) 0, &buffer, &flags) >= 0) + if (buffer.len == 0) + break; + else + ACE_OS::write (ACE_STDOUT, buffer.buf, buffer.len); + return 0; +} +#else +#include +int main (void) +{ + ACE_OS::fprintf (stderr, "This feature is not supported\n"); + return 0; +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/examples/IPC_SAP/SPIPE_SAP/consumer_read.cpp b/examples/IPC_SAP/SPIPE_SAP/consumer_read.cpp new file mode 100644 index 00000000000..bffa3ff90b8 --- /dev/null +++ b/examples/IPC_SAP/SPIPE_SAP/consumer_read.cpp @@ -0,0 +1,50 @@ +#include "ace/Log_Msg.h" +// @(#)consumer_read.cpp 1.1 10/18/96 + +#include "ace/SPIPE_Addr.h" +#include "ace/SPIPE_Acceptor.h" +#include "ace/Time_Value.h" +#include "shared.h" + +#if defined (ACE_HAS_STREAM_PIPES) + +int +main (int argc, char *argv[]) +{ + ACE_SPIPE_Acceptor peer_acceptor; + ACE_SPIPE_Stream new_stream; + char buf[BUFSIZ]; + int n; + + // Wait up to ACE_DEFAULT_TIMEOUT seconds to accept connection. + ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT); + + if (argc > 1) + rendezvous = argv[1]; + + ACE_OS::unlink (rendezvous); + ACE_OS::fdetach (rendezvous); + + if (peer_acceptor.open (ACE_SPIPE_Addr (rendezvous)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), 1); + + ACE_DEBUG ((LM_DEBUG, "waiting for connection\n")); + + if (peer_acceptor.accept (new_stream, 0, &timeout) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "accept"), 1); + + ACE_DEBUG ((LM_DEBUG, "accepted\n")); + + while ((n = new_stream.recv (buf, sizeof buf)) > 0) + ACE_OS::write (ACE_STDOUT, buf, n); + + return 0; +} +#else +#include +int main (void) +{ + ACE_OS::fprintf (stderr, "This feature is not supported\n"); + return 0; +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/examples/IPC_SAP/SPIPE_SAP/producer_msg.cpp b/examples/IPC_SAP/SPIPE_SAP/producer_msg.cpp new file mode 100644 index 00000000000..4109fbe31ca --- /dev/null +++ b/examples/IPC_SAP/SPIPE_SAP/producer_msg.cpp @@ -0,0 +1,52 @@ +#include "ace/Log_Msg.h" +// @(#)producer_msg.cpp 1.1 10/18/96 + +#include "ace/SPIPE_Addr.h" +#include "ace/SPIPE_Connector.h" +#include "shared.h" + +#if defined (ACE_HAS_STREAM_PIPES) + +const int DEFAULT_SIZE = 4 * 1024; +const int DEFAULT_COUNT = 100; + +int +main (int argc, char *argv[]) +{ + int size = argc > 1 ? atoi (argv[1]) : DEFAULT_SIZE; + int iterations = argc > 2 ? atoi (argv[2]) : DEFAULT_COUNT; + char *buf = new char[size]; + + if (argc > 3) + rendezvous = argv[3]; + + ACE_SPIPE_Stream cli_stream; + ACE_SPIPE_Connector con; + int i; + + if (con.connect (cli_stream, ACE_SPIPE_Addr (rendezvous)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", rendezvous), 1); + + for (i = 0; i < size; i++) + buf[i] = 'a'; + + ACE_Str_Buf buffer (buf, size); + + for (i = 0; i < iterations; i++) + if (cli_stream.send ((ACE_Str_Buf *) 0, &buffer) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), 1); + + if (cli_stream.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), 1); + + delete buf; + return 0; +} +#else +#include +int main (void) +{ + ACE_OS::fprintf (stderr, "This feature is not supported\n"); + return 0; +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/examples/IPC_SAP/SPIPE_SAP/producer_read.cpp b/examples/IPC_SAP/SPIPE_SAP/producer_read.cpp new file mode 100644 index 00000000000..883b2994110 --- /dev/null +++ b/examples/IPC_SAP/SPIPE_SAP/producer_read.cpp @@ -0,0 +1,49 @@ +#include "ace/Log_Msg.h" +// @(#)producer_read.cpp 1.1 10/18/96 + +#include "ace/SPIPE_Addr.h" +#include "ace/SPIPE_Connector.h" +#include "shared.h" + +#if defined (ACE_HAS_STREAM_PIPES) + +const int DEFAULT_SIZE = 8 * 1024; +const int DEFAULT_COUNT = 100; + +int +main (int argc, char *argv[]) +{ + int size = argc > 1 ? atoi (argv[1]) : DEFAULT_SIZE; + int iterations = argc > 2 ? atoi (argv[2]) : DEFAULT_COUNT; + char *buf = new char[size]; + + if (argc > 3) + rendezvous = argv[3]; + + ACE_SPIPE_Stream cli_stream; + ACE_SPIPE_Connector con; + int i; + + if (con.connect (cli_stream, ACE_SPIPE_Addr (rendezvous)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", rendezvous), -1); + + for (i = 0; i < size; i++) + buf[i] = 'a'; + + for (i = 0; i < iterations; i++) + if (cli_stream.send (buf, size) != size) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "putmsg"), -1); + + if (cli_stream.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), -1); + + return 0; +} +#else +#include +int main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "this feature is not supported"), -1); + return 0; +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/examples/IPC_SAP/SPIPE_SAP/server.cpp b/examples/IPC_SAP/SPIPE_SAP/server.cpp new file mode 100644 index 00000000000..3173d6433cf --- /dev/null +++ b/examples/IPC_SAP/SPIPE_SAP/server.cpp @@ -0,0 +1,116 @@ +#include "ace/SPIPE_Addr.h" +// @(#)server.cpp 1.1 10/18/96 + +#include "ace/SPIPE_Acceptor.h" +#include "shared.h" + +#if defined (ACE_HAS_STREAM_PIPES) + +/* Maximum per-process open I/O descriptors */ +const int MAX_FDS = 200; +const int PERMS = 0666; + +int +main (int argc, char *argv[]) +{ + ACE_SPIPE_Acceptor peer_acceptor; + ACE_SPIPE_Stream new_stream; + int s_handle; + struct pollfd poll_array[MAX_FDS]; + + if (argc > 1) + rendezvous = argv[1]; + + ACE_OS::fdetach (rendezvous); + + ACE_SPIPE_Addr addr (rendezvous); + + if ((s_handle = peer_acceptor.open (addr)) == -1) + ACE_OS::perror ("peer_acceptor.open"), ACE_OS::exit (1); + + for (int fd = 0; fd < MAX_FDS; fd++) + { + poll_array[fd].fd = -1; + poll_array[fd].events = POLLIN; + } + + poll_array[0].fd = s_handle; + + for (int width = 1;;) + { + // Block waiting for client I/O events (handle interrupts). + while (ACE_OS::poll (poll_array, width) == -1 && errno == EINTR) + continue; + + /* Handle pending logging messages first (s_handle + 1 + is guaranteed to be lowest client descriptor) */ + + for (int fd = s_handle + 1; fd < width; fd++) + if ((poll_array[fd].revents & POLLIN) + || (poll_array[fd].revents & POLLHUP)) + { + char buf[BUFSIZ]; + int n; + + /* recv will not block in this case! */ + if ((n = ACE_OS::read (fd, buf, sizeof buf)) == -1) + ACE_OS::perror ("read failed"); + else if (n == 0) + { + /* Handle client connection shutdown */ + if (ACE_OS::close (poll_array[fd].fd) == -1) + ACE_OS::perror ("close"); + poll_array[fd].fd = -1; + + if (fd + 1 == width) + { + while (poll_array[fd].fd == -1) + fd--; + width = fd + 1; + } + } + else + { + ::printf ("%*s\n", n, buf); + fflush (stdout); + } + } + + if (poll_array[0].revents & POLLIN) + { + int arg; + int n_handle; + ACE_SPIPE_Addr client; + + if (peer_acceptor.accept (new_stream) == -1) + ACE_OS::perror ("local_accept"); + + n_handle = new_stream.get_handle (); + + if (new_stream.get_remote_addr (client) == -1) + ACE_OS::perror ("get_remote_addr"); + + ACE_OS::printf ("n_handle = %d, uid = %d, gid = %d\n", + n_handle, client.user_id (), client.group_id ()); + + arg = RMSGN | RPROTDAT; + + if (ACE_OS::ioctl (n_handle, I_SRDOPT, (void *) arg) == -1) + ACE_OS::perror ("I_RRDOPT"); + + poll_array[n_handle].fd = n_handle; + if (n_handle >= width) + width = n_handle + 1; + } + } + + return 0; +} +#else +#include +int main (void) +{ + ACE_OS::fprintf (stderr, "This feature is not supported\n"); + return 0; +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/examples/IPC_SAP/SPIPE_SAP/shared.h b/examples/IPC_SAP/SPIPE_SAP/shared.h new file mode 100644 index 00000000000..13fcf34fac2 --- /dev/null +++ b/examples/IPC_SAP/SPIPE_SAP/shared.h @@ -0,0 +1,6 @@ +/* -*- C++ -*- */ +// @(#)shared.h 1.1 10/18/96 + +#include "ace/OS.h" + +static const char *rendezvous = ACE_DEFAULT_RENDEZVOUS; diff --git a/examples/IPC_SAP/TLI_SAP/CPP-client.cpp b/examples/IPC_SAP/TLI_SAP/CPP-client.cpp new file mode 100644 index 00000000000..8c34dfe866a --- /dev/null +++ b/examples/IPC_SAP/TLI_SAP/CPP-client.cpp @@ -0,0 +1,68 @@ +#include "ace/Log_Msg.h" +// @(#)CPP-client.cpp 1.1 10/18/96 + +#include "ace/TLI_Connector.h" +#include "ace/INET_Addr.h" +#include "ace/Time_Value.h" + +#if defined (ACE_HAS_TLI) + +/* ACE_TLI Client */ + +int main (int argc, char *argv[]) +{ + char *host = argc > 1 ? argv[1] : ACE_DEFAULT_SERVER_HOST; + u_short r_port = argc > 2 ? ACE_OS::atoi (argv[2]) : ACE_DEFAULT_SERVER_PORT; + int timeout = argc > 3 ? ACE_OS::atoi (argv[3]) : ACE_DEFAULT_TIMEOUT; + u_short l_port = argc > 4 ? ACE_OS::atoi (argv[4]) : ACE_DEFAULT_LOCAL_PORT; + char buf[BUFSIZ]; + + ACE_TLI_Stream cli_stream; + ACE_INET_Addr remote_addr (r_port, host); + ACE_INET_Addr local_addr (l_port); + + ACE_DEBUG ((LM_DEBUG, "starting non-blocking connect\n")); + + // Initiate timed, non-blocking connection with server. + ACE_TLI_Connector con; + + if (con.connect (cli_stream, remote_addr, + (ACE_Time_Value *) &ACE_Time_Value::zero, + local_addr, 1) == -1) + { + if (errno != EWOULDBLOCK) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "connection failed"), 1); + + ACE_DEBUG ((LM_DEBUG, "starting timed connect\n")); + + // Check if non-blocking connection is in progress, + // and wait up to timeout seconds for it to complete. + ACE_Time_Value tv (timeout); + + if (con.complete (cli_stream, &remote_addr, &tv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "connection failed"), 1); + else + ACE_DEBUG ((LM_DEBUG, "connected to %s\n", + remote_addr.get_host_name ())); + } + + // Send data to server (correctly handles "incomplete writes"). + + for (int r_bytes; + (r_bytes = ACE_OS::read (ACE_STDIN, buf, sizeof buf)) > 0; ) + if (cli_stream.send_n (buf, r_bytes) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send_n"), 1); + + /* Explicitly close the connection */ + if (cli_stream.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), -1); + + return 0; +} +#else +int main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "your platform must support ACE_TLI\n"), 1); +} +#endif /* ACE_HAS_TLI */ diff --git a/examples/IPC_SAP/TLI_SAP/CPP-server.cpp b/examples/IPC_SAP/TLI_SAP/CPP-server.cpp new file mode 100644 index 00000000000..b0852615b70 --- /dev/null +++ b/examples/IPC_SAP/TLI_SAP/CPP-server.cpp @@ -0,0 +1,68 @@ +#include "ace/Log_Msg.h" +// @(#)CPP-server.cpp 1.1 10/18/96 + +#include "ace/TLI_Acceptor.h" +#include "ace/INET_Addr.h" + +#if defined (ACE_HAS_TLI) +/* ACE_TLI Server */ + +int +main (int argc, char *argv[]) +{ + u_short port = argc > 1 ? ACE_OS::atoi (argv[1]) : ACE_DEFAULT_SERVER_PORT; + ACE_Time_Value timeout (argc > 2 ? ACE_OS::atoi (argv[2]) : ACE_DEFAULT_TIMEOUT); + + /* Create a server address. */ + ACE_INET_Addr addr (port); + + /* Create a server, reuse the addr. */ + ACE_TLI_Acceptor peer_acceptor; + + if (peer_acceptor.open (addr, 1) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + + ACE_TLI_Stream new_stream; + + ACE_DEBUG ((LM_DEBUG, "starting server at port %d\n", + addr.get_port_number ())); + + /* Performs the iterative server activities */ + + for (;;) + { + char buf[BUFSIZ]; + + /* Create a new ACE_TLI_Stream endpoint (note automatic restart + if errno == EINTR) */ + if (peer_acceptor.accept (new_stream, + &addr, &timeout) == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "accept")); + continue; + } + + ACE_DEBUG ((LM_DEBUG, "client %s connected from %d\n", + addr.get_host_name (), addr.get_port_number ())); + + // Read data from client (terminate on error). + + for (int r_bytes; + (r_bytes = new_stream.recv (buf, sizeof buf)) > 0; ) + if (ACE_OS::write (ACE_STDOUT, buf, r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE::send_n")); + + // Close new endpoint (listening endpoint stays open). + if (new_stream.close () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "close")); + + } + /* NOTREACHED */ + return 0; +} +#else +int main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "your platform must support ACE_TLI\n"), 1); +} +#endif /* ACE_HAS_TLI */ diff --git a/examples/IPC_SAP/TLI_SAP/Makefile b/examples/IPC_SAP/TLI_SAP/Makefile new file mode 100644 index 00000000000..ce6a90c2a83 --- /dev/null +++ b/examples/IPC_SAP/TLI_SAP/Makefile @@ -0,0 +1,197 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for TLI_SAP test +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = ftp-client \ + ftp-server \ + db-client \ + db-server \ + CPP-client \ + CPP-server + +LSRC = $(addsuffix .cpp,$(BIN)) + +LDLIBS= + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +INSTALL = + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/ftp-client.o .shobj/ftp-client.so: ftp-client.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/TLI_Connector.h \ + $(WRAPPER_ROOT)/ace/TLI_Stream.h \ + $(WRAPPER_ROOT)/ace/TLI.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/TLI.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/TLI_Stream.i \ + $(WRAPPER_ROOT)/ace/TLI_Connector.i +.obj/ftp-server.o .shobj/ftp-server.so: ftp-server.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/TLI_Acceptor.h \ + $(WRAPPER_ROOT)/ace/TLI.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/TLI.i \ + $(WRAPPER_ROOT)/ace/TLI_Stream.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/TLI_Stream.i \ + $(WRAPPER_ROOT)/ace/TLI_Acceptor.i +.obj/db-client.o .shobj/db-client.so: db-client.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/TLI_Connector.h \ + $(WRAPPER_ROOT)/ace/TLI_Stream.h \ + $(WRAPPER_ROOT)/ace/TLI.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/TLI.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/TLI_Stream.i \ + $(WRAPPER_ROOT)/ace/TLI_Connector.i +.obj/db-server.o .shobj/db-server.so: db-server.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/TLI_Acceptor.h \ + $(WRAPPER_ROOT)/ace/TLI.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/TLI.i \ + $(WRAPPER_ROOT)/ace/TLI_Stream.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/TLI_Stream.i \ + $(WRAPPER_ROOT)/ace/TLI_Acceptor.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i +.obj/CPP-client.o .shobj/CPP-client.so: CPP-client.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/TLI_Connector.h \ + $(WRAPPER_ROOT)/ace/TLI_Stream.h \ + $(WRAPPER_ROOT)/ace/TLI.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/TLI.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/TLI_Stream.i \ + $(WRAPPER_ROOT)/ace/TLI_Connector.i +.obj/CPP-server.o .shobj/CPP-server.so: CPP-server.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/TLI_Acceptor.h \ + $(WRAPPER_ROOT)/ace/TLI.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/TLI.i \ + $(WRAPPER_ROOT)/ace/TLI_Stream.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/TLI_Stream.i \ + $(WRAPPER_ROOT)/ace/TLI_Acceptor.i + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/IPC_SAP/TLI_SAP/db-client.cpp b/examples/IPC_SAP/TLI_SAP/db-client.cpp new file mode 100644 index 00000000000..b8396d03705 --- /dev/null +++ b/examples/IPC_SAP/TLI_SAP/db-client.cpp @@ -0,0 +1,52 @@ +#include "ace/Log_Msg.h" +// @(#)db-client.cpp 1.1 10/18/96 + +#include "ace/TLI_Connector.h" + +#if defined (ACE_HAS_TLI) +const int MAXLINE = 255; + +int +main (int argc, char *argv[]) +{ + if (argc < 2) + ACE_ERROR_RETURN ((LM_ERROR, "Usage: %s employee_id [server-host port-number]\n", + argv[0]), -1); + + const char *emp_num = argv[1]; + const char *host_name = argc < 3 ? ACE_DEFAULT_SERVER_HOST : argv[2]; + unsigned short port = argc < 4 ? ACE_DEFAULT_SERVER_PORT : ACE_OS::atoi (argv[3]); + int n; + char buf[MAXLINE]; + + ACE_TLI_Stream client; + ACE_TLI_Connector con; + + if (con.connect (client, ACE_INET_Addr (port, host_name)) == -1) + ACE_OS::t_error ((char *)host_name), ACE_OS::exit (1); + + ACE_OS::strcpy (buf, emp_num); + n = ACE_OS::strlen (buf); + + if (client.send_n (buf, n) != n) + ACE_OS::t_error ("client.send error"); + + if (client.recv (buf, MAXLINE) == -1 && t_errno != TLOOK && client.look () != T_DISCONNECT) + ACE_OS::t_error ("client.recv error"); + + if (ACE_OS::strcmp (buf, "ERROR") == 0) + ACE_OS::printf ("Employee ID %s not in database\n", emp_num); + else + ACE_OS::printf ("Employee name requested is: %s\n", buf); + + if (client.close () == -1) + ACE_OS::t_error ("cli_close"), ACE_OS::exit (1); + + return 0; +} +#else +int main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "your platform must support ACE_TLI\n"), 1); +} +#endif /* ACE_HAS_TLI */ diff --git a/examples/IPC_SAP/TLI_SAP/db-server.cpp b/examples/IPC_SAP/TLI_SAP/db-server.cpp new file mode 100644 index 00000000000..ec293242db0 --- /dev/null +++ b/examples/IPC_SAP/TLI_SAP/db-server.cpp @@ -0,0 +1,111 @@ +/* Simple multi-threaded database server example. */ +// @(#)db-server.cpp 1.1 10/18/96 + +#include "ace/Log_Msg.h" +#include "ace/TLI_Acceptor.h" +#include "ace/Thread_Manager.h" + +#if defined (ACE_HAS_THREADS) && defined (ACE_HAS_TLI) + +/* Global thread manager. */ +ACE_Thread_Manager thr_mgr; + +void * +lookup_name (ACE_HANDLE handle) +{ + ACE_Thread_Control tc (&thr_mgr); + + enum + { + MAXLINE = 255, + EMPNAMELEN = 512 + }; + + static struct + { + int emp_id; + const char emp_name[EMPNAMELEN]; + } employee_db[] = + { + {123, "John Wayne Bobbit"}, + {124, "Cindy Crawford"}, + {125, "O. J. Simpson"}, + {126, "Bill Clinton"}, + {127, "Rush Limbaugh"}, + {128, "Michael Jackson"}, + {129, "George Burns"}, + {130, "Paula Jones"}, + {0, ""} + }; + + int n; + int flags; + int len; + int employee_id; + int index; + int found; + ACE_TLI_Stream stream; + char recvline[MAXLINE]; + char sendline[MAXLINE]; + + ACE_DEBUG ((LM_DEBUG, "stream handle = %d, thread id = %t\n", handle)); + stream.set_handle (handle); + + if ((n = stream.recv (recvline, MAXLINE, &flags)) == -1) + ACE_OS::t_error ("stream.recv error"); + + employee_id = ACE_OS::atoi (recvline); + found = 0; + + for (index = 0; found == 0 && employee_db[index].emp_id; index++) + if (employee_id == employee_db[index].emp_id) + { + found = 1; + n = ACE_OS::sprintf (sendline, "%s", employee_db[index].emp_name); + } + + if (found == 0) + n = ACE_OS::sprintf (sendline, "%s", "ERROR"); + + if ((len = stream.send (sendline, n + 1, 0)) == -1) + ACE_OS::t_error ("stream.send error"); + + if (stream.sndrel () == -1) + ACE_OS::t_error ("stream.send error"); + + if (stream.close () == -1) + ACE_OS::t_error ("stream.close error"); + + return 0; +} + +int +main (int argc, char *argv[]) +{ + u_short port = argc > 1 ? ACE_OS::atoi (argv[1]) : ACE_DEFAULT_SERVER_PORT; + ACE_INET_Addr l_addr (port); + ACE_TLI_Acceptor server (l_addr, 1); // Create server, reuse addr if in use. + ACE_TLI_Stream new_stream; + + // Wait for a connection from a client. This is an example of a + // concurrent server. + + for (;;) + { + if (server.accept (new_stream) == -1) + ::t_error ("server.accept error"); + + if (thr_mgr.spawn (ACE_THR_FUNC (lookup_name), + (void *) new_stream.get_handle (), + THR_DETACHED) == -1) + ACE_DEBUG ((LM_ERROR, "server: can't create worker thread %d\n")); + } + return 0; +} +#else +#include +int main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "your platform must support ACE_TLI\n"), 1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/IPC_SAP/TLI_SAP/ftp-client.cpp b/examples/IPC_SAP/TLI_SAP/ftp-client.cpp new file mode 100644 index 00000000000..e664c31c06e --- /dev/null +++ b/examples/IPC_SAP/TLI_SAP/ftp-client.cpp @@ -0,0 +1,45 @@ +#include "ace/Log_Msg.h" +// @(#)ftp-client.cpp 1.1 10/18/96 + +#include "ace/TLI_Connector.h" + +#if defined (ACE_HAS_TLI) + +const int MAXLINE = 255; + +int +main (int argc, char *argv[]) +{ + if (argc < 2) + ACE_OS::fprintf (stderr, "Usage: %s filename [server-host port-number]\n", argv[0]), ACE_OS::exit (1); + + const char *filename = argv[1]; + const char *host_name = argc < 3 ? ACE_DEFAULT_SERVER_HOST : argv[2]; + unsigned short port = argc < 4 ? ACE_DEFAULT_SERVER_PORT : ACE_OS::atoi (argv[3]); + + ACE_TLI_Stream client; + ACE_TLI_Connector con; + int fd; + char buf[BUFSIZ]; + + if (con.connect (client, ACE_INET_Addr (port, host_name)) == -1) + ACE_OS::t_error ((char *) host_name), ACE_OS::exit (1); + + if ((fd = ACE_OS::open (filename, O_RDONLY)) == -1) + ACE_OS::perror (filename), ACE_OS::exit (1); + + for (int n; (n = ACE_OS::read (fd, buf, sizeof buf)) > 0; ) + if (client.send_n (buf, n) != n) + ACE_OS::t_error ("client.send error"); + + if (client.close () == -1) + ACE_OS::t_error ("cli_close"), ACE_OS::exit (1); + + return 0; +} +#else +int main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "your platform does not support ACE_TLI\n"), 1); +} +#endif /* ACE_HAS_TLI */ diff --git a/examples/IPC_SAP/TLI_SAP/ftp-server.cpp b/examples/IPC_SAP/TLI_SAP/ftp-server.cpp new file mode 100644 index 00000000000..116af9c2942 --- /dev/null +++ b/examples/IPC_SAP/TLI_SAP/ftp-server.cpp @@ -0,0 +1,75 @@ +/* Simple file transfer example */ +// @(#)ftp-server.cpp 1.1 10/18/96 + +#include "ace/Log_Msg.h" +#include "ace/Thread_Manager.h" +#include "ace/TLI_Acceptor.h" + +#if defined (ACE_HAS_THREADS) && defined (ACE_HAS_TLI) + +ACE_Thread_Manager thr_mgr; + +void * +read_file (void *fd) +{ + ACE_Thread_Control tc (&thr_mgr); + ACE_TLI_Stream stream; + char buf[BUFSIZ]; + int flags = 0; + int n; + + stream.set_handle (int (fd)); + + ACE_OS::printf ("start (tid = %d, fd = %d)\n", ACE_OS::thr_self (), stream.get_handle ()); + ACE_OS::fflush (stdout); + + while ((n = stream.recv (buf, sizeof buf, &flags)) > 0) + continue; + + ACE_OS::printf ("finish (tid = %d, fd = %d)\n", ACE_OS::thr_self (), stream.get_handle ()); + + if (stream.close () == -1) + ACE_OS::t_error ("stream.close error"); + + return 0; +} + +int +main (int argc, char *argv[]) +{ + u_short port = argc > 1 ? ACE_OS::atoi (argv[1]) : ACE_DEFAULT_SERVER_PORT; + ACE_TLI_Acceptor server; + ACE_TLI_Stream new_stream; + + /* Allow up to 100 simultaneous threads */ + if (thr_mgr.open (100) == -1) + ACE_OS::perror ("thr_mgr.open"), ACE_OS::exit (1); + + // Open the server and reuse the address if in use... + if (server.open (ACE_INET_Addr (port), 1) == -1) + ACE_OS::t_error ("server.open"), ACE_OS::exit (1); + + /* Wait for a connection from a client. This is an example of a concurrent server */ + + for (int count = 1; ; count++) + { + ACE_OS::fprintf (stderr, "thread %d, blocking for accept #%d\n", + ACE_OS::thr_self (), count); + + if (server.accept (new_stream) == -1) + ACE_OS::t_error ("server.accept error"); + + else if (thr_mgr.spawn (ACE_THR_FUNC (read_file), + (void *) new_stream.get_handle (), + THR_DETACHED | THR_BOUND) == -1) + ACE_OS::perror ("can't create worker thread\n"); + } + return 0; +} +#else +#include +int main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "your platform must support ACE_TLI\n"), 1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/IPC_SAP/TLI_SAP/signal_thread.c b/examples/IPC_SAP/TLI_SAP/signal_thread.c new file mode 100644 index 00000000000..e3a3485f1a2 --- /dev/null +++ b/examples/IPC_SAP/TLI_SAP/signal_thread.c @@ -0,0 +1,53 @@ +#define _REENTRANT +// @(#)signal_thread.c 1.1 10/18/96 + +#include +#include +#include +#include +#include +#include + +void *handle (v) + void *v; +{ + sigset_t set; + + sigemptyset (&set); + sigaddset (&set, SIGINT); + + for (;;) + if (sigwait (&set) != SIGINT) + perror ("sigwait"), exit (1); + else + fprintf (stderr, "got sigint!\n"); +} + +int +main (void) +{ + int retval; + sigset_t set; + thread_t t_id; + + sigemptyset (&set); + sigaddset (&set, SIGINT); + + if (sigprocmask (SIG_BLOCK, &set, 0) == -1) + perror ("sigprocmask"), exit (1); + + if (thr_sigsetmask (SIG_BLOCK, &set, 0) == -1) + perror ("sigprocmask"), exit (1); + + if (thr_create (0, 0, handle, 0, THR_DETACHED, &t_id) != 0) + perror ("thr_create"), exit (1); + + for (;;) + { + fprintf (stderr, "blocking for read in thread\n"); + if (read (0, &retval, sizeof retval) != sizeof retval) + perror ("read"); + } + fprintf (stderr, "I'm exiting!\n"); + return 0; +} diff --git a/examples/IPC_SAP/UPIPE_SAP/Makefile b/examples/IPC_SAP/UPIPE_SAP/Makefile new file mode 100644 index 00000000000..ba8ff4b7735 --- /dev/null +++ b/examples/IPC_SAP/UPIPE_SAP/Makefile @@ -0,0 +1,300 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the simple ACE_UPIPE client/server test file +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = ex1 \ + ex2 \ + ex3 + +LSRC = $(addsuffix .cpp,$(BIN)) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/ex1.o .shobj/ex1.so: ex1.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/UPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Acceptor.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Connector.h \ + $(WRAPPER_ROOT)/ace/UPIPE_Connector.i +.obj/ex2.o .shobj/ex2.so: ex2.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Connector.h \ + $(WRAPPER_ROOT)/ace/UPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Connector.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/UPIPE_Acceptor.i \ + auto_builtin_ptr.h +.obj/ex3.o .shobj/ex3.so: ex3.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Connector.h \ + $(WRAPPER_ROOT)/ace/UPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Connector.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/UPIPE_Acceptor.i \ + auto_builtin_ptr.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/IPC_SAP/UPIPE_SAP/auto_builtin_ptr.h b/examples/IPC_SAP/UPIPE_SAP/auto_builtin_ptr.h new file mode 100644 index 00000000000..3dd22c04967 --- /dev/null +++ b/examples/IPC_SAP/UPIPE_SAP/auto_builtin_ptr.h @@ -0,0 +1,20 @@ +/* -*- C++ -*- */ +// @(#)auto_builtin_ptr.h 1.1 10/18/96 + +template +class auto_builtin_ptr + // = TITLE + // Implements an simple-minded auto_ptr abstraction for builtin types. +{ +public: + // = Initialization and termination methods + auto_builtin_ptr (X *p = 0): p_ (p) {} + ~auto_builtin_ptr (void) { delete [] this->p_; } + + // = Accessor methods. + operator X * (void) const { return this->p_; } + +private: + X *p_; +}; + diff --git a/examples/IPC_SAP/UPIPE_SAP/ex1.cpp b/examples/IPC_SAP/UPIPE_SAP/ex1.cpp new file mode 100644 index 00000000000..8f2246e425b --- /dev/null +++ b/examples/IPC_SAP/UPIPE_SAP/ex1.cpp @@ -0,0 +1,155 @@ +// Example for using ACE_UPIPE_SAP and ACE_Thread for intra-process +// @(#)ex1.cpp 1.1 10/18/96 + +// communication. +// +// Author : Gerhard Lenzer and Douglas C. Schmidt + +#include "ace/Log_Msg.h" +#include "ace/Stream.h" +#include "ace/UPIPE_Acceptor.h" +#include "ace/UPIPE_Connector.h" + +#if defined (ACE_HAS_THREADS) + +// Global thread manager. +static ACE_Thread_Manager thr_mgr; + +//ACE_UPIPE_Manager ltc_mgr; + +// Global pattern +static ACE_UPIPE_Addr addr ("pattern"); + +// peer1 thread. + +static void * +peer1 (void *) +{ + // Insert thread into thr_mgr. + ACE_Thread_Control thread_control (&thr_mgr); + ACE_UPIPE_Stream c_stream; + + ACE_UPIPE_Addr c_addr ("pattern"); + + ACE_DEBUG ((LM_DEBUG, "(%t) peer1 starting connect\n")); + ACE_UPIPE_Connector con; + + if (con.connect (c_stream, addr) == -1) + ACE_DEBUG ((LM_DEBUG, "(%t) peer1 ACE_UPIPE_Connector failed\n")); + + ACE_Message_Block *mb = new ACE_Message_Block (20); + mb->copy ("hello", 6); + + if (c_stream.send (mb) == -1) + ACE_DEBUG ((LM_DEBUG, "(%t) error peer1 send\n")); + + if (c_stream.recv (mb) == -1) + ACE_DEBUG ((LM_DEBUG, "(%t) error peer1 recv\n")); + + ACE_DEBUG ((LM_DEBUG, "(%t) peer1 ack is \"%s\"\n", mb->rd_ptr ())); + + // Free up the memory block. + delete mb; + + // Now try the send()/recv() interface. + char mytext[] = "This string is sent by peer1 as buffer"; + + ACE_DEBUG ((LM_DEBUG, "(%t) peer1 sending text\n")); + if (c_stream.send (mytext, sizeof mytext) == -1) + ACE_DEBUG ((LM_DEBUG, + "(%t) buffer send from peer1 failed\n")); + + char conbuf[30]; // Buffer to receive response. + + int i = 0; + + for (char c = ' '; c != '!'; i++) + { + if (c_stream.recv (&c, 1) == -1) + ACE_DEBUG ((LM_DEBUG, + "(%t) buffer recv from peer1 failed\n")); + else + conbuf[i] = c; + } + + conbuf[i] = '\0'; + ACE_DEBUG ((LM_DEBUG, + "(%t) peer1 received buffer with \"%s\"\n", + conbuf)); + c_stream.close (); + return 0; +} + +static void * +peer2 (void *) +{ + // Insert thread into thr_mgr. + ACE_Thread_Control thread_control (&thr_mgr); + + ACE_UPIPE_Addr serv_addr ("pattern"); + ACE_UPIPE_Acceptor acc (addr); + ACE_UPIPE_Stream s_stream; + + // Spawn a peer1 thread. + if (thr_mgr.spawn (ACE_THR_FUNC (peer1), (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), 0); + + ACE_DEBUG ((LM_DEBUG, "(%t) peer2 starting accept\n")); + + if (acc.accept (s_stream) == -1) + ACE_DEBUG ((LM_DEBUG, + "(%t) ACE_UPIPE_Acceptor.accept failed\n")); + + ACE_Message_Block *mb = 0; + + if (s_stream.recv (mb) == -1) + ACE_DEBUG ((LM_DEBUG, "(%t) peer2 recv failed\n")); + + ACE_DEBUG ((LM_DEBUG, "(%t) peer2 recv is \"%s\"\n", + mb->rd_ptr ())); + + mb->wr_ptr (mb->rd_ptr ()); + mb->copy ("thanks", 7); + + if (s_stream.send (mb) == -1) + ACE_DEBUG ((LM_DEBUG, "(%t) peer2 send failed\n")); + + char s_buf[42]; + ACE_DEBUG ((LM_DEBUG, "(%t) peer2 sleeping on recv\n")); + + if (s_stream.recv (s_buf, sizeof s_buf) == -1) + ACE_DEBUG ((LM_DEBUG, "(%t) peer2 recv failed\n")); + else + ACE_DEBUG ((LM_DEBUG, + "(%t) peer2 received buffer with \"%s\"\n", + s_buf)); + + ACE_OS::strcpy (s_buf, "this is the peer2 response!"); + + if (s_stream.send (s_buf, 30) == -1) + ACE_DEBUG ((LM_DEBUG, "(%t) peer2 send failed\n")); + + s_stream.close (); + return 0; +} + +int +main (int, char *[]) +{ + // Spawn a peer2 thread. + if (thr_mgr.spawn (ACE_THR_FUNC (peer2), (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), 1); + + // Wait for peer2 and peer1 threads to exit. + thr_mgr.wait (); + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, "threads not supported on this platform\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/IPC_SAP/UPIPE_SAP/ex2.cpp b/examples/IPC_SAP/UPIPE_SAP/ex2.cpp new file mode 100644 index 00000000000..5677fd0ae4c --- /dev/null +++ b/examples/IPC_SAP/UPIPE_SAP/ex2.cpp @@ -0,0 +1,153 @@ +// Example for using ACE_UPIPE_SAP and ACE_Thread for intra-process +// @(#)ex2.cpp 1.1 10/18/96 + +// communication. +// +// Author : Gerhard Lenzer and Douglas C. Schmidt + +#include +#include "ace/Log_Msg.h" +#include "ace/UPIPE_Connector.h" +#include "ace/UPIPE_Acceptor.h" +#include "auto_builtin_ptr.h" + +#if defined (ACE_HAS_THREADS) + +// Global thread manager. +static ACE_Thread_Manager thr_mgr; + +// Data for testsuite. +int size = 0; +int iterations = 0; + +static void * +supplier (void *) +{ + // Insert thread into thr_mgr. + ACE_Thread_Control thread_control (&thr_mgr); + ACE_UPIPE_Stream s_stream; + + ACE_UPIPE_Addr c_addr ("pattern"); + + auto_builtin_ptr mybuf = new char[size]; + + for (int i = 0; i < size; i++) + mybuf[i] = 'a'; + + ACE_DEBUG ((LM_DEBUG, "(%t) supplier starting connect thread\n")); + + ACE_UPIPE_Connector con; + + if (con.connect (s_stream, c_addr) == -1) + ACE_DEBUG ((LM_DEBUG, "(%t) %p\n", + "ACE_UPIPE_Acceptor.connect failed")); + + // Test asynchronisity. + s_stream.enable (SIGIO); + + for (int j = 0; j < iterations; j++) + { + ACE_Message_Block *mb_p = + new ACE_Message_Block (size, ACE_Message_Block::MB_DATA, + (ACE_Message_Block *) 0, mybuf); + + if (s_stream.send (mb_p) == -1) + { + ACE_DEBUG ((LM_DEBUG, "(%t) %p\n", "send failed")); + return 0; + } + } + + // Insert a 0-sized message block to signal the other side to shut + // down. + if (s_stream.send (new ACE_Message_Block ((size_t) 0)) == -1) + { + cout << "error put" << endl; + return 0; + } + + s_stream.close (); + return 0; +} + +static void * +consumer (void *) +{ + // Insert thread into thr_mgr. + ACE_Thread_Control thread_control (&thr_mgr); + ACE_UPIPE_Stream c_stream; + + // Set the high water mark to size to achieve optimum performance. + + int wm = size * iterations; + + if (c_stream.control (ACE_IO_Cntl_Msg::SET_HWM, &wm) == -1) + ACE_DEBUG ((LM_DEBUG, "set HWM failed\n")); + + ACE_UPIPE_Addr serv_addr ("pattern"); + + ACE_UPIPE_Acceptor acc (serv_addr); // accept will wait up to 4 seconds + + ACE_DEBUG ((LM_DEBUG, "(%t) consumer spawning the supplier thread\n")); + + // Spawn the supplier thread. + if (thr_mgr.spawn (ACE_THR_FUNC (supplier), (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), 0); + + ACE_DEBUG ((LM_DEBUG, "(%t) consumer starting accept\n")); + + if (acc.accept (c_stream) == -1) + ACE_DEBUG ((LM_DEBUG, "(%t) %p\n", + "ACE_UPIPE_Acceptor.accept failed")); + + // time measurement + time_t currsec; + ACE_OS::time (&currsec); + time_t start = (time_t) currsec; + + int received_messages = 0; + + for (ACE_Message_Block *mb = 0; + c_stream.recv (mb) != -1 && mb->size () != 0; + delete mb) + received_messages++; + + ACE_OS::time (&currsec); + time_t secs = (time_t) currsec - start; + + ACE_DEBUG ((LM_DEBUG, + "(%t) Transferred %d blocks of size %d\n" + "The program ran %d seconds\n", + received_messages, size, secs)); + + c_stream.close (); + return 0; +} + +int +main (int argc, char *argv[]) +{ + size = argc > 1 ? ACE_OS::atoi (argv[1]) : 32; + iterations = argc > 2 ? ACE_OS::atoi (argv[2]) : 16; + + // Spawn the two threads. + if (thr_mgr.spawn (ACE_THR_FUNC (consumer), (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ( (LM_ERROR, "%p\n", "spawn"), 1); + + // Wait for producer and consumer threads to exit. + thr_mgr.wait (); + return 0; +} + +#else +int +main (int, char *[]) +{ + ACE_ERROR ( (LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ + + diff --git a/examples/IPC_SAP/UPIPE_SAP/ex3.cpp b/examples/IPC_SAP/UPIPE_SAP/ex3.cpp new file mode 100644 index 00000000000..55568f24ef8 --- /dev/null +++ b/examples/IPC_SAP/UPIPE_SAP/ex3.cpp @@ -0,0 +1,147 @@ +// Example for using ACE_UPIPE_SAP and ACE_Thread for intra-process +// @(#)ex3.cpp 1.1 10/18/96 + +// communication. This example uses char buffers as input/output +// interface to the ACE_UPIPE_Stream +// +// Authors: Gerhard Lenzer and Prashant Jain. + +#include +#include "ace/Log_Msg.h" +#include "ace/UPIPE_Connector.h" +#include "ace/UPIPE_Acceptor.h" +#include "auto_builtin_ptr.h" + +#if defined (ACE_HAS_THREADS) + +// Global thread manager. +static ACE_Thread_Manager thr_mgr; + +// Data for testsuite. +int size = 0; +int iterations = 0; + +static void * +supplier (void *) +{ + // Insert thread into thr_mgr. + ACE_Thread_Control thread_control (&thr_mgr); + + ACE_UPIPE_Stream s_stream; + ACE_UPIPE_Addr c_addr ("pattern"); + + ACE_UPIPE_Connector con; + + ACE_DEBUG ((LM_DEBUG, "(%t) supplier starting connect thread\n")); + + if (con.connect (s_stream, c_addr) == -1) + ACE_DEBUG ((LM_DEBUG, "(%t) %p\n", + "ACE_UPIPE_Acceptor.connect failed")); + + auto_builtin_ptr mybuf = new char[size]; + + for (int i = 0; i < size; i++) + mybuf[i] = 'a'; + + for (int j = 0; j < iterations; j++) + if (s_stream.send (mybuf, size) == -1) + { + ACE_DEBUG ((LM_DEBUG, "(%t) %p\n", "send failed")); + return 0; + } + + // Insert a 0-sized message block to signal the other side to shut + // down. + if (s_stream.send (new ACE_Message_Block ((size_t) 0)) == -1) + { + cout << "error put" << endl; + return 0; + } + + s_stream.close (); + return 0; +} + +static void * +consumer (void *) +{ + // Insert thread into thr_mgr. + ACE_Thread_Control thread_control (&thr_mgr); + + ACE_UPIPE_Stream c_stream; + ACE_UPIPE_Addr serv_addr ("pattern"); + + // Accept will wait up to 4 seconds + ACE_UPIPE_Acceptor acc (serv_addr); + + ACE_DEBUG ((LM_DEBUG, "(%t) consumer spawning the supplier thread\n")); + + // Spawn the supplier thread. + if (thr_mgr.spawn (ACE_THR_FUNC (supplier), (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), 0); + + ACE_DEBUG ((LM_DEBUG, "(%t) consumer starting accept\n")); + + if (acc.accept (c_stream) == -1) + ACE_DEBUG ((LM_DEBUG, "(%t) %p\n", + "ACE_UPIPE_Acceptor.accept failed")); + + // Ensure deletion upon exit. + auto_builtin_ptr mybuf = new char[size]; + time_t currsec; + + ACE_OS::time (&currsec); + + time_t start = (time_t) currsec; + int result = 0; + int blocks = 0; + + for (;; blocks++) + { + result = c_stream.recv (mybuf, size); + if (result <= 0) + break; + // ACE_DEBUG ((LM_DEBUG, "(%t) %d: %s\n", size, (char *) mybuf)); + } + + if (result == -1) + ACE_DEBUG ((LM_DEBUG, "(%t) %p\n", "recv failed")); + + ACE_OS::time (&currsec); + time_t secs = (time_t) currsec - start; + + ACE_DEBUG ((LM_DEBUG, + "(%t) Transferred %d blocks of size %d\n" + "The program ran %d seconds\n", + blocks, size, secs)); + + c_stream.close (); + return 0; +} + +int +main (int argc, char *argv[]) +{ + size = argc > 1 ? ACE_OS::atoi (argv[1]) : 32; + iterations = argc > 2 ? ACE_OS::atoi (argv[2]) : 16; + + // Spawn the thread. + if (thr_mgr.spawn (ACE_THR_FUNC (consumer), (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ( (LM_ERROR, "%p\n", "spawn"), 1); + + // Wait for producer and consumer threads to exit. + thr_mgr.wait (); + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR ( (LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ + + diff --git a/examples/Log_Msg/Makefile b/examples/Log_Msg/Makefile new file mode 100644 index 00000000000..9949795ba24 --- /dev/null +++ b/examples/Log_Msg/Makefile @@ -0,0 +1,55 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for testing the Log_Msg logger +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = test_log_msg + +LSRC = $(addsuffix .cpp,$(BIN)) + +LDLIBS = + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/test_log_msg.o .shobj/test_log_msg.so: test_log_msg.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/Log_Msg/test_log_msg.cpp b/examples/Log_Msg/test_log_msg.cpp new file mode 100644 index 00000000000..1f93dcc20b0 --- /dev/null +++ b/examples/Log_Msg/test_log_msg.cpp @@ -0,0 +1,105 @@ +// Test the Log_Msg abstraction. +// @(#)test_log_msg.cpp 1.1 10/18/96 + + +#include "ace/Log_Msg.h" + +static void +cleanup (void) +{ + ACE_DEBUG ((LM_INFO, "leaving (%P)!\n")); +} + +static void +cause_error (void) +{ + errno = EWOULDBLOCK; + ACE_ERROR ((LM_DEBUG, "would block\n")); +} + +int +main (int argc, char *argv[]) +{ + // Note that the default behavior is to log to STDERR... + + if (argc > 1) + { + if (ACE_LOG_MSG->open (argv[0], ACE_Log_Msg::OSTREAM) == -1) + ACE_ERROR ((LM_ERROR, "cannot open logger!!!\n")); + + cause_error (); + // Check to see what happened. + if (ACE_LOG_MSG->op_status () == -1 + && ACE_LOG_MSG->errnum () == EWOULDBLOCK) + ACE_DEBUG ((LM_DEBUG, "op_status and errnum work!\n")); + else + ACE_ERROR ((LM_ERROR, "op_status and errnum failed!\n")); + } + else + { + if (ACE_LOG_MSG->open (argv[0]) == -1) + ACE_ERROR ((LM_ERROR, "cannot open logger!!!\n")); + + cause_error (); + + // Check to see what happened. + if (ACE_LOG_MSG->op_status () == -1 + && ACE_LOG_MSG->errnum () == EWOULDBLOCK) + ACE_DEBUG ((LM_DEBUG, "op_status and errnum work!\n")); + else + ACE_ERROR ((LM_ERROR, "op_status and errnum failed!\n")); + + // Exercise many different combinations of STDERR and OSTREAM. + + ACE_DEBUG ((LM_INFO, "%f, %*s%s = %d\n", + 3.1416, 8, "", "hello", 10000)); + + ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM); + ACE_LOG_MSG->msg_ostream (&cout); + + ACE_DEBUG ((LM_INFO, "%f, %*s%s = %d\n", + 3.1416 * 3.1416, 8, "", "world", 20000)); + + ACE_LOG_MSG->clr_flags (ACE_Log_Msg::STDERR); + + ACE_DEBUG ((LM_INFO, "%f, %*s%s = %d\n", + 3.1416 * 3.1416, 8, "", "world", 20000)); + + ACE_LOG_MSG->msg_ostream (0); + + ACE_LOG_MSG->set_flags (ACE_Log_Msg::STDERR); + + ACE_DEBUG ((LM_INFO, "%f, %*s%s = %d\n", + 3.1416 * 3.1416, 8, "", "world", 20000)); + + ACE_LOG_MSG->clr_flags (ACE_Log_Msg::OSTREAM); + ACE_LOG_MSG->msg_ostream (&cerr); + + ACE_DEBUG ((LM_INFO, "%f, %*s%s = %d\n", + 3.1416 * 3.1416, 8, "", "world", 20000)); + + static int array[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048}; + + // Print out the binary bytes of the array in hex form. + ACE_LOG_MSG->log_hexdump (LM_DEBUG, (char *) array, sizeof array); + + // Disable the LM_DEBUG and LM_INFO messages. + int priority_mask = ACE_LOG_MSG->priority_mask (); + ACE_CLR_BITS (priority_mask, LM_DEBUG | LM_INFO); + ACE_LOG_MSG->priority_mask (priority_mask); + + ACE_DEBUG ((LM_INFO, "This LM_INFO message should not print!\n")); + ACE_DEBUG ((LM_DEBUG, "This LM_DEBUG message should not print!\n")); + + char *badname = "badname"; + + char *l_argv[2]; + l_argv[0] = badname; + l_argv[1] = 0; + + if (ACE_OS::execv (badname, l_argv) == -1) + ACE_ERROR ((LM_ERROR, "%n: (%x), %p%r%a\n", + 10000, badname, cleanup, 1)); + } + return 0; +} diff --git a/examples/Logger/Acceptor-server/Makefile b/examples/Logger/Acceptor-server/Makefile new file mode 100644 index 00000000000..caf3e445e80 --- /dev/null +++ b/examples/Logger/Acceptor-server/Makefile @@ -0,0 +1,107 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Reactor version of the Server Logging Daemon +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = server_loggerd + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/Logging_Acceptor.o .shobj/Logging_Acceptor.so: Logging_Acceptor.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + Logging_Acceptor.h \ + $(WRAPPER_ROOT)/ace/Singleton.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + Logging_Handler.h +.obj/Logging_Handler.o .shobj/Logging_Handler.so: Logging_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + Logging_Handler.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/Logger/Acceptor-server/server_loggerd.cpp b/examples/Logger/Acceptor-server/server_loggerd.cpp new file mode 100644 index 00000000000..f8d6008948d --- /dev/null +++ b/examples/Logger/Acceptor-server/server_loggerd.cpp @@ -0,0 +1,268 @@ +// This server daemon collects, formats, and displays logging +// @(#)server_loggerd.cpp 1.1 10/18/96 + +// information forwarded from client daemons running on other hosts in +// the network. In addition, this example illustrates how to use the +// ACE_Reactor, ACE_Acceptor, ACE_Singleton, and ACE_Test_and_Set +// components. + +#include "ace/Get_Opt.h" +#include "ace/Log_Msg.h" +#include "ace/Acceptor.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/Synch.h" +#include "ace/Singleton.h" + +// ---------------------------------------- + +class Options +{ + // = TITLE + // Keeps track of the options. +public: + void parse_args (int argc, char *argv[]); + u_short port (void); + +private: + u_short port_; + // Port number; +}; + +// Return the port number. + +u_short +Options::port (void) +{ + return this->port_; +} + +// Parse the command-line options. + +void +Options::parse_args (int argc, char *argv[]) +{ + this->port_ = ACE_DEFAULT_SERVER_PORT; + + ACE_Get_Opt get_opt (argc, argv, "p:"); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'p': + this->port_ = ACE_OS::atoi (get_opt.optarg); + break; + default: + break; + } +} + +// ---------------------------------------- + +// Our Reactor Singleton. +typedef ACE_Singleton + REACTOR; + +// Our Options Singleton. +typedef ACE_Singleton + OPTIONS; + +// Our ACE_Test_and_Set Singleton. +typedef ACE_Singleton, ACE_Null_Mutex> + QUIT_HANDLER; + +// ---------------------------------------- + +class Logging_Handler : public ACE_Svc_Handler + // = TITLE + // Receive client message from the remote clients. + // + // = DESCRIPTION + // This class demonstrates how to receive messages from remote + // clients using the notification mechanisms in the + // . In addition, it also illustrates how to + // utilize the timer mechanisms, as well. +{ +public: + // = Initialization and termination methods. + Logging_Handler (void); + + virtual void destroy (void); + // Ensure dynamic allocation. + + // = Hooks for opening and closing handlers. + virtual int open (void *); + virtual int close (u_long); + +protected: + // = Demultiplexing hooks. + virtual int handle_input (ACE_HANDLE); + virtual int handle_timeout (const ACE_Time_Value &tv, + const void *arg); + +private: + char peer_name_[MAXHOSTNAMELEN + 1]; + // Host we are connected to. +}; + +// Specialize a Logging Acceptor. +typedef ACE_Acceptor + Logging_Acceptor; + +// Default constructor. + +Logging_Handler::Logging_Handler (void) +{ +} + +void +Logging_Handler::destroy (void) +{ + REACTOR::instance ()->cancel_timer (this); + this->peer ().close (); +} + +int +Logging_Handler::handle_timeout (const ACE_Time_Value &, + const void *arg) +{ + ACE_ASSERT (arg == this); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) handling timeout from this = %u\n", this)); + return 0; +} + +// Perform the logging record receive. + +int +Logging_Handler::handle_input (ACE_HANDLE) +{ + // Perform two recv's to emulate record-oriented semantics. Note + // that this code is not entirely portable since it relies on the + // fact that sizeof (ssize_t) is the same on both the sender and + // receiver side. To correctly handle this is painful, and we leave + // it as an exercise for the reader ;-). + + ssize_t len; + ssize_t n = this->peer ().recv ((void *) &len, sizeof len); + + switch (n) + { + case -1: + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p at host %s\n", + "client logger", this->peer_name_), -1); + /* NOTREACHED */ + case 0: + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) closing log daemon at host %s (fd = %d)\n", + this->peer_name_, this->get_handle ()), -1); + /* NOTREACHED */ + case sizeof (size_t): + { + ACE_Log_Record lp; + + len = ntohl (len); + if ((n = this->peer ().recv_n ((void *) &lp, len)) != len) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p at host %s\n", + "client logger", this->peer_name_), -1); + /* NOTREACHED */ + + lp.decode (); + + if (lp.length () == n) + { + ACE_DEBUG ((LM_DEBUG, "(%P|%t) ")); + lp.print (this->peer_name_, 1, cerr); + } + else + ACE_ERROR ((LM_ERROR, "(%P|%t) error, lp.length = %d, n = %d\n", + lp.length (), n)); + break; + } + default: + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p at host %s\n", + "client logger", this->peer_name_), -1); + /* NOTREACHED */ + } + + return 0; +} + +int +Logging_Handler::open (void *) +{ + ACE_INET_Addr addr; + + if (this->peer ().get_remote_addr (addr) == -1) + return -1; + else + { + ACE_OS::strncpy (this->peer_name_, + addr.get_host_name (), + MAXHOSTNAMELEN + 1); + + if (REACTOR::instance ()->register_handler + (this, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) can't register with reactor\n"), -1); + else if (REACTOR::instance ()->schedule_timer + (this, + (const void *) this, + ACE_Time_Value (2), + ACE_Time_Value (2)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "can'(%P|%t) t register with reactor\n"), -1); + else + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) connected with %s\n", this->peer_name_)); + return 0; + } +} + +// Perform termination activities when deregistered from the +// ACE_Reactor. + +int +Logging_Handler::close (u_long) +{ + this->destroy (); + return 0; +} + +int +main (int argc, char *argv[]) +{ + // Acceptor factory. + Logging_Acceptor peer_acceptor; + + OPTIONS::instance ()->parse_args (argc, argv); + + if (peer_acceptor.open + (ACE_INET_Addr (OPTIONS::instance ()->port ())) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + + else if (REACTOR::instance ()->register_handler + (&peer_acceptor, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "registering service with ACE_Reactor\n"), -1); + + // Register QUIT_HANDLER to receive SIGINT commands. When received, + // QUIT_HANDLER becomes "set" and thus, the event loop below will + // exit. + else if (REACTOR::instance ()->register_handler + (SIGINT, QUIT_HANDLER::instance ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "registering service with ACE_Reactor\n"), -1); + + // Run forever, performing logging service. + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) starting up server logging daemon\n")); + + // Perform logging service until QUIT_HANDLER receives SIGINT. + while (QUIT_HANDLER::instance ()->is_set () == 0) + REACTOR::instance ()->handle_events (); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) shutting down server logging daemon\n")); + + return 0; +} diff --git a/examples/Logger/Makefile b/examples/Logger/Makefile new file mode 100644 index 00000000000..05c41ee6fc2 --- /dev/null +++ b/examples/Logger/Makefile @@ -0,0 +1,27 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the distributed logger tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +INFO = README + +DIRS = Acceptor-server \ + client \ + simple-server + + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + diff --git a/examples/Logger/README b/examples/Logger/README new file mode 100644 index 00000000000..9fa30aafbc0 --- /dev/null +++ b/examples/Logger/README @@ -0,0 +1,32 @@ +This directory contains a simple client/server implementation of the +distributed logging server described in several papers in the C++ +Report (which can be obtained via the following WWW URLs: +http://www.cs.wustl.edu/~schmidt/{Reactor1-93.ps.gz,Reactor2-93.ps.gz}). + +The example consists of the following two directories: + + . client + + This program talks directly to the server logging + daemon. The server daemon must be started before you + can run this test. + + . simple-server + + This program runs a simple, non-templated, + single-threaded Reactive implementation of the + distributed logging server daemon. + + . Acceptor-server + + This program runs templated, Acceptor-based + single-threaded Reactive implementation of the + distributed logging server daemon. + +To see a more complex solution that implements the design described in +the C++ Report articles, please see the: + +$WRAPPER_ROOT/netsvcs/{clients,lib,servers} + +directories. + diff --git a/examples/Logger/client/Makefile b/examples/Logger/client/Makefile new file mode 100644 index 00000000000..665086e9d8f --- /dev/null +++ b/examples/Logger/client/Makefile @@ -0,0 +1,43 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for client logging applications +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = logging_app + +LSRC = $(addsuffix .cpp,$(BIN)) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + + + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/Logger/client/logging_app.cpp b/examples/Logger/client/logging_app.cpp new file mode 100644 index 00000000000..0875092cc61 --- /dev/null +++ b/examples/Logger/client/logging_app.cpp @@ -0,0 +1,53 @@ +// This program sends logging records directly to the server, rather +// @(#)logging_app.cpp 1.1 10/18/96 + +// than going through the client logging daemon. + +#include "ace/SOCK_Connector.h" +#include "ace/Log_Msg.h" +#include "ace/Log_Record.h" + +static u_short LOGGER_PORT = ACE_DEFAULT_SERVER_PORT; +static const char *const LOGGER_HOST = ACE_DEFAULT_SERVER_HOST; +static const int MAX_ITERATIONS = 10; + +int +main (int argc, char *argv[]) +{ + const char *logger_host = argc > 1 ? argv[1] : LOGGER_HOST; + u_short logger_port = argc > 2 ? ACE_OS::atoi (argv[2]) : LOGGER_PORT; + int max_iterations = argc > 3 ? ACE_OS::atoi (argv[3]) : MAX_ITERATIONS; + + ACE_SOCK_Stream logger; + ACE_SOCK_Connector connector; + ACE_INET_Addr addr (logger_port, logger_host); + + if (connector.connect (logger, addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + + for (int i = 0; i < max_iterations; i++) + { + ACE_Log_Record log_record (LM_DEBUG, + ACE_OS::time ((time_t *) 0), + ACE_OS::getpid ()); + + char buf[BUFSIZ]; + ::sprintf (buf, "message = %d\n", i + 1); + log_record.msg_data (buf); + size_t len = log_record.length (); + size_t encoded_len = htonl (len); + + log_record.encode (); + + if (logger.send (4, &encoded_len, sizeof encoded_len, + (char *) &log_record, len) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), -1); + else + ACE_OS::sleep (1); + } + + if (logger.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), -1); + + return 0; +} diff --git a/examples/Logger/simple-server/Logging_Acceptor.cpp b/examples/Logger/simple-server/Logging_Acceptor.cpp new file mode 100644 index 00000000000..75e35dec595 --- /dev/null +++ b/examples/Logger/simple-server/Logging_Acceptor.cpp @@ -0,0 +1,64 @@ +#include "ace/Log_Msg.h" +// @(#)Logging_Acceptor.cpp 1.1 10/18/96 + +#include "Logging_Acceptor.h" +#include "Logging_Handler.h" +#include "Reactor_Singleton.h" + +// Initialize peer_acceptor object. + +int +Logging_Acceptor::open (const ACE_INET_Addr &addr) +{ + // Reuse addr if already in use. + if (this->peer_acceptor_.open (addr, 1) == -1) + return -1; + else + return 0; +} + +// Default constructor. + +Logging_Acceptor::Logging_Acceptor (void) +{ +} + +// Performs termination activities. + +int +Logging_Acceptor::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + return this->peer_acceptor_.close (); +} + +Logging_Acceptor::~Logging_Acceptor (void) +{ + this->handle_close (ACE_INVALID_HANDLE, + ACE_Event_Handler::READ_MASK); +} + +// Returns underlying device descriptor. + +ACE_HANDLE +Logging_Acceptor::get_handle (void) const +{ + return this->peer_acceptor_.get_handle (); +} + +// Accepts connections from client and registers new object with the +// ACE_Reactor. + +int +Logging_Acceptor::handle_input (ACE_HANDLE) +{ + Logging_Handler *svc_handler = new Logging_Handler; + + // Accept the connection from a client client daemon. + + if (this->peer_acceptor_.accept (*svc_handler) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p", "accept failed"), -1); + else if (svc_handler->open () == -1) + svc_handler->close (); + + return 0; +} diff --git a/examples/Logger/simple-server/Logging_Acceptor.h b/examples/Logger/simple-server/Logging_Acceptor.h new file mode 100644 index 00000000000..bb431f0150f --- /dev/null +++ b/examples/Logger/simple-server/Logging_Acceptor.h @@ -0,0 +1,49 @@ +/* -*- C++ -*- */ +// @(#)Logging_Acceptor.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// examples +// +// = FILENAME +// Logging_Acceptor.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (_CLIENT_ACCEPTOR_H) +#define _CLIENT_ACCEPTOR_H + +#include "ace/SOCK_Acceptor.h" +#include "ace/Event_Handler.h" + +class Logging_Acceptor : public ACE_Event_Handler + // = TITLE + // Handle connection requests from remote client clients. + // + // = DESCRIPTION + // Accepts client connection requests, creates Logging_Handler's + // to process them, and registers these Handlers with the + // ACE_Reactor Singleton. +{ +friend class Logging_Handler; +public: + Logging_Acceptor (void); + ~Logging_Acceptor (void); + + int open (const ACE_INET_Addr &a); + +private: + virtual ACE_HANDLE get_handle (void) const; + virtual int handle_input (ACE_HANDLE); + virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask); + + ACE_SOCK_Acceptor peer_acceptor_; + // Passive connection acceptor factory. +}; + +#endif /* _CLIENT_ACCEPTOR_H */ diff --git a/examples/Logger/simple-server/Logging_Handler.cpp b/examples/Logger/simple-server/Logging_Handler.cpp new file mode 100644 index 00000000000..5aba39d7601 --- /dev/null +++ b/examples/Logger/simple-server/Logging_Handler.cpp @@ -0,0 +1,139 @@ +#include "ace/Log_Msg.h" +// @(#)Logging_Handler.cpp 1.1 10/18/96 + +#include "Logging_Handler.h" +#include "Reactor_Singleton.h" + +// Default constructor. + +Logging_Handler::Logging_Handler (void) +{ +} + +Logging_Handler::~Logging_Handler (void) +{ + REACTOR::instance ()->cancel_timer (this); + this->cli_stream_.close (); +} + +// Extract the underlying ACE_SOCK_Stream (e.g., for purposes of +// accept()). + +Logging_Handler::operator ACE_SOCK_Stream &() +{ + return this->cli_stream_; +} + +int +Logging_Handler::handle_timeout (const ACE_Time_Value &, + const void *arg) +{ + ACE_ASSERT (arg == this); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) handling timeout from this = %u\n", this)); + return 0; +} + +// Perform the logging record receive. + +int +Logging_Handler::handle_input (ACE_HANDLE) +{ + ssize_t n; + size_t len; + + // Perform two recv's to emulate record-oriented semantics. Note + // that this code is not entirely portable since it relies on the + // fact that sizeof (ssize_t) is the same on both the sender and + // receiver side. To correctly handle this is painful, and we leave + // it as an exercise for the reader ;-). + + switch (n = this->cli_stream_.recv ((void *) &len, sizeof len)) + { + case -1: + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p at host %s\n", + "client logger", this->host_name_), -1); + /* NOTREACHED */ + case 0: + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) closing log daemon at host %s (fd = %d)\n", + this->host_name_, this->get_handle ()), -1); + /* NOTREACHED */ + case sizeof (size_t): + { + ACE_Log_Record lp; + + len = ntohl (len); + if ((n = this->cli_stream_.recv_n ((void *) &lp, len)) != len) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p at host %s\n", + "client logger", this->host_name_), -1); + /* NOTREACHED */ + + lp.decode (); + + if (lp.length () == n) + { + ACE_DEBUG ((LM_DEBUG, "(%P|%t) ")); + lp.print (this->host_name_, 1, cerr); + } + else + ACE_ERROR ((LM_ERROR, "(%P|%t) error, lp.length = %d, n = %d\n", + lp.length (), n)); + break; + } + default: + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p at host %s\n", + "client logger", this->host_name_), -1); + /* NOTREACHED */ + } + + return 0; +} + +// Extract underlying device descriptor. + +ACE_HANDLE +Logging_Handler::get_handle (void) const +{ + return this->cli_stream_.get_handle (); +} + +int +Logging_Handler::open (void) +{ + ACE_INET_Addr addr; + + if (this->cli_stream_.get_remote_addr (addr) == -1) + return -1; + else + { + ACE_OS::strncpy (this->host_name_, addr.get_host_name (), MAXHOSTNAMELEN + 1); + + if (REACTOR::instance ()->register_handler + (this, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) can't register with reactor\n"), -1); + else if (REACTOR::instance ()->schedule_timer + (this, (const void *) this, ACE_Time_Value (2), ACE_Time_Value (2)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "can'(%P|%t) t register with reactor\n"), -1); + else + ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected with %s\n", this->host_name_)); + return 0; + } +} + +// Perform termination activities when deregistered from the ACE_Reactor. + +int +Logging_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + // Must be allocated dynamically! + delete this; + return 0; +} + +// Perform termination activities when close fails. + +int +Logging_Handler::close (void) +{ + return this->handle_close (ACE_INVALID_HANDLE, + ACE_Event_Handler::RWE_MASK); +} diff --git a/examples/Logger/simple-server/Logging_Handler.h b/examples/Logger/simple-server/Logging_Handler.h new file mode 100644 index 00000000000..f26a83df550 --- /dev/null +++ b/examples/Logger/simple-server/Logging_Handler.h @@ -0,0 +1,64 @@ +/* -*- C++ -*- */ +// @(#)Logging_Handler.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// examples +// +// = FILENAME +// Logging_Handler.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (_CLIENT_HANDLER_H) +#define _CLIENT_HANDLER_H + +#include "ace/Event_Handler.h" +#include "ace/INET_Addr.h" +#include "ace/SOCK_Stream.h" + +class Logging_Handler : public ACE_Event_Handler + // = TITLE + // Receive client message from the remote clients. + // + // = DESCRIPTION + // This class demonstrates how to receive messages from remote + // clients using the notification mechanisms in the + // . In addition, it also illustrates how to + // utilize the timer mechanisms, as well. +{ +public: + Logging_Handler (void); + + // = Hooks for opening and closing handlers. + virtual int open (void); + virtual int close (void); + + operator ACE_SOCK_Stream &(); + // Conversion operators. + +protected: + // = Demultiplexing hooks. + virtual ACE_HANDLE get_handle (void) const; + virtual int handle_input (ACE_HANDLE); + virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask); + virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg); + + // = Really should be private... + virtual ~Logging_Handler (void); + // Ensure dynamic allocation. + +private: + char host_name_[MAXHOSTNAMELEN + 1]; + // Host we are connected to. + + ACE_SOCK_Stream cli_stream_; + // Connection with client +}; + +#endif /* _CLIENT_HANDLER_H */ diff --git a/examples/Logger/simple-server/Makefile b/examples/Logger/simple-server/Makefile new file mode 100644 index 00000000000..773d9f513b8 --- /dev/null +++ b/examples/Logger/simple-server/Makefile @@ -0,0 +1,116 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Reactor Server Logging Daemon +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = server_loggerd + +FILES = Logging_Acceptor \ + Logging_Handler + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(addsuffix .o,$(FILES)) +SHOBJ = $(addsuffix .so,$(FILES)) + +LDLIBS = $(addprefix .shobj/,$(SHOBJ)) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/Logging_Acceptor.o .shobj/Logging_Acceptor.so: Logging_Acceptor.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + Logging_Acceptor.h \ + $(WRAPPER_ROOT)/ace/Singleton.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + Logging_Handler.h +.obj/Logging_Handler.o .shobj/Logging_Handler.so: Logging_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + Logging_Handler.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/Logger/simple-server/Reactor_Singleton.h b/examples/Logger/simple-server/Reactor_Singleton.h new file mode 100644 index 00000000000..7aa08b00f0b --- /dev/null +++ b/examples/Logger/simple-server/Reactor_Singleton.h @@ -0,0 +1,27 @@ +/* -*- C++ -*- */ +// @(#)Reactor_Singleton.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// examples +// +// = FILENAME +// Reactor_Singleton.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (_REACTOR_SINGLETON_H) +#define _REACTOR_SINGLETON_H + +#include "ace/Singleton.h" +#include "ace/Reactor.h" + +// Our global Reactor Singleton. +typedef ACE_Singleton REACTOR; + +#endif /* _REACTOR_SINGLETON_H */ diff --git a/examples/Logger/simple-server/server_loggerd.cpp b/examples/Logger/simple-server/server_loggerd.cpp new file mode 100644 index 00000000000..9d0a03fd607 --- /dev/null +++ b/examples/Logger/simple-server/server_loggerd.cpp @@ -0,0 +1,61 @@ +// This server daemon collects, formats, and displays logging +// @(#)server_loggerd.cpp 1.1 10/18/96 + +// information forwarded from client daemons running on other hosts in +// the network. + +// In addition, it also illustrates how the ACE_Reactor framework is +// used. + +#include "ace/Get_Opt.h" +#include "ace/Log_Msg.h" +#include "Logging_Acceptor.h" +#include "Reactor_Singleton.h" + +static sig_atomic_t finished = 0; + +static void +handler (int) +{ + finished = 1; +} + +// It doesn't get anymore const than this.... +static const u_short PORT = ACE_DEFAULT_SERVER_PORT; + +int +main (int argc, char *argv[]) +{ + Logging_Acceptor peer_acceptor; + ACE_INET_Addr addr (PORT); + ACE_Get_Opt get_opt (argc, argv, "p:"); + + ACE_Sig_Action sig ((ACE_SignalHandler) handler, SIGINT); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'p': + addr.set (ACE_OS::atoi (get_opt.optarg)); + break; + default: + break; + } + + if (peer_acceptor.open (addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + else if (REACTOR::instance ()->register_handler + (&peer_acceptor, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "registering service with ACE_Reactor\n"), -1); + + // Run forever, performing logging service. + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server logging daemon\n")); + + while (!finished) + REACTOR::instance ()->handle_events (); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting down server logging daemon\n")); + + return 0; +} diff --git a/examples/Makefile b/examples/Makefile new file mode 100644 index 00000000000..577cc88a4fe --- /dev/null +++ b/examples/Makefile @@ -0,0 +1,39 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the tests directory +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +INFO = README + +DIRS = ASX \ + Connection \ + IPC_SAP \ + Logger \ + Log_Msg \ + Mem_Map \ + Misc \ + Reactor \ + Service_Configurator \ + Shared_Malloc \ + Threads + +# Makefiles TBD: +# ttcp +# CORBA + + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + diff --git a/examples/Mem_Map/IO-tests/IO_Test.cpp b/examples/Mem_Map/IO-tests/IO_Test.cpp new file mode 100644 index 00000000000..979fd724181 --- /dev/null +++ b/examples/Mem_Map/IO-tests/IO_Test.cpp @@ -0,0 +1,186 @@ +#include "ace/OS.h" +// @(#)IO_Test.cpp 1.1 10/18/96 + +#include "ace/Mem_Map.h" +#include "IO_Test.h" + +IO_Test::IO_Test (const char *name, ACE_Profile_Timer &tm) + : name_ (name), tm_ (tm) +{ +} + +const char * +IO_Test::name (void) +{ + return this->name_; +} + +Slow_Read_Write_Test::Slow_Read_Write_Test (char *name, ACE_Profile_Timer &tm) + : IO_Test (name, tm) +{ +} + +int +Slow_Read_Write_Test::run_test (int iterations, FILE *input_fp, FILE *output_fp) +{ + int ifd = fileno (input_fp); + int ofd = fileno (output_fp); + + this->tm_.start (); + + while (--iterations >= 0) + { + char c; + + while (ACE_OS::read (ifd, &c, sizeof c) > 0) + ::write (ofd, &c, sizeof c); + + ACE_OS::lseek (ifd, 0, SEEK_SET); + ACE_OS::lseek (ofd, 0, SEEK_SET); + } + + this->tm_.stop (); + return 0; +} + +Stdio_Test::Stdio_Test (char *name, ACE_Profile_Timer &tm) + : IO_Test (name, tm) +{ +} + +int +Stdio_Test::run_test (int iterations, FILE *input_fp, FILE *output_fp) +{ + this->tm_.start (); + + while (--iterations >= 0) + { + int c; + + while ((c = getc (input_fp)) != EOF) + putc (c, output_fp); + + ACE_OS::rewind (input_fp); + ACE_OS::rewind (output_fp); + } + this->tm_.stop (); + return 0; +} + +Block_Read_Write_Test::Block_Read_Write_Test (char *name, ACE_Profile_Timer &tm) + : IO_Test (name, tm) +{ +} + +int +Block_Read_Write_Test::run_test (int iterations, FILE *input_fp, FILE *output_fp) +{ + int ifd = fileno (input_fp); + int ofd = fileno (output_fp); + + this->tm_.start (); + + while (--iterations >= 0) + { + char buf[BUFSIZ]; + int n; + + while ((n = ACE_OS::read (ifd, buf, sizeof buf)) > 0) + ::write (ofd, buf, n); + + ACE_OS::lseek (ifd, 0, SEEK_SET); + ACE_OS::lseek (ofd, 0, SEEK_SET); + } + + this->tm_.stop (); + return 0; +} + +Block_Fread_Fwrite_Test::Block_Fread_Fwrite_Test (char *name, ACE_Profile_Timer &tm) + : IO_Test (name, tm) +{ +} + +int +Block_Fread_Fwrite_Test::run_test (int iterations, FILE *input_fp, FILE *output_fp) +{ + this->tm_.start (); + + while (--iterations >= 0) + { + char buf[BUFSIZ]; + int n; + + while ((n = ACE_OS::fread (buf, 1, sizeof buf, input_fp)) != 0) + ::fwrite (buf, n, 1, output_fp); + + ACE_OS::rewind (input_fp); + ACE_OS::rewind (output_fp); + } + + this->tm_.stop (); + return 0; +} + +Mmap1_Test::Mmap1_Test (char *name, ACE_Profile_Timer &tm) + : IO_Test (name, tm) +{ +} + +int +Mmap1_Test::run_test (int iterations, FILE *input_fp, FILE *output_fp) +{ + ACE_Mem_Map map_input (fileno (input_fp)); + void *src = 0; + + if (map_input (src) == -1) + return -1; + else + { + this->tm_.start (); + + while (--iterations >= 0) + if (ACE_OS::write (fileno (output_fp), src, map_input.size ()) == -1) + return -1; + + this->tm_.stop (); + } + + if (map_input.unmap () == -1) + return -1; + else + return 0; +} + +Mmap2_Test::Mmap2_Test (char *name, ACE_Profile_Timer &tm) + : IO_Test (name, tm) +{ +} + +int +Mmap2_Test::run_test (int iterations, FILE *input_fp, FILE *output_fp) +{ + ACE_Mem_Map map_input (fileno (input_fp)); + int size = map_input.size (); + ACE_Mem_Map map_output (fileno (output_fp), size, PROT_WRITE, MAP_SHARED); + void *src = 0; + void *dst = 0; + + if (map_input (src) == -1 || map_output (dst) == -1) + return -1; + else + { + this->tm_.start (); + + while (--iterations >= 0) + ACE_OS::memcpy (dst, src, size); + + this->tm_.stop (); + } + + if (map_input.unmap () == -1 + || map_output.unmap () == -1) + return -1; + else + return 0; +} diff --git a/examples/Mem_Map/IO-tests/IO_Test.h b/examples/Mem_Map/IO-tests/IO_Test.h new file mode 100644 index 00000000000..b45aabf17d9 --- /dev/null +++ b/examples/Mem_Map/IO-tests/IO_Test.h @@ -0,0 +1,71 @@ +/* -*- C++ -*- */ +// @(#)IO_Test.h 1.1 10/18/96 + +/* Class hierarchy for the File I/O tests. */ + +#include "ace/Profile_Timer.h" + +/* Base class for all the File I/O tests. */ + +class IO_Test +{ +public: + // Initialize the test name + IO_Test (const char *name, ACE_Profile_Timer &tm); + + // Return the name of the test + const char *name (void); + + // Execute the IO test (note this is a pure virtual function...) + virtual int run_test (int iterations, FILE *input_fp, FILE *output_fp) = 0; + +protected: + // Name of the test + const char *name_; + + // Reference to a timer + ACE_Profile_Timer &tm_; +}; + +class Slow_Read_Write_Test : public IO_Test +{ +public: + Slow_Read_Write_Test (char *name, ACE_Profile_Timer &tm); + virtual int run_test (int iterations, FILE *input_fp, FILE *output_fp); +}; + +class Stdio_Test : public IO_Test +{ +public: + Stdio_Test (char *name, ACE_Profile_Timer &tm); + virtual int run_test (int iterations, FILE *input_fp, FILE *output_fp); +}; + +class Block_Read_Write_Test : public IO_Test +{ +public: + Block_Read_Write_Test (char *name, ACE_Profile_Timer &tm); + virtual int run_test (int iterations, FILE *input_fp, FILE *output_fp); +}; + +class Block_Fread_Fwrite_Test : public IO_Test +{ +public: + Block_Fread_Fwrite_Test (char *name, ACE_Profile_Timer &tm); + virtual int run_test (int iterations, FILE *input_fp, FILE *output_fp); +}; + +class Mmap1_Test : public IO_Test +{ +public: + Mmap1_Test (char *name, ACE_Profile_Timer &tm); + virtual int run_test (int iterations, FILE *input_fp, FILE *output_fp); +}; + +class Mmap2_Test : public IO_Test +{ +public: + Mmap2_Test (char *name, ACE_Profile_Timer &tm); + virtual int run_test (int iterations, FILE *input_fp, FILE *output_fp); +}; + diff --git a/examples/Mem_Map/IO-tests/Makefile b/examples/Mem_Map/IO-tests/Makefile new file mode 100644 index 00000000000..c7f825136cb --- /dev/null +++ b/examples/Mem_Map/IO-tests/Makefile @@ -0,0 +1,63 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for Mem_Map IO tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = test_io + +FILES = IO_Test + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(addsuffix .o,$(FILES)) +SHOBJ = $(addsuffix .so,$(FILES)) + +LDLIBS = $(addprefix .shobj/,$(SHOBJ)) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/IO_Test.o .shobj/IO_Test.so: IO_Test.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + IO_Test.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/Mem_Map/IO-tests/test_io.cpp b/examples/Mem_Map/IO-tests/test_io.cpp new file mode 100644 index 00000000000..a9a9a918712 --- /dev/null +++ b/examples/Mem_Map/IO-tests/test_io.cpp @@ -0,0 +1,155 @@ +/* Test program for different methods of copying files. */ +// @(#)test_io.cpp 1.1 10/18/96 + + +#include "ace/OS.h" +#include "ace/Profile_Timer.h" +#include "ace/Get_Opt.h" +#include "ace/Signal.h" +#include "IO_Test.h" + +/* Name of program. */ +static char *program_name; + +/* Name of default input file. */ +static char *input_filename = "/usr/dict/words"; + +/* Name of default output file. */ +static char *output_filename = "/tmp/foo"; + +/* Check if removing output file upon completion... */ +static int remove_output = 1; + +/* Count of the number of iterations to run the tests. */ +static int iteration_count = 100; + +/* Profiler used to keep track of file I/O time. */ +static ACE_Profile_Timer tm; + +/* Explain usage and exit. */ + +static void +print_usage_and_die (void) +{ + cerr << "usage: " + << program_name + << " [-i input_file] [-o output_file] [-n iteration_count] [-r]\n"; + ACE_OS::exit (1); +} + +/* Clean up the output file on exit from a signal. */ + +static void +clean_up (int = 0) +{ + if (remove_output) + ACE_OS::unlink (output_filename); + ACE_OS::exit (0); +} + +/* Set up the program name used in error messages. */ + +static void +set_program_name (char name[]) +{ + if ((name = strrchr (name, '/')) == 0) + program_name = name; + else + program_name = name + 1; +} + +/* Parse the command-line arguments and set options. */ + +static void +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, "i:n:o:r"); + + for (int c; ((c = get_opt ()) != -1); ) + switch (c) + { + case 'i': + input_filename = get_opt.optarg; + break; + case 'n': + iteration_count = ACE_OS::atoi (get_opt.optarg); + break; + case 'o': + output_filename = get_opt.optarg; + break; + case 'r': + remove_output = 0; + break; + default: + print_usage_and_die (); + break; + } +} + +/* Vector of pointers to derived classes that inherit from IO_Test base class. */ + +static IO_Test *test_vector[100]; + +static void +run_tests (int iterations, FILE *input_fp, FILE *output_fp) +{ + // If HP/UX didn't suck so badly we could initialize in the global scope... + test_vector[0] = new Stdio_Test ("Stdio_Test", tm); + test_vector[1] = new Block_Fread_Fwrite_Test ("Block_Fread_Fwrite_Test", tm); + test_vector[2] = new Block_Read_Write_Test ("Block_Read_Write_Test", tm); + test_vector[3] = new Mmap1_Test ("Mmap1_Test", tm); + test_vector[4] = new Mmap2_Test ("Mmap2_Test", tm); + /* test_vector[5] = new Slow_Read_Write_Test ("Slow"Read_Write_Test", tm) */ + test_vector[5] = (IO_Test *) 0; + + for (int i = 0; test_vector[i] != 0; i++) + { + if (ACE_OS::ftruncate (fileno (output_fp), 0) == -1) + ::perror ("ftruncate"); + + cerr << "--------------------\n" + << "starting " << test_vector[i]->name () << " for " << iterations + << " iteration(s):\n"; + + if (test_vector[i]->run_test (iterations, input_fp, output_fp) == -1) + ::perror (test_vector[i]->name ()); + + ACE_Profile_Timer::ACE_Elapsed_Time et; + tm.elapsed_time (et); + + cerr << "wallclock time = " << et.real_time + << ", user time = " << et.user_time + << ", system time = " << et.system_time << endl; + + delete test_vector[i]; + } + + cerr << "--------------------\n"; +} + +int +main (int argc, char *argv[]) +{ + FILE *input_fp; + FILE *output_fp; + + set_program_name (argv[0]); + parse_args (argc, argv); + ACE_Sig_Action sig ((ACE_SignalHandler) clean_up, SIGINT); + + if ((input_fp = ACE_OS::fopen (input_filename, "r")) == 0) + ACE_OS::perror (input_filename), ACE_OS::exit (1); + + ACE_OS::unlink (output_filename); + + if ((output_fp = ACE_OS::fopen (output_filename, "w+")) == 0) + ACE_OS::perror (output_filename), ACE_OS::exit (1); + + run_tests (iteration_count, input_fp, output_fp); + + if (ACE_OS::fclose (input_fp) == -1 || ACE_OS::fclose (output_fp) == -1) + ACE_OS::perror ("fclose"), ACE_OS::exit (1); + + clean_up (); + return 0; +} diff --git a/examples/Mem_Map/Makefile b/examples/Mem_Map/Makefile new file mode 100644 index 00000000000..3c5d5f2d800 --- /dev/null +++ b/examples/Mem_Map/Makefile @@ -0,0 +1,22 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Mem_Map test directory +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +DIRS = IO-tests \ + file-reverse + +#---------------------------------------------------------------------------- +# macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU diff --git a/examples/Mem_Map/file-reverse/Makefile b/examples/Mem_Map/file-reverse/Makefile new file mode 100644 index 00000000000..ccc7ce66724 --- /dev/null +++ b/examples/Mem_Map/file-reverse/Makefile @@ -0,0 +1,58 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for Mem_Map file reverse test +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = file-reverse + +LSRC = $(addsuffix .cpp,$(BIN)) + +LDLIBS = + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +INSTALL = + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/file-reverse.o .shobj/file-reverse.so: file-reverse.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/Mem_Map/file-reverse/file-reverse.cpp b/examples/Mem_Map/file-reverse/file-reverse.cpp new file mode 100644 index 00000000000..d3431c40b0f --- /dev/null +++ b/examples/Mem_Map/file-reverse/file-reverse.cpp @@ -0,0 +1,45 @@ +#include "ace/Log_Msg.h" +// @(#)file-reverse.cpp 1.1 10/18/96 + +#include "ace/Mem_Map.h" + +static void +putline (const char *s) +{ + while (putchar (*s++) != '\n') + continue; +} + +static void +print_array_in_reverse (char *array, int size) +{ + size--; + + if (array[size] == '\0') + array[size] = '\n'; + + while (--size >= 0) + if (array[size] == '\n') + putline (array + size + 1); + + putline (array); +} + +int +main (int argc, char **argv) +{ + ACE_LOG_MSG->open (argv[0]); + void *cp; + + if (argc != 2) + ACE_ERROR_RETURN ((LM_ERROR, "usage: %n file\n%a"), -1); + + ACE_Mem_Map mmap; + + if (mmap.map (argv[1]) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n%a", "mmap"), -1); + + print_array_in_reverse ((char *) mmap.addr (), mmap.size ()); + + return 0; +} diff --git a/examples/Misc/Makefile b/examples/Misc/Makefile new file mode 100644 index 00000000000..8f950973535 --- /dev/null +++ b/examples/Misc/Makefile @@ -0,0 +1,283 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for testing the miscellaneous ACE components. +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = test_dump \ + test_profile_timer \ + test_read_buffer \ + test_sstring \ + test_trace \ + test_XtReactor1 \ + test_XtReactor2 + +LSRC = $(addsuffix .cpp,$(BIN)) + +LDLIBS = + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/test_dump.o .shobj/test_dump.so: test_dump.cpp \ + $(WRAPPER_ROOT)/ace/Dump.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Dump_T.h \ + $(WRAPPER_ROOT)/ace/Dump_T.cpp +.obj/test_profile_timer.o .shobj/test_profile_timer.so: test_profile_timer.cpp \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i +.obj/test_read_buffer.o .shobj/test_read_buffer.so: test_read_buffer.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Read_Buffer.h \ + $(WRAPPER_ROOT)/ace/Read_Buffer.i +.obj/test_sstring.o .shobj/test_sstring.so: test_sstring.cpp \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i +.obj/test_trace.o .shobj/test_trace.so: test_trace.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i +.obj/test_XtReactor1.o .shobj/test_XtReactor1.so: test_XtReactor1.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/XtReactor.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h +.obj/test_XtReactor2.o .shobj/test_XtReactor2.so: test_XtReactor2.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/XtReactor.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/Misc/test_XtReactor1.cpp b/examples/Misc/test_XtReactor1.cpp new file mode 100644 index 00000000000..0204278a3e9 --- /dev/null +++ b/examples/Misc/test_XtReactor1.cpp @@ -0,0 +1,138 @@ +// The following is another test that exercises the Eric C. Newton's +// @(#)test_XtReactor1.cpp 1.1 10/18/96 + +// XtReactor implementation. + +#include "ace/Log_Msg.h" +#include "ace/XtReactor.h" +#include "ace/Message_Block.h" + +#if defined (ACE_HAS_XT) +#include + +class Stdout : public ACE_Event_Handler +{ +public: + Stdout (ACE_Reactor * r) + : reactor_ (r), msg_ (1000000) + { + int flags; + flags = ACE_OS::fcntl (ACE_STDOUT, F_GETFL); + + if (flags != -1 + && ACE_OS::fcntl (ACE_STDOUT, F_SETFL, flags | O_NONBLOCK) != -1) + return; + else + ACE_DEBUG ((LM_DEBUG, "Unable to set stdout to non-block.")); + } + + ACE_HANDLE get_handle (void) const { return ACE_STDOUT; } + + int handle_output (ACE_HANDLE) + { + char *s = msg_.rd_ptr (); + + if (ACE_OS::write (ACE_STDOUT, s, 1)==1) + { + ACE_DEBUG ((LM_DEBUG, "wrote output '%d'\n", (int) *s)); + msg_.rd_ptr (1); + } + + if (msg_.length () == 0) + { + reactor_->remove_handler (this, ACE_Event_Handler::WRITE_MASK); + msg_.rd_ptr (msg_.base ()); + msg_.wr_ptr (msg_.base ()); + } + return 0; + } + + void put (char c) + { + if (msg_.length () == 0) + reactor_->register_handler (this, ACE_Event_Handler::WRITE_MASK); + + if (msg_.wr_ptr () < msg_.end ()) + { + *msg_.wr_ptr () = c; + msg_.wr_ptr (1); + } + else + ACE_DEBUG ((LM_DEBUG, "Oops... data falling off the end of the buffer!\n")); + } + +private: + ACE_Reactor *reactor_; + ACE_Message_Block msg_; +}; + +class Stdin : public ACE_Event_Handler +{ +public: + Stdin (Stdout *out) + : out_ (out) {} + + ACE_HANDLE get_handle () const { return ACE_STDIN; } + + int handle_input (ACE_HANDLE) + { + char c; + + if (ACE_OS::read (ACE_STDIN, &c, 1) == 1) + out_->put (c); + + return 0; + } + + int handle_timeout (const ACE_Time_Value &tv, const void *) + { + ACE_DEBUG ((LM_DEBUG, "Timeout! %f\n", (double) (tv.msec ()/1000.))); + return 0; + } + +private: + Stdout *out_; +}; + +static void +ActivateCB (Widget, XtPointer, XtPointer) +{ + ACE_DEBUG ((LM_DEBUG, "Button pushed!\n")); +} + +int +main (int argc, char**argv) +{ + // The worlds most useless user interface + Widget top_level = XtVaAppInitialize (NULL, "buttontest", NULL, 0, + &argc, argv, NULL, NULL); + Widget button = XmCreatePushButton (top_level, "change", 0, 0); + XtManageChild (button); + XtAddCallback (button, XmNactivateCallback, ActivateCB, NULL); + + // A reactor beastie + ACE_XtReactor reactor (XtWidgetToApplicationContext (top_level)); + + // Print a message when data is recv'd on stdin... + ACE_Event_Handler *stdin_ = new Stdin (new Stdout (&reactor)); + reactor.register_handler (stdin_, ACE_Event_Handler::READ_MASK); + + // Print a message every 10 seconds. + reactor.schedule_timer (stdin_, 0, ACE_Time_Value (10), ACE_Time_Value (10)); + + // Show the top_level widget. + XtRealizeWidget (top_level); + + // Demonstrate Reactor/Xt event loop unification. + XtAppMainLoop (XtWidgetToApplicationContext (top_level)); + + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "XT not configured for this platform\n")); + return 0; +} +#endif /* ACE_HAS_XT */ diff --git a/examples/Misc/test_XtReactor2.cpp b/examples/Misc/test_XtReactor2.cpp new file mode 100644 index 00000000000..31d43c6cab5 --- /dev/null +++ b/examples/Misc/test_XtReactor2.cpp @@ -0,0 +1,70 @@ +// The following test exercises the Eric C. Newton's +// @(#)test_XtReactor2.cpp 1.1 10/18/96 + +// XtReactor implementation. + +#include "ace/Log_Msg.h" +#include "ace/XtReactor.h" +#include "ace/Message_Block.h" + +#if defined (ACE_HAS_XT) +#include + +class Stdin : public ACE_Event_Handler +{ +public: + ACE_HANDLE get_handle (void) const { return ACE_STDIN; } + + int handle_input (ACE_HANDLE fd) + { + char c; + if (read (0, &c, 1)==1) + printf ("Got input '%d'\n", (int)c); + return 0; + } + + int handle_timeout (const ACE_Time_Value &tv, const void *arg) + { + printf ("Timeout! %f\n", (double) (tv.msec ()/1000.)); + return 0; + } +}; + +void ActivateCB (Widget w, XtPointer, XtPointer) +{ + printf ("Button pushed!\n"); +} + +int main (int argc, char**argv) +{ + // The worlds most useless user interface + Widget top_level = XtVaAppInitialize (NULL, "buttontest", NULL, 0, + &argc, argv, NULL, NULL); + Widget button = XmCreatePushButton (top_level, "change", 0, 0); + XtManageChild (button); + XtAddCallback (button, XmNactivateCallback, ActivateCB, NULL); + + // A reactor beastie + XtReactor reactor (XtWidgetToApplicationContext (top_level)); + + // Print a message when data is recv'd on stdin... + ACE_Event_Handler * stdin_ = new Stdin; + reactor.register_handler (stdin_, ACE_Event_Handler::READ_MASK); + + // Print a message every 10 seconds + reactor.schedule_timer (stdin_, 0, ACE_Time_Value (10), ACE_Time_Value (10)); + + // Show the top_level widget + XtRealizeWidget (top_level); + + // Demonstrate Reactor/Xt event loop unification: + XtAppMainLoop (XtWidgetToApplicationContext (top_level)); +} +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "XT not configured for this platform\n")); + return 0; +} +#endif /* ACE_HAS_XT */ diff --git a/examples/Misc/test_dump.cpp b/examples/Misc/test_dump.cpp new file mode 100644 index 00000000000..e76190b491a --- /dev/null +++ b/examples/Misc/test_dump.cpp @@ -0,0 +1,71 @@ +// The following code illustrates how the ACE_Dumpable mechanisms are +// @(#)test_dump.cpp 1.1 10/18/96 + +// integrated into ACE components like the SOCK_Acceptor and +// SOCK_Stream. + +#include "ace/Dump.h" + +class SOCK +{ +public: + SOCK (void) { ACE_REGISTER_OBJECT (SOCK); } + ~SOCK (void) { ACE_REMOVE_OBJECT; } + + void dump (void) const { + cerr << "hello from SOCK = " << (u_long) this << endl; + } + + // ... +}; + +class SOCK_Acceptor : public SOCK +{ +public: + SOCK_Acceptor (void) { ACE_REGISTER_OBJECT (SOCK_Acceptor); } + ~SOCK_Acceptor (void) { ACE_REMOVE_OBJECT; } + + void dump (void) const { + cerr << "hello from SOCK_Acceptor = " << (u_long) this << endl; + } + + // ... +}; + +class SOCK_Stream : public SOCK +{ +public: + SOCK_Stream (void) { ACE_REGISTER_OBJECT (SOCK_Stream); } + ~SOCK_Stream (void) { ACE_REMOVE_OBJECT; } + + void dump (void) const { + cerr << "hello from SOCK_Stream = " << (u_long) this << endl; + } + + // ... +}; + +int +main (void) +{ + SOCK sock; + // Note that the SOCK superclass is *not* printed. + SOCK_Stream stream; + SOCK_Acceptor acceptor; + ACE_ODB::instance ()->dump_objects (); + { + SOCK sock; + // Note that the SOCK superclass is *not* printed. + SOCK_Stream stream; + SOCK_Acceptor acceptor; + ACE_ODB::instance ()->dump_objects (); + } + ACE_ODB::instance ()->dump_objects (); + return 0; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Dumpable_Adapter; +template class ACE_Dumpable_Adapter; +template class ACE_Dumpable_Adapter; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/examples/Misc/test_profile_timer.cpp b/examples/Misc/test_profile_timer.cpp new file mode 100644 index 00000000000..5b888eb2362 --- /dev/null +++ b/examples/Misc/test_profile_timer.cpp @@ -0,0 +1,33 @@ +#include "ace/Profile_Timer.h" +// @(#)test_profile_timer.cpp 1.1 10/18/96 + +#include "ace/Log_Msg.h" + +static const int DEFAULT_ITERATIONS = 100000000; + +int +main (int argc, char *argv[]) +{ + ACE_Profile_Timer timer; + int iterations = argc > 1 ? ACE_OS::atoi (argv[1]) : DEFAULT_ITERATIONS; + + timer.start (); + + for (int i = 0; i < iterations; i++) + ACE_OS::getpid (); + + timer.stop (); + + ACE_Profile_Timer::ACE_Elapsed_Time et; + + timer.elapsed_time (et); + + ACE_DEBUG ((LM_DEBUG, "iterations = %d\n", iterations)); + ACE_DEBUG ((LM_DEBUG, "real time = %f secs, user time = %f secs, system time = %f secs\n", + et.real_time, et.user_time, et.system_time)); + + ACE_DEBUG ((LM_DEBUG, "time per call = %f usecs\n", + (et.real_time / double (iterations)) * 1000000)); + return 0; +} + diff --git a/examples/Misc/test_read_buffer.cpp b/examples/Misc/test_read_buffer.cpp new file mode 100644 index 00000000000..b7eb4947b3a --- /dev/null +++ b/examples/Misc/test_read_buffer.cpp @@ -0,0 +1,30 @@ +#include "ace/Service_Config.h" +// @(#)test_read_buffer.cpp 1.1 10/18/96 + +#include "ace/Read_Buffer.h" + +int +main (int argc, char *argv[]) +{ + int handle = argc > 1 ? ::open (argv[1], O_RDONLY) : 0; + int term = argc > 2 ? ::atoi (argv[2]) : EOF; + int search = argc > 3 ? ::atoi (argv[3]) : '\n'; + int replace = argc > 4 ? ::atoi (argv[4]) : '\0'; + + ACE_Read_Buffer rb (handle); + + char *buf; + + while ((buf = rb.read (term, search, replace)) != 0) + { + ::write (1, buf, rb.size ()); + ACE_Service_Config::allocator ()->free (buf); + } + return 0; +} + +#if 0 +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Stream; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ +#endif diff --git a/examples/Misc/test_sstring.cpp b/examples/Misc/test_sstring.cpp new file mode 100644 index 00000000000..fb04760c724 --- /dev/null +++ b/examples/Misc/test_sstring.cpp @@ -0,0 +1,22 @@ +#include "ace/SString.h" +// @(#)test_sstring.cpp 1.1 10/18/96 + + +int +main (int argc, char *argv[]) +{ + ACE_CString s1 ("hello"); + ACE_CString s2 ("world"); + ACE_CString s3 ("el"); + ACE_WString s4 ("hello"); + ACE_WString s5 ("world"); + ACE_WString s6 ("el"); + + ACE_ASSERT (s1 != s2); + ACE_ASSERT (s1.strstr (s2) == -1); + ACE_ASSERT (s1.strstr (s2) == -1); + ACE_ASSERT (s1.strstr (s3)); + ACE_ASSERT (s4.strstr (s5) == -1); + ACE_ASSERT (s5.strstr (s6)); + return 0; +} diff --git a/examples/Misc/test_trace.cpp b/examples/Misc/test_trace.cpp new file mode 100644 index 00000000000..e452140f665 --- /dev/null +++ b/examples/Misc/test_trace.cpp @@ -0,0 +1,52 @@ +// Enable tracing +// @(#)test_trace.cpp 1.1 10/18/96 + +#define ACE_NTRACE 0 +#include "ace/Log_Msg.h" + +#if defined (ACE_MT_SAFE) +#include "ace/Thread.h" +#endif /* ACE_MT_SAFE */ + +#include "ace/Signal.h" + +static void +foo (int max_depth) +{ + ACE_Trace _ ("void foo (void)", __LINE__, __FILE__); + + if (max_depth > 0) + foo (max_depth - 1); + /* Destructor automatically called */ +} + +int +main (int argc, char *argv[]) +{ + const int MAX_DEPTH = argc == 1 ? 10 : atoi (argv[1]); + + if (argc > 2) + ACE_Trace::set_nesting_indent (ACE_OS::atoi (argv[2])); + + ACE_Trace _ ("int main (int argc, char *argv[])", __LINE__, __FILE__); + + ACE_Sig_Action sig1 ((ACE_SignalHandler) ACE_Trace::start_tracing, SIGUSR1); + ACE_Sig_Action sig2 ((ACE_SignalHandler) ACE_Trace::stop_tracing, SIGUSR2); + +#if defined (ACE_MT_SAFE) + int n_threads = argc > 3 ? ACE_OS::atoi (argv[3]) : 4; + + if (ACE_Thread::spawn_n (n_threads, ACE_THR_FUNC (foo), + (void *) MAX_DEPTH, + THR_BOUND | THR_DETACHED) != n_threads) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn_n"), -1); + ACE_OS::thr_exit (0); +#else + for (;;) + foo (MAX_DEPTH); +#endif /* ACE_MT_SAFE */ + + /* Destructor automatically called */ + return 0; +} + diff --git a/examples/OS/Makefile b/examples/OS/Makefile new file mode 100644 index 00000000000..57607591fea --- /dev/null +++ b/examples/OS/Makefile @@ -0,0 +1,21 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the OS class examples +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +DIRS = Process + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU diff --git a/examples/OS/Process/Makefile b/examples/OS/Process/Makefile new file mode 100644 index 00000000000..a4113d16997 --- /dev/null +++ b/examples/OS/Process/Makefile @@ -0,0 +1,47 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for repeating token client application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = process + +FILES = process + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + + + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/OS/Process/Process.mak b/examples/OS/Process/Process.mak new file mode 100644 index 00000000000..bf99fd864af --- /dev/null +++ b/examples/OS/Process/Process.mak @@ -0,0 +1,311 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +!IF "$(CFG)" == "" +CFG=Process - Win32 Debug +!MESSAGE No configuration specified. Defaulting to Process - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "Process - Win32 Release" && "$(CFG)" !=\ + "Process - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Process.mak" CFG="Process - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Process - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Process - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +RSC=rc.exe +CPP=cl.exe + +!IF "$(CFG)" == "Process - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +OUTDIR=.\Release +INTDIR=.\Release + +ALL : "$(OUTDIR)\Process.exe" + +CLEAN : + -@erase ".\Release\Process.exe" + -@erase ".\Release\process.obj" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\ + /Fp"$(INTDIR)/Process.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Process.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ace.lib /nologo /subsystem:console /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ace.lib /nologo\ + /subsystem:console /incremental:no /pdb:"$(OUTDIR)/Process.pdb" /machine:I386\ + /out:"$(OUTDIR)/Process.exe" +LINK32_OBJS= \ + "$(INTDIR)/process.obj" + +"$(OUTDIR)\Process.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Process - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +OUTDIR=. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Process.exe" + +CLEAN : + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + -@erase ".\Process.exe" + -@erase ".\Debug\process.obj" + -@erase ".\Process.ilk" + -@erase ".\Process.pdb" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\ + /Fp"$(INTDIR)/Process.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Process.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ace.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ace.lib /nologo\ + /subsystem:console /incremental:yes /pdb:"$(OUTDIR)/Process.pdb" /debug\ + /machine:I386 /out:"$(OUTDIR)/Process.exe" +LINK32_OBJS= \ + "$(INTDIR)/process.obj" + +"$(OUTDIR)\Process.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "Process - Win32 Release" +# Name "Process - Win32 Debug" + +!IF "$(CFG)" == "Process - Win32 Release" + +!ELSEIF "$(CFG)" == "Process - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\process.cpp +DEP_CPP_PROCE=\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Process.h"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\types.h"\ + {$(INCLUDE)}"\sys\stat.h"\ + {$(INCLUDE)}"\sys\timeb.h"\ + {$(INCLUDE)}"\ace\msg_hack.h"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\ARGV.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Svc_Handler.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Acceptor.h"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.h"\ + {$(INCLUDE)}"\ace\Process.i"\ + {$(INCLUDE)}"\ace\ARGV.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Task.h"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\Svc_Handler.i"\ + {$(INCLUDE)}"\ace\Svc_Handler.cpp"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Message_Queue.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Task.i"\ + {$(INCLUDE)}"\ace\Task.cpp"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\ + {$(INCLUDE)}"\ace\Message_Queue.i"\ + {$(INCLUDE)}"\ace\Message_Queue.cpp"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Module.h"\ + {$(INCLUDE)}"\ace\Module.i"\ + {$(INCLUDE)}"\ace\Module.cpp"\ + {$(INCLUDE)}"\ace\Stream_Modules.h"\ + {$(INCLUDE)}"\ace\Stream_Modules.i"\ + {$(INCLUDE)}"\ace\Stream_Modules.cpp"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Dynamic.h"\ + {$(INCLUDE)}"\ace\Dynamic.i"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Strategies.h"\ + {$(INCLUDE)}"\ace\Acceptor.i"\ + {$(INCLUDE)}"\ace\Acceptor.cpp"\ + {$(INCLUDE)}"\ace\Strategies.cpp"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.i"\ + +NODEP_CPP_PROCE=\ + "..\..\ACE_wrappers\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\process.obj" : $(SOURCE) $(DEP_CPP_PROCE) "$(INTDIR)" + + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/examples/OS/Process/Process.mdp b/examples/OS/Process/Process.mdp new file mode 100644 index 00000000000..dba659ad56d Binary files /dev/null and b/examples/OS/Process/Process.mdp differ diff --git a/examples/OS/Process/README b/examples/OS/Process/README new file mode 100644 index 00000000000..2c2c801d5df --- /dev/null +++ b/examples/OS/Process/README @@ -0,0 +1,10 @@ +This example shows how to use ACE_Process to "portably" create new +processes and set their standard handles (stdin, stdout, and stderr). +On UNIX, ACE_Process uses fork and exec. On Win32, it uses +CreateProcess. Since we can set the standard handles, we can mimic +UNIX pipes on Win32 by building chains of processes. + +Run the application by typing ./process [filename]. It creates a new +process to print the contents of (default is the name of +the file "process.cpp") to the main console. So all you should see is +process.cpp printed to the screen. Not very exciting... diff --git a/examples/OS/Process/process.cpp b/examples/OS/Process/process.cpp new file mode 100644 index 00000000000..56979c31cd4 --- /dev/null +++ b/examples/OS/Process/process.cpp @@ -0,0 +1,64 @@ +// ============================================================================ +// @(#)process.cpp 1.1 10/18/96 + +// +// = LIBRARY +// examples +// +// = FILENAME +// process.cpp +// +// = DESCRIPTION +// This example tests the ACE_Process. For more info, check the +// README file in this directory. +// +// = AUTHOR +// Tim Harrison. +// +// ============================================================================ + +#include "ace/OS.h" +#include "ace/Log_Msg.h" +#include "ace/Process.h" + +#if defined (ACE_WIN32) +#define EXEC_NAME "c:\\WINNT35\\system32\\MORE.COM" +#else +#define EXEC_NAME "/usr/bin/cat"; +#endif /* ACE_WIN32 */ + +int +main (int argc, char *argv[]) +{ + if (ACE_LOG_MSG->open (argv[0]) == -1) + ACE_ERROR ((LM_ERROR, "cannot open logger!!!\n")); + + char *executable = argc > 1 ? argv[1] : EXEC_NAME; + char *input_file = argc > 2 ? argv[2] : "process.cpp"; + + ACE_HANDLE infile = ACE_OS::open (input_file, O_RDONLY); + + if (infile == ACE_INVALID_HANDLE) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", input_file), 1); + + static char *l_argv[2]; // Starts out with 0's ;-) + l_argv[0] = executable; + + // Try to create a new process running the . + ACE_Process new_process (l_argv, infile); + + if (ACE_LOG_MSG->op_status () == -1) + { + int error = ACE_OS::last_error (); + ACE_ERROR ((LM_ERROR, "%p errno = %d.\n", + executable, error)); + } + + new_process.wait (); + ACE_OS::close (infile); + + ACE_DEBUG ((LM_DEBUG, "Goodbye.\n")); + return 42; +} + + diff --git a/examples/README b/examples/README new file mode 100644 index 00000000000..38bb99b7d1d --- /dev/null +++ b/examples/README @@ -0,0 +1,74 @@ +This directory contains a number of examples that illustrate how to +use the following ACE library components. If you want to see how +to program using ACE, this is the best place to start reading code and +learning the ACE design. + +These examples are roughly divided up according to the class +categories in ACE. For more information on ACE class categories, +please take a look at $WRAPPER_ROOT/ACE-categories. + + . ASX + Illustrate various components in the ADAPTIVE Service + eXecutive, which is a user-level implementation of + System V STREAMS written in C++. + + + . CORBA + Illustrate how CORBA can be integrated into ACE. + + . Connection + Illustrate how the various Acceptor and Connector + components can be used. + + . IPC_SAP + Illustrate the C++ wrappers for Sockets, TLI, UNIX and + Win32 Named Pipes, and UNIX Stream Pipes. + + . Log_Msg + Illustrate some of the features of the logging + facility used in ACE to consolidate debugging and + error report. + + . Logger + This is a simple version of a Server Logging Daemon + that illustrates the "bare-bones" usage of the + Reactor. A more sophisticated set of logging examples + are in the $WRAPPER_ROOT/netsvcs/{client,lib,server} + directories. + + . Mem_Map + Illustrate how the ACE memory-mapped file components + work. + + . Misc + Various miscellaneous tests that illustrate how ACE + utility components work. + + . Reactor + Contains many examples of how to utilize the ACE + object-oriented event demultiplexer. + + . Service_Configurator + Illustrates the use of the ACE mechanism for + dynamically configuring communication services. + + . Shared_Malloc + Illustrates the use of ACE wrappers for + sophisticated use of the ACE_Malloc shared + memory components. + + . Shared_Memory + Illustrates the use of simple ACE wrappers for + shared memory and memory mapped file. + + . System_V_IPC + Illustrates how to use the ACE wrappers for System V + IPC (i.e., semphores, shared memory, and message + queues). + + . Threads + Illustrates the use of ACE wrappers for threading + and synchronization. + + + diff --git a/examples/Reactor/Dgram/CODgram.cpp b/examples/Reactor/Dgram/CODgram.cpp new file mode 100644 index 00000000000..8856e92d3c5 --- /dev/null +++ b/examples/Reactor/Dgram/CODgram.cpp @@ -0,0 +1,121 @@ +/* Exercise the ACE_SOCK_CODgram wrapper along with the ACE_Reactor. +// @(#)CODgram.cpp 1.1 10/18/96 + + + Typical invocation sequence is: + + % CODgram 10000 localhost 10001 & + % CODgram 10001 localhost 10000 + + This will start two interacting copies of the CODgram + application. */ + +#include "ace/Reactor.h" +#include "ace/SOCK_CODgram.h" +#include "ace/INET_Addr.h" + +class AAL_CP : public ACE_Event_Handler, public ACE_SOCK_CODgram +{ +public: + AAL_CP (const ACE_INET_Addr &remote_addr, + const ACE_INET_Addr &local_addr); + + virtual int get_handle () const; + + virtual int handle_input (int fd); + + virtual int handle_timeout (const ACE_Time_Value & tv, + const void *arg = 0); +}; + +AAL_CP::AAL_CP (const ACE_INET_Addr &remote_addr, + const ACE_INET_Addr &local_addr) + : ACE_SOCK_CODgram (remote_addr, local_addr) +{ +} + +int +AAL_CP::get_handle () const +{ + return ACE_SOCK_CODgram::get_handle (); +} + +int +AAL_CP::handle_input (int) +{ + char buf[128]; + int n; + ACE_DEBUG ((LM_DEBUG, "Activity occurred on handle %d!\n", + ACE_SOCK_CODgram::get_handle ())); + if ((n = ACE_SOCK_CODgram::recv (buf, sizeof buf)) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "handle_input")); + else + ACE_DEBUG ((LM_DEBUG, "got buf = %s\n", buf)); + + return 0; +} + +int +AAL_CP::handle_timeout (const ACE_Time_Value &, const void *) +{ + ACE_DEBUG ((LM_DEBUG, "timed out for aa1\n")); + return 0; +} + +main(int argc, char *argv[]) +{ + /* Estabish call backs, and socket names */ + if (argc != 4) + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s localport remotehost remoteport\n", + argv[0]), -1); + + ACE_Reactor reactor; + char buf[128]; + u_short localport = ACE_OS::atoi (argv[1]); + u_short remoteport = ACE_OS::atoi (argv[3]); + char *remotehost = argv[2]; + + ACE_INET_Addr remote_addr (remoteport, remotehost); + ACE_INET_Addr local_addr (localport); + + AAL_CP aal (remote_addr, local_addr); + + if (localport == 10000) // HACK + { + ACE_OS::memcpy (buf, "Data to transmit", sizeof buf); + ACE_DEBUG ((LM_DEBUG, "sending data\n")); + + for (int i = 0; i < 20; i++) + { + aal.send (buf, sizeof buf); + ACE_DEBUG ((LM_DEBUG, ".\n")); + ACE_OS::sleep (1); + } + } + + /* read data from other side */ + if (reactor.register_handler (&aal, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "ACE_Reactor::register_handler"), -1); + + if (reactor.schedule_timer (&aal, 0, + ACE_Time_Value (1, 0), + ACE_Time_Value (0, 3500000)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "ACE_Reactor::schedule_timer"), -1); + + ACE_OS::memcpy (buf, "Data to transmit", sizeof buf); + + for (;;) + { + /* Wait at most two seconds */ + ACE_Time_Value tv (2, 0); + + reactor.handle_events (tv); + + ACE_DEBUG ((LM_DEBUG, "return from handle events\n")); + aal.send (buf, sizeof buf); + ACE_DEBUG ((LM_DEBUG, ".\n")); + } + + return 0; +} diff --git a/examples/Reactor/Dgram/Dgram.cpp b/examples/Reactor/Dgram/Dgram.cpp new file mode 100644 index 00000000000..d2f4305f267 --- /dev/null +++ b/examples/Reactor/Dgram/Dgram.cpp @@ -0,0 +1,121 @@ +// Exercise the ACE_SOCK_Dgram wrapper along with the ACE_Reactor. +// @(#)Dgram.cpp 1.1 10/18/96 + +// Typical invocation sequence is: +// +// % Dgram 10000 localhost 10001 & +// % Dgram 10001 localhost 10000 +// +// This will start two interacting copies of the Dgram +// application. + +#include "ace/Reactor.h" +#include "ace/SOCK_Dgram.h" +#include "ace/INET_Addr.h" + +class AAL_CP : public ACE_Event_Handler, public ACE_SOCK_Dgram +{ +public: + AAL_CP (const ACE_INET_Addr &local_addr); + + virtual ACE_HANDLE get_handle (void) const; + + virtual int handle_input (ACE_HANDLE handle); + + virtual int handle_timeout (const ACE_Time_Value & tv, + const void *arg = 0); +}; + +AAL_CP::AAL_CP (const ACE_INET_Addr &local_addr) + : ACE_SOCK_Dgram (local_addr) +{ +} + +ACE_HANDLE +AAL_CP::get_handle (void) const +{ + return ACE_SOCK_Dgram::get_handle (); +} + +int +AAL_CP::handle_input (ACE_HANDLE) +{ + char buf[BUFSIZ]; + int n; + ACE_INET_Addr from_addr; + + ACE_DEBUG ((LM_DEBUG, "Activity occurred on handle %d!\n", + ACE_SOCK_Dgram::get_handle ())); + if ((n = ACE_SOCK_Dgram::recv (buf, sizeof buf, from_addr)) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "handle_input")); + else + ACE_DEBUG ((LM_DEBUG, "got buf = %s\n", buf)); + + return 0; +} + +int +AAL_CP::handle_timeout (const ACE_Time_Value &, const void *) +{ + ACE_DEBUG ((LM_DEBUG, "timed out for aa1\n")); + return 0; +} + +int +main (int argc, char *argv[]) +{ + // Estabish call backs, and socket names. + if (argc != 4) + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s localport remotehost remoteport\n", + argv[0]), -1); + + ACE_Reactor reactor; + char buf[128]; + u_short localport = ACE_OS::atoi (argv[1]); + u_short remoteport = ACE_OS::atoi (argv[3]); + char *remotehost = argv[2]; + + ACE_INET_Addr remote_addr (remoteport, remotehost); + ACE_INET_Addr local_addr (localport); + + AAL_CP aal (local_addr); + + if (localport == 10000) // HACK + { + ACE_OS::memcpy (buf, "Data to transmit", sizeof buf); + ACE_DEBUG ((LM_DEBUG, "sending data\n")); + + for (size_t i = 0; i < 20; i++) + { + aal.send (buf, sizeof buf, remote_addr); + ACE_DEBUG ((LM_DEBUG, ".\n")); + ACE_OS::sleep (1); + } + } + + // Read data from other side. + if (reactor.register_handler (&aal, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "ACE_Reactor::register_handler"), -1); + + if (reactor.schedule_timer (&aal, 0, + ACE_Time_Value (1, 0), + ACE_Time_Value (0, 3500000)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "ACE_Reactor::schedule_timer"), -1); + + ACE_OS::memcpy (buf, "Data to transmit", sizeof buf); + + for (;;) + { + // Wait at most two seconds. + ACE_Time_Value tv (2, 0); + + reactor.handle_events (tv); + + ACE_DEBUG ((LM_DEBUG, "return from handle events\n")); + aal.send (buf, sizeof buf, remote_addr); + ACE_DEBUG ((LM_DEBUG, ".\n")); + } + + return 0; +} diff --git a/examples/Reactor/Dgram/Makefile b/examples/Reactor/Dgram/Makefile new file mode 100644 index 00000000000..5c2204cd91a --- /dev/null +++ b/examples/Reactor/Dgram/Makefile @@ -0,0 +1,135 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for a test of the CODgram and Dgram facilities and the Reactor +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = CODgram Dgram + +LSRC = CODgram.cpp Dgram.cpp + +LDLIBS = + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +INSTALL = + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/CODgram.o .shobj/CODgram.so: CODgram.cpp \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/SOCK_CODgram.h \ + $(WRAPPER_ROOT)/ace/SOCK_CODgram.i +.obj/Dgram.o .shobj/Dgram.so: Dgram.cpp \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.h \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.i + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/Reactor/Makefile b/examples/Reactor/Makefile new file mode 100644 index 00000000000..4613709a2a2 --- /dev/null +++ b/examples/Reactor/Makefile @@ -0,0 +1,24 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Reactor tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +DIRS = Dgram \ + Misc \ + Multicast \ + Ntalker + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU diff --git a/examples/Reactor/Misc/Makefile b/examples/Reactor/Misc/Makefile new file mode 100644 index 00000000000..31d49795de7 --- /dev/null +++ b/examples/Reactor/Misc/Makefile @@ -0,0 +1,378 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for a test of the miscellaneous Reactor examples +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = pingpong \ + notification \ + signal_tester \ + test_event_handler_t \ + test_handle_set \ + test_reactors \ + test_signals \ + test_time_value \ + test_timer_queue + +LSRC = $(addsuffix .cpp,$(BIN)) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/pingpong.o .shobj/pingpong.so: pingpong.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i +.obj/notification.o .shobj/notification.so: notification.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h +.obj/signal_tester.o .shobj/signal_tester.so: signal_tester.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h +.obj/test_event_handler_t.o .shobj/test_event_handler_t.so: test_event_handler_t.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler_T.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h +.obj/test_handle_set.o .shobj/test_handle_set.so: test_handle_set.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Handle_Set.h +.obj/test_reactors.o .shobj/test_reactors.so: test_reactors.cpp \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i +.obj/test_signals.o .shobj/test_signals.so: test_signals.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i +.obj/test_time_value.o .shobj/test_time_value.so: test_time_value.cpp \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i +.obj/test_timer_queue.o .shobj/test_timer_queue.so: test_timer_queue.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/Reactor/Misc/notification.cpp b/examples/Reactor/Misc/notification.cpp new file mode 100644 index 00000000000..45836446b5a --- /dev/null +++ b/examples/Reactor/Misc/notification.cpp @@ -0,0 +1,249 @@ +#include "ace/Log_Msg.h" +// @(#)notification.cpp 1.1 10/18/96 + +#include "ace/Service_Config.h" +#include "ace/Thread.h" + +#if defined (ACE_HAS_THREADS) + +class Thread_Handler : public ACE_Event_Handler + // = TITLE + // Illustrate how the ACE_Reactor's thread-safe event notification + // mechanism works. + // + // = DESCRIPTION + // Handle timeouts in the main thread via the ACE_Reactor and I/O + // events in a separate thread. Just before the separate I/O thread + // exits it notifies the ACE_Reactor in the main thread using the + // ACE_Reactor's notification mechanism. +{ +public: + Thread_Handler (int delay, int interval, int n_threads); + Thread_Handler (size_t id): id_ (id) {} + + virtual int handle_signal (int signum, siginfo_t * = 0, ucontext_t * = 0); + // Handle signals. + + virtual int handle_exception (ACE_HANDLE); + // Print data from main thread. + + virtual int handle_output (ACE_HANDLE); + // Print data from main thread. + + virtual int handle_timeout (const ACE_Time_Value &, + const void *); + // Handle timeout events in the main thread. + + virtual int handle_input (ACE_HANDLE); + // General notification messages to the Reactor. + + virtual int notify (void); + // Perform notifications. + + virtual int svc (void); + // Handle I/O events in a separate threads. + +private: + static void *svc_run (void *); + // Glues C++ to C thread library functions. + + size_t id_; + // ID passed in by Thread_Handler constructor. + + // = Timing variables. + // Delay factor for timer-driven I/O. + static ACE_Time_Value delay_; + + // Interval factor for Event_Handler timer. + static ACE_Time_Value interval_; +}; + +// Delay factor for timer-driven I/O. +ACE_Time_Value Thread_Handler::delay_; + +// Interval factor for Event_Handler timer. +ACE_Time_Value Thread_Handler::interval_; + +Thread_Handler::Thread_Handler (int delay, + int interval, + int n_threads) +{ + delay_.set (delay); + interval_.set (interval); + + ACE_Sig_Set sig_set; + + sig_set.sig_add (SIGQUIT); + sig_set.sig_add (SIGINT); + + this->id_ = 0; + + if (ACE::register_stdin_handler (this, + ACE_Service_Config::reactor (), + ACE_Service_Config::thr_mgr ()) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "register_stdin_handler")); + + else if (ACE_Service_Config::reactor ()->register_handler (sig_set, this) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "register_handler")); + + else if (ACE_Service_Config::reactor ()->schedule_timer + (this, 0, Thread_Handler::delay_, Thread_Handler::interval_) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "schedule_timer")); + + // Set up this thread's signal mask, which is inherited by the + // threads it spawns. + + ACE_Thread::sigsetmask (SIG_BLOCK, sig_set); + + // Create N new threads of control Thread_Handlers. + + for (size_t i = 0; i < n_threads; i++) + if (ACE_Thread::spawn (&Thread_Handler::svc_run, + new Thread_Handler (i + 1), + THR_NEW_LWP | THR_DETACHED) != 0) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Thread::spawn")); + + // Unblock signal set so that only this thread receives them! + ACE_Thread::sigsetmask (SIG_UNBLOCK, sig_set); +} + +// Test stdin handling (can use select to demultiplex HANDLEs) + +int +Thread_Handler::handle_input (ACE_HANDLE handle) +{ + char buf[BUFSIZ]; + ssize_t n = ACE_OS::read (handle, buf, sizeof buf); + + if (n > 0) + { + ACE_DEBUG ((LM_DEBUG, "(%t) %*s", n, buf)); + return this->notify (); + } + else + return -1; +} + +int +Thread_Handler::notify (void) +{ + // Just do something to test the ACE_Reactor's multi-thread + // capabilities... + + if (ACE_Service_Config::reactor ()->notify + (this, ACE_Event_Handler::EXCEPT_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "notify"), -1); + + else if (ACE_Service_Config::reactor ()->notify + (this, ACE_Event_Handler::WRITE_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "notify"), -1); + + return 0; +} + +// Perform a task that will test the ACE_Reactor's multi-threading +// capabilities in separate threads. + +int +Thread_Handler::svc (void) +{ + for (;;) + { + if (Thread_Handler::delay_.sec () > 0) + // Block for delay_.secs () / 2, then notify the Reactor. + ACE_OS::sleep (Thread_Handler::delay_.sec () / 2); + + this->notify (); + } + return 0; +} + +// Test signal handling. + +int +Thread_Handler::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) received signal %S\n", signum)); + + switch (signum) + { + case SIGINT: + case SIGQUIT: + ACE_ERROR ((LM_ERROR, + "(%t) ******************** shutting down %n on signal %S\n", + signum)); + ACE_Service_Config::end_reactor_event_loop (); + } + return 0; +} + +int +Thread_Handler::handle_timeout (const ACE_Time_Value &time, + const void *) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) received timeout at (%u, %u)\n", + time.sec (), time.usec ())); + return 0; +} + +// Called by the ACE_Reactor when it receives a notification. + +int +Thread_Handler::handle_exception (ACE_HANDLE) +{ + ACE_DEBUG ((LM_DEBUG, + "(%t) handle_exception received notification from id %d\n", + this->id_)); + return 0; +} + +// Called by the ACE_Reactor when it receives a notification. + +int +Thread_Handler::handle_output (ACE_HANDLE) +{ + ACE_DEBUG ((LM_DEBUG, + "(%t) handle_output received notification from id %d\n", + this->id_)); + return 0; +} + +// "Shim" function that integrates C thread API with C++. + +void * +Thread_Handler::svc_run (void *eh) +{ + Thread_Handler *this_handler = (Thread_Handler *) eh; + + return this_handler->svc () == 0 ? 0 : (void *) -1; +} + +int +main (int argc, char *argv[]) +{ + // Required to initialize the Service Configurator. + ACE_Service_Config daemon (argv[0]); + + if (argc != 4) + ACE_ERROR ((LM_ERROR, + "usage: %s delay interval n_threads%a\n", + argv[0], 1)); + + int delay = ACE_OS::atoi (argv[1]); + int interval = ACE_OS::atoi (argv[2]); + size_t n_threads = ACE_OS::atoi (argv[3]); + + Thread_Handler thr_handler (delay, interval, n_threads); + + ACE_Service_Config::run_reactor_event_loop (); + ACE_DEBUG ((LM_DEBUG, "exiting from main%a\n", 1)); + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "threads not supported on this platform\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/Reactor/Misc/pingpong.cpp b/examples/Reactor/Misc/pingpong.cpp new file mode 100644 index 00000000000..a44267f4e82 --- /dev/null +++ b/examples/Reactor/Misc/pingpong.cpp @@ -0,0 +1,241 @@ +/* Simple program that illustrates all the features of the ACE_Reactor: +// @(#)pingpong.cpp 1.1 10/18/96 + + + 1. I/O event demultiplexing + 2. Signal-based demultiplexing + 3. Timer-based demultiplexing + + To test this program, compile it and then execute it as follows: + + % ./pingpong hello + + You should see lots of the following output: + + writing <4> [7860] + writing <4> [7860] + writing <4> [7860] + writing <4> [7860] + reading <5> (7860) [1] = hello + writing <4> [7860] + writing <5> [7861] + reading <4> (7861) [2] = hello + reading <5> (7860) [2] = hello + writing <4> [7860] + writing <5> [7861] + reading <4> (7861) [3] = hello + reading <5> (7860) [3] = hello + + After 10 seconds you'll see the following: + + ./pingpong: shutting down tester (pid = 7861) + ./pingpong: shutting down tester (pid = 7860) + + and the program will stop. If you'd like to + stop it earlier, just hit the control-C sequence + and you'll see the same messages. */ + +#include "ace/Log_Msg.h" +#include "ace/Synch.h" +#include "ace/Reactor.h" +#include "ace/Pipe.h" + +class Ping_Pong : public ACE_Test_and_Set +{ +public: + Ping_Pong (char b[], ACE_HANDLE f); + virtual ACE_HANDLE get_handle (void) const; + virtual int handle_input (ACE_HANDLE); + virtual int handle_output (ACE_HANDLE); + virtual int handle_timeout (const ACE_Time_Value &, const void *); + +private: + char buf_[BUFSIZ]; + // Buffer to send. + + size_t buflen_; + // Length of the buffer to send. + + int pid_; + // Process ID. + + ACE_HANDLE handle_; + // Open handle. +}; + +Ping_Pong::Ping_Pong (char b[], ACE_HANDLE f) + : handle_ (f), + buflen_ (ACE_OS::strlen (b) + 1 + (2 * sizeof (int))), + pid_ (ACE_OS::getpid ()) +{ + *((int *) this->buf_) = (int) this->pid_; + *((int *) (this->buf_ + sizeof (int))) = 0; + ACE_OS::strcpy (this->buf_ + (2 * sizeof (int)), b); + this->buf_[this->buflen_ - 1] = '\n'; + this->buf_[this->buflen_] = '\0'; +} + +ACE_HANDLE +Ping_Pong::get_handle (void) const +{ + return this->handle_; +} + +int +Ping_Pong::handle_input (ACE_HANDLE) +{ +#if defined (ACE_HAS_STREAM_PIPES) + // We can rely on record-oriented reads... + + ssize_t n = ACE::recv (this->handle_, this->buf_, this->buflen_); + + if (n != this->buflen_) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) reading [%d] %p\n", handle_, "read"), -1); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) reading <%d> (%d) [%d] = %s\n", + this->handle_, + *(int *) this->buf_, + *(int *) (this->buf_ + sizeof (int)), + this->buf_ + (2 * sizeof (int)))); +#else + ssize_t n = ACE::recv (this->handle_, this->buf_, sizeof this->buf_); + + if (n == -1) + ACE_ERROR_RETURN ((LM_ERROR, "[%d] %p\n", handle_, "read"), -1); + + n -= (2 * sizeof (int)); + char *buf = this->buf_ + (2 * sizeof (int)); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) reading <%d> = %*s\n", + this->handle_, n, buf)); +#endif /* ACE_HAS_STREAM_PIPES */ + return 0; +} + +int +Ping_Pong::handle_output (ACE_HANDLE) +{ +#if defined (ACE_HAS_STREAM_PIPES) + // We can rely on record-oriented reads... + + (*(int *) (this->buf_)) = this->pid_; + (*(int *) (this->buf_ + sizeof (int)))++; + if (ACE::send (this->handle_, this->buf_, this->buflen_) == -1) + return -1; + else + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) writing <%d> [%d]\n", + this->handle_, this->pid_)); + return 0; + } +#else + if (ACE::send (this->handle_, this->buf_, this->buflen_) == -1) + return -1; + else + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) writing <%d>\n", this->handle_)); + return 0; + } +#endif /* ACE_HAS_STREAM_PIPES */ +} + +int +Ping_Pong::handle_timeout (const ACE_Time_Value &, + const void *) +{ + this->set (1); + return 0; +} + +// Contains the string to "pingpong" back and forth... +static char *string_name; + +// Wait for 10 seconds and then shut down. +static const int SHUTDOWN_TIME = 10; + +#if defined (ACE_WIN32) +static ACE_Barrier barrier (3); + +static void * +worker (void *arg) +{ + ACE_HANDLE handle = (ACE_HANDLE) arg; + + run_svc (handle); + barrier.wait (); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) %n: shutting down tester\n")); + return 0; +} +#endif /* ACE_WIN32 */ + +static void +run_svc (ACE_HANDLE handle) +{ + ACE_Reactor reactor; + + Ping_Pong callback (string_name, handle); + + // Register the callback object for the various I/O, signal, and + // timer-based events. + + if (reactor.register_handler (&callback, + ACE_Event_Handler::READ_MASK + | ACE_Event_Handler::WRITE_MASK) == -1 + || reactor.register_handler (SIGINT, &callback) == -1 + || reactor.schedule_timer (&callback, 0, SHUTDOWN_TIME) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "reactor", 1)); + + // Main event loop (one per process). + + while (callback.is_set () == 0) + reactor.handle_events (); +} + +int +main (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0]); + + if (argc != 2) + ACE_ERROR ((LM_ERROR, "usage: %n string\n%a", 1)); + + string_name = argv[1]; + + ACE_HANDLE handles[2]; + + // Create a pipe and initialize the handles. + ACE_Pipe pipe (handles); + +#if defined (ACE_WIN32) + if (ACE_Thread::spawn (ACE_THR_FUNC (worker), + (void *) handles[0], + THR_DETACHED) == -1 + || ACE_Thread::spawn (ACE_THR_FUNC (worker), + (void *) handles[1], + THR_DETACHED) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "spawn", 1)); + + barrier.wait (); + +#else + pid_t pid = ACE_OS::fork (); + + if (pid == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "fork", 1)); + + // Resync the ACE_Log_Msg notion of process id and program name. + ACE_LOG_MSG->sync (argv[0]); + + run_svc (handles[pid == 0]); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) %n: shutting down tester\n")); +#endif /* ACE_WIN32 */ + + if (pipe.close () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "close")); + + return 0; +} diff --git a/examples/Reactor/Misc/signal_tester.cpp b/examples/Reactor/Misc/signal_tester.cpp new file mode 100644 index 00000000000..1631c00b2d0 --- /dev/null +++ b/examples/Reactor/Misc/signal_tester.cpp @@ -0,0 +1,221 @@ +// Perform an extensive test of the ACE_Reactor's event dispatching +// @(#)signal_tester.cpp 1.1 10/18/96 + +// mechanisms. These mechanisms illustrate how signals, I/O, and +// timeout events can all be handled within the same framework. In +// addition, this example illustrates how to use the ACE_Reactor for +// devices that perform I/O via signals (such as SVR4 message queues). + +#include "ace/Log_Msg.h" +#include "ace/Service_Config.h" + +// Used to shut down the event loop. +static sig_atomic_t done = 0; + +// This class illustrates how to handle signal-driven I/O using the +// ACE_Reactor framework. Note that signals may be caught and +// processed without requiring the use of global signal handler +// functions or global signal handler data. + +class Sig_Handler : public ACE_Event_Handler +{ +public: + Sig_Handler (void); + virtual ACE_HANDLE get_handle (void) const; + virtual int handle_input (ACE_HANDLE); + virtual int shutdown (ACE_HANDLE, ACE_Reactor_Mask); + virtual int handle_signal (ACE_HANDLE signum, siginfo_t * = 0, + ucontext_t * = 0); + +private: + ACE_HANDLE handle_; +}; + +// A dummy_handle is required to reserve a slot in the ACE_Reactor's +// descriptor table. + +Sig_Handler::Sig_Handler (void) +{ + // Assign the Sig_Handler a dummy I/O descriptor. Note that even + // though we open this file "Write Only" we still need to use the + // ACE_Event_Handler::NULL_MASK when registering this with the + // ACE_Reactor (see below). + this->handle_ = ACE_OS::open (ACE_DEV_NULL, O_WRONLY); + ACE_ASSERT (this->handle_ != -1); + + // Register signal handler object. Note that NULL_MASK is used to + // keep the ACE_Reactor from calling us back on the "/dev/null" + // descriptor. + if (ACE_Service_Config::reactor ()->register_handler + (this, ACE_Event_Handler::NULL_MASK) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "register_handler", 1)); + + // Create a sigset_t corresponding to the signals we want to catch. + ACE_Sig_Set sig_set; + + sig_set.sig_add (SIGINT); + sig_set.sig_add (SIGQUIT); + sig_set.sig_add (SIGALRM); + + // Register the signal handler object to catch the signals. + if (ACE_Service_Config::reactor ()->register_handler (sig_set, this) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "register_handler", 1)); +} + +// Called by the ACE_Reactor to extract the fd. + +ACE_HANDLE +Sig_Handler::get_handle (void) const +{ + return this->handle_; +} + +// In a real application, this method would be where the read on the +// signal-driven I/O device would occur asynchronously. For now we'll +// just print a greeting to let you know that everything is working +// properly! + +int +Sig_Handler::handle_input (ACE_HANDLE) +{ + ACE_DEBUG ((LM_DEBUG, "handling asynchonrous input...\n")); + return 0; +} + +// In a real application, this method would do any cleanup activities +// required when shutting down the I/O device. + +int +Sig_Handler::shutdown (ACE_HANDLE, ACE_Reactor_Mask) +{ + ACE_DEBUG ((LM_DEBUG, "closing down Sig_Handler...\n")); + return 0; +} + +// This method handles all the signals that are being caught by this +// object. In our simple example, we are simply catching SIGALRM, +// SIGINT, and SIGQUIT. Anything else is logged and ignored. +// +// There are several advantages to using this approach. First, +// the behavior triggered by the signal is handled in the main event +// loop, rather than in the signal handler. Second, the ACE_Reactor's +// signal handling mechanism eliminates the need to use global signal +// handler functions and data. + +int +Sig_Handler::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + ACE_DEBUG ((LM_DEBUG, "received signal %S\n", signum)); + + switch (signum) + { + case SIGALRM: + // Rearm the alarm. + ACE_OS::alarm (4); + break; + case SIGINT: + // Tell the ACE_Reactor to enable the ready bit for + // this->handle_. The ACE_Reactor will subsequently call the + // Sig_Handler::handle_input method from within its event loop. + return ACE_Service_Config::reactor ()->ready_ops + (this->handle_, ACE_Event_Handler::READ_MASK, ACE_Reactor::ADD_MASK); + case SIGQUIT: + ACE_DEBUG ((LM_DEBUG, "%S: shutting down signal tester\n", signum)); + ACE_Service_Config::end_reactor_event_loop (); + break; + default: + ACE_DEBUG ((LM_DEBUG, + "%S: not handled, returning to program\n", signum)); + break; + } + return 0; +} + +// This class illustrates that the ACE_Reactor can handle signals, +// STDIO, and timeouts using the same mechanisms. + +class STDIN_Handler : public ACE_Event_Handler +{ +public: + STDIN_Handler (void); + virtual int handle_input (ACE_HANDLE); + virtual int handle_timeout (const ACE_Time_Value &, + const void *arg); +}; + +STDIN_Handler::STDIN_Handler (void) +{ + if (ACE::register_stdin_handler (this, + ACE_Service_Config::reactor (), + ACE_Service_Config::thr_mgr ()) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "register_stdin_handler")); + + // Register the STDIN_Handler to be dispatched once every second. + else if (ACE_Service_Config::reactor ()->schedule_timer + (this, 0, ACE_Time_Value (1), ACE_Time_Value (1)) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "schedule_timer", 1)); +} + +int +STDIN_Handler::handle_timeout (const ACE_Time_Value &tv, + const void *arg) +{ + ACE_DEBUG ((LM_DEBUG, "timeout occurred at %d sec, %d usec\n", + tv.sec (), tv.usec ())); + return 0; +} + +// Read from input descriptor and write to stdout descriptor. + +int +STDIN_Handler::handle_input (ACE_HANDLE handle) +{ + ssize_t n; + char buf[BUFSIZ]; + + switch (n = ACE_OS::read (handle, buf, sizeof buf)) + { + case -1: + if (errno == EINTR) + return 0; + /* NOTREACHED */ + else + ACE_ERROR ((LM_ERROR, "%p\n", "read")); + /* FALLTHROUGH */ + case 0: + ACE_Service_Config::end_reactor_event_loop (); + break; + default: + { + ssize_t result = ACE::write_n (ACE_STDOUT, buf, n); + + if (result != n) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "write"), + result == -1 && errno == EINTR ? 0 : -1); + } + } + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config daemon (argv [0]); + + // Signal handler. + Sig_Handler sh; + + // Define an I/O handler object. + STDIN_Handler ioh; + + // Optionally start the alarm. + if (argc > 1) + ACE_OS::alarm (4); + + // Loop handling signals and I/O events until SIGQUIT occurs. + + while (daemon.reactor_event_loop_done () == 0) + daemon.run_reactor_event_loop (); + + return 0; +} diff --git a/examples/Reactor/Misc/test_event_handler_t.cpp b/examples/Reactor/Misc/test_event_handler_t.cpp new file mode 100644 index 00000000000..a28108baf10 --- /dev/null +++ b/examples/Reactor/Misc/test_event_handler_t.cpp @@ -0,0 +1,45 @@ +#include "ace/Log_Msg.h" +// @(#)test_event_handler_t.cpp 1.1 10/18/96 + +#include "ace/Event_Handler_T.h" + +#if defined (ACE_HAS_TEMPLATE_TYPEDEFS) + +class ACE_Sig_Handler +{ +public: + ACE_Sig_Handler (void) {} + virtual ACE_HANDLE get_handle (void) const { return 0; } + virtual void set_handle (ACE_HANDLE) {} + virtual int handle_async_io (ACE_HANDLE) { return 0; } + virtual int shutdown (ACE_HANDLE, ACE_Reactor_Mask) { return 0; } + virtual int signal_handler (ACE_HANDLE signum +#if defined (ACE_HAS_SIGINFO_T) + , siginfo_t * = 0, ucontext_t * = 0 +#endif /* ACE_HAS_SIGINFO_T */ + ) + { + return 0; + } +}; + +int +main (void) +{ + typedef ACE_Event_Handler_T EH_SH; + + // Tie the ACE_Event_Handler_T together with the methods from ACE_Sig_Handler. + EH_SH tied_sh (new ACE_Sig_Handler, 1, + &ACE_Sig_Handler::get_handle, + &ACE_Sig_Handler::handle_async_io, + &ACE_Sig_Handler::shutdown, + &ACE_Sig_Handler::signal_handler); + return 0; +} +#else +int +main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "your platform does not support template typedefs\n"), 1); +} +#endif /* ACE_HAS_TEMPLATE_TYPEDEFS */ diff --git a/examples/Reactor/Misc/test_handle_set.cpp b/examples/Reactor/Misc/test_handle_set.cpp new file mode 100644 index 00000000000..65e7db3fc67 --- /dev/null +++ b/examples/Reactor/Misc/test_handle_set.cpp @@ -0,0 +1,75 @@ +#include "ace/Log_Msg.h" +// @(#)test_handle_set.cpp 1.1 10/18/96 + +#include "ace/Handle_Set.h" + +#define IS_ODD(X) (((X) & 1) != 0) + +void +test1 (int count) +{ + int duplicates = 0; + int sets = 0; + int clears = 0; + + ACE_Handle_Set handle_set; + + ACE_OS::srand (ACE_OS::time (0L)); + + for (int i = 0; i < count; i++) + { + int i = int (ACE_OS::rand () % ACE_Handle_Set::MAXSIZE); + + if (IS_ODD (i)) + { + if (handle_set.is_set (i)) + duplicates++; + + handle_set.set_bit (i); + sets++; + } + else + { + if (handle_set.is_set (i)) + duplicates--; + + handle_set.clr_bit (i); + clears++; + } + } + + ACE_DEBUG ((LM_DEBUG, "count = %d, set_size = %d, duplicates = %d\n", + count, handle_set.num_set (), (sets - clears) == duplicates)); +} + +void +test2 (void) +{ + ACE_Handle_Set handle_set; + ACE_HANDLE handle; + + handle_set.set_bit (0); + handle_set.set_bit (1); + handle_set.set_bit (32); + handle_set.set_bit (63); + handle_set.set_bit (64); + handle_set.set_bit (65); + handle_set.set_bit (122); + handle_set.set_bit (129); + handle_set.set_bit (245); + handle_set.set_bit (255); + + for (ACE_Handle_Set_Iterator fi (handle_set); + (handle = fi ()) != -1; + ++fi) + ACE_DEBUG ((LM_DEBUG, "handle = %d\n", handle)); +} + +int +main (int argc, char *argv[]) +{ + int count = argc > 1 ? ACE_OS::atoi (argv[1]) : ACE_Handle_Set::MAXSIZE; + test1 (count); + test2 (); +} + diff --git a/examples/Reactor/Misc/test_reactors.cpp b/examples/Reactor/Misc/test_reactors.cpp new file mode 100644 index 00000000000..81bc1c3a20d --- /dev/null +++ b/examples/Reactor/Misc/test_reactors.cpp @@ -0,0 +1,205 @@ +// Perform a torture test of multiple ACE_Reactors and ACE_Tasks in +// @(#)test_reactors.cpp 1.1 10/18/96 + +// the same process... Thanks to Detlef Becker for contributing this. + +#include "ace/Reactor.h" +#include "ace/Synch.h" +#include "ace/Service_Config.h" +#include "ace/Task.h" + +#if defined (ACE_HAS_THREADS) + +static const int NUM_INVOCATIONS = 10; +static const int MAX_TASKS = 20; + +class Test_Task : public ACE_Task +{ +public: + Test_Task (void); + ~Test_Task (void); + + virtual int open (void *args = 0); + virtual int close (u_long flags = 0); + virtual int put (ACE_Message_Block *, ACE_Time_Value *tv = 0); + virtual int svc (void); + + virtual int handle_input (ACE_HANDLE handle); + virtual int handle_close (ACE_HANDLE fd, + ACE_Reactor_Mask close_mask); + +private: + ACE_Reactor *r_; + int handled_; + + static int task_count_; +}; + +int Test_Task::task_count_ = 0; + +static ACE_Atomic_Op done_count = MAX_TASKS * 2; + +static ACE_Recursive_Thread_Mutex reclock_; + +Test_Task::Test_Task (void) + : handled_ (0) +{ + ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, reclock_); + + Test_Task::task_count_++; + ACE_DEBUG ((LM_DEBUG, + "(%t) TT+ Test_Task::task_count_ = %d\n", + Test_Task::task_count_)); +} + +Test_Task::~Test_Task (void) +{ + ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, reclock_); + + ACE_DEBUG ((LM_DEBUG, + "(%t) TT- Test_Task::task_count_ = %d\n", + Test_Task::task_count_)); +} + +int +Test_Task::open (void *args) +{ + r_ = (ACE_Reactor *) args; + return this->activate (THR_NEW_LWP); +} + +int +Test_Task::close (u_long flags) +{ + ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, reclock_, -1); + + Test_Task::task_count_--; + ACE_DEBUG ((LM_DEBUG, + "(%t) close Test_Task::task_count_ = %d\n", + Test_Task::task_count_)); + return 0; +} + +int +Test_Task::put (ACE_Message_Block *mb, + ACE_Time_Value *tv) +{ + return 0; +} + +int +Test_Task::svc (void) +{ + for (int i = 0; i < NUM_INVOCATIONS; i++) + { + ACE_OS::thr_yield (); + + // ACE_DEBUG ((LM_DEBUG, "(%t) calling notify %d\n", i)); + + if (r_->notify (this, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "notify"), -1); + + // ACE_DEBUG ((LM_DEBUG, "(%t) leaving notify %d\n", i)); + } + + return 0; +} + +int +Test_Task::handle_close (ACE_HANDLE fd, + ACE_Reactor_Mask close_mask) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) handle_close\n")); + return 0; +} + +int +Test_Task::handle_input (ACE_HANDLE fd) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) handle_input\n")); + + this->handled_++; + + if (this->handled_ == NUM_INVOCATIONS) + { + done_count--; + ACE_DEBUG ((LM_DEBUG, + "(%t) handle_input, handled_ = %d, done_count = %d\n", + this->handled_, (u_long) done_count)); + } + + ACE_OS::thr_yield (); + return -1; +} + +static void * +worker (void *args) +{ + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + ACE_Reactor *reactor = (ACE_Reactor *) args; + + reactor->owner (ACE_Thread::self ()); + + ACE_Time_Value timeout (4); + + for (;;) + { + //ACE_DEBUG ((LM_DEBUG, "(%t) calling handle_events\n")); + + switch (reactor->handle_events (timeout)) + { + case -1: + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "reactor"), 0); + /* NOTREACHED */ + case 0: + ACE_ERROR_RETURN ((LM_ERROR, "timeout\n"), 0); + /* NOTREACHED */ + } + + // ACE_DEBUG ((LM_DEBUG, "(%t) done with handle_events\n")); + + } + + return 0; +} + +int +main (void) +{ + ACE_Reactor *react1 = ACE_Service_Config::reactor (); + ACE_Reactor *react2 = new ACE_Reactor (); + Test_Task tt1[MAX_TASKS]; + Test_Task tt2[MAX_TASKS]; + + for (int i = 0; i < MAX_TASKS; i++) + { + tt1[i].open (react1); + tt2[i].open (react2); + } + + if (ACE_Service_Config::thr_mgr ()->spawn + (ACE_THR_FUNC (worker), (void *) react1, THR_NEW_LWP) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), -1); + + else if (ACE_Service_Config::thr_mgr ()->spawn + (ACE_THR_FUNC (worker), (void *) react2, THR_NEW_LWP) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), -1); + + ACE_Service_Config::thr_mgr ()->wait (); + ACE_DEBUG ((LM_DEBUG, "(%t) done\n")); + + return 42; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Atomic_Op; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ + +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/Reactor/Misc/test_signals.cpp b/examples/Reactor/Misc/test_signals.cpp new file mode 100644 index 00000000000..b3725f66c89 --- /dev/null +++ b/examples/Reactor/Misc/test_signals.cpp @@ -0,0 +1,226 @@ +// Test the ability of the Reactor/Signal_Handler to register multiple +// @(#)test_signals.cpp 1.1 10/18/96 + +// handler per-signal. + +/* This test works as follows: + + 1. To test the "original" semantics of ACE (i.e., only one + ACE_Event_Handler can be registered per signal), you don't + need to do anything special. Existing programs work the + same since giving the Reactor's constructor a 0 value + (which is the default argument, BTW) instructs it to behave + as before. When a 0 is given, the ACE_Reactor's + constructor/open method creates an instance of + ACE_Sig_Handler and assigns this to an internal pointer. + This pointer is then used to dispatch all signal-related + methods within the Reactor. The default ACE_Sig_Handler + only allows *one* ACE_Event_Handler to be registered + per-signal. + + To run this version of the test do the following: + + % ./test-signal + ./test_signals + waiting for SIGINT or SIGQUIT + ^C + signal Interrupt occurred in Sig_Handler_2 (fruity, 0, 0) with count = 1 + waiting for SIGINT or SIGQUIT + ^\ + signal Quit occurred in Sig_Handler_2 (fruity, 0, 0) with count = 2 + shutting down SIGQUIT in Sig_Handler_2 (fruity, 0, 0) + waiting for SIGINT or SIGQUIT + ^C + signal Interrupt occurred in Sig_Handler_2 (fruity, 0, 0) with count = 3 + waiting for SIGINT or SIGQUIT + ^\Quit (core dumped) + + Note that in this test only one handler (the last one -- + "Sig_Handler_2 (fruity)") is actually registered. BTW, the + core dump is the expected behavior since the default + disposition is restored when there are no more handlers + (see the code below). + + 2. To test the "multiple handlers per-signal semantics", you + need to pass the constructor/open method of the ACE_Reactor + a pointer to a an instance of ACE_Sig_Handlers (note the + plural "s"). ACE_Sig_Handlers is a class that derives from + ACE_Sig_Handler. The difference between these two classes + is that (1) ACE_Sig_Handlers::register_signal allows + multiple ACE_Event_Handlers to be registered per-signal and + (2) it enables SA_RESTART by default. This class also + implements Detlef Becker's algorithm for integrating ACE + signal handling with 3rd party libraries. + + To run this version of the test do the following: + + % ./test_signals 1 + + waiting for SIGINT or SIGQUIT + ^C + signal Interrupt occurred in external handler! + signal Interrupt occurred in Sig_Handler_1 (howdy, 3, 1) with count = 1 + shutting down SIGINT in Sig_Handler_1 (howdy, 3, 1) + signal Interrupt occurred in Sig_Handler_1 (doody, 5, 4) with count = 1 + shutting down SIGINT in Sig_Handler_1 (doody, 5, 4) + signal Interrupt occurred in Sig_Handler_2 (tutty, 7, 6) with count = 1 + signal Interrupt occurred in Sig_Handler_2 (fruity, 9, 8) with count = 1 + waiting for SIGINT or SIGQUIT + ^\ + signal Quit occurred in Sig_Handler_1 (howdy, 3, 1) with count = 2 + shutting down SIGQUIT in Sig_Handler_1 (howdy, 3, 1) + signal Quit occurred in Sig_Handler_1 (doody, 5, 4) with count = 2 + shutting down SIGQUIT in Sig_Handler_1 (doody, 5, 4) + signal Quit occurred in Sig_Handler_2 (tutty, 7, 6) with count = 2 + shutting down SIGQUIT in Sig_Handler_2 (tutty, 7, 6) + signal Quit occurred in Sig_Handler_2 (fruity, 9, 8) with count = 2 + shutting down SIGQUIT in Sig_Handler_2 (fruity, 9, 8) + waiting for SIGINT or SIGQUIT + ^C + signal Interrupt occurred in external handler! + signal Interrupt occurred in Sig_Handler_2 (tutty, 7, 6) with count = 3 + signal Interrupt occurred in Sig_Handler_2 (fruity, 9, 8) with count = 3 + waiting for SIGINT or SIGQUIT + ^\Quit (core dumped) + + When this test begins all four handlers are registered and + dispatched when a SIGINT or SIGQUIT occurs. After the + first SIGINT, the handle_signal method of the Sig_Handler_1 + objects unregister themselves. At that point there are 4 + SIGQUIT handlers left, but only 2 of our SIGINT handlers + left (and the 1 external handler). After the first + SIGQUIT, there are no SIGQUIT handlers left since they all + deregister themselves (which restores the "SIG_DFL" + disposition). On the second SIGINT there are only 3 + handlers left (2 of ours and 1 external). Finally, on the + second SIGQUIT we exit and dump core since that's what + happens with the default disposition for SIGQUIT. */ + +#include "ace/Log_Msg.h" +#include "ace/Reactor.h" + +class Sig_Handler_1 : public ACE_Event_Handler +{ +public: + Sig_Handler_1 (ACE_Reactor &reactor, char *msg) + : msg_ (msg), + count_ (0), + reactor_ (reactor) + { + // Register the signal handlers. + this->quit_sigkey_ = reactor.register_handler (SIGQUIT, this); + this->int_sigkey_ = reactor.register_handler (SIGINT, this); + + if (this->quit_sigkey_ == -1 || this->int_sigkey_ == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "register_handler")); + } + + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *) + { + this->count_++; + ACE_DEBUG ((LM_DEBUG, + "\nsignal %S occurred in Sig_Handler_1 (%s, %d, %d) with count = %d", + signum, this->msg_, this->int_sigkey_, this->quit_sigkey_, this->count_)); + if (this->count_ != 1 && signum == SIGQUIT) + { + if (this->reactor_.remove_handler (SIGQUIT, 0, 0, + this->quit_sigkey_) == -1) + ACE_ERROR ((LM_ERROR, "\n%p", "remove_handler")); + else + ACE_DEBUG ((LM_DEBUG, "\nshutting down SIGQUIT in Sig_Handler_1 (%s, %d, %d)", + this->msg_, this->int_sigkey_, this->quit_sigkey_)); + } + else if (this->count_ != 2 && signum == SIGINT) + { + if (this->reactor_.remove_handler (SIGINT, 0, 0, + this->int_sigkey_) == -1) + ACE_ERROR ((LM_ERROR, "\n%p", "remove_handler")); + else + ACE_DEBUG ((LM_DEBUG, "\nshutting down SIGINT in Sig_Handler_1 (%s, %d, %d)", + this->msg_, this->int_sigkey_, this->quit_sigkey_)); + } + return 0; + } + +protected: + char *msg_; + int count_; + int int_sigkey_; + int quit_sigkey_; + ACE_Reactor &reactor_; +}; + +class Sig_Handler_2 : public Sig_Handler_1 +{ +public: + Sig_Handler_2 (ACE_Reactor &reactor, char *msg) + : Sig_Handler_1 (reactor, msg) + { + } + + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *) + { + this->count_++; + ACE_DEBUG ((LM_DEBUG, + "\nsignal %S occurred in Sig_Handler_2 (%s, %d, %d) with count = %d", + signum, this->msg_, this->int_sigkey_, this->quit_sigkey_, this->count_)); + if (this->count_ != 0 && signum == SIGQUIT) + { + if (this->reactor_.remove_handler (SIGQUIT, 0, 0, + this->quit_sigkey_) == -1) + ACE_ERROR ((LM_ERROR, "\n%p", "remove_handler")); + else + ACE_DEBUG ((LM_DEBUG, "\nshutting down SIGQUIT in Sig_Handler_2 (%s, %d, %d)", + this->msg_, this->int_sigkey_, this->quit_sigkey_)); + } + else + return 0; + } +}; + +static void +external_handler (int signum) +{ + ACE_DEBUG ((LM_DEBUG, "\nsignal %S occurred in external handler!", signum)); +} + +#if !defined (HPUX) +int +main (int argc, char *argv) +{ + // If argc > 1 then allow multiple handlers per-signal, else just + // allow 1 handler per-signal. + ACE_Sig_Handlers multi_handlers; + + ACE_Reactor reactor (argc > 1 ? &multi_handlers: 0); + + if (argc > 1) + { + // Register an "external" signal handler so that the + // ACE_Sig_Handlers code will have something to incorporate! + ACE_SignalHandler eh = ACE_SignalHandler (external_handler); + ACE_Sig_Action sa (eh); + + sa.register_action (SIGINT); + } + + // Create a bevy of handlers. + Sig_Handler_1 h1 (reactor, "howdy"), h2 (reactor, "doody"); + Sig_Handler_2 h3 (reactor, "tutty"), h4 (reactor, "fruity"); + + // Wait for user to type SIGINT and SIGQUIT. + + for (;;) + { + ACE_DEBUG ((LM_DEBUG, "\nwaiting for SIGINT or SIGQUIT\n")); + reactor.handle_events (); + } + return 0; +} +#else +int +main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "The HP C++ compiler is too lame to support this feature\n"), -1); +} +#endif /* HPUX */ diff --git a/examples/Reactor/Misc/test_time_value.cpp b/examples/Reactor/Misc/test_time_value.cpp new file mode 100644 index 00000000000..691528eb292 --- /dev/null +++ b/examples/Reactor/Misc/test_time_value.cpp @@ -0,0 +1,69 @@ +#include "ace/ACE.h" +// @(#)test_time_value.cpp 1.1 10/18/96 + + +inline int my_abs (int d) { return d > 0 ? d : -d; } + +ostream & +operator<< (ostream &stream, const ACE_Time_Value &tv) +{ + if (tv.usec () < 0 || tv.sec () < 0) + stream << "-"; + + stream << dec << my_abs (int (tv.sec ())) << "." +// << setw (6) << setfill ('0') + << dec << my_abs (int (tv.usec ())); + return stream; +} + +int +main (int argc, char *argv[]) +{ + ACE_Time_Value tv1; + ACE_Time_Value tv2 (2); + ACE_Time_Value tv3 (100); + ACE_Time_Value tv4 (1, 1000000); + ACE_Time_Value tv5 (2); + ACE_Time_Value tv6 (1, -1000000); + + ACE_ASSERT (tv1 == ACE_Time_Value (0)); + ACE_ASSERT (tv2 < tv3); + ACE_ASSERT (tv2 <= tv2); + ACE_ASSERT (tv2 >= tv4); + ACE_ASSERT (tv5 >= tv6); + ACE_ASSERT (tv2 == ACE_Time_Value (1, 1000000)); + ACE_ASSERT (tv5 == tv4); + ACE_ASSERT (tv2 == tv4); + ACE_ASSERT (tv1 != tv2); + ACE_ASSERT (tv6 == tv1); + + cout << "0,0 :\t\t" << ACE_Time_Value (0,0) << endl; + cout << "-0,0 :\t\t" << ACE_Time_Value (-0,0) << endl; + cout << "0,-0 :\t\t" << ACE_Time_Value (0,-0) << endl; + cout << "-0,-0 :\t\t" << ACE_Time_Value (-0,-0) << endl; + cout << endl; + + cout << "0,1 :\t\t" << ACE_Time_Value (0,1) << endl; + cout << "1,0 :\t\t" << ACE_Time_Value (1,0) << endl; + cout << "-1,0 :\t\t" << ACE_Time_Value (-1,0) << endl; + cout << "-1,-0 :\t\t" << ACE_Time_Value (-1,-0) << endl; + cout << endl; + + cout << "1,1 :\t\t" << ACE_Time_Value (1,1) << endl; + cout << "-1,1 :\t\t" << ACE_Time_Value (-1,1) << endl; + cout << "1,-1 :\t\t" << ACE_Time_Value (1,-1) << endl; + cout << "-1,-1 :\t\t" << ACE_Time_Value (-1,-1) << endl; + cout << endl; + + cout << "1,-1111111 :\t" << ACE_Time_Value (1,-1111111) << endl; + cout << "1,-100000 :\t" << ACE_Time_Value (1,-100000) << endl; + cout << "1,-1000000 :\t" << ACE_Time_Value (1,-1000000) << endl; + cout << "-1,1000000 :\t" << ACE_Time_Value (-1,1000000) << endl; + cout << "5,-1000000 :\t" << ACE_Time_Value (5,-1000000) << endl; + cout << "5,-1500000 :\t" << ACE_Time_Value (5,-1500000) << endl; + cout << "2,-2500000 :\t" << ACE_Time_Value (2,-2500000) << endl; + cout << "2,-4500000 :\t" << ACE_Time_Value (2,-4500000) << endl; + + return 0; +} + diff --git a/examples/Reactor/Misc/test_timer_queue.cpp b/examples/Reactor/Misc/test_timer_queue.cpp new file mode 100644 index 00000000000..4e7010d1e94 --- /dev/null +++ b/examples/Reactor/Misc/test_timer_queue.cpp @@ -0,0 +1,47 @@ +#include "ace/Log_Msg.h" +// @(#)test_timer_queue.cpp 1.1 10/18/96 + +#include "ace/Timer_Queue.h" + +class Example_Handler : public ACE_Event_Handler +{ +public: + Example_Handler (void) + : count_ (0) + {} + + virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg) + { + ACE_DEBUG ((LM_DEBUG, "yow, the time has come and gone %d times %d, Horatio!\n", + this->count_++, int (arg))); + return 0; + } + +private: + int count_; +}; + +int +main (int argc, char *argv[]) +{ + ACE_Timer_Queue tq; + Example_Handler eh; + + ACE_ASSERT (tq.is_empty ()); + ACE_ASSERT (ACE_Time_Value::zero == ACE_Time_Value (0)); + int timer_id; + + timer_id = tq.schedule (&eh, (const void *) 1, ACE_OS::gettimeofday ()); + tq.schedule (&eh, (const void *) 2, ACE_OS::gettimeofday ()); + tq.schedule (&eh, (const void *) 3, ACE_OS::gettimeofday ()); + tq.cancel (timer_id); + ACE_ASSERT (!tq.is_empty ()); + tq.expire (ACE_OS::gettimeofday ()); + tq.schedule (&eh, (const void *) 4, ACE_OS::gettimeofday ()); + tq.schedule (&eh, (const void *) 5, ACE_OS::gettimeofday ()); + tq.cancel (&eh); + ACE_ASSERT (tq.is_empty ()); + tq.expire (ACE_OS::gettimeofday ()); + return 0; +} + diff --git a/examples/Reactor/Multicast/Log_Wrapper.cpp b/examples/Reactor/Multicast/Log_Wrapper.cpp new file mode 100644 index 00000000000..0b0526cdf2c --- /dev/null +++ b/examples/Reactor/Multicast/Log_Wrapper.cpp @@ -0,0 +1,75 @@ +// client.C +// @(#)Log_Wrapper.cpp 1.1 10/18/96 + + +#include "Log_Wrapper.h" + +Log_Wrapper::Log_Wrapper (void) +{ + this->log_msg_.sequence_number = 0; + this->log_msg_.app_id = ACE_OS::getpid(); +} + +Log_Wrapper::~Log_Wrapper (void) +{ +} + +// Set the log_msg_ host address. +// Get a binding to a logger object from orbixd + +int +Log_Wrapper::open (const int port, const char *mcast_addr) +{ + struct hostent *host_info; + struct utsname host_data; + + if (ACE_OS::uname (&host_data) < 0) + return -1; + + if ((host_info = ACE_OS::gethostbyname (host_data.nodename)) == NULL) + return -1; + else + ACE_OS::memcpy ((char *) &this->log_msg_.host, + (char *) host_info->h_addr, + host_info->h_length); + + // This starts out initialized to all zeros! + ACE_INET_Addr sockdg_addr; + + if (this->logger_.open (sockdg_addr) == -1) + return -1; + + if (this->server_.set (port, mcast_addr) == -1) + return -1; + + // success. + return 0; +} + +// Send the message to a logger object. +// This wrapper fills in all the log_record info for you. +// uses iovector stuff to make contiguous header and message. + +int +Log_Wrapper::log_message (ACE_Log_Priority type, char *message) +{ + this->log_msg_.type = type; this->log_msg_.time = time (0); + this->log_msg_.msg_length = strlen(message); + this->log_msg_.sequence_number++; + + iovec *iovp = new iovec[2]; + iovp[0].iov_base = (char *) &log_msg_; + iovp[0].iov_len = sizeof log_msg_; + iovp[1].iov_base = message; + iovp[1].iov_len = log_msg_.msg_length; + + logger_.send (iovp, 2, server_); + + delete iovp; + + // success. + return 0; +} + + + diff --git a/examples/Reactor/Multicast/Log_Wrapper.h b/examples/Reactor/Multicast/Log_Wrapper.h new file mode 100644 index 00000000000..d1932d92cfa --- /dev/null +++ b/examples/Reactor/Multicast/Log_Wrapper.h @@ -0,0 +1,59 @@ +/* -*- C++ -*- */ +// @(#)Log_Wrapper.h 1.1 10/18/96 + + +// log_wrapper.h +// wrapper around sending log messages via multicast + +#include "ace/Profile_Timer.h" +#include "ace/INET_Addr.h" +#include "ace/SOCK_Dgram.h" + +#if !defined (_LM_WRAPPER_H) +#define _LM_WRAPPER_H + +class Log_Wrapper +{ +public: + Log_Wrapper (void); + ~Log_Wrapper (void); + + // = Types of logging messages. + enum ACE_Log_Priority + { + LM_MESSAGE, + LM_DEBUG, + LM_WARNING, + LM_ERROR, + LM_EMERG + }; + + int open (const int port, const char* mcast_addr); + // get an object reference from an orbixd + + int log_message (ACE_Log_Priority type, char *message); + // send a string to the logger + + // = Format of the logging record. + struct ACE_Log_Record + { + unsigned long sequence_number; + ACE_Log_Priority type; + long host; + long time; + long app_id; + long msg_length; + }; + +private: + ACE_INET_Addr server_; + // Server address where records are logged. + + ACE_Log_Record log_msg_; + // One record used for many log messages. + + ACE_SOCK_Dgram logger_; + // A logger object. +}; + +#endif /* _LM_WRAPPER_H */ diff --git a/examples/Reactor/Multicast/Makefile b/examples/Reactor/Multicast/Makefile new file mode 100644 index 00000000000..980cb7d28b3 --- /dev/null +++ b/examples/Reactor/Multicast/Makefile @@ -0,0 +1,69 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Reactor multicast tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = client server + +FILES = Log_Wrapper + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(addsuffix .o,$(FILES)) +SHOBJ = $(addsuffix .so,$(FILES)) + +LDLIBS = $(addprefix .shobj/,$(SHOBJ)) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# ACE stuff +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/Log_Wrapper.o .shobj/Log_Wrapper.so: Log_Wrapper.cpp Log_Wrapper.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.i + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/Reactor/Multicast/README b/examples/Reactor/Multicast/README new file mode 100644 index 00000000000..85f64cc8120 --- /dev/null +++ b/examples/Reactor/Multicast/README @@ -0,0 +1,15 @@ +The following test illustrates the SOCK Mcast multicast wrappers in +conjunction with the Reactor. This test was written by Tim Harrison +(harrison@cs.wustl.edu). + +To run the server type: + +% server & + +It will wait for the first message sent to it and then read for 5 seconds. + +To run the client type any of these: + +% client -m max_message_size -i iterations +% client < +% client diff --git a/examples/Reactor/Multicast/client.cpp b/examples/Reactor/Multicast/client.cpp new file mode 100644 index 00000000000..1f5774fdb26 --- /dev/null +++ b/examples/Reactor/Multicast/client.cpp @@ -0,0 +1,110 @@ +// client.C (written by Tim Harrison) +// @(#)client.cpp 1.1 10/18/96 + +// This program reads in messages from stdin and sends them +// to a Log_Wrapper. + +#include "ace/Log_Msg.h" +#include "Log_Wrapper.h" + +const char *MCAST_ADDR = ACE_DEFAULT_MULTICAST_ADDR; + +// this is hardware specific. +// use netstat(1M) to find whether your interface +// is le0 or ie0 + +const int UDP_PORT = ACE_DEFAULT_MULTICAST_PORT; + +// maximum message size +static int max_message_size = BUFSIZ * 20; + +// number of times to send message of max_message_size +static int iterations = 0; + +static void +parse_args (int argc, char *argv[]) +{ + extern char *optarg; + extern int optind; + int c; + + ACE_LOG_MSG->open (argv[0]); + + while ((c = ACE_OS::getopt (argc, argv, "m:ui:")) != -1) + switch (c) + { + case 'm': + max_message_size = ACE_OS::atoi (optarg) * BUFSIZ; + break; + case 'i': + iterations = ACE_OS::atoi (optarg); + break; + case 'u': + // usage fallthrough + default: + ACE_ERROR ((LM_ERROR, "%n: -m max_message_size (in k) -i iterations\n%a", 1)); + /* NOTREACHED */ + } +} + +int +main (int argc, char **argv) +{ + int user_prompt; + + parse_args (argc,argv); + + ACE_DEBUG ((LM_DEBUG, "Max Buffer size = %d\n", max_message_size)); + + // Instantiate a log wrapper for logging + Log_Wrapper log; + + // make a connection to a logger via orbixd + if (log.open (UDP_PORT, MCAST_ADDR) == -1) + ACE_OS::perror ("connect failed"), ACE_OS::exit (1); + + char *buf = new char[::max_message_size]; + + // if -i has been specified, send max_message_size messages + // iterations number of times + if (iterations) + { + ACE_OS::memset (buf,1,::max_message_size); + while (iterations--) + if (log.log_message (Log_Wrapper::LM_DEBUG, buf) == -1) + perror("log failed."), exit(1); + } + + // otherwise, a file has been redirected, or give prompts + else + { + // If a file has been redirected, don't activate user prompts + if (ACE_OS::isatty (0)) + user_prompt = 1; + else + user_prompt = 0; + + int nbytes; + // continually read messages from stdin and log them. + while (1) + { + if (user_prompt) + ACE_DEBUG ((LM_DEBUG, "\nEnter message ('Q':quit):\n")); + + if ((nbytes = read (0, buf, max_message_size)) == 0) + break; // end of file + buf[nbytes] = '\0'; + + // quitting? + if (buf[0] == 'Q') + break; + + // send the message to the logger + else if (log.log_message (Log_Wrapper::LM_DEBUG, buf) == -1) + perror("log failed."), exit(1); + } // while(1) + } + + ACE_DEBUG ((LM_DEBUG, "Client done.\n")); + return 0; +} diff --git a/examples/Reactor/Multicast/server.cpp b/examples/Reactor/Multicast/server.cpp new file mode 100644 index 00000000000..b9c3942a9a7 --- /dev/null +++ b/examples/Reactor/Multicast/server.cpp @@ -0,0 +1,157 @@ +// server.C (written by Tim Harrison) +// @(#)server.cpp 1.1 10/18/96 + +// +// listens to multicast address. after first message received, will +// listen for 5 more seconds. prints Mbits/sec received from client. + +#include "ace/SOCK_Dgram.h" +#include "ace/INET_Addr.h" +#include "ace/Log_Msg.h" +#include "ace/SOCK_Dgram_Mcast.h" +#include "ace/Reactor.h" +#include "Log_Wrapper.h" + +#if defined (ACE_HAS_IP_MULTICAST) +class Server_Events : public ACE_Event_Handler +{ +public: + Server_Events (u_short port, + const char *mcast_addr, + long time_interval = 0); + ~Server_Events (void); + + virtual int handle_input (ACE_HANDLE fd); + virtual ACE_HANDLE get_handle (void) const; + + ACE_Time_Value *wait_time (void); + +private: + char *message_; + Log_Wrapper::ACE_Log_Record *log_record_; + char buf_[4*BUFSIZ]; + + int interval_; + // time interval to log messages + + ACE_Time_Value *how_long_; + ACE_Reactor *reactor_; + ACE_SOCK_Dgram_Mcast mcast_dgram_; + ACE_INET_Addr remote_addr_; + ACE_INET_Addr mcast_addr_; + + // = statistics on messages received + double total_bytes_received_; + int total_messages_received_; + int last_sequence_number_; +}; + +ACE_HANDLE +Server_Events::get_handle (void) const +{ + return this->mcast_dgram_.get_handle (); +} + +ACE_Time_Value * +Server_Events::wait_time (void) +{ + return this->how_long_; +} + +Server_Events::Server_Events (u_short port, + const char *mcast_addr, + long time_interval) + : total_bytes_received_ (0), + interval_ (time_interval), + mcast_addr_ (port, mcast_addr) +{ + // use ACE_SOCK_Dgram_Mcast factory to subscribe to multicast group. + + if (this->mcast_dgram_.subscribe (this->mcast_addr_) == -1) + perror("can't subscribe to multicast group"), exit(1); + + // Point to NULL so that we block in the beginning. + this->how_long_ = 0; + + this->log_record_ = (Log_Wrapper::ACE_Log_Record *) &buf_; + this->message_ = &buf_[sizeof (Log_Wrapper::ACE_Log_Record)]; +} + +// A destructor that emacs refuses to color blue ;-) + +Server_Events::~Server_Events (void) +{ + this->mcast_dgram_.unsubscribe (); + + ACE_DEBUG ((LM_DEBUG, "total bytes received = %d after %d second\n", + this->total_bytes_received_, this->interval_)); + + ACE_DEBUG ((LM_DEBUG, "Mbits/sec = %.2f\n", + (float) (total_bytes_received_ * 8 / (float) (1024*1024*interval_)))); + + ACE_DEBUG ((LM_DEBUG, + "last sequence number = %d\ntotal messages received = %d\ndiff = %d\n", + this->last_sequence_number_, + this->total_messages_received_, + this->last_sequence_number_ - total_messages_received_)); +} + +int +Server_Events::handle_input (ACE_HANDLE fd) +{ + // after the first message, point this to a timer + // that way, the next time reactor::handle_events is called, + // a nonzero time value will be passed in. + if (this->how_long_ == 0) + this->how_long_ = new ACE_Time_Value (this->interval_); + + // receive message from multicast group + int retcode = this->mcast_dgram_.recv (this->buf_, + sizeof this->buf_, + this->remote_addr_); + if (retcode != -1) + { + total_messages_received_++; + total_bytes_received_ += retcode; + last_sequence_number_ = log_record_->sequence_number; + ACE_DEBUG ((LM_DEBUG, "sequence number = %d\n", + log_record_->sequence_number)); + return 0; + } + else + return -1; +} + +static const char MCAST_ADDR[] = ACE_DEFAULT_MULTICAST_ADDR; +static const int UDP_PORT = ACE_DEFAULT_MULTICAST_PORT; + +int +main(int argc, char *argv[]) +{ + int duration = 5; + + // Instantiate a server which will receive messages for 5 seconds. + Server_Events server_events (UDP_PORT, MCAST_ADDR, duration); + + // Instance of the ACE_Reactor. + ACE_Reactor reactor; + + if (reactor.register_handler (&server_events, + ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "register_handler", 1)); + + for (;;) + reactor.handle_events (server_events.wait_time ()); + + /* NOTREACHED */ + return 0; +} +#else +int +main (int argc, char *argv[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "error: %s must be run on a platform that support IP multicast\n", + argv[0]), -1); +} +#endif /* ACE_HAS_IP_MULTICAST */ diff --git a/examples/Reactor/Ntalker/Makefile b/examples/Reactor/Ntalker/Makefile new file mode 100644 index 00000000000..d01010c27a0 --- /dev/null +++ b/examples/Reactor/Ntalker/Makefile @@ -0,0 +1,91 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for ntalker demo of SOCK_Dgram_Mcast +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = ntalker + +SRC = $(addsuffix .cpp,$(BIN)) + +LDLIBS = +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# ACE stuff +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/ntalker.o .shobj/ntalker.so: ntalker.cpp \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram_Mcast.h \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.i \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram_Mcast.i \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/Reactor/Ntalker/ntalker.cpp b/examples/Reactor/Ntalker/ntalker.cpp new file mode 100644 index 00000000000..54c8e20f453 --- /dev/null +++ b/examples/Reactor/Ntalker/ntalker.cpp @@ -0,0 +1,188 @@ +// Server.C +// @(#)ntalker.cpp 1.1 10/18/96 + +// +// listens to multicast address. after first message received, will +// listen for 5 more seconds. prints Mbits/sec received from client + +#include "ace/INET_Addr.h" +#include "ace/SOCK_Dgram_Mcast.h" +#include "ace/Reactor.h" + +#if defined (ACE_HAS_IP_MULTICAST) +// network interface to subscribe to +// this is hardware specific. +// use netstat(1M) to find whether your interface +// is le0 or ie0 + +static const char *interface = "le0"; +static const char *MCAST_ADDR = ACE_DEFAULT_MULTICAST_ADDR; +static const u_short UDP_PORT = ACE_DEFAULT_MULTICAST_PORT; + +// Handle both multicast and stdin events. + +class Handle_Events : public ACE_Event_Handler +{ +public: + Handle_Events (u_short udp_port, + const char *ip_addr, + const char *interface, + ACE_Reactor &reactor); + ~Handle_Events (void); + + virtual int handle_input (ACE_HANDLE); + virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask); + +private: + ACE_SOCK_Dgram_Mcast mcast_; + ACE_Handle_Set handle_set_; +}; + +int +Handle_Events::handle_input (ACE_HANDLE h) +{ + char buf[BUFSIZ]; + + if (h == 0) + { + int readresult = ACE_OS::read (h, buf, BUFSIZ); + if (readresult > 0) + { + if (this->mcast_.send (buf, readresult) != readresult) + { + ACE_OS::perror ("send error"); + return -1; + } + return 0; + } + else if (readresult == -1) + ::perror ("can't read from STDIN"); + + return -1; + } + else + { + ACE_INET_Addr remote_addr; + + // receive message from multicast group + int retcode = this->mcast_.recv (buf, sizeof buf, remote_addr); + + if (retcode != -1) + { + cout << "received datagram from host " << remote_addr.get_host_name () + << " on port " << remote_addr.get_port_number () + << " bytes = " << retcode << endl; + ACE_OS::write (ACE_STDOUT, buf, retcode); + cout << endl; + return 0; + } + + ACE_OS::perror ("Something amiss."); + return -1; + } +} + +int +Handle_Events::handle_close (ACE_HANDLE h, ACE_Reactor_Mask) +{ + if (h == 0) + cout << "STDIN_Events handle removed from reactor." << endl << flush; + else + cout << "Mcast_Events handle removed from reactor." << endl << flush; + return 0; +} + +Handle_Events::~Handle_Events (void) +{ + // ACE_OS::exit on error (bogus)... + + if (this->mcast_.unsubscribe () == -1) + ACE_OS::perror ("unsubscribe fails"), ACE_OS::exit (1); +} + +Handle_Events::Handle_Events (u_short udp_port, + const char *ip_addr, + const char *interface, + ACE_Reactor &reactor) +{ + // Create multicast address to listen on. + + ACE_INET_Addr sockmc_addr (udp_port, ip_addr); + + // subscribe to multicast group. + + if (this->mcast_.subscribe (sockmc_addr, 1, interface) == -1) + ACE_OS::perror ("can't subscribe to multicast group"), ACE_OS::exit (1); + + // disable loopbacks + +// if (this->mcast_.set_option (IP_MULTICAST_LOOP, 0) == -1 ) +// ACE_OS::perror (" can't disable loopbacks " ), ACE_OS::exit (1); + + this->handle_set_.set_bit (0); + this->handle_set_.set_bit (this->mcast_.get_handle ()); + + // Register callbacks with the ACE_Reactor. + if (reactor.register_handler (this->handle_set_, + this, + ACE_Event_Handler::READ_MASK) == -1) + ACE_OS::perror ("can't register events"), ACE_OS::exit (1); +} + +static void +parse_args (int argc, char *argv[]) +{ + extern char *optarg; + extern int optind; + int c; + + while ((c = ACE_OS::getopt (argc, argv, "i:u")) != -1) + switch (c) + { + case 'i': + interface = optarg; + break; + case 'u': + // usage fallthrough + default: + cerr << argv[0] << " -i interface\n"; + ::exit (1); + } +} + +static sig_atomic_t done = 0; + +// Signal handler. + +static void +handler (int) +{ + done = 1; +} + +int +main (int argc, char *argv[]) +{ + ACE_Sig_Action sig ((ACE_SignalHandler) handler, SIGINT); + parse_args (argc, argv); + + ACE_Reactor reactor; + Handle_Events handle_events (UDP_PORT, MCAST_ADDR, interface, reactor); + + // main loop + + while (!done) + reactor.handle_events (); + + cout << "\ntalker Done.\n"; + return 0; +} +#else +int +main (int argc, char *argv[]) +{ + ACE_ERROR ((LM_ERROR, "error: %s must be run on a platform that support IP multicast\n", + argv[0])); + return 0; +} +#endif /* ACE_HAS_IP_MULTICAST */ diff --git a/examples/Reactor/README b/examples/Reactor/README new file mode 100644 index 00000000000..fefaeeaf317 --- /dev/null +++ b/examples/Reactor/README @@ -0,0 +1,20 @@ +This directory contains subdirectories that test the ACE Reactor and Proactor + + . Dgram + Tests the CODgram and Dgram classes with the Reactor. + + . Misc + Various miscellaneous tests of Reactor functionality + (e.g., signals, timers, notification, etc.). + + . Multicast + Tests out the ACE multicast capabilities in conjunction + with the Reactor. + + . Ntalker + A program that implements a multicast "chat" program. + + + . Proactor + A program that illustrates the "Proactive" version of + the Reactor diff --git a/examples/Reactor/ReactorEx/README b/examples/Reactor/ReactorEx/README new file mode 100644 index 00000000000..1184d09dd68 --- /dev/null +++ b/examples/Reactor/ReactorEx/README @@ -0,0 +1,204 @@ +The ACE_ReactorEx encapsulates the Win32 WaitForMultipleObjects() API +within ACE. The ACE_ReactorEx is similar in spirit to the +ACE_Reactor, except that (1) it is much simpler and (2) it works for +the complete range of Win32 handles (whereas the ACE_Reactor just +works for socket handles. + +Here's the API for the ACE_ReactorEx: + +class ACE_ReactorEx +{ +public: + // = Event loop. + virtual int handle_events (ACE_Time_Value *); + + // = Handler registration management. + virtual int register_handler (ACE_Event_Handler *); + virtual int remove_handler (ACE_Event_Handler *); + + virtual int notify (void); + + // = Timer management + virtual int schedule_timer (), etc. + // ... +}; + +---------------------------------------- + +Here's how you might use it: + +---------------------------------------- + +class My_Thread_Handler : public ACE_Event_Handler +{ +public: + My_Thread_Handler (void) { + // Create a thread that will run + // for a time and then exit. + this->thread_handle_ = + ACE_OS::thr_create (run, ......); + } + + // Called back by the ACE_ReactorEx when the + // event is signaled. + virtual int handle_signal (int) + { + cout << "thread is done" << endl; + } + + virtual ACE_HANDLE get_handle (void) const + { + return this->thread_handle_; + } + +private: + ACE_HANDLE thread_handle_; + + static void *run (void *) { + // Sleep for a while and then exit. + ACE_OS::sleep (100000); + return 0; + } +}; + +---------------------------------------- + +The main program might look something like this: + +---------------------------------------- + +int main (void) +{ + // ... + ACE_ReactorEx dispatcher; + My_Thread_Handler handler; + + // Register the thread handler. + dispatcher.register_handler (&handler); + + // Block until the thread exits and the + // handle_signal() method of the My_Thread_Handler + // is called! + dispatcher.handle_events (); + + // ... +} + +---------------------------------------- + +. test_remove_handler -- + +This application tests the ReactorEx's ability to handle simultaneous +events. If you pass anything on the command-line, then each handler +requests to be removed from the ReactorEx after each event. This has +a funky effect on the order in which handlers are serviced. So, if no +parameters are passed in, the handlers should be serviced 1 through +MAXIMUM_WAIT_OBJECTS. If handlers to request to be removed as signals +occur, they will be serviced 1, MAX, MAX-1, ..., 2. This is because +of a ReactorEx bookkeeping optimization. + +. test_reactorEx.cpp -- + +This test application tests a wide range of events that can be +demultiplexed using various ACE utilities. Events used include ^C +events, reading from STDIN, vanilla Win32 events, thread exits, +ReactorEx notifications, proactive reads, and proactive writes. + +The proactive I/O events are demultiplexed by the ACE_Proactor. The +thread exits, notications, and vanilla Win32 events are demultiplexed +by the ACE_ReactorEx. To enable a single thread to run all these +events, the Proactor is integrated with the ReactorEx. + +The test application prototypes a simple ntalk program. Two instances +of the application connect. Input from either console is displayed on +the others console also. Because of the evils of Win32 STDIN, a +separate thread is used to read from STDIN. To test the Proactor and +ReactorEx, I/O between the remote processes is performed proactively +and interactions between the STDIN thread and the main thread are +performed reactively. + +The following description of the test application is in two parts. +The participants section explains the main components involved in the +application. The collaboration section describes how the partipants +interact in response to the multiple event types which occur. + +The ReactorEx test application has the following participants: + +. ReactorEx -- The ReactorEx demultiplexes Win32 "waitable" events + using WaitForMultipleObjects. + +. Proactor -- The proactor initiates and demultiplexes overlapped I/O + operations. The Proactor registers with the ReactorEx so that a + single-thread can demultiplex all application events. + +. STDIN_Handler -- STDIN_Handler is an Active Object which reads from + STDIN and forwards the input to the Peer_Handler. This runs + in a separate thread to make the test more interesting. However, + STDIN is "waitable", so in general it can be waited on by the ACE + ReactorEx, thanks MicroSlush! + +. Peer_Handler -- The Peer_Handler connects to another instance of + test_reactorEx. It Proactively reads and writes data to the peer. + When the STDIN_Handler gives it messages, it fowards them to the + remote peer. When it receives messages from the remote peer, it + prints the output to the console. + +The collaborations of the participants are as follows: + +. Initialization + + Peer_Handler -- connects to the remote peer. It then begins + proactively reading from the remote connection. Note that it will + be notified by the Proactor when a read completes. It also + registers a new_msg_event with the ReactorEx. Note that when the + new_msg_event is signaled (by the STDIN_Handler), + Peer_Handler::handle_signal will get called. + + STDIN_Handler -- STDIN_Handler registers a signal handler for + SIGINT. This just captures the exception so that the kernel doesn't + kill our process; We want to exit gracefully. It also creates an + Exit_Hook object which registers the STDIN_Handler's thread handle + with the ReactorEx. The Exit_Hook will get called back when the + STDIN_Handler thread exits. After registering these, it blocks + reading from STDIN. + + Proactor -- is registered with the ReactorEx. + + The main thread of control waits in the ReactorEx. + +. STDIN events -- When the STDIN_Handler thread reads from STDIN, it + puts the message on Peer_Handler's message queue and signals the + new_msg_event. It then returns to reading from STDIN. + +. new_msg_events -- The ReactorEx thread wakes up and calls + Peer_Handler::handle_signal. The Peer_Handler then tries to dequeue + a message from its message queue. If it can, the message is + Proactively sent to the remote peer. Note that the Peer_Handler + will be notified with this operation is complete. The Peer_Handler + then falls back into the ReactorEx event loop. + +. Send complete event -- When a proactive send is complete, the + Proactor is notified by the ReactorEx. The Proactor, in turn, + notifies the Peer_Handler. The Peer_Handler then checks for more + messages from the message queue. If there are any, it tries to send + them. If there are not, it returns to the ReactorEx event loop. + This is ok since it is notified via new_msg_event when new message + arrive. + +. Read complete event -- When a proactive read is complete (the + Peer_Handler initiated a proactive read when it connected to the + remote peer), the Proactor is notified by the ReactorEx. The + Proactor, in turn notifies the Peer_Handler. If the read was + successful the Peer_Handler just displays the received msg to the + console and reinvokes a proactive read from the network connection. + If the read failed (i.e. the remote peer exited), the Peer_Handler + sets a flag to end the event loop and returns. This will cause the + application to exit. + +. ^C events -- When the user types ^C at the console, the + STDIN_Handler's signal handler will be called. It does nothing, but + as a result of the signal, the STDIN_Handler thread will exit. + +. STDIN_Handler thread exits -- The Exit_Hook will get called back + from the ReactorEx. Exit_Hook::handle_signal sets a flag to end the + event loop and returns. This will cause the application to exit. diff --git a/examples/Reactor/ReactorEx/reactorex.mak b/examples/Reactor/ReactorEx/reactorex.mak new file mode 100644 index 00000000000..150d04508d7 --- /dev/null +++ b/examples/Reactor/ReactorEx/reactorex.mak @@ -0,0 +1,535 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +!IF "$(CFG)" == "" +CFG=test_remove_handler - Win32 Debug +!MESSAGE No configuration specified. Defaulting to test_remove_handler - Win32\ + Debug. +!ENDIF + +!IF "$(CFG)" != "ntalk - Win32 Release" && "$(CFG)" != "ntalk - Win32 Debug" &&\ + "$(CFG)" != "test_remove_handler - Win32 Release" && "$(CFG)" !=\ + "test_remove_handler - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "reactorEx.mak" CFG="test_remove_handler - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ntalk - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "ntalk - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "test_remove_handler - Win32 Release" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "test_remove_handler - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "ntalk - Win32 Debug" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "ntalk - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ntalk\Release" +# PROP BASE Intermediate_Dir "ntalk\Release" +# PROP BASE Target_Dir "ntalk" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ntalk\Release" +# PROP Intermediate_Dir "ntalk\Release" +# PROP Target_Dir "ntalk" +OUTDIR=.\ntalk\Release +INTDIR=.\ntalk\Release + +ALL : "$(OUTDIR)\ntalk.exe" + +CLEAN : + -@erase ".\ntalk\Release\ntalk.exe" + -@erase ".\ntalk\Release\test_reactorEx.obj" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\ + /Fp"$(INTDIR)/ntalk.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\ntalk\Release/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/ntalk.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ace.lib /nologo /subsystem:console /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib ace.lib /nologo /subsystem:console /incremental:no\ + /pdb:"$(OUTDIR)/ntalk.pdb" /machine:I386 /out:"$(OUTDIR)/ntalk.exe" +LINK32_OBJS= \ + "$(INTDIR)/test_reactorEx.obj" + +"$(OUTDIR)\ntalk.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "ntalk - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "ntalk\Debug" +# PROP BASE Intermediate_Dir "ntalk\Debug" +# PROP BASE Target_Dir "ntalk" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "debug" +# PROP Target_Dir "ntalk" +OUTDIR=. +INTDIR=.\debug + +ALL : "$(OUTDIR)\test_reactorEx.exe" + +CLEAN : + -@erase ".\debug\vc40.pdb" + -@erase ".\debug\vc40.idb" + -@erase ".\test_reactorEx.exe" + -@erase ".\debug\test_reactorEx.obj" + -@erase ".\test_reactorEx.ilk" + -@erase ".\test_reactorEx.pdb" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\ + /Fp"$(INTDIR)/ntalk.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/ntalk.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ace.lib /nologo /subsystem:console /debug /machine:I386 /out:"test_reactorEx.exe" +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib ace.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/test_reactorEx.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/test_reactorEx.exe" +LINK32_OBJS= \ + "$(INTDIR)/test_reactorEx.obj" + +"$(OUTDIR)\test_reactorEx.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "test_remove_handler - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "test_remove_handler\Release" +# PROP BASE Intermediate_Dir "test_remove_handler\Release" +# PROP BASE Target_Dir "test_remove_handler" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "test_remove_handler\Release" +# PROP Intermediate_Dir "test_remove_handler\Release" +# PROP Target_Dir "test_remove_handler" +OUTDIR=.\test_remove_handler\Release +INTDIR=.\test_remove_handler\Release + +ALL : "$(OUTDIR)\test_remove_handler.exe" + +CLEAN : + -@erase ".\test_remove_handler\Release\test_remove_handler.exe" + -@erase ".\test_remove_handler\Release\test_remove_handler.obj" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\ + /Fp"$(INTDIR)/test_remove_handler.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\test_remove_handler\Release/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/test_remove_handler.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib /nologo /subsystem:console /incremental:no\ + /pdb:"$(OUTDIR)/test_remove_handler.pdb" /machine:I386\ + /out:"$(OUTDIR)/test_remove_handler.exe" +LINK32_OBJS= \ + "$(INTDIR)/test_remove_handler.obj" + +"$(OUTDIR)\test_remove_handler.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "test_remove_handler - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "test_remove_handler\Debug" +# PROP BASE Intermediate_Dir "test_remove_handler\Debug" +# PROP BASE Target_Dir "test_remove_handler" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "test_remove_handler" +OUTDIR=. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\test_remove_handler.exe" + +CLEAN : + -@erase ".\debug\vc40.pdb" + -@erase ".\debug\vc40.idb" + -@erase ".\test_remove_handler.exe" + -@erase ".\Debug\test_remove_handler.obj" + -@erase ".\test_remove_handler.ilk" + -@erase ".\test_remove_handler.pdb" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\ + /Fp"$(INTDIR)/test_remove_handler.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/test_remove_handler.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ace.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib ace.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/test_remove_handler.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/test_remove_handler.exe" +LINK32_OBJS= \ + "$(INTDIR)/test_remove_handler.obj" + +"$(OUTDIR)\test_remove_handler.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "ntalk - Win32 Release" +# Name "ntalk - Win32 Debug" + +!IF "$(CFG)" == "ntalk - Win32 Release" + +!ELSEIF "$(CFG)" == "ntalk - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\test_reactorEx.cpp +DEP_CPP_TEST_=\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\SOCK_Connector.h"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.h"\ + {$(INCLUDE)}"\ace\Get_Opt.h"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Task.h"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\SOCK_Connector.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.i"\ + {$(INCLUDE)}"\ace\Get_Opt.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Message_Queue.h"\ + {$(INCLUDE)}"\ace\Task.i"\ + {$(INCLUDE)}"\ace\Task.cpp"\ + {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\ + {$(INCLUDE)}"\ace\Message_Queue.i"\ + {$(INCLUDE)}"\ace\Message_Queue.cpp"\ + {$(INCLUDE)}"\ace\Module.h"\ + {$(INCLUDE)}"\ace\Module.i"\ + {$(INCLUDE)}"\ace\Module.cpp"\ + {$(INCLUDE)}"\ace\Stream_Modules.h"\ + {$(INCLUDE)}"\ace\Stream_Modules.i"\ + {$(INCLUDE)}"\ace\Stream_Modules.cpp"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\OS.i"\ + +NODEP_CPP_TEST_=\ + ".\..\..\ace\ace\Sync_T.h"\ + ".\..\..\ace\semLib.h"\ + + +"$(INTDIR)\test_reactorEx.obj" : $(SOURCE) $(DEP_CPP_TEST_) "$(INTDIR)" + + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "test_remove_handler - Win32 Release" +# Name "test_remove_handler - Win32 Debug" + +!IF "$(CFG)" == "test_remove_handler - Win32 Release" + +!ELSEIF "$(CFG)" == "test_remove_handler - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\test_remove_handler.cpp +DEP_CPP_TEST_R=\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + +NODEP_CPP_TEST_R=\ + ".\..\..\ace\semLib.h"\ + ".\..\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\test_remove_handler.obj" : $(SOURCE) $(DEP_CPP_TEST_R) "$(INTDIR)" + + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/examples/Reactor/ReactorEx/reactorex.mdp b/examples/Reactor/ReactorEx/reactorex.mdp new file mode 100644 index 00000000000..0135cc67b75 Binary files /dev/null and b/examples/Reactor/ReactorEx/reactorex.mdp differ diff --git a/examples/Reactor/ReactorEx/test_reactorEx.cpp b/examples/Reactor/ReactorEx/test_reactorEx.cpp new file mode 100644 index 00000000000..757e78c1e9e --- /dev/null +++ b/examples/Reactor/ReactorEx/test_reactorEx.cpp @@ -0,0 +1,444 @@ +// ============================================================================ +// @(#)test_reactorEx.cpp 1.1 10/18/96 + +// +// = LIBRARY +// examples +// +// = FILENAME +// test_reactorEx.cpp +// +// = DESCRIPTION +// This test application tests a wide range of events that can be +// demultiplexed using various ACE utilities. Events used include ^C +// events, reading from STDIN, vanilla Win32 events, thread exits, +// ReactorEx notifications, proactive reads, and proactive writes. +// +// The proactive I/O events are demultiplexed by the ACE_Proactor. +// The thread exits, notications, and vanilla Win32 events are +// demultiplexed by the ACE_ReactorEx. To enable a single thread +// to run all these events, the Proactor is integrated with the +// ReactorEx. +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#include "ace/ReactorEx.h" +#include "ace/Proactor.h" +#include "ace/SOCK_Connector.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/Get_Opt.h" +#include "ace/Time_Value.h" +#include "ace/Service_Config.h" +#include "ace/Synch.h" +#include "ace/Task.h" +#include "ace/OS.h" + +typedef ACE_Task MT_TASK; + +class Peer_Handler : public MT_TASK + // = TITLE + // Connect to a server. Receive messages from STDIN_Handler + // and forward them to the server using proactive I/O. +{ +public: + Peer_Handler (int argc, char *argv[]); + + int open (void * =0); + // This method creates the network connection to the remote peer. + // It does blocking connects and accepts depending on whether a + // hostname was specified from the command line. + + virtual int handle_output_complete (ACE_Message_Block *msg, + long bytes_transfered); + // One of our asynchronous writes to the remote peer has completed. + // Make sure it succeeded and then delete the message. + + virtual int handle_input_complete (ACE_Message_Block *msg, + long bytes_transfered); + // The remote peer has sent us something. If it succeeded, print + // out the message and reinitiate a read. Otherwise, fail. In both + // cases, delete the message sent. + + virtual ACE_Message_Block *get_message (void); + // This is so the Proactor can get a message to read into. + + virtual ACE_HANDLE get_handle (void) const; + // This is so the Proactor can get our handle. + + virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask); + // We've been removed from the ReactorEx. + + virtual int handle_signal (int index, siginfo_t *, ucontext_t *); + // We've been signaled by the STDIN thread. Try to dequeue a + // message. + + void try_send (void); + // Try to dequeue a message. If successful, send it proactively to + // the remote peer. + + virtual int put (ACE_Message_Block *mb, + ACE_Time_Value *tv = 0); + // Enqueue the new mb and signal the main thread. + +private: + ACE_SOCK_Stream stream_; + // Socket that we have connected to the server. + + ACE_HANDLE new_msg_event_; + // Event that gets signaled when messages arrive. + + // = Remote peer info. + char *host_; + // Name of remote host. + + u_short port_; + // Port number for remote host. + + // = Make Task happy. + int close (u_long) { return 0; } +}; + +class STDIN_Handler : public ACE_Task + // = TITLE + // Active Object. Reads from STDIN and passes message blocks to + // the peer handler. +{ +public: + STDIN_Handler (MT_TASK &ph); + + virtual int open (void * = 0); + // Activate object. + + virtual int close (u_long = 0); + // Shut down. + + int svc (void); + // Thread runs here. + +private: + MT_TASK &ph_; + // Send all input to ph_. + + static void handler (int signum); + // Handle a ^C. (Do nothing). + + int put (ACE_Message_Block *, ACE_Time_Value *) { return 0; } + // Make Task happy. + + void register_thread_exit_hook (void); + // Helper function to register with the ReactorEx for thread exit. + + virtual int handle_signal (int index, siginfo_t *, ucontext_t *); + // The STDIN thread has exited. This means the user hit ^C. We can + // end the event loop. +}; + +Peer_Handler::Peer_Handler (int argc, char *argv[]) + : host_ (0), + port_ (ACE_DEFAULT_SERVER_PORT) +{ + ACE_Get_Opt get_opt (argc, argv, "h:p:"); + int c; + + while ((c = get_opt ()) != EOF) + { + switch (c) + { + case 'h': + host_ = get_opt.optarg; + break; + case 'p': + port_ = ACE_OS::atoi (get_opt.optarg); + break; + } + } + + // Auto reset event. + new_msg_event_ = ::CreateEvent (NULL, FALSE, FALSE, NULL); + ACE_Service_Config::reactorEx ()-> + register_handler (this, new_msg_event_); +} + +// This method creates the network connection to the remote peer. It +// does blocking connects and accepts depending on whether a hostname +// was specified from the command line. + +int +Peer_Handler::open (void *) +{ + if (host_ != 0) // Connector + { + ACE_INET_Addr addr (port_, host_); + ACE_SOCK_Connector connector; + + // Establish connection with server. + if (connector.connect (stream_, addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "connect"), -1); + + ACE_DEBUG ((LM_DEBUG, "connected.\n")); + } + else // Acceptor + { + ACE_SOCK_Acceptor acceptor; + ACE_INET_Addr local_addr (port_); + + if ((acceptor.open (local_addr) == -1) || + (acceptor.accept (this->stream_) == -1)) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "accept failed"), -1); + + ACE_DEBUG ((LM_DEBUG, "accepted.\n")); + } + + return ACE_Service_Config::proactor ()->initiate + (this, ACE_Event_Handler::READ_MASK); +} + +// One of our asynchronous writes to the remote peer has completed. +// Make sure it succeeded and then delete the message. + +int +Peer_Handler::handle_output_complete (ACE_Message_Block *msg, + long bytes_transfered) +{ + if (bytes_transfered <= 0) + ACE_DEBUG ((LM_DEBUG, "%p bytes = %d\n", "Message failed", + bytes_transfered)); + + // This was allocated by the STDIN_Handler, queued, dequeued, + // passed to the proactor, and now passed back to us. + delete msg; + return 0; // Do not reinvoke a send. +} + +// The remote peer has sent us something. If it succeeded, print +// out the message and reinitiate a read. Otherwise, fail. In both +// cases, delete the message sent. + +int +Peer_Handler::handle_input_complete (ACE_Message_Block *msg, + long bytes_transfered) +{ + if ((bytes_transfered > 0) && (msg->length () > 0)) + { + msg->rd_ptr ()[bytes_transfered] = '\0'; + // Print out the message received from the server. + ACE_DEBUG ((LM_DEBUG, "%s", msg->rd_ptr ())); + delete msg; + return 1; // Reinvokes the recv() operation! + } + + delete msg; + // If a read failed, we will assume it's because the remote peer + // went away. We will end the event loop. Since we're in the main + // thread, we don't need to do a notify. + ACE_Service_Config::end_reactorEx_event_loop (); + return -1; // Close down. +} + +// This is so the Proactor can get a message to read into. + +ACE_Message_Block * +Peer_Handler::get_message (void) +{ + // An extra byte for NUL termination. + ACE_Message_Block *message = + new ACE_Message_Block (BUFSIZ + 1); + + message->size (BUFSIZ); + return message; +} + +// This is so the Proactor can get our handle. +ACE_HANDLE +Peer_Handler::get_handle (void) const +{ + return this->stream_.get_handle (); +} + +// We've been removed from the ReactorEx. +int +Peer_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + ACE_DEBUG ((LM_DEBUG, "Peer_Handler closing down\n")); + return 0; +} + +// We've been signaled by the STDIN thread. Try to dequeue a +// message. + +int +Peer_Handler::handle_signal (int, siginfo_t *, ucontext_t *) +{ + this->try_send (); + return 0; +} + +// Try to dequeue a message. If successful, send it proactively to +// the remote peer. + +void +Peer_Handler::try_send (void) +{ + ACE_Message_Block *mb; + + ACE_Time_Value tv (ACE_Time_Value::zero); + + if (this->getq (mb, &tv) != -1) + { + if (ACE_Service_Config::proactor ()-> + initiate (this, ACE_Event_Handler::WRITE_MASK, mb) == -1) + ACE_ERROR ((LM_ERROR, "%p Write initiate.\n", "Peer_Handler")); + } +} + +// Enqueue the new mb and signal the main thread. + +int +Peer_Handler::put (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + // Enqueue the mb. + int result = this->putq (mb, tv); + + // Signal the main thread. This will remain signaled until the main + // thread wakes up. + + if (::SetEvent (new_msg_event_) == 0) + ACE_ERROR ((LM_ERROR, "Pulse Failed!\n")); + + return result; +} + +void +STDIN_Handler::handler (int signum) +{ + ACE_DEBUG ((LM_DEBUG, "signal = %S\n", signum)); +} + +STDIN_Handler::STDIN_Handler (MT_TASK &ph) + : ph_ (ph) +{ + // Register for ^C from the console. We just need to catch the + // exception so that the kernel doesn't kill our process. + // Registering this signal handler just tells the kernel that we + // know what we're doing; to leave us alone. + ACE_OS::signal (SIGINT, ACE_SignalHandler (STDIN_Handler::handler)); +}; + +// Activate object. + +int +STDIN_Handler::open (void *) +{ + if (this->activate (THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), -1); + + return 0; +} + +// Shut down. + +int +STDIN_Handler::close (u_long) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) thread is exiting.\n")); + return 0; +} + +// Thread runs here. + +int +STDIN_Handler::svc (void) +{ + this->register_thread_exit_hook (); + + for (;;) + { + ACE_Message_Block *mb = new ACE_Message_Block (BUFSIZ); + + // Read from stdin into mb. + int read_result = ACE_OS::read (ACE_STDIN, + mb->rd_ptr (), + mb->size ()); + + // If read succeeds, put mb to peer handler, else end the loop. + if (read_result > 0) + { + mb->wr_ptr (read_result); + this->ph_.put (mb); + } + else + break; + } + + // handle_signal will get called. + return 42; +} + +// Register an exit hook with the reactorEx. All this junk is testing +// out how ACE_Thread::self (hthread_id&) doesn't work!! + +void +STDIN_Handler::register_thread_exit_hook (void) +{ + ACE_hthread_t handle; + + // Get a real handle to our thread. + ACE_Service_Config::thr_mgr ()->thr_self (handle); + + // Register ourselves to get called back when our thread exits. + + if (ACE_Service_Config::reactorEx ()-> + register_handler (this, handle) == -1) + ACE_ERROR ((LM_ERROR, "Exit_Hook Register failed.\n")); + + // We're in another thread, so we need to notify the ReactorEx so + // that it wakes up and waits on the new set of handles. + ACE_Service_Config::reactorEx ()->notify (); +} + +// The STDIN thread has exited. This means the user hit ^C. We can +// end the event loop and delete ourself. + +int +STDIN_Handler::handle_signal (int, siginfo_t *, ucontext_t *) +{ + ACE_DEBUG ((LM_DEBUG, "STDIN thread has exited.\n")); + ACE_Service_Config::end_reactorEx_event_loop (); + return 0; +} + +int +main (int argc, char *argv[]) +{ + // Open handler for remote peer communications this will run from + // the main thread. + Peer_Handler peer_handler (argc, argv); + + if (peer_handler.open () == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p open failed, errno = %d.\n", + "peer_handler", errno), 0); + + // Open active object for reading from stdin. + STDIN_Handler stdin_handler (peer_handler); + + if (stdin_handler.open () == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p open failed, errno = %d.\n", + "stdin_handler", errno), 0); + + // Register proactor with ReactorEx so that we can demultiplex + // "waitable" events and I/O operations from a single thread. + if (ACE_Service_Config::reactorEx ()->register_handler + (ACE_Service_Config::proactor ()) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p failed to register Proactor.\n", + argv[0]), -1); + + // Run main event demultiplexor. + ACE_Service_Config::run_reactorEx_event_loop (); + + return 42; +} diff --git a/examples/Reactor/ReactorEx/test_remove_handler.cpp b/examples/Reactor/ReactorEx/test_remove_handler.cpp new file mode 100644 index 00000000000..fb61519b1e9 --- /dev/null +++ b/examples/Reactor/ReactorEx/test_remove_handler.cpp @@ -0,0 +1,94 @@ +// ============================================================================ +// @(#)test_remove_handler.cpp 1.1 10/18/96 + +// +// = LIBRARY +// examples +// +// = FILENAME +// test_remove_handler.cpp +// +// = DESCRIPTION +// Tests the ReactorEx's ability to handle simultaneous events. If +// you pass anything on the command-line, then each handler +// requests to be removed from the ReactorEx after each event. +// This has a funky effect on the order in which handlers are +// serviced. So, if no parameters are passed in, the handlers +// should be serviced 1 through MAXIMUM_WAIT_OBJECTS. If handlers +// to request to be removed as signals occur, they will be serviced +// 1, MAX, MAX-1, ..., 2. This is because of a ReactorEx +// bookkeeping optimization. +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#include "ace/ReactorEx.h" +#include "ace/Service_Config.h" +#include "ace/Synch.h" + +class Event_Handler : public ACE_Event_Handler +// = TITLE +// Generic Event Handler. +// +// = DESCRIPTION +// +// Creates event. Registers with ReactorEx. Signals event. If +// created with -close_down- it returns -1 from handle signal. +{ +public: + Event_Handler (int event_number, + int close_down) + : event_number_ (event_number), + close_down_ (close_down) + { + ACE_Service_Config::reactorEx ()->register_handler (this, + this->event_.handle ()); + this->event_.signal (); + } + + virtual int handle_signal (int index, siginfo_t *, ucontext_t *) + { + ACE_DEBUG ((LM_DEBUG, "event %d occured.\n", event_number_)); + + if (this->close_down_) + return -1; + else + return 0; + } + + virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask) + { + // ACE_DEBUG ((LM_DEBUG, "event handler %d closed.\n", event_number_)); + delete this; + return 0; + } + + virtual ACE_HANDLE get_handle (void) const + { + return event_.handle (); + } + +private: + int event_number_; + // Our event number. + + int close_down_; + // Shall we close down or not. + + ACE_Event event_; + // Signaled to shut down the handler. +}; + +int +main (int argc, char *argv[]) +{ + int close_down = arg > 1 ? 1 : 0; + + for (int i = 0; i < ACE_ReactorEx::MAX_SIZE; i++) + new Event_Handler (i, close_down); + + ACE_Service_Config::reactorEx ()->handle_events (); + return 42; +} diff --git a/examples/Reactor/WFMO_Reactor/README b/examples/Reactor/WFMO_Reactor/README new file mode 100644 index 00000000000..1184d09dd68 --- /dev/null +++ b/examples/Reactor/WFMO_Reactor/README @@ -0,0 +1,204 @@ +The ACE_ReactorEx encapsulates the Win32 WaitForMultipleObjects() API +within ACE. The ACE_ReactorEx is similar in spirit to the +ACE_Reactor, except that (1) it is much simpler and (2) it works for +the complete range of Win32 handles (whereas the ACE_Reactor just +works for socket handles. + +Here's the API for the ACE_ReactorEx: + +class ACE_ReactorEx +{ +public: + // = Event loop. + virtual int handle_events (ACE_Time_Value *); + + // = Handler registration management. + virtual int register_handler (ACE_Event_Handler *); + virtual int remove_handler (ACE_Event_Handler *); + + virtual int notify (void); + + // = Timer management + virtual int schedule_timer (), etc. + // ... +}; + +---------------------------------------- + +Here's how you might use it: + +---------------------------------------- + +class My_Thread_Handler : public ACE_Event_Handler +{ +public: + My_Thread_Handler (void) { + // Create a thread that will run + // for a time and then exit. + this->thread_handle_ = + ACE_OS::thr_create (run, ......); + } + + // Called back by the ACE_ReactorEx when the + // event is signaled. + virtual int handle_signal (int) + { + cout << "thread is done" << endl; + } + + virtual ACE_HANDLE get_handle (void) const + { + return this->thread_handle_; + } + +private: + ACE_HANDLE thread_handle_; + + static void *run (void *) { + // Sleep for a while and then exit. + ACE_OS::sleep (100000); + return 0; + } +}; + +---------------------------------------- + +The main program might look something like this: + +---------------------------------------- + +int main (void) +{ + // ... + ACE_ReactorEx dispatcher; + My_Thread_Handler handler; + + // Register the thread handler. + dispatcher.register_handler (&handler); + + // Block until the thread exits and the + // handle_signal() method of the My_Thread_Handler + // is called! + dispatcher.handle_events (); + + // ... +} + +---------------------------------------- + +. test_remove_handler -- + +This application tests the ReactorEx's ability to handle simultaneous +events. If you pass anything on the command-line, then each handler +requests to be removed from the ReactorEx after each event. This has +a funky effect on the order in which handlers are serviced. So, if no +parameters are passed in, the handlers should be serviced 1 through +MAXIMUM_WAIT_OBJECTS. If handlers to request to be removed as signals +occur, they will be serviced 1, MAX, MAX-1, ..., 2. This is because +of a ReactorEx bookkeeping optimization. + +. test_reactorEx.cpp -- + +This test application tests a wide range of events that can be +demultiplexed using various ACE utilities. Events used include ^C +events, reading from STDIN, vanilla Win32 events, thread exits, +ReactorEx notifications, proactive reads, and proactive writes. + +The proactive I/O events are demultiplexed by the ACE_Proactor. The +thread exits, notications, and vanilla Win32 events are demultiplexed +by the ACE_ReactorEx. To enable a single thread to run all these +events, the Proactor is integrated with the ReactorEx. + +The test application prototypes a simple ntalk program. Two instances +of the application connect. Input from either console is displayed on +the others console also. Because of the evils of Win32 STDIN, a +separate thread is used to read from STDIN. To test the Proactor and +ReactorEx, I/O between the remote processes is performed proactively +and interactions between the STDIN thread and the main thread are +performed reactively. + +The following description of the test application is in two parts. +The participants section explains the main components involved in the +application. The collaboration section describes how the partipants +interact in response to the multiple event types which occur. + +The ReactorEx test application has the following participants: + +. ReactorEx -- The ReactorEx demultiplexes Win32 "waitable" events + using WaitForMultipleObjects. + +. Proactor -- The proactor initiates and demultiplexes overlapped I/O + operations. The Proactor registers with the ReactorEx so that a + single-thread can demultiplex all application events. + +. STDIN_Handler -- STDIN_Handler is an Active Object which reads from + STDIN and forwards the input to the Peer_Handler. This runs + in a separate thread to make the test more interesting. However, + STDIN is "waitable", so in general it can be waited on by the ACE + ReactorEx, thanks MicroSlush! + +. Peer_Handler -- The Peer_Handler connects to another instance of + test_reactorEx. It Proactively reads and writes data to the peer. + When the STDIN_Handler gives it messages, it fowards them to the + remote peer. When it receives messages from the remote peer, it + prints the output to the console. + +The collaborations of the participants are as follows: + +. Initialization + + Peer_Handler -- connects to the remote peer. It then begins + proactively reading from the remote connection. Note that it will + be notified by the Proactor when a read completes. It also + registers a new_msg_event with the ReactorEx. Note that when the + new_msg_event is signaled (by the STDIN_Handler), + Peer_Handler::handle_signal will get called. + + STDIN_Handler -- STDIN_Handler registers a signal handler for + SIGINT. This just captures the exception so that the kernel doesn't + kill our process; We want to exit gracefully. It also creates an + Exit_Hook object which registers the STDIN_Handler's thread handle + with the ReactorEx. The Exit_Hook will get called back when the + STDIN_Handler thread exits. After registering these, it blocks + reading from STDIN. + + Proactor -- is registered with the ReactorEx. + + The main thread of control waits in the ReactorEx. + +. STDIN events -- When the STDIN_Handler thread reads from STDIN, it + puts the message on Peer_Handler's message queue and signals the + new_msg_event. It then returns to reading from STDIN. + +. new_msg_events -- The ReactorEx thread wakes up and calls + Peer_Handler::handle_signal. The Peer_Handler then tries to dequeue + a message from its message queue. If it can, the message is + Proactively sent to the remote peer. Note that the Peer_Handler + will be notified with this operation is complete. The Peer_Handler + then falls back into the ReactorEx event loop. + +. Send complete event -- When a proactive send is complete, the + Proactor is notified by the ReactorEx. The Proactor, in turn, + notifies the Peer_Handler. The Peer_Handler then checks for more + messages from the message queue. If there are any, it tries to send + them. If there are not, it returns to the ReactorEx event loop. + This is ok since it is notified via new_msg_event when new message + arrive. + +. Read complete event -- When a proactive read is complete (the + Peer_Handler initiated a proactive read when it connected to the + remote peer), the Proactor is notified by the ReactorEx. The + Proactor, in turn notifies the Peer_Handler. If the read was + successful the Peer_Handler just displays the received msg to the + console and reinvokes a proactive read from the network connection. + If the read failed (i.e. the remote peer exited), the Peer_Handler + sets a flag to end the event loop and returns. This will cause the + application to exit. + +. ^C events -- When the user types ^C at the console, the + STDIN_Handler's signal handler will be called. It does nothing, but + as a result of the signal, the STDIN_Handler thread will exit. + +. STDIN_Handler thread exits -- The Exit_Hook will get called back + from the ReactorEx. Exit_Hook::handle_signal sets a flag to end the + event loop and returns. This will cause the application to exit. diff --git a/examples/Reactor/WFMO_Reactor/reactorex.mak b/examples/Reactor/WFMO_Reactor/reactorex.mak new file mode 100644 index 00000000000..150d04508d7 --- /dev/null +++ b/examples/Reactor/WFMO_Reactor/reactorex.mak @@ -0,0 +1,535 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +!IF "$(CFG)" == "" +CFG=test_remove_handler - Win32 Debug +!MESSAGE No configuration specified. Defaulting to test_remove_handler - Win32\ + Debug. +!ENDIF + +!IF "$(CFG)" != "ntalk - Win32 Release" && "$(CFG)" != "ntalk - Win32 Debug" &&\ + "$(CFG)" != "test_remove_handler - Win32 Release" && "$(CFG)" !=\ + "test_remove_handler - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "reactorEx.mak" CFG="test_remove_handler - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ntalk - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "ntalk - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "test_remove_handler - Win32 Release" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "test_remove_handler - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "ntalk - Win32 Debug" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "ntalk - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ntalk\Release" +# PROP BASE Intermediate_Dir "ntalk\Release" +# PROP BASE Target_Dir "ntalk" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ntalk\Release" +# PROP Intermediate_Dir "ntalk\Release" +# PROP Target_Dir "ntalk" +OUTDIR=.\ntalk\Release +INTDIR=.\ntalk\Release + +ALL : "$(OUTDIR)\ntalk.exe" + +CLEAN : + -@erase ".\ntalk\Release\ntalk.exe" + -@erase ".\ntalk\Release\test_reactorEx.obj" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\ + /Fp"$(INTDIR)/ntalk.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\ntalk\Release/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/ntalk.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ace.lib /nologo /subsystem:console /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib ace.lib /nologo /subsystem:console /incremental:no\ + /pdb:"$(OUTDIR)/ntalk.pdb" /machine:I386 /out:"$(OUTDIR)/ntalk.exe" +LINK32_OBJS= \ + "$(INTDIR)/test_reactorEx.obj" + +"$(OUTDIR)\ntalk.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "ntalk - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "ntalk\Debug" +# PROP BASE Intermediate_Dir "ntalk\Debug" +# PROP BASE Target_Dir "ntalk" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "debug" +# PROP Target_Dir "ntalk" +OUTDIR=. +INTDIR=.\debug + +ALL : "$(OUTDIR)\test_reactorEx.exe" + +CLEAN : + -@erase ".\debug\vc40.pdb" + -@erase ".\debug\vc40.idb" + -@erase ".\test_reactorEx.exe" + -@erase ".\debug\test_reactorEx.obj" + -@erase ".\test_reactorEx.ilk" + -@erase ".\test_reactorEx.pdb" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\ + /Fp"$(INTDIR)/ntalk.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/ntalk.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ace.lib /nologo /subsystem:console /debug /machine:I386 /out:"test_reactorEx.exe" +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib ace.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/test_reactorEx.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/test_reactorEx.exe" +LINK32_OBJS= \ + "$(INTDIR)/test_reactorEx.obj" + +"$(OUTDIR)\test_reactorEx.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "test_remove_handler - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "test_remove_handler\Release" +# PROP BASE Intermediate_Dir "test_remove_handler\Release" +# PROP BASE Target_Dir "test_remove_handler" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "test_remove_handler\Release" +# PROP Intermediate_Dir "test_remove_handler\Release" +# PROP Target_Dir "test_remove_handler" +OUTDIR=.\test_remove_handler\Release +INTDIR=.\test_remove_handler\Release + +ALL : "$(OUTDIR)\test_remove_handler.exe" + +CLEAN : + -@erase ".\test_remove_handler\Release\test_remove_handler.exe" + -@erase ".\test_remove_handler\Release\test_remove_handler.obj" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\ + /Fp"$(INTDIR)/test_remove_handler.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\test_remove_handler\Release/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/test_remove_handler.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib /nologo /subsystem:console /incremental:no\ + /pdb:"$(OUTDIR)/test_remove_handler.pdb" /machine:I386\ + /out:"$(OUTDIR)/test_remove_handler.exe" +LINK32_OBJS= \ + "$(INTDIR)/test_remove_handler.obj" + +"$(OUTDIR)\test_remove_handler.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "test_remove_handler - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "test_remove_handler\Debug" +# PROP BASE Intermediate_Dir "test_remove_handler\Debug" +# PROP BASE Target_Dir "test_remove_handler" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "test_remove_handler" +OUTDIR=. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\test_remove_handler.exe" + +CLEAN : + -@erase ".\debug\vc40.pdb" + -@erase ".\debug\vc40.idb" + -@erase ".\test_remove_handler.exe" + -@erase ".\Debug\test_remove_handler.obj" + -@erase ".\test_remove_handler.ilk" + -@erase ".\test_remove_handler.pdb" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\ + /Fp"$(INTDIR)/test_remove_handler.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/test_remove_handler.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ace.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib ace.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/test_remove_handler.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/test_remove_handler.exe" +LINK32_OBJS= \ + "$(INTDIR)/test_remove_handler.obj" + +"$(OUTDIR)\test_remove_handler.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "ntalk - Win32 Release" +# Name "ntalk - Win32 Debug" + +!IF "$(CFG)" == "ntalk - Win32 Release" + +!ELSEIF "$(CFG)" == "ntalk - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\test_reactorEx.cpp +DEP_CPP_TEST_=\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\SOCK_Connector.h"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.h"\ + {$(INCLUDE)}"\ace\Get_Opt.h"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Task.h"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\SOCK_Connector.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.i"\ + {$(INCLUDE)}"\ace\Get_Opt.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Message_Queue.h"\ + {$(INCLUDE)}"\ace\Task.i"\ + {$(INCLUDE)}"\ace\Task.cpp"\ + {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\ + {$(INCLUDE)}"\ace\Message_Queue.i"\ + {$(INCLUDE)}"\ace\Message_Queue.cpp"\ + {$(INCLUDE)}"\ace\Module.h"\ + {$(INCLUDE)}"\ace\Module.i"\ + {$(INCLUDE)}"\ace\Module.cpp"\ + {$(INCLUDE)}"\ace\Stream_Modules.h"\ + {$(INCLUDE)}"\ace\Stream_Modules.i"\ + {$(INCLUDE)}"\ace\Stream_Modules.cpp"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\OS.i"\ + +NODEP_CPP_TEST_=\ + ".\..\..\ace\ace\Sync_T.h"\ + ".\..\..\ace\semLib.h"\ + + +"$(INTDIR)\test_reactorEx.obj" : $(SOURCE) $(DEP_CPP_TEST_) "$(INTDIR)" + + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "test_remove_handler - Win32 Release" +# Name "test_remove_handler - Win32 Debug" + +!IF "$(CFG)" == "test_remove_handler - Win32 Release" + +!ELSEIF "$(CFG)" == "test_remove_handler - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\test_remove_handler.cpp +DEP_CPP_TEST_R=\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + +NODEP_CPP_TEST_R=\ + ".\..\..\ace\semLib.h"\ + ".\..\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\test_remove_handler.obj" : $(SOURCE) $(DEP_CPP_TEST_R) "$(INTDIR)" + + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/examples/Reactor/WFMO_Reactor/reactorex.mdp b/examples/Reactor/WFMO_Reactor/reactorex.mdp new file mode 100644 index 00000000000..0135cc67b75 Binary files /dev/null and b/examples/Reactor/WFMO_Reactor/reactorex.mdp differ diff --git a/examples/Reactor/WFMO_Reactor/test_reactorEx.cpp b/examples/Reactor/WFMO_Reactor/test_reactorEx.cpp new file mode 100644 index 00000000000..757e78c1e9e --- /dev/null +++ b/examples/Reactor/WFMO_Reactor/test_reactorEx.cpp @@ -0,0 +1,444 @@ +// ============================================================================ +// @(#)test_reactorEx.cpp 1.1 10/18/96 + +// +// = LIBRARY +// examples +// +// = FILENAME +// test_reactorEx.cpp +// +// = DESCRIPTION +// This test application tests a wide range of events that can be +// demultiplexed using various ACE utilities. Events used include ^C +// events, reading from STDIN, vanilla Win32 events, thread exits, +// ReactorEx notifications, proactive reads, and proactive writes. +// +// The proactive I/O events are demultiplexed by the ACE_Proactor. +// The thread exits, notications, and vanilla Win32 events are +// demultiplexed by the ACE_ReactorEx. To enable a single thread +// to run all these events, the Proactor is integrated with the +// ReactorEx. +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#include "ace/ReactorEx.h" +#include "ace/Proactor.h" +#include "ace/SOCK_Connector.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/Get_Opt.h" +#include "ace/Time_Value.h" +#include "ace/Service_Config.h" +#include "ace/Synch.h" +#include "ace/Task.h" +#include "ace/OS.h" + +typedef ACE_Task MT_TASK; + +class Peer_Handler : public MT_TASK + // = TITLE + // Connect to a server. Receive messages from STDIN_Handler + // and forward them to the server using proactive I/O. +{ +public: + Peer_Handler (int argc, char *argv[]); + + int open (void * =0); + // This method creates the network connection to the remote peer. + // It does blocking connects and accepts depending on whether a + // hostname was specified from the command line. + + virtual int handle_output_complete (ACE_Message_Block *msg, + long bytes_transfered); + // One of our asynchronous writes to the remote peer has completed. + // Make sure it succeeded and then delete the message. + + virtual int handle_input_complete (ACE_Message_Block *msg, + long bytes_transfered); + // The remote peer has sent us something. If it succeeded, print + // out the message and reinitiate a read. Otherwise, fail. In both + // cases, delete the message sent. + + virtual ACE_Message_Block *get_message (void); + // This is so the Proactor can get a message to read into. + + virtual ACE_HANDLE get_handle (void) const; + // This is so the Proactor can get our handle. + + virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask); + // We've been removed from the ReactorEx. + + virtual int handle_signal (int index, siginfo_t *, ucontext_t *); + // We've been signaled by the STDIN thread. Try to dequeue a + // message. + + void try_send (void); + // Try to dequeue a message. If successful, send it proactively to + // the remote peer. + + virtual int put (ACE_Message_Block *mb, + ACE_Time_Value *tv = 0); + // Enqueue the new mb and signal the main thread. + +private: + ACE_SOCK_Stream stream_; + // Socket that we have connected to the server. + + ACE_HANDLE new_msg_event_; + // Event that gets signaled when messages arrive. + + // = Remote peer info. + char *host_; + // Name of remote host. + + u_short port_; + // Port number for remote host. + + // = Make Task happy. + int close (u_long) { return 0; } +}; + +class STDIN_Handler : public ACE_Task + // = TITLE + // Active Object. Reads from STDIN and passes message blocks to + // the peer handler. +{ +public: + STDIN_Handler (MT_TASK &ph); + + virtual int open (void * = 0); + // Activate object. + + virtual int close (u_long = 0); + // Shut down. + + int svc (void); + // Thread runs here. + +private: + MT_TASK &ph_; + // Send all input to ph_. + + static void handler (int signum); + // Handle a ^C. (Do nothing). + + int put (ACE_Message_Block *, ACE_Time_Value *) { return 0; } + // Make Task happy. + + void register_thread_exit_hook (void); + // Helper function to register with the ReactorEx for thread exit. + + virtual int handle_signal (int index, siginfo_t *, ucontext_t *); + // The STDIN thread has exited. This means the user hit ^C. We can + // end the event loop. +}; + +Peer_Handler::Peer_Handler (int argc, char *argv[]) + : host_ (0), + port_ (ACE_DEFAULT_SERVER_PORT) +{ + ACE_Get_Opt get_opt (argc, argv, "h:p:"); + int c; + + while ((c = get_opt ()) != EOF) + { + switch (c) + { + case 'h': + host_ = get_opt.optarg; + break; + case 'p': + port_ = ACE_OS::atoi (get_opt.optarg); + break; + } + } + + // Auto reset event. + new_msg_event_ = ::CreateEvent (NULL, FALSE, FALSE, NULL); + ACE_Service_Config::reactorEx ()-> + register_handler (this, new_msg_event_); +} + +// This method creates the network connection to the remote peer. It +// does blocking connects and accepts depending on whether a hostname +// was specified from the command line. + +int +Peer_Handler::open (void *) +{ + if (host_ != 0) // Connector + { + ACE_INET_Addr addr (port_, host_); + ACE_SOCK_Connector connector; + + // Establish connection with server. + if (connector.connect (stream_, addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "connect"), -1); + + ACE_DEBUG ((LM_DEBUG, "connected.\n")); + } + else // Acceptor + { + ACE_SOCK_Acceptor acceptor; + ACE_INET_Addr local_addr (port_); + + if ((acceptor.open (local_addr) == -1) || + (acceptor.accept (this->stream_) == -1)) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "accept failed"), -1); + + ACE_DEBUG ((LM_DEBUG, "accepted.\n")); + } + + return ACE_Service_Config::proactor ()->initiate + (this, ACE_Event_Handler::READ_MASK); +} + +// One of our asynchronous writes to the remote peer has completed. +// Make sure it succeeded and then delete the message. + +int +Peer_Handler::handle_output_complete (ACE_Message_Block *msg, + long bytes_transfered) +{ + if (bytes_transfered <= 0) + ACE_DEBUG ((LM_DEBUG, "%p bytes = %d\n", "Message failed", + bytes_transfered)); + + // This was allocated by the STDIN_Handler, queued, dequeued, + // passed to the proactor, and now passed back to us. + delete msg; + return 0; // Do not reinvoke a send. +} + +// The remote peer has sent us something. If it succeeded, print +// out the message and reinitiate a read. Otherwise, fail. In both +// cases, delete the message sent. + +int +Peer_Handler::handle_input_complete (ACE_Message_Block *msg, + long bytes_transfered) +{ + if ((bytes_transfered > 0) && (msg->length () > 0)) + { + msg->rd_ptr ()[bytes_transfered] = '\0'; + // Print out the message received from the server. + ACE_DEBUG ((LM_DEBUG, "%s", msg->rd_ptr ())); + delete msg; + return 1; // Reinvokes the recv() operation! + } + + delete msg; + // If a read failed, we will assume it's because the remote peer + // went away. We will end the event loop. Since we're in the main + // thread, we don't need to do a notify. + ACE_Service_Config::end_reactorEx_event_loop (); + return -1; // Close down. +} + +// This is so the Proactor can get a message to read into. + +ACE_Message_Block * +Peer_Handler::get_message (void) +{ + // An extra byte for NUL termination. + ACE_Message_Block *message = + new ACE_Message_Block (BUFSIZ + 1); + + message->size (BUFSIZ); + return message; +} + +// This is so the Proactor can get our handle. +ACE_HANDLE +Peer_Handler::get_handle (void) const +{ + return this->stream_.get_handle (); +} + +// We've been removed from the ReactorEx. +int +Peer_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + ACE_DEBUG ((LM_DEBUG, "Peer_Handler closing down\n")); + return 0; +} + +// We've been signaled by the STDIN thread. Try to dequeue a +// message. + +int +Peer_Handler::handle_signal (int, siginfo_t *, ucontext_t *) +{ + this->try_send (); + return 0; +} + +// Try to dequeue a message. If successful, send it proactively to +// the remote peer. + +void +Peer_Handler::try_send (void) +{ + ACE_Message_Block *mb; + + ACE_Time_Value tv (ACE_Time_Value::zero); + + if (this->getq (mb, &tv) != -1) + { + if (ACE_Service_Config::proactor ()-> + initiate (this, ACE_Event_Handler::WRITE_MASK, mb) == -1) + ACE_ERROR ((LM_ERROR, "%p Write initiate.\n", "Peer_Handler")); + } +} + +// Enqueue the new mb and signal the main thread. + +int +Peer_Handler::put (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + // Enqueue the mb. + int result = this->putq (mb, tv); + + // Signal the main thread. This will remain signaled until the main + // thread wakes up. + + if (::SetEvent (new_msg_event_) == 0) + ACE_ERROR ((LM_ERROR, "Pulse Failed!\n")); + + return result; +} + +void +STDIN_Handler::handler (int signum) +{ + ACE_DEBUG ((LM_DEBUG, "signal = %S\n", signum)); +} + +STDIN_Handler::STDIN_Handler (MT_TASK &ph) + : ph_ (ph) +{ + // Register for ^C from the console. We just need to catch the + // exception so that the kernel doesn't kill our process. + // Registering this signal handler just tells the kernel that we + // know what we're doing; to leave us alone. + ACE_OS::signal (SIGINT, ACE_SignalHandler (STDIN_Handler::handler)); +}; + +// Activate object. + +int +STDIN_Handler::open (void *) +{ + if (this->activate (THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), -1); + + return 0; +} + +// Shut down. + +int +STDIN_Handler::close (u_long) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) thread is exiting.\n")); + return 0; +} + +// Thread runs here. + +int +STDIN_Handler::svc (void) +{ + this->register_thread_exit_hook (); + + for (;;) + { + ACE_Message_Block *mb = new ACE_Message_Block (BUFSIZ); + + // Read from stdin into mb. + int read_result = ACE_OS::read (ACE_STDIN, + mb->rd_ptr (), + mb->size ()); + + // If read succeeds, put mb to peer handler, else end the loop. + if (read_result > 0) + { + mb->wr_ptr (read_result); + this->ph_.put (mb); + } + else + break; + } + + // handle_signal will get called. + return 42; +} + +// Register an exit hook with the reactorEx. All this junk is testing +// out how ACE_Thread::self (hthread_id&) doesn't work!! + +void +STDIN_Handler::register_thread_exit_hook (void) +{ + ACE_hthread_t handle; + + // Get a real handle to our thread. + ACE_Service_Config::thr_mgr ()->thr_self (handle); + + // Register ourselves to get called back when our thread exits. + + if (ACE_Service_Config::reactorEx ()-> + register_handler (this, handle) == -1) + ACE_ERROR ((LM_ERROR, "Exit_Hook Register failed.\n")); + + // We're in another thread, so we need to notify the ReactorEx so + // that it wakes up and waits on the new set of handles. + ACE_Service_Config::reactorEx ()->notify (); +} + +// The STDIN thread has exited. This means the user hit ^C. We can +// end the event loop and delete ourself. + +int +STDIN_Handler::handle_signal (int, siginfo_t *, ucontext_t *) +{ + ACE_DEBUG ((LM_DEBUG, "STDIN thread has exited.\n")); + ACE_Service_Config::end_reactorEx_event_loop (); + return 0; +} + +int +main (int argc, char *argv[]) +{ + // Open handler for remote peer communications this will run from + // the main thread. + Peer_Handler peer_handler (argc, argv); + + if (peer_handler.open () == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p open failed, errno = %d.\n", + "peer_handler", errno), 0); + + // Open active object for reading from stdin. + STDIN_Handler stdin_handler (peer_handler); + + if (stdin_handler.open () == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p open failed, errno = %d.\n", + "stdin_handler", errno), 0); + + // Register proactor with ReactorEx so that we can demultiplex + // "waitable" events and I/O operations from a single thread. + if (ACE_Service_Config::reactorEx ()->register_handler + (ACE_Service_Config::proactor ()) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p failed to register Proactor.\n", + argv[0]), -1); + + // Run main event demultiplexor. + ACE_Service_Config::run_reactorEx_event_loop (); + + return 42; +} diff --git a/examples/Reactor/WFMO_Reactor/test_remove_handler.cpp b/examples/Reactor/WFMO_Reactor/test_remove_handler.cpp new file mode 100644 index 00000000000..fb61519b1e9 --- /dev/null +++ b/examples/Reactor/WFMO_Reactor/test_remove_handler.cpp @@ -0,0 +1,94 @@ +// ============================================================================ +// @(#)test_remove_handler.cpp 1.1 10/18/96 + +// +// = LIBRARY +// examples +// +// = FILENAME +// test_remove_handler.cpp +// +// = DESCRIPTION +// Tests the ReactorEx's ability to handle simultaneous events. If +// you pass anything on the command-line, then each handler +// requests to be removed from the ReactorEx after each event. +// This has a funky effect on the order in which handlers are +// serviced. So, if no parameters are passed in, the handlers +// should be serviced 1 through MAXIMUM_WAIT_OBJECTS. If handlers +// to request to be removed as signals occur, they will be serviced +// 1, MAX, MAX-1, ..., 2. This is because of a ReactorEx +// bookkeeping optimization. +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#include "ace/ReactorEx.h" +#include "ace/Service_Config.h" +#include "ace/Synch.h" + +class Event_Handler : public ACE_Event_Handler +// = TITLE +// Generic Event Handler. +// +// = DESCRIPTION +// +// Creates event. Registers with ReactorEx. Signals event. If +// created with -close_down- it returns -1 from handle signal. +{ +public: + Event_Handler (int event_number, + int close_down) + : event_number_ (event_number), + close_down_ (close_down) + { + ACE_Service_Config::reactorEx ()->register_handler (this, + this->event_.handle ()); + this->event_.signal (); + } + + virtual int handle_signal (int index, siginfo_t *, ucontext_t *) + { + ACE_DEBUG ((LM_DEBUG, "event %d occured.\n", event_number_)); + + if (this->close_down_) + return -1; + else + return 0; + } + + virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask) + { + // ACE_DEBUG ((LM_DEBUG, "event handler %d closed.\n", event_number_)); + delete this; + return 0; + } + + virtual ACE_HANDLE get_handle (void) const + { + return event_.handle (); + } + +private: + int event_number_; + // Our event number. + + int close_down_; + // Shall we close down or not. + + ACE_Event event_; + // Signaled to shut down the handler. +}; + +int +main (int argc, char *argv[]) +{ + int close_down = arg > 1 ? 1 : 0; + + for (int i = 0; i < ACE_ReactorEx::MAX_SIZE; i++) + new Event_Handler (i, close_down); + + ACE_Service_Config::reactorEx ()->handle_events (); + return 42; +} diff --git a/examples/Service_Configurator/IPC-tests/Makefile b/examples/Service_Configurator/IPC-tests/Makefile new file mode 100644 index 00000000000..a90224788d8 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/Makefile @@ -0,0 +1,24 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the IPC tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +INFO = + +DIRS = client \ + server + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU diff --git a/examples/Service_Configurator/IPC-tests/README b/examples/Service_Configurator/IPC-tests/README new file mode 100644 index 00000000000..4af5114358a --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/README @@ -0,0 +1,112 @@ +This file describes how to invoke the Reactor client/server tests in +the $WRAPPER_ROOT/tests/Reactor/{client,server} directories. + +These tests exercise all of the IPC_SAP communication mechanisms, the +Reactor event demultiplexor, and the Service Configurator dynamic +service configuration framework. To gain a deeper understanding of +what is going on, you should read the IPC_SAP.ps, reactor-[1-3].ps, +and service_configurator.ps papers available for anonymous ftp from +ics.uci.edu in the ftp/gnu/C++_wrappers_doc.tar.Za[a-c] files. + +The key to running the Reactor client/server tests is to understand +the purpose of the svc.conf file located in the +$WRAPPER_ROOT/tests/Reactor/server directory. This file contains a +list of services that may be dynamically configured into a the address +space of a network daemon process. If you look at the example +svc.conf file included in the Reactor tests you'll see that most of +the entries are commented out (the comment symbol is the '#', which is +an "ignore until end-of-line comment" with the same semantics as the +UNIX C and Bourne shells). Before reading any further, take a look at +this svc.conf file with your favorite editor or file browser. + +There are several types of entries in this file. The two most +important are the lines beginning with the keywords "static" and +"dynamic". For example, the first non-commented line says: + +static Svc_Manager "-d -p 3911" + +When this line is parsed at startup time by the Service Configurator +object in the ./server_test executable, it causes the pre-configured +Svc_Manager object to be initialized with an "argv" argument of "-d -p +3911." This results in TCP port 3911 being created to listen +connection requests from clients. To see how this works do the +following: + +1. Comment out all the other lines except + +static Svc_Manager "-d -p 3911" + + in the svc.conf file + +2. Start up the ./server_test executable in one window, as follows: + + % ./server_test -d + +3. Make another window on the *same* host and cd to the ../client + directory + +4. Run the ./remote_service_directory_test program as follows: + + % ./remote_service_directory_test -p 3911 -h localhost + +If everything has been compiled and initialized correctly, you should +get the following message: + + Svc_Manager 3911/tcp # lists all services in the daemon + +This message is telling you that the Svc_Manager is currently the only +service that is active within the ./server_test program. To configure +and activate another service dynamically, perform the following steps: + +1. *Without* shutting down the ./server_test program, edit the svc.conf + file. Comment out the Svc_Manager line by adding a '#' at the front, i.e.: + +# static Svc_Manager "-d -p 3911" + + and then uncomment the second line: + +dynamic Remote_Brdcast Service_Object * .obj/Handle_Broadcast.so:remote_broadcast "-p 10001" + +2. Send the SIGHUP signal to the process running the ./server_test program + (use "ps -gux" on SunOS 4.x or "ps -elf" on SunOS 5.x to find the + correct process id). This will cause the ./server_test program to + reconfigure itself based on the new contents of the svc.conf file. + After reconfiguration, you'll now have a second active service in + the address space of the ./server_test daemon. To see this, rerun + the remote_service_directory_test command, e.g.: + + % ./remote_service_directory_test -p 3911 -h localhost + + You should now see the following output: + + Svc_Manager 3911/tcp # lists all services in the daemon + Remote_Brdcast 10001/udp # tests broadcasting + + which indicates that the remote broadcast service is now active. + +3. To test the remote broadcast service, run the following program + in the ../client directory: + + % ./broadcast_client_test -p 10001 + + This should cause the window running the ./server_test to + display the following output: + + received broadcast datagram from host spare.ics.uci.edu + ---------------------------------------- + testing socket broadcast service + ---------------------------------------- + +If you want to run other tests, using other configurations, simply +uncomment the appropriate lines in the svc.conf file and experiment +with the corresponding test drivers in the ../client directory. All +the source code is available so once you get the hang of what is +happening, you might want to take a look at how it is all implemented. +I think you'll be surprised at how much of the ACE framework code is +reused for each different service. Moreover, writing a new service is +often simply a matter of copying an existing file and filling in the +behavior of some of the methods (e.g., the handle_input() method and +the init() method). + +The service_configurator.ps paper and the ACE.ps paper describe the +details of the Service Configurator framework. diff --git a/examples/Service_Configurator/IPC-tests/client/Makefile b/examples/Service_Configurator/IPC-tests/client/Makefile new file mode 100644 index 00000000000..d6fbca0eeac --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/client/Makefile @@ -0,0 +1,306 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the client-side of the primary Reactor tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = local_dgram_client_test \ + local_stream_client_test \ + local_pipe_client_test \ + remote_stream_client_test \ + remote_thr_stream_client_test \ + remote_dgram_client_test \ + local_fifo_client_test \ + broadcast_client_test \ + local_spipe_client_test \ + remote_service_directory_test + +LSRC = $(addsuffix .cpp,$(BIN)) + +LDLIBS = + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +INSTALL = + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/local_dgram_client_test.o .shobj/local_dgram_client_test.so: local_dgram_client_test.cpp \ + $(WRAPPER_ROOT)/ace/LSOCK_CODgram.h \ + $(WRAPPER_ROOT)/ace/LSOCK.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/LSOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_CODgram.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_CODgram.i \ + $(WRAPPER_ROOT)/ace/LSOCK_CODgram.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Dgram.h \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.h \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Dgram.i \ + $(WRAPPER_ROOT)/ace/UNIX_Addr.h \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/local_stream_client_test.o .shobj/local_stream_client_test.so: local_stream_client_test.cpp \ + $(WRAPPER_ROOT)/ace/LSOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/LSOCK.h \ + $(WRAPPER_ROOT)/ace/LSOCK.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/UNIX_Addr.h \ + $(WRAPPER_ROOT)/ace/LSOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/local_pipe_client_test.o .shobj/local_pipe_client_test.so: local_pipe_client_test.cpp \ + $(WRAPPER_ROOT)/ace/LSOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/LSOCK.h \ + $(WRAPPER_ROOT)/ace/LSOCK.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/UNIX_Addr.h \ + $(WRAPPER_ROOT)/ace/LSOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/remote_stream_client_test.o .shobj/remote_stream_client_test.so: remote_stream_client_test.cpp \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/SOCK_CODgram.h \ + $(WRAPPER_ROOT)/ace/SOCK_CODgram.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/remote_thr_stream_client_test.o .shobj/remote_thr_stream_client_test.so: remote_thr_stream_client_test.cpp \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/TLI_Connector.h \ + $(WRAPPER_ROOT)/ace/TLI_Stream.h \ + $(WRAPPER_ROOT)/ace/TLI.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/TLI.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/TLI_Stream.i \ + $(WRAPPER_ROOT)/ace/TLI_Connector.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/remote_dgram_client_test.o .shobj/remote_dgram_client_test.so: remote_dgram_client_test.cpp \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/local_fifo_client_test.o .shobj/local_fifo_client_test.so: local_fifo_client_test.cpp \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/FIFO_Send_Msg.h \ + $(WRAPPER_ROOT)/ace/FIFO_Send.h \ + $(WRAPPER_ROOT)/ace/FIFO.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/FIFO_Send.i \ + $(WRAPPER_ROOT)/ace/FIFO_Send_Msg.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/broadcast_client_test.o .shobj/broadcast_client_test.so: broadcast_client_test.cpp \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram_Bcast.h \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.i \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram_Bcast.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/local_spipe_client_test.o .shobj/local_spipe_client_test.so: local_spipe_client_test.cpp \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Connector.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Connector.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/remote_service_directory_test.o .shobj/remote_service_directory_test.so: remote_service_directory_test.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/Service_Configurator/IPC-tests/client/broadcast_client_test.cpp b/examples/Service_Configurator/IPC-tests/client/broadcast_client_test.cpp new file mode 100644 index 00000000000..57d417441f7 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/client/broadcast_client_test.cpp @@ -0,0 +1,56 @@ +/* Tests out the broadcast service of the +// @(#)broadcast_client_test.cpp 1.1 10/18/96 + + Internet domain IPC-SAP dgram abstraction. */ + +#include "ace/INET_Addr.h" +#include "ace/SOCK_Dgram_Bcast.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" + +/* Name of the program. */ +static char *program_name; + +/* Port number to use. */ +static unsigned short broadcast_port_number = ACE_DEFAULT_BROADCAST_PORT; + +static void +print_usage_and_die (void) +{ + ACE_OS::fprintf (stderr, "usage: %s [-p broadcast portnum]\n", + program_name); + ACE_OS::exit (1); +} + +void +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, "p:"); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'p': + broadcast_port_number = ACE_OS::atoi (get_opt.optarg); + break; + default: + print_usage_and_die (); + break; + } +} + +int +main (int argc, char *argv[]) +{ + program_name = argv[0]; + parse_args (argc, argv); + + ACE_SOCK_Dgram_Bcast sd (ACE_Addr::sap_any); + + static char buf[] = "testing socket broadcast service"; + + if (sd.send (buf, strlen (buf), broadcast_port_number) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "can't send broadcast"), -1); + + return 0; +} diff --git a/examples/Service_Configurator/IPC-tests/client/local_data b/examples/Service_Configurator/IPC-tests/client/local_data new file mode 100644 index 00000000000..1faba1b8091 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/client/local_data @@ -0,0 +1,22 @@ +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal +locallocallocallocallocallocallocallocal diff --git a/examples/Service_Configurator/IPC-tests/client/local_dgram_client_test.cpp b/examples/Service_Configurator/IPC-tests/client/local_dgram_client_test.cpp new file mode 100644 index 00000000000..249bdfa83d5 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/client/local_dgram_client_test.cpp @@ -0,0 +1,94 @@ +/* Tests out the UNIX domain IPC-SAP abstraction. */ +// @(#)local_dgram_client_test.cpp 1.1 10/18/96 + + +#include "ace/LSOCK_CODgram.h" +#include "ace/LSOCK_Dgram.h" +#include "ace/UNIX_Addr.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" + +#if defined (ACE_HAS_MSG) && !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) +/* Name of the program. */ +static char *program_name; + +/* Number of seconds to sleep. */ +static int seconds = 3; + +/* Name of rendezvous point. */ +static char *rendezvous_codgram = "/tmp/foo_codgram"; +static char *rendezvous_dgram = "/tmp/foo_dgram"; + +/* Name of file to send. */ +static char *file_name = "local_data"; + +static void print_usage_and_die (void) +{ + ACE_ERROR ((LM_ERROR, "usage: %s [-r rendezvous_dgram] [-c rendezvous_codgram] [-f file] [-n seconds]\n%a", + program_name, -1)); +} + +void +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, "c:f:n:r:"); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'f': + file_name = get_opt.optarg; + break; + case 'n': + seconds = atoi (get_opt.optarg); + break; + case 'r': + rendezvous_dgram = get_opt.optarg; + break; + case 'c': + rendezvous_codgram = get_opt.optarg; + break; + default: + print_usage_and_die (); + break; + } +} + +int +main (int argc, char *argv[]) +{ + program_name = argv[0]; + + parse_args (argc, argv); + + ACE_LSOCK_Dgram sd (ACE_Addr::sap_any); + ACE_LSOCK_CODgram sc; + int fd; + + if (sc.open (ACE_UNIX_Addr (rendezvous_codgram), ACE_Addr::sap_any) < 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + + if ((fd = ACE_OS::open (file_name, O_RDONLY)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + + /* Send the open file descriptor to the server! */ + + if (sc.send_handle (fd) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), -1); + + char *name = ACE_OS::cuserid (0); + + if (sd.send (name, strlen (name) + 1, ACE_UNIX_Addr (rendezvous_dgram)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), -1); + + if (ACE_OS::close (fd) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), -1); + + return 0; +} +#else +int main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "your platform must support sendmsg/recvmsg to run this test\n"), -1); +} +#endif /* ACE_HAS_MSG */ diff --git a/examples/Service_Configurator/IPC-tests/client/local_fifo_client_test.cpp b/examples/Service_Configurator/IPC-tests/client/local_fifo_client_test.cpp new file mode 100644 index 00000000000..f136ce465bf --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/client/local_fifo_client_test.cpp @@ -0,0 +1,85 @@ +/* Send a file through ACE_FIFO communication channel by +// @(#)local_fifo_client_test.cpp 1.1 10/18/96 + + break it (the file) into pieces. */ + +#include "ace/Mem_Map.h" +#include "ace/FIFO_Send_Msg.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" + +static const BUF_LEN = 256; + +// Name of the program. +static char *program_name; + +// debug state on or off +static int debug = 0; + +char *rendezvous_fifo = "/tmp/foo_fifo"; + +/* Name of file to send. */ +static char *file_name = "./local_data"; + +static void +print_usage_and_die (void) +{ + ACE_ERROR ((LM_ERROR, "usage: %s [-d] [-f rendezvous_fifo]\n%a", + program_name, -1)); +} + +static void +parse_arguments (int argc, char *argv[]) +{ + int tracing = 1; + program_name = argv[0]; + + ACE_Get_Opt get_opt (argc, argv, "df:"); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'd': + debug = 1; + break; + case 'f': + rendezvous_fifo = get_opt.optarg; + break; + default: + print_usage_and_die (); + break; + } + + if (debug) + ACE_DEBUG ((LM_DEBUG, + "rendezvous_fifo = %s\n" + "trace = %s\n", + rendezvous_fifo, tracing ? "on" : "off")); +} + +int +main(int argc, char *argv[]) +{ + parse_arguments (argc, argv); + + ACE_FIFO_Send_Msg fifo; + + if (fifo.open ((const char *) rendezvous_fifo, O_WRONLY, 0666) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "Cannot open %s for requesting a new communication channel" + "in local_fifo_client_test\n", rendezvous_fifo), -1); + + + void *cp; + ACE_Mem_Map mmap (file_name); + + if (mmap (cp) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "mmap"), -1); + + /* Next, send the file's contents. */ + + ACE_Str_Buf msg (cp, int (mmap.size ())); + + if (fifo.send (msg) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), -1); + return 0; +} diff --git a/examples/Service_Configurator/IPC-tests/client/local_pipe_client_test.cpp b/examples/Service_Configurator/IPC-tests/client/local_pipe_client_test.cpp new file mode 100644 index 00000000000..cb09bd0eade --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/client/local_pipe_client_test.cpp @@ -0,0 +1,122 @@ +// Another test of UNIX domain IPC-SAP abstraction. This one opens 2 +// @(#)local_pipe_client_test.cpp 1.1 10/18/96 + +// pipes and then ships certain ends over to the server to act as a +// filter! + +#include "ace/LSOCK_Connector.h" +#include "ace/UNIX_Addr.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" + +#if defined (ACE_HAS_MSG) && !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) +/* Name of the program. */ +static char *program_name; + +/* Name of rendezvous point. */ +static char *rendezvous = "/tmp/foo_pipe"; + +/* Name of file to send. */ +static char *file_name = "local_data"; + +static void +print_usage_and_die (void) +{ + ACE_ERROR ((LM_ERROR, "usage: %s [-r rendezvous] [-f file]\n%a", + program_name, -1)); +} + +void +parse_args (int argc, char *argv[]) +{ + program_name = argv[0]; + + ACE_Get_Opt get_opt (argc, argv, "f:r:"); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'f': + file_name = get_opt.optarg; + break; + case 'r': + rendezvous = get_opt.optarg; + break; + default: + print_usage_and_die (); + break; + } +} + +int +do_client_processing (ACE_LSOCK_Stream &sc) +{ + int fd_read[2]; + int fd_write[2]; + char buf[BUFSIZ]; + int n; + int fd1; + + if (ACE_OS::pipe (fd_read) == -1 || ACE_OS::pipe (fd_write) == -1) + return -1; + + if (sc.send_handle (fd_write[0]) == -1 || sc.send_handle (fd_read[1]) == -1) + return -1; + + /* Close off the ends we aren't interested in. */ + + if (ACE_OS::close (fd_read[1]) || ACE_OS::close (fd_write[0]) == -1) + return -1; + + /* Do a silly dup just for fun... */ + + if ((fd1 = ACE_OS::open (file_name, O_RDONLY)) == -1) + return -1; + + while ((n = ACE_OS::read (fd1, buf, sizeof buf)) > 0) + { + if (ACE_OS::write (fd_write[1], buf, n) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "write"), -1); + if ((n = ACE_OS::read (fd_read[0], buf, sizeof buf)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "read"), -1); + if (ACE_OS::write (ACE_STDOUT, buf, n) == -1) + return -1; + } + + if (ACE_OS::close (fd_read[0]) == -1 + || ACE_OS::close (fd_write[1]) == -1 + || ACE_OS::close (fd1) == -1) + ACE_OS::exit (1); + + return 0; +} + +int +main (int argc, char *argv[]) +{ + parse_args (argc, argv); + + ACE_LSOCK_Stream sc; + ACE_LSOCK_Connector con; + + if (con.connect (sc, ACE_UNIX_Addr (rendezvous)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "connect"), -1); + + if (do_client_processing (sc) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "do_client_processing"), -1); + +#if defined (SunOS4) + ACE_OS::sleep (1); +#endif /* SunOS4 */ + + if (sc.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), -1); + + return 0; +} +#else +int main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "your platform must support sendmsg/recvmsg to run this test\n"), -1); +} +#endif /* ACE_HAS_MSG */ diff --git a/examples/Service_Configurator/IPC-tests/client/local_spipe_client_test.cpp b/examples/Service_Configurator/IPC-tests/client/local_spipe_client_test.cpp new file mode 100644 index 00000000000..0dbe3abbed2 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/client/local_spipe_client_test.cpp @@ -0,0 +1,88 @@ +/* Send a file through ACE_SPIPE communication channel by +// @(#)local_spipe_client_test.cpp 1.1 10/18/96 + + break it (the file) into pieces. */ + +#include "ace/Mem_Map.h" +#include "ace/SPIPE_Connector.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" + +#if defined (ACE_HAS_STREAM_PIPES) + +static char *program_name; + +// debug state on or off +static int debug = 0; + +char *rendezvous_spipe = "/tmp/foo_spipe"; + +/* Name of file to send. */ +static char *file_name = "./local_data"; + +static void +print_usage_and_die (void) +{ + ACE_ERROR ((LM_ERROR, "usage: %s [-d] [-r rendezvous_spipe]\n%a", + program_name, -1)); +} + +static void +parse_arguments (int argc, char *argv[]) +{ + program_name = argv[0]; + ACE_Get_Opt get_opt (argc, argv, "dr:"); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'd': + debug = 1; + break; + case 'r': + rendezvous_spipe = get_opt.optarg; + break; + default: + print_usage_and_die (); + break; + } + if (debug) + ACE_DEBUG ((LM_DEBUG, "rendezvous_spipe = %s\n", + rendezvous_spipe)); +} + +int +main(int argc, char *argv[]) +{ + parse_arguments (argc, argv); + + ACE_SPIPE_Stream spipe; + ACE_SPIPE_Connector con; + + if (con.connect (spipe, ACE_SPIPE_Addr (rendezvous_spipe)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "Cannot open %s for requesting a new communication channel" + " in local_spipe_client_test.\n", rendezvous_spipe), -1); + + ACE_Mem_Map mmap (file_name); + void *cp; + + if (mmap (cp) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "mmap"), -1); + + /* Next, send the file's contents. */ + + ACE_Str_Buf msg (cp, int (mmap.size ())); + + if (spipe.send ((ACE_Str_Buf *) 0, &msg) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), -1); + return 0; +} +#else +#include +int +main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "This feature is not supported\n"), -1); +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/examples/Service_Configurator/IPC-tests/client/local_stream_client_test.cpp b/examples/Service_Configurator/IPC-tests/client/local_stream_client_test.cpp new file mode 100644 index 00000000000..bf168d0056e --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/client/local_stream_client_test.cpp @@ -0,0 +1,85 @@ +/* Tests out the UNIX domain IPC-SAP abstraction. */ +// @(#)local_stream_client_test.cpp 1.1 10/18/96 + +#include "ace/LSOCK_Connector.h" +#include "ace/UNIX_Addr.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" + +#if defined (ACE_HAS_MSG) && !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) +/* Name of the program. */ +static char *program_name; + +/* Name of rendezvous point. */ +static char *rendezvous = "/tmp/foo_stream"; + +/* Name of file to send. */ +static char *file_name = "local_data"; + +static void +print_usage_and_die (void) +{ + ACE_ERROR ((LM_ERROR, "usage: %s [-r rendezvous] [-f file]%a\n", + program_name, -1)); +} + +void +parse_args (int argc, char *argv[]) +{ + program_name = argv[0]; + ACE_Get_Opt get_opt (argc, argv, "f:r:"); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'f': + file_name = get_opt.optarg; + break; + case 'r': + rendezvous = get_opt.optarg; + break; + default: + print_usage_and_die (); + break; + } +} + +int +main (int argc, char *argv[]) +{ + parse_args (argc, argv); + + int fd; + char buf[BUFSIZ]; + int n; + + ACE_LSOCK_Stream sc; + ACE_LSOCK_Connector con; + + if (con.connect (sc, ACE_UNIX_Addr (rendezvous)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "connect"), -1); + + if ((fd = ACE_OS::open (file_name, O_RDONLY)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + + /* Send the open file descriptor to the server! */ + + if (sc.send_handle (fd) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send_handle"), -1); + + if ((n = sc.recv_n (buf, sizeof buf)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv"), -1); + else + ACE_OS::write (ACE_STDOUT, buf, n); + + if (ACE_OS::close (fd) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), -1); + + return 0; +} +#else +int main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "your platform must support sendmsg/recvmsg to run this test\n"), -1); +} +#endif /* ACE_HAS_MSG */ diff --git a/examples/Service_Configurator/IPC-tests/client/remote_data b/examples/Service_Configurator/IPC-tests/client/remote_data new file mode 100644 index 00000000000..ae7e1fbb88e --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/client/remote_data @@ -0,0 +1,22 @@ +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote +remoteremoteremoteremoteremoteremoteremoteremote diff --git a/examples/Service_Configurator/IPC-tests/client/remote_data1 b/examples/Service_Configurator/IPC-tests/client/remote_data1 new file mode 100644 index 00000000000..6faaee46729 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/client/remote_data1 @@ -0,0 +1,22 @@ +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 +remote1remote1remote1remote1remote1remote1remote1remote1 diff --git a/examples/Service_Configurator/IPC-tests/client/remote_data2 b/examples/Service_Configurator/IPC-tests/client/remote_data2 new file mode 100644 index 00000000000..ae6bf12d49f --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/client/remote_data2 @@ -0,0 +1,22 @@ +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 +remote2remote2remote2remote2remote2remote2remote2remote2 diff --git a/examples/Service_Configurator/IPC-tests/client/remote_data3 b/examples/Service_Configurator/IPC-tests/client/remote_data3 new file mode 100644 index 00000000000..7f2ec1aa81b --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/client/remote_data3 @@ -0,0 +1,22 @@ +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 +remote3remote3remote3remote3remote3remote3remote3remote3 diff --git a/examples/Service_Configurator/IPC-tests/client/remote_data4 b/examples/Service_Configurator/IPC-tests/client/remote_data4 new file mode 100644 index 00000000000..6c5a9633d56 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/client/remote_data4 @@ -0,0 +1,22 @@ +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 +remote4remote4remote4remote4remote4remote4remote4remote4 diff --git a/examples/Service_Configurator/IPC-tests/client/remote_dgram_client_test.cpp b/examples/Service_Configurator/IPC-tests/client/remote_dgram_client_test.cpp new file mode 100644 index 00000000000..54cde3aef67 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/client/remote_dgram_client_test.cpp @@ -0,0 +1,78 @@ +/* Tests out the Internet domain IPC-SAP dgram abstraction. */ +// @(#)remote_dgram_client_test.cpp 1.1 10/18/96 + + +#include "ace/Mem_Map.h" +#include "ace/SOCK_Dgram.h" +#include "ace/Log_Msg.h" +#include "ace/INET_Addr.h" +#include "ace/Get_Opt.h" + +/* Name of the program. */ +static char *program_name; + +/* Port number to use. */ +static unsigned short port_number = ACE_DEFAULT_SERVER_PORT; + +/* Name of remote host. */ +static char *host_name = ACE_DEFAULT_SERVER_HOST; + +/* Name of file to send. */ +static char *file_name = "./remote_data"; + +static void print_usage_and_die (void) +{ + ACE_ERROR ((LM_ERROR, "usage: %s [-p portnum] [-h host_name] [-f file]\n%a", + program_name, -1)); +} + +void +parse_args (int argc, char *argv[]) +{ + program_name = argv[0]; + + ACE_Get_Opt get_opt (argc, argv, "f:h:p:"); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'f': + file_name = get_opt.optarg; + break; + case 'h': + host_name = get_opt.optarg; + break; + case 'p': + port_number = ACE_OS::atoi (get_opt.optarg); + break; + default: + print_usage_and_die (); + break; + } +} + +int +main (int argc, char *argv[]) +{ + parse_args (argc, argv); + + ACE_SOCK_Dgram sd (ACE_Addr::sap_any); + void *cp; + ACE_INET_Addr sa (port_number, host_name); + + ACE_Mem_Map mmap (file_name); + + if (mmap (cp) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "mmap"), -1); + + /* Next, send the file's contents. */ + + int cc = sd.send (cp, mmap.size (), sa); + + if (cc == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), -1); + else if (cc != mmap.size()) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", + "Not all the contents of mmap file are sent."), -1); + return 0; +} diff --git a/examples/Service_Configurator/IPC-tests/client/remote_service_directory_test.cpp b/examples/Service_Configurator/IPC-tests/client/remote_service_directory_test.cpp new file mode 100644 index 00000000000..365f6c7efb0 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/client/remote_service_directory_test.cpp @@ -0,0 +1,80 @@ +/* Test program for the INET IPC-SAPs... */ +// @(#)remote_service_directory_test.cpp 1.1 10/18/96 + + +#include "ace/Log_Msg.h" +#include "ace/SOCK_Connector.h" +#include "ace/INET_Addr.h" +#include "ace/Get_Opt.h" + +/* Port number to use. */ +static unsigned short port_number = ACE_DEFAULT_SERVICE_PORT; + +/* Name of remote host. */ +static char *host_name = ACE_DEFAULT_SERVER_HOST; + +/* Trigger a remote reconfiguration */ +static int remote_reconfigure = 0; + +static void +print_usage_and_die (void) +{ + ACE_ERROR ((LM_ERROR, "usage: %n [-p portnum] [-h host_name] [-r] [-f file]\n%a", 1)); +} + +void +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, "p:h:r:"); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'h': + host_name = get_opt.optarg; + break; + case 'p': + port_number = ACE_OS::atoi (get_opt.optarg); + break; + case 'r': + remote_reconfigure = 1; + break; + default: + print_usage_and_die (); + break; + } +} + +int +main (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0]); + + parse_args (argc, argv); + static char buf[BUFSIZ] = "help"; + int n; + ACE_SOCK_Stream sc; + ACE_SOCK_Connector con; + + if (con.connect (sc, ACE_INET_Addr (port_number, host_name)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n%a", "connect", 1), -1); + + if (remote_reconfigure) + ACE_OS::strcpy (buf, "reconfigure"); + + /* Send the command */ + + if (sc.send_n (buf, ACE_OS::strlen (buf) + 1) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n%a", "send", 1), -1); + + /* Next, read the response. */ + + while ((n = sc.recv (buf, sizeof buf)) > 0) + if (ACE_OS::write (ACE_STDOUT, buf, n) != n) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n%a", "write", 1), -1); + + if (sc.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n%a", "close", 1), -1); + + return 0; +} diff --git a/examples/Service_Configurator/IPC-tests/client/remote_stream_client_test.cpp b/examples/Service_Configurator/IPC-tests/client/remote_stream_client_test.cpp new file mode 100644 index 00000000000..80444b8da8e --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/client/remote_stream_client_test.cpp @@ -0,0 +1,105 @@ +/* Test program for the INET IPC-SAPs... */ +// @(#)remote_stream_client_test.cpp 1.1 10/18/96 + + +#include "ace/Mem_Map.h" +#include "ace/Log_Msg.h" +#include "ace/SOCK_Connector.h" +#include "ace/SOCK_CODgram.h" +#include "ace/INET_Addr.h" +#include "ace/Get_Opt.h" + +/* Name of the program. */ +static char *program_name; + +/* Port number to use. */ +static unsigned short port_number = ACE_DEFAULT_SERVER_PORT; + +/* Name of remote host. */ +static char *host_name = ACE_DEFAULT_SERVER_HOST; + +/* Name of file to send. */ +static char *file_name = "./remote_data"; + +static void +print_usage_and_die (void) +{ + ACE_ERROR ((LM_ERROR, "usage: %s [-p portnum] [-h host_name] [-f file]\n%a", + program_name, -1)); +} + +void +parse_args (int argc, char *argv[]) +{ + program_name = argv[0]; + ACE_Get_Opt get_opt (argc, argv, "f:h:p:"); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'f': + file_name = get_opt.optarg; + break; + case 'h': + host_name = get_opt.optarg; + break; + case 'p': + port_number = ACE_OS::atoi (get_opt.optarg); + break; + default: + print_usage_and_die (); + break; + } +} + +int +main (int argc, char *argv[]) +{ + parse_args (argc, argv); + ACE_INET_Addr sa (port_number, host_name); + void *cp; + char buf[BUFSIZ]; + int n; + ACE_SOCK_CODgram dc; + + if (dc.open (sa, ACE_Addr::sap_any) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + + /* First send the name of the file as a datagram. */ + + iovec iov[2]; + + iov[0].iov_base = "filename: "; + iov[0].iov_len = 11; + iov[1].iov_base = file_name; + iov[1].iov_len = ACE_OS::strlen (file_name); + + if (dc.send (iov, 2) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), -1); + + ACE_SOCK_Stream sc; + ACE_SOCK_Connector con; + + if (con.connect (sc, sa) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "connect"), -1); + + ACE_Mem_Map mmap (file_name); + + if (mmap (cp) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "mmap"), -1); + + /* Next, send the file's contents. */ + + if (sc.send_n (cp, mmap.size ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send_urg"), -1); + + if (sc.close_writer () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close_writer"), -1); + + if ((n = sc.recv_n (buf, sizeof buf)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv"), -1); + else + ACE_OS::write (ACE_STDOUT, buf, n); + + return 0; +} diff --git a/examples/Service_Configurator/IPC-tests/client/remote_thr_stream_client_test.cpp b/examples/Service_Configurator/IPC-tests/client/remote_thr_stream_client_test.cpp new file mode 100644 index 00000000000..18c6162c788 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/client/remote_thr_stream_client_test.cpp @@ -0,0 +1,96 @@ +/* Test program for the INET ACE_TLI-SAPs... */ +// @(#)remote_thr_stream_client_test.cpp 1.1 10/18/96 + + +#include "ace/Mem_Map.h" +#include "ace/TLI_Connector.h" +#include "ace/INET_Addr.h" +#include "ace/Log_Msg.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" + +#if defined (ACE_HAS_TLI) + +/* Name of the program. */ +static char *program_name; + +/* Port number to use. */ +static unsigned short port_number = ACE_DEFAULT_THR_PORT; + +/* Name of remote host. */ +static char *host_name = ACE_DEFAULT_SERVER_HOST; + +/* Name of file to send. */ +static char *file_name = "./remote_data"; + +static void print_usage_and_die (void) +{ + ACE_ERROR ((LM_ERROR, "usage: %s [-p portnum] [-h host_name] [-f file]\n%a", + program_name, -1)); +} + +void +parse_args (int argc, char *argv[]) +{ + program_name = argv[0]; + ACE_Get_Opt get_opt (argc, argv, "f:h:p:"); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'f': + file_name = get_opt.optarg; + break; + case 'h': + host_name = get_opt.optarg; + break; + case 'p': + port_number = ACE_OS::atoi (get_opt.optarg); + break; + default: + print_usage_and_die (); + break; + } +} + +int +main (int argc, char *argv[]) +{ + parse_args (argc, argv); + void *cp; + char buf[BUFSIZ]; + ACE_TLI_Stream sc; + ACE_TLI_Connector con; + + if (con.connect (sc, ACE_INET_Addr (port_number, host_name)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + + ACE_Mem_Map mmap (file_name, PROT_READ); + + if (mmap (cp) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "mmap"), -1); + + /* Next, send the file's contents. */ + + if (sc.send_n (cp, mmap.size ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send_n"), -1); + + if (sc.sndrel () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close_writer"), -1); + + for (int n; (n = sc.recv (buf, sizeof buf)) > 0; ) + if (ACE_OS::write (ACE_STDOUT, buf, n) != n) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "write"), -1); + + if (sc.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), -1); + + return 0; +} +#else +int +main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "you must have TLI to run this test\n"), 1); +} +#endif /* ACE_HAS_TLI */ diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_Broadcast.cpp b/examples/Service_Configurator/IPC-tests/server/Handle_Broadcast.cpp new file mode 100644 index 00000000000..3e6f852a53d --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_Broadcast.cpp @@ -0,0 +1,36 @@ +#include "Handle_Broadcast.h" +// @(#)Handle_Broadcast.cpp 1.1 10/18/96 + + +#if defined (SunOS4) +extern "C" +{ + int init (void); + int fini (void); + void __sti__Handle_Broadcast_C_init_(); + void __std__Handle_Broadcast_C_init_(); +} + +int +init (void) +{ + __sti__Handle_Broadcast_C_init_(); + return 0; +} + +int +fini (void) +{ + __std__Handle_Broadcast_C_init_(); + return 0; +} +#endif /* SunOS4 */ + +unsigned short Handle_Broadcast::DEFAULT_PORT = ACE_DEFAULT_BROADCAST_PORT; + +#if !defined (__ACE_INLINE__) +#include "Handle_Broadcast.i" +#endif /* __ACE_INLINE__ */ + +Handle_Broadcast remote_broadcast; +ACE_Service_Object_Type rb (&remote_broadcast, "Remote_Brdcast"); diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_Broadcast.h b/examples/Service_Configurator/IPC-tests/server/Handle_Broadcast.h new file mode 100644 index 00000000000..3d22d6b473f --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_Broadcast.h @@ -0,0 +1,41 @@ +/* -*- C++ -*- */ +// @(#)Handle_Broadcast.h 1.1 10/18/96 + +/* Handles INET broadcast datagram messages from remote hosts on the local subnet. */ + +#if !defined (_HANDLE_BROADCAST_H) +#define _HANDLE_BROADCAST_H + +#include "ace/Service_Config.h" +#include "ace/Service_Record.h" +#include "ace/INET_Addr.h" +#include "ace/SOCK_Dgram.h" + +class Handle_Broadcast : public ACE_Service_Object, public ACE_SOCK_Dgram +{ +public: + Handle_Broadcast (void); + ~Handle_Broadcast (void); + virtual int init (int argc, char *argv[]); + virtual int info (char **, size_t) const; + virtual int fini (void); + +private: + int open (const ACE_INET_Addr &r, int async = 0); + virtual int get_handle (void) const; + virtual int handle_input (int fd); + virtual int handle_close (int fd, ACE_Reactor_Mask); + + static unsigned short DEFAULT_PORT; +}; + +extern ACE_Service_Object_Type rb; + +#if defined (__ACE_INLINE__) +#define ACE_INLINE inline +#include "Handle_Broadcast.i" +#else +#define ACE_INLINE +#endif /* __ACE_INLINE__ */ + +#endif /* _HANDLE_BROADCAST_H */ diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_Broadcast.i b/examples/Service_Configurator/IPC-tests/server/Handle_Broadcast.i new file mode 100644 index 00000000000..624ee1edb26 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_Broadcast.i @@ -0,0 +1,110 @@ +/* -*- C++ -*- */ +// @(#)Handle_Broadcast.i 1.1 10/18/96 + + +#include "ace/Get_Opt.h" + +ACE_INLINE +Handle_Broadcast::~Handle_Broadcast (void) +{ +} + +ACE_INLINE +Handle_Broadcast::Handle_Broadcast (void) +{ +} + +ACE_INLINE int +Handle_Broadcast::open (const ACE_INET_Addr &r, int async) +{ + if (this->ACE_SOCK_Dgram::open (r) == -1) + return -1; + else if (async && ACE_SOCK_Dgram::enable (SIGIO) == -1) + return -1; + else + return 0; +} + +ACE_INLINE int +Handle_Broadcast::info (char **strp, size_t length) const +{ + char buf[BUFSIZ]; + ACE_INET_Addr sa; + + if (this->get_local_addr (sa) == -1) + return -1; + + ACE_OS::sprintf (buf, "%d/%s %s", sa.get_port_number (), "udp", "# tests broadcasting\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +ACE_INLINE int +Handle_Broadcast::init (int argc, char *argv[]) +{ + ACE_INET_Addr sba (Handle_Broadcast::DEFAULT_PORT); + ACE_Get_Opt get_opt (argc, argv, "p:", 0); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'p': + sba.set (ACE_OS::atoi (get_opt.optarg)); + break; + default: + break; + } + + if (this->open (sba) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + else if (ACE_Service_Config::reactor ()->register_handler + (this, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "registering service with ACE_Reactor\n"), -1); + return 0; +} + +ACE_INLINE int +Handle_Broadcast::fini (void) +{ + return ACE_Service_Config::reactor ()->remove_handler + (this, ACE_Event_Handler::READ_MASK); +} + +ACE_INLINE int +Handle_Broadcast::get_handle (void) const +{ + return this->ACE_SOCK_Dgram::get_handle (); +} + +ACE_INLINE int +Handle_Broadcast::handle_input (int) +{ + ACE_INET_Addr sa; + char buf[0x2000]; /* 8 k buffer */ + int n; + + if ((n = this->recv (buf, sizeof buf, sa)) == -1) + return -1; + else + ACE_DEBUG ((LM_INFO, "received broadcast datagram from host %s\n", sa.get_host_name ())); + + ACE_OS::puts ("----------------------------------------"); + ACE_OS::write (ACE_STDOUT, buf, n); + + if (buf[n - 1] != '\n') + putchar ('\n'); + + ACE_OS::puts ("----------------------------------------"); + + return 0; +} + +ACE_INLINE int +Handle_Broadcast::handle_close (int, ACE_Reactor_Mask) +{ + return this->ACE_SOCK_Dgram::close (); +} diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_L_CODgram.cpp b/examples/Service_Configurator/IPC-tests/server/Handle_L_CODgram.cpp new file mode 100644 index 00000000000..9750154c1b3 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_L_CODgram.cpp @@ -0,0 +1,36 @@ +#include "Handle_L_CODgram.h" +// @(#)Handle_L_CODgram.cpp 1.1 10/18/96 + + +#if defined (SunOS4) +extern "C" +{ + int init (void); + int fini (void); + void __sti__Handle_L_CODgram_C_init_(); + void __std__Handle_L_CODgram_C_init_(); +} + +int +init (void) +{ + __sti__Handle_L_CODgram_C_init_(); + return 0; +} + +int +fini (void) +{ + __std__Handle_L_CODgram_C_init_(); + return 0; +} +#endif /* SunOS4 */ + +const char *Handle_L_CODgram::DEFAULT_RENDEZVOUS = "/tmp/foo_codgram"; + +#if !defined (__ACE_INLINE__) +#include "Handle_L_CODgram.i" +#endif /* __ACE_INLINE__ */ + +Handle_L_CODgram local_codgram; +ACE_Service_Object_Type lc (&local_codgram, "Local_CODgram"); diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_L_CODgram.h b/examples/Service_Configurator/IPC-tests/server/Handle_L_CODgram.h new file mode 100644 index 00000000000..0d2692c63d2 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_L_CODgram.h @@ -0,0 +1,41 @@ +/* -*- C++ -*- */ +// @(#)Handle_L_CODgram.h 1.1 10/18/96 + +/* Handles UNIX datagram messages from local host. */ + +#if !defined (_HANDLE_L_CODGRAM_H) +#define _HANDLE_L_CODGRAM_H + +#include "ace/Service_Config.h" +#include "ace/Service_Record.h" +#include "ace/LSOCK_CODgram.h" +#include "ace/UNIX_Addr.h" + +class Handle_L_CODgram : public ACE_Service_Object, public ACE_LSOCK_CODgram +{ +public: + Handle_L_CODgram (void); + virtual int init (int argc, char *argv[]); + virtual int info (char **, size_t) const; + virtual int fini (void); + +public: + int open (const ACE_UNIX_Addr &suad, int async = 0); + virtual ACE_HANDLE get_handle (void) const; + virtual int handle_input (ACE_HANDLE); + virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask); + + char rendezvous[MAXPATHLEN + 1]; + static const char *DEFAULT_RENDEZVOUS; +}; + +extern ACE_Service_Object_Type lc; + +#if defined (__ACE_INLINE__) +#define ACE_INLINE inline +#include "Handle_L_CODgram.i" +#else +#define ACE_INLINE +#endif /* __ACE_INLINE__ */ + +#endif /* _HANDLE_L_CODGRAM_H */ diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_L_CODgram.i b/examples/Service_Configurator/IPC-tests/server/Handle_L_CODgram.i new file mode 100644 index 00000000000..6c69af48c20 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_L_CODgram.i @@ -0,0 +1,113 @@ +/* -*- C++ -*- */ +// @(#)Handle_L_CODgram.i 1.1 10/18/96 + + +#include "ace/Get_Opt.h" + +ACE_INLINE +Handle_L_CODgram::Handle_L_CODgram (void) +{ +} + +ACE_INLINE int +Handle_L_CODgram::open (const ACE_UNIX_Addr &suad, int async) +{ + if (this->ACE_LSOCK_CODgram::open (ACE_Addr::sap_any, suad) == -1) + return -1; + else if (async && this->ACE_LSOCK_CODgram::enable (SIGIO) == -1) + return -1; + else + return 0; +} + +ACE_INLINE int +Handle_L_CODgram::info (char **strp, size_t length) const +{ + char buf[BUFSIZ]; + ACE_UNIX_Addr sa; + + if (ACE_LSOCK_CODgram::get_local_addr (sa) == -1) + return -1; + + ACE_OS::sprintf (buf, "%s %s", sa.get_path_name (), + "# tests local connected datagram\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +ACE_INLINE int +Handle_L_CODgram::init (int argc, char *argv[]) +{ + ACE_UNIX_Addr sucd; + ACE_Get_Opt get_opt (argc, argv, "r:", 0); + const char *r = Handle_L_CODgram::DEFAULT_RENDEZVOUS; + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'r': + r = get_opt.optarg; + break; + default: + break; + } + + ACE_OS::strncpy (this->rendezvous, r, MAXPATHLEN); + ACE_OS::unlink (this->rendezvous); + sucd.set (this->rendezvous); + if (this->open (sucd) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + else if (ACE_Service_Config::reactor ()->register_handler + (this, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "registering service with ACE_Reactor\n"), -1); + return 0; +} + +ACE_INLINE int +Handle_L_CODgram::fini(void) +{ + return ACE_Service_Config::reactor ()->remove_handler + (this, ACE_Event_Handler::READ_MASK); +} + +ACE_INLINE ACE_HANDLE +Handle_L_CODgram::get_handle (void) const +{ + return ACE_LSOCK_CODgram::get_handle (); +} + +ACE_INLINE int +Handle_L_CODgram::handle_input (ACE_HANDLE) +{ + ACE_HANDLE handle = ACE_INVALID_HANDLE; + char buf[BUFSIZ]; + + if (this->recv_handle (handle) == -1) + return -1; + else + ACE_DEBUG ((LM_INFO, "received handle (%d)\n", handle)); + + ACE_OS::puts ("----------------------------------------"); + + for (ssize_t n; n = ACE_OS::read (handle, buf, sizeof buf); ) + ACE_OS::write (ACE_STDOUT, buf, n); + + ACE_OS::puts ("----------------------------------------"); + + if (ACE_OS::close (handle) == -1) + return -1; + + return 0; +} + +ACE_INLINE int +Handle_L_CODgram::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + this->ACE_LSOCK_CODgram::close (); + return ACE_OS::unlink (this->rendezvous); +} diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_L_Dgram.cpp b/examples/Service_Configurator/IPC-tests/server/Handle_L_Dgram.cpp new file mode 100644 index 00000000000..f8615d3cd26 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_L_Dgram.cpp @@ -0,0 +1,15 @@ +#include "Handle_L_Dgram.h" +// @(#)Handle_L_Dgram.cpp 1.1 10/18/96 + + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +const char *Handle_L_Dgram::DEFAULT_RENDEZVOUS = "/tmp/foo_dgram"; + +#if !defined (__ACE_INLINE__) +#include "Handle_L_Dgram.i" +#endif /* __ACE_INLINE__ */ + +Handle_L_Dgram local_dgram; +ACE_Service_Object_Type ld (&local_dgram, "Local_Dgram"); +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_L_Dgram.h b/examples/Service_Configurator/IPC-tests/server/Handle_L_Dgram.h new file mode 100644 index 00000000000..72c2914ef6a --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_L_Dgram.h @@ -0,0 +1,43 @@ +/* -*- C++ -*- */ +// @(#)Handle_L_Dgram.h 1.1 10/18/96 + +// Handles UNIX datagram messages from local host. + +#if !defined (_HANDLE_L_DGRAM_H) +#define _HANDLE_L_DGRAM_H + +#include "ace/Service_Config.h" +#include "ace/Service_Record.h" +#include "ace/LSOCK_Dgram.h" +#include "ace/UNIX_Addr.h" + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +class Handle_L_Dgram : public ACE_Service_Object, public ACE_LSOCK_Dgram +{ +public: + Handle_L_Dgram (void); + virtual int init (int argc, char *argv[]); + virtual int info (char **, size_t) const; + virtual int fini (void); + +private: + int open (const ACE_UNIX_Addr &suad, int async = 0); + virtual int get_handle (void) const; + virtual int handle_input (int fd); + virtual int handle_close (int fd, ACE_Reactor_Mask); + + char rendezvous[MAXPATHLEN + 1]; + static const char *DEFAULT_RENDEZVOUS; +}; + +extern ACE_Service_Object_Type ld; + +#if defined (__ACE_INLINE__) +#define ACE_INLINE inline +#include "Handle_L_Dgram.i" +#else +#define ACE_INLINE +#endif /* __ACE_INLINE__ */ +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ +#endif /* _HANDLE_L_DGRAM_H */ diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_L_Dgram.i b/examples/Service_Configurator/IPC-tests/server/Handle_L_Dgram.i new file mode 100644 index 00000000000..4133a0d6a4f --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_L_Dgram.i @@ -0,0 +1,109 @@ +/* -*- C++ -*- */ +// @(#)Handle_L_Dgram.i 1.1 10/18/96 + + +#include "ace/Get_Opt.h" + +ACE_INLINE +Handle_L_Dgram::Handle_L_Dgram (void) +{ +} + +ACE_INLINE int +Handle_L_Dgram::open (const ACE_UNIX_Addr &suad, int async) +{ + if (this->ACE_LSOCK_Dgram::open (suad) == -1) + return -1; + else if (async && this->ACE_LSOCK_Dgram::enable (SIGIO) == -1) + return -1; + else + return 0; +} + +ACE_INLINE int +Handle_L_Dgram::info (char **strp, size_t length) const +{ + char buf[BUFSIZ]; + ACE_UNIX_Addr sa; + + if (this->ACE_LSOCK_Dgram::get_local_addr (sa) == -1) + return -1; + + ACE_OS::sprintf (buf, "%s %s", sa.get_path_name (), "# tests local datagram\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +ACE_INLINE int +Handle_L_Dgram::init (int argc, char *argv[]) +{ + ACE_UNIX_Addr sudg; + ACE_Get_Opt get_opt (argc, argv, "r:", 0); + const char *r = Handle_L_Dgram::DEFAULT_RENDEZVOUS; + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'r': + r = get_opt.optarg; + break; + default: + break; + } + + ACE_OS::strncpy (this->rendezvous, r, MAXPATHLEN); + ACE_OS::unlink (this->rendezvous); + sudg.set (this->rendezvous); + if (this->open (sudg) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + else if (ACE_Service_Config::reactor ()->register_handler (this, + ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "registering service with ACE_Reactor\n"), -1); + return 0; +} + +ACE_INLINE int +Handle_L_Dgram::fini (void) +{ + return ACE_Service_Config::reactor ()->remove_handler (this, ACE_Event_Handler::READ_MASK); +} + +ACE_INLINE int +Handle_L_Dgram::get_handle (void) const +{ + return this->ACE_LSOCK_Dgram::get_handle (); +} + +ACE_INLINE int +Handle_L_Dgram::handle_input (int) +{ + ACE_UNIX_Addr sa; + char buf[8 * 1024]; /* 8 k buffer */ + int n; + + if ((n = this->recv (buf, sizeof buf, sa)) == -1) + return -1; + else + ACE_DEBUG ((LM_INFO, "received datagram from %s\n", sa.get_path_name ())); + + ACE_OS::puts ("----------------------------------------"); + ACE_OS::write (ACE_STDOUT, buf, n); + + if (buf[n - 1] != '\n') + putchar ('\n'); + + ACE_OS::puts ("----------------------------------------"); + + return 0; +} + +ACE_INLINE int +Handle_L_Dgram::handle_close (int, ACE_Reactor_Mask) +{ + this->ACE_LSOCK_Dgram::close (); + return ACE_OS::unlink (this->rendezvous); +} diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_L_FIFO.cpp b/examples/Service_Configurator/IPC-tests/server/Handle_L_FIFO.cpp new file mode 100644 index 00000000000..7106034f33f --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_L_FIFO.cpp @@ -0,0 +1,36 @@ +#include "Handle_L_FIFO.h" +// @(#)Handle_L_FIFO.cpp 1.1 10/18/96 + + +#if defined (SunOS4) +extern "C" +{ + int init (void); + int fini (void); + void __sti__Handle_L_FIFO_C_init_(); + void __std__Handle_L_FIFO_C_init_(); +} + +int +init (void) +{ + __sti__Handle_L_FIFO_C_init_(); + return 0; +} + +int +fini (void) +{ + __std__Handle_L_FIFO_C_init_(); + return 0; +} +#endif /* SunOS4 */ + +const char *Handle_L_FIFO::DEFAULT_RENDEZVOUS = "/tmp/foo_fifo"; + +#if !defined (__ACE_INLINE__) +#include "Handle_L_FIFO.i" +#endif /* __ACE_INLINE__ */ + +Handle_L_FIFO local_fifo; +ACE_Service_Object_Type lf (&local_fifo, "Local_FIFO"); diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_L_FIFO.h b/examples/Service_Configurator/IPC-tests/server/Handle_L_FIFO.h new file mode 100644 index 00000000000..82ab2f5df51 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_L_FIFO.h @@ -0,0 +1,42 @@ +/* -*- C++ -*- */ +// @(#)Handle_L_FIFO.h 1.1 10/18/96 + +/* Handle connections from local UNIX ACE_FIFO */ +/* Read from a well known ACE_FIFO and write to stdout. */ + +#if !defined (_HANDLE_L_FIFO_H) +#define _HANDLE_L_FIFO_H + +#include "ace/Service_Config.h" +#include "ace/Service_Record.h" +#include "ace/FIFO_Recv_Msg.h" + +class Handle_L_FIFO : public ACE_Service_Object, public ACE_FIFO_Recv_Msg +{ +public: + Handle_L_FIFO (void); + virtual int init (int argc, char *argv[]); + virtual int info (char **, size_t) const; + virtual int fini (void); + +private: + int open (const char *rendezvous_fifo); + virtual int get_handle (void) const; + virtual int handle_input (int fd); + virtual int handle_close (int fd, ACE_Reactor_Mask); + + static const char *DEFAULT_RENDEZVOUS; +}; + +extern ACE_Service_Object_Type lf; + +#if defined (__ACE_INLINE__) +#define ACE_INLINE inline +#include "Handle_L_FIFO.i" +#else +#define ACE_INLINE +#endif /* __ACE_INLINE__ */ + +#endif /* _HANDLE_L_FIFO_H */ + + diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_L_FIFO.i b/examples/Service_Configurator/IPC-tests/server/Handle_L_FIFO.i new file mode 100644 index 00000000000..6ba9f212d6c --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_L_FIFO.i @@ -0,0 +1,94 @@ +/* -*- C++ -*- */ +// @(#)Handle_L_FIFO.i 1.1 10/18/96 + + +#include "ace/Get_Opt.h" + +ACE_INLINE +Handle_L_FIFO::Handle_L_FIFO (void) +{ +} + +ACE_INLINE int +Handle_L_FIFO::open (const char *rendezvous_fifo) +{ + if (this->ACE_FIFO_Recv_Msg::open (rendezvous_fifo) == -1) + return -1; + else + return 0; +} + +ACE_INLINE int +Handle_L_FIFO::info (char **strp, size_t length) const +{ + char buf[BUFSIZ]; + const char *rendezvous_fifo; + + this->get_local_addr (rendezvous_fifo); + + ACE_OS::sprintf (buf, "%s %s", rendezvous_fifo, "# tests local ACE_FIFO\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +ACE_INLINE int +Handle_L_FIFO::init (int argc, char *argv[]) +{ + const char *rendezvous_fifo = Handle_L_FIFO::DEFAULT_RENDEZVOUS; + ACE_Get_Opt get_opt (argc, argv, "r:", 0); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'r': + rendezvous_fifo = get_opt.optarg; + break; + default: + break; + } + + ACE_OS::unlink (rendezvous_fifo); + if (this->open (rendezvous_fifo) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + else if (ACE_Service_Config::reactor ()->register_handler (this, + ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "registering service with ACE_Reactor\n"), -1); + return 0; +} + +ACE_INLINE int +Handle_L_FIFO::fini (void) +{ + return ACE_Service_Config::reactor ()->remove_handler (this, ACE_Event_Handler::READ_MASK); +} + +ACE_INLINE int +Handle_L_FIFO::get_handle (void) const +{ + return this->ACE_FIFO::get_handle (); +} + +ACE_INLINE int +Handle_L_FIFO::handle_input (int) +{ + char buf[PIPE_BUF]; + ACE_Str_Buf msg (buf, 0, sizeof buf); + + /* Accept communication requests */ + if (this->recv (msg) == -1) + return -1; + else + + ACE_OS::write (ACE_STDOUT, (const char *) msg.buf, (int) msg.len); + return 0; +} + +ACE_INLINE int +Handle_L_FIFO::handle_close (int, ACE_Reactor_Mask) +{ + return this->ACE_FIFO::remove (); +} diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_L_Pipe.cpp b/examples/Service_Configurator/IPC-tests/server/Handle_L_Pipe.cpp new file mode 100644 index 00000000000..086f8c2e86c --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_L_Pipe.cpp @@ -0,0 +1,36 @@ +#include "Handle_L_Pipe.h" +// @(#)Handle_L_Pipe.cpp 1.1 10/18/96 + + +#if defined (SunOS4) +extern "C" +{ + int init (void); + int fini (void); + void __sti__Handle_L_Pipe_C_recv_n_(); + void __std__Handle_L_Pipe_C_recv_n_(); +} + +int +init (void) +{ + __sti__Handle_L_Pipe_C_recv_n_(); + return 0; +} + +int +fini (void) +{ + __std__Handle_L_Pipe_C_recv_n_(); + return 0; +} +#endif /* SunOS4 */ + +const char *Handle_L_Pipe::DEFAULT_RENDEZVOUS = "/tmp/foo_pipe"; + +#if !defined (__ACE_INLINE__) +#include "Handle_L_Pipe.i" +#endif /* __ACE_INLINE__ */ + +Handle_L_Pipe local_pipe; +ACE_Service_Object_Type lp (&local_pipe, "Local_Pipe"); diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_L_Pipe.h b/examples/Service_Configurator/IPC-tests/server/Handle_L_Pipe.h new file mode 100644 index 00000000000..ffd7651048a --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_L_Pipe.h @@ -0,0 +1,44 @@ +/* -*- C++ -*- */ +// @(#)Handle_L_Pipe.h 1.1 10/18/96 + +/* Handle connections from local UNIX domain sockets that are sending + end-points from a pipe! */ + +#if !defined (_HANDLE_L_PIPE_H) +#define _HANDLE_L_PIPE_H + +#include "ace/Service_Config.h" +#include "ace/Service_Record.h" +#include "ace/UNIX_Addr.h" +#include "ace/LSOCK_Acceptor.h" + +class Handle_L_Pipe : public ACE_Service_Object, public ACE_LSOCK_Acceptor +{ +public: + Handle_L_Pipe (void); + ~Handle_L_Pipe (void); + virtual int init (int argc, char *argv[]); + virtual int info (char **, size_t) const; + virtual int fini (void); + +private: + int open (const ACE_UNIX_Addr &suap, int async = 0); + virtual ACE_HANDLE get_handle (void) const; + virtual int handle_input (ACE_HANDLE fd); + virtual int handle_close (ACE_HANDLE fd, ACE_Reactor_Mask); + + char rendezvous[MAXPATHLEN + 1]; + static const char *DEFAULT_RENDEZVOUS; +}; + +extern ACE_Service_Object_Type lp; + +#if defined (__ACE_INLINE__) +#define ACE_INLINE inline +#include "Handle_L_Pipe.i" +#else +#define ACE_INLINE +#endif /* __ACE_INLINE__ */ + +#endif /* _HANDLE_L_PIPE_H */ + diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_L_Pipe.i b/examples/Service_Configurator/IPC-tests/server/Handle_L_Pipe.i new file mode 100644 index 00000000000..b5c430a8e51 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_L_Pipe.i @@ -0,0 +1,136 @@ +/* -*- C++ -*- */ +// @(#)Handle_L_Pipe.i 1.1 10/18/96 + + +#include "ace/Get_Opt.h" + +ACE_INLINE +Handle_L_Pipe::~Handle_L_Pipe (void) +{ +} + +/* Uppercase N bytes of S. */ + +static char * +upper_case (char s[], int n) +{ + while (--n >= 0) + if (islower (s[n])) + s[n] = toupper (s[n]); + + return s; +} + +ACE_INLINE +Handle_L_Pipe::Handle_L_Pipe (void) +{ +} + +ACE_INLINE int +Handle_L_Pipe::open (const ACE_UNIX_Addr &suap, int async) +{ + if (this->ACE_LSOCK_Acceptor::open (suap) == -1) + return -1; + else if (async && this->ACE_LSOCK_Acceptor::enable (SIGIO) == -1) + return -1; + else + return 0; +} + +ACE_INLINE int +Handle_L_Pipe::info (char **strp, size_t length) const +{ + char buf[BUFSIZ]; + ACE_UNIX_Addr sa; + + if (ACE_LSOCK_Acceptor::get_local_addr (sa) == -1) + return -1; + + ACE_OS::sprintf (buf, "%s %s", sa.get_path_name (), "# tests local pipe\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +ACE_INLINE int +Handle_L_Pipe::init (int argc, char *argv[]) +{ + ACE_UNIX_Addr sup; + const char *r = Handle_L_Pipe::DEFAULT_RENDEZVOUS; + ACE_Get_Opt get_opt (argc, argv, "r:", 0); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'r': + r = get_opt.optarg; + break; + default: + break; + } + + ACE_OS::strncpy (this->rendezvous, r, MAXPATHLEN); + ACE_OS::unlink (this->rendezvous); + sup.set (this->rendezvous); + if (this->open (sup) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + else if (ACE_Service_Config::reactor ()->register_handler + (this, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "registering service with ACE_Reactor\n"), -1); + return 0; +} + +ACE_INLINE int +Handle_L_Pipe::fini (void) +{ + return ACE_Service_Config::reactor ()->remove_handler + (this, ACE_Event_Handler::READ_MASK); +} + +ACE_INLINE int +Handle_L_Pipe::get_handle (void) const +{ + return ACE_LSOCK_Acceptor::get_handle (); +} + +ACE_INLINE int +Handle_L_Pipe::handle_input (ACE_HANDLE) +{ + ACE_LSOCK_Stream new_local_stream; + int n; + ACE_HANDLE fd1 = ACE_INVALID_HANDLE; + ACE_HANDLE fd2 = ACE_INVALID_HANDLE; + char buf[BUFSIZ]; + + if (this->accept (new_local_stream) == -1) + return -1; + + if (new_local_stream.recv_handle (fd1) == -1 + || new_local_stream.recv_handle (fd2) == -1) + return -1; + else + ACE_DEBUG ((LM_INFO, "received file descriptors %d and %d\n", fd1, fd2)); + + if ((n = ACE_OS::read (fd1, buf, sizeof buf)) == -1) + return -1; + else if (ACE_OS::write (fd2, upper_case (buf, n), n) == -1) + return -1; + if (ACE_OS::close (fd1) == -1 + || ACE_OS::close (fd2) == -1) + return -1; + if (new_local_stream.close () == -1) + return -1; + + return 0; +} + +ACE_INLINE int +Handle_L_Pipe::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + this->ACE_LSOCK_Acceptor::close (); + return ACE_OS::unlink (this->rendezvous); +} diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_L_SPIPE.cpp b/examples/Service_Configurator/IPC-tests/server/Handle_L_SPIPE.cpp new file mode 100644 index 00000000000..bd34890dbbc --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_L_SPIPE.cpp @@ -0,0 +1,16 @@ +#include "Handle_L_SPIPE.h" +// @(#)Handle_L_SPIPE.cpp 1.1 10/18/96 + + +#if !defined (__ACE_INLINE__) +#include "Handle_L_SPIPE.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_HAS_STREAM_PIPES) + +const char *Handle_L_SPIPE::DEFAULT_RENDEZVOUS = "/tmp/foo_spipe"; + +Handle_L_SPIPE local_spipe; +ACE_Service_Object_Type lsp (&local_spipe, "Local_SPIPE"); + +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_L_SPIPE.h b/examples/Service_Configurator/IPC-tests/server/Handle_L_SPIPE.h new file mode 100644 index 00000000000..a844764d0dd --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_L_SPIPE.h @@ -0,0 +1,45 @@ +/* -*- C++ -*- */ +// @(#)Handle_L_SPIPE.h 1.1 10/18/96 + +/* Handle connections from local UNIX ACE_SPIPE */ +/* Read from a well known ACE_SPIPE and write to stdout. */ + +#if !defined (_HANDLE_L_SPIPE_H) +#define _HANDLE_L_SPIPE_H + +#include "ace/Service_Config.h" +#include "ace/Service_Record.h" +#include "ace/SPIPE_Acceptor.h" + +#if defined (ACE_HAS_STREAM_PIPES) + +class Handle_L_SPIPE : public ACE_Service_Object, public ACE_SPIPE_Acceptor +{ +public: + Handle_L_SPIPE (void); + virtual int init (int argc, char *argv[]); + virtual int info (char **, size_t) const; + virtual int fini (void); + +private: + int open (const ACE_SPIPE_Addr &rendezvous_spipe); + virtual int get_handle (void) const; + virtual int handle_input (int fd); + virtual int handle_close (int fd, ACE_Reactor_Mask); + + static const char *DEFAULT_RENDEZVOUS; +}; + +extern ACE_Service_Object_Type lsp; + +#if defined (__ACE_INLINE__) +#define ACE_INLINE inline +#include "Handle_L_SPIPE.i" +#else +#define ACE_INLINE +#endif /* __ACE_INLINE__ */ + +#endif /* _HANDLE_L_SPIPE_H */ + + +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_L_SPIPE.i b/examples/Service_Configurator/IPC-tests/server/Handle_L_SPIPE.i new file mode 100644 index 00000000000..0d5e77e1b01 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_L_SPIPE.i @@ -0,0 +1,118 @@ +/* -*- C++ -*- */ +// @(#)Handle_L_SPIPE.i 1.1 10/18/96 + + +#include "ace/SPIPE_Stream.h" +#include "ace/Get_Opt.h" + +#if defined (ACE_HAS_STREAM_PIPES) + +ACE_INLINE +Handle_L_SPIPE::Handle_L_SPIPE (void) +{ +} + +ACE_INLINE int +Handle_L_SPIPE::open (const ACE_SPIPE_Addr &rendezvous_spipe) +{ + if (this->ACE_SPIPE_Acceptor::open (rendezvous_spipe) == -1) + return -1; + else + return 0; +} + +ACE_INLINE int +Handle_L_SPIPE::info (char **strp, size_t length) const +{ + char buf[BUFSIZ]; + ACE_SPIPE_Addr sa; + + if (ACE_SPIPE_Acceptor::get_local_addr (sa) == -1) + return -1; + + ACE_OS::sprintf (buf, "%s %s", sa.get_path_name (), "# tests local STREAM pipe\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +ACE_INLINE int +Handle_L_SPIPE::init (int argc, char *argv[]) +{ + ACE_SPIPE_Addr susp; + const char *rendezvous = Handle_L_SPIPE::DEFAULT_RENDEZVOUS; + ACE_Get_Opt get_opt (argc, argv, "r:", 0); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'r': + rendezvous = get_opt.optarg; + break; + default: + break; + } + + ACE_OS::unlink (rendezvous); + susp.set (rendezvous); + if (this->open (susp) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + else if (ACE_Service_Config::reactor ()->register_handler (this, + ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "registering service with ACE_Reactor\n"), -1); + return 0; +} + +ACE_INLINE int +Handle_L_SPIPE::fini (void) +{ + return ACE_Service_Config::reactor ()->remove_handler (this, ACE_Event_Handler::READ_MASK); +} + +ACE_INLINE int +Handle_L_SPIPE::get_handle (void) const +{ + return ACE_SPIPE::get_handle(); +} + +ACE_INLINE int +Handle_L_SPIPE::handle_input (int) +{ + ACE_SPIPE_Stream new_spipe; + char buf[PIPE_BUF]; + ACE_Str_Buf msg (buf, 0, sizeof buf); + int flags = 0; + + /* Accept communication requests */ + if (this->ACE_SPIPE_Acceptor::accept (new_spipe) == -1) + return -1; + else + { + ACE_SPIPE_Addr sa; + + new_spipe.get_remote_addr (sa); + + ACE_DEBUG ((LM_INFO, "accepted request from %s (gid = %d, uid = %d)\n", + sa.get_path_name (), sa.group_id (), sa.user_id ())); + } + + while (new_spipe.recv ((ACE_Str_Buf *) 0, &msg, &flags) >= 0) + if (msg.len != 0) + ACE_OS::write (ACE_STDOUT, (const char *) msg.buf, (int) msg.len); + else + break; + + if (new_spipe.close () == -1) + return -1; + return 0; +} + +ACE_INLINE int +Handle_L_SPIPE::handle_close (int, ACE_Reactor_Mask) +{ + return this->ACE_SPIPE_Acceptor::remove (); +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_L_Stream.cpp b/examples/Service_Configurator/IPC-tests/server/Handle_L_Stream.cpp new file mode 100644 index 00000000000..e9b2ba2483b --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_L_Stream.cpp @@ -0,0 +1,17 @@ +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) +// @(#)Handle_L_Stream.cpp 1.1 10/18/96 + +#include "Handle_L_Stream.h" + +/* Static variables. */ + +const char *Handle_L_Stream::DEFAULT_RENDEZVOUS = "/tmp/foo_stream"; +char *Handle_L_Stream::login_name = 0; + +#if !defined (__ACE_INLINE__) +#include "Handle_L_Stream.i" +#endif /* __ACE_INLINE__ */ + +Handle_L_Stream local_stream; +ACE_Service_Object_Type ls (&local_stream, "Local_Stream"); +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_L_Stream.h b/examples/Service_Configurator/IPC-tests/server/Handle_L_Stream.h new file mode 100644 index 00000000000..b06b914cfd4 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_L_Stream.h @@ -0,0 +1,48 @@ +/* -*- C++ -*- */ +// @(#)Handle_L_Stream.h 1.1 10/18/96 + + +/* Handle connections from local UNIX domain sockets. */ + +#if !defined (_HANDLE_L_STREAM_H) +#define _HANDLE_L_STREAM_H + +#include "ace/Service_Config.h" +#include "ace/Service_Record.h" +#include "ace/UNIX_Addr.h" +#include "ace/LSOCK_Acceptor.h" + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +class Handle_L_Stream : public ACE_Service_Object, public ACE_LSOCK_Acceptor +{ +public: + Handle_L_Stream (void); + ~Handle_L_Stream (void); + virtual int init (int argc, char *argv[]); + virtual int info (char **, size_t) const; + virtual int fini (void); + +private: + int open (const ACE_UNIX_Addr &suas, int async = 0); + virtual ACE_HANDLE get_handle (void) const; + virtual int handle_input (ACE_HANDLE fd); + virtual int handle_close (ACE_HANDLE fd, ACE_Reactor_Mask); + + char rendezvous[MAXPATHLEN + 1]; + static char *login_name; + static const char *DEFAULT_RENDEZVOUS; +}; + +extern ACE_Service_Object_Type ls; + +#if defined (__ACE_INLINE__) +#define ACE_INLINE inline +#include "Handle_L_Stream.i" +#else +#define ACE_INLINE +#endif /* __ACE_INLINE__ */ +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ +#endif /* _HANDLE_L_STREAM_H */ + + diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_L_Stream.i b/examples/Service_Configurator/IPC-tests/server/Handle_L_Stream.i new file mode 100644 index 00000000000..e0ef5373b0b --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_L_Stream.i @@ -0,0 +1,134 @@ +/* -*- C++ -*- */ +// @(#)Handle_L_Stream.i 1.1 10/18/96 + + +#include "ace/Get_Opt.h" + +ACE_INLINE +Handle_L_Stream::~Handle_L_Stream (void) +{ +} + +ACE_INLINE +Handle_L_Stream::Handle_L_Stream (void) +{ + if (Handle_L_Stream::login_name == 0) + Handle_L_Stream::login_name = ACE_OS::cuserid (0); +} + +ACE_INLINE int +Handle_L_Stream::open (const ACE_UNIX_Addr &suas, int async) +{ + if (this->ACE_LSOCK_Acceptor::open (suas) == -1) + return -1; + else if (async && this->ACE_LSOCK_Acceptor::enable (SIGIO) == -1) + return -1; + else + return 0; +} + +ACE_INLINE int +Handle_L_Stream::info (char **strp, size_t length) const +{ + char buf[BUFSIZ]; + ACE_UNIX_Addr sa; + + if (this->get_local_addr (sa) == -1) + return -1; + + ACE_OS::sprintf (buf, "%s %s", sa.get_path_name (), + "# tests local ACE_Stream\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +ACE_INLINE int +Handle_L_Stream::init (int argc, char *argv[]) +{ + ACE_UNIX_Addr sus; + const char *r = Handle_L_Stream::DEFAULT_RENDEZVOUS; + ACE_Get_Opt get_opt (argc, argv, "r:", 0); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'r': + r = get_opt.optarg; + break; + default: + break; + } + + ACE_OS::strncpy (this->rendezvous, r, MAXPATHLEN); + ACE_OS::unlink (this->rendezvous); + sus.set (this->rendezvous); + if (this->open (sus) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + else if (ACE_Service_Config::reactor ()->register_handler (this, + ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "registering service with ACE_Reactor\n"), -1); + return 0; +} + +ACE_INLINE int +Handle_L_Stream::fini (void) +{ + return ACE_Service_Config::reactor ()->remove_handler (this, ACE_Event_Handler::READ_MASK); +} + +ACE_INLINE ACE_HANDLE +Handle_L_Stream::get_handle (void) const +{ + return ACE_LSOCK_Acceptor::get_handle (); +} + +ACE_INLINE int +Handle_L_Stream::handle_input (ACE_HANDLE) +{ + ACE_LSOCK_Stream new_local_stream; + ACE_UNIX_Addr sa; + int fd = ACE_INVALID_HANDLE; + char buf[BUFSIZ]; + + if (this->accept (new_local_stream, &sa) == -1) + return -1; + + if (new_local_stream.recv_handle (fd) == -1) + return -1; + else + ACE_DEBUG ((LM_INFO, + "received file descriptor %d on ACE_Stream %s\n", + fd, sa.get_path_name ())); + + ACE_OS::puts ("----------------------------------------"); + + for (ssize_t n; n = ACE_OS::read (fd, buf, sizeof buf); ) + ACE_OS::write (ACE_STDOUT, buf, n); + + ACE_OS::puts ("----------------------------------------"); + + time_t t = ACE_OS::time (0L); + char *cs = ACE_OS::ctime (&t); + + if (new_local_stream.send (4, + Handle_L_Stream::login_name, ACE_OS::strlen (Handle_L_Stream::login_name), + cs, ACE_OS::strlen (cs)) == -1) + return -1; + + if (ACE_OS::close (fd) == -1) + return -1; + if (new_local_stream.close () == -1) + return -1; + return 0; +} + +ACE_INLINE int +Handle_L_Stream::handle_close (ACE_HANDLE, ACE_Reactor_Mask) +{ + this->ACE_LSOCK_Acceptor::close (); + return ACE_OS::unlink (this->rendezvous); +} diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_R_Dgram.cpp b/examples/Service_Configurator/IPC-tests/server/Handle_R_Dgram.cpp new file mode 100644 index 00000000000..b5a3622a5ba --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_R_Dgram.cpp @@ -0,0 +1,36 @@ +#include "Handle_R_Dgram.h" +// @(#)Handle_R_Dgram.cpp 1.1 10/18/96 + + +#if defined (SunOS4) +extern "C" +{ + int init (void); + int fini (void); + void __sti__Handle_R_Dgram_C_init_(); + void __std__Handle_R_Dgram_C_init_(); +} + +int +init (void) +{ + __sti__Handle_R_Dgram_C_init_(); + return 0; +} + +int +fini (void) +{ + __std__Handle_R_Dgram_C_init_(); + return 0; +} +#endif /* SunOS4 */ + +unsigned short Handle_R_Dgram::DEFAULT_PORT = ACE_DEFAULT_SERVER_PORT; + +#if !defined (__ACE_INLINE__) +#include "Handle_R_Dgram.i" +#endif /* __ACE_INLINE__ */ + +Handle_R_Dgram remote_dgram; +ACE_Service_Object_Type rd (&remote_dgram, "Remote_Dgram"); diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_R_Dgram.h b/examples/Service_Configurator/IPC-tests/server/Handle_R_Dgram.h new file mode 100644 index 00000000000..493a4c85d7a --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_R_Dgram.h @@ -0,0 +1,40 @@ +/* -*- C++ -*- */ +// @(#)Handle_R_Dgram.h 1.1 10/18/96 + +/* Handles INET datagram messages from remote hosts. */ + +#if !defined (_HANDLE_R_DGRAM_H) +#define _HANDLE_R_DGRAM_H + +#include "ace/Service_Config.h" +#include "ace/Service_Record.h" +#include "ace/INET_Addr.h" +#include "ace/SOCK_Dgram.h" + +class Handle_R_Dgram : public ACE_Service_Object, public ACE_SOCK_Dgram +{ +public: + Handle_R_Dgram (void); + virtual int init (int argc, char *argv[]); + virtual int info (char **, size_t) const; + virtual int fini (void); + +private: + int open (const ACE_INET_Addr &r, int async = 0); + virtual int get_handle (void) const; + virtual int handle_input (int fd); + virtual int handle_close (int fd, ACE_Reactor_Mask); + + static unsigned short DEFAULT_PORT; +}; + +extern ACE_Service_Object_Type rd; + +#if defined (__ACE_INLINE__) +#define ACE_INLINE inline +#include "Handle_R_Dgram.i" +#else +#define ACE_INLINE +#endif /* __ACE_INLINE__ */ + +#endif /* _HANDLE_R_DGRAM_H */ diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_R_Dgram.i b/examples/Service_Configurator/IPC-tests/server/Handle_R_Dgram.i new file mode 100644 index 00000000000..9cefc302b00 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_R_Dgram.i @@ -0,0 +1,106 @@ +/* -*- C++ -*- */ +// @(#)Handle_R_Dgram.i 1.1 10/18/96 + + +#include "ace/Get_Opt.h" + +ACE_INLINE +Handle_R_Dgram::Handle_R_Dgram (void) +{ +} + +ACE_INLINE +Handle_R_Dgram::open (const ACE_INET_Addr &r, int async) +{ + if (this->ACE_SOCK_Dgram::open (r) == -1) + return -1; + else if (async && this->ACE_SOCK_Dgram::enable (SIGIO) == -1) + return -1; + else + return 0; +} + +ACE_INLINE int +Handle_R_Dgram::info (char **strp, size_t length) const +{ + char buf[BUFSIZ]; + ACE_INET_Addr sa; + + if (this->get_local_addr (sa) == -1) + return -1; + + ACE_OS::sprintf (buf, "%d/%s %s", sa.get_port_number (), "udp", "# tests remote dgram\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +ACE_INLINE int +Handle_R_Dgram::init (int argc, char *argv[]) +{ + ACE_INET_Addr sidg (Handle_R_Dgram::DEFAULT_PORT); + ACE_Get_Opt get_opt (argc, argv, "p:", 0); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'p': + sidg.set (ACE_OS::atoi (get_opt.optarg)); + break; + default: + break; + } + + if (this->open (sidg) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + else if (ACE_Service_Config::reactor ()->register_handler + (this, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "registering service with ACE_Reactor\n"), -1); + return 0; +} + +ACE_INLINE int +Handle_R_Dgram::fini (void) +{ + return ACE_Service_Config::reactor ()->remove_handler + (this, ACE_Event_Handler::READ_MASK); +} + +ACE_INLINE int +Handle_R_Dgram::get_handle (void) const +{ + return ACE_SOCK_Dgram::get_handle (); +} + +ACE_INLINE int +Handle_R_Dgram::handle_input (int) +{ + ACE_INET_Addr sa; + char buf[0x2000]; /* 8 k buffer */ + int n; + + if ((n = this->recv (buf, sizeof buf, sa)) == -1) + return -1; + else + ACE_DEBUG ((LM_INFO, "received datagram from host %s on port %d\n", + sa.get_host_name (), sa.get_port_number ())); + + ACE_OS::puts ("----------------------------------------"); + ACE_OS::write (ACE_STDOUT, buf, n); + + if (buf[n - 1] != '\n') + putchar ('\n'); + + ACE_OS::puts ("----------------------------------------"); + + return 0; +} + +ACE_INLINE int +Handle_R_Dgram::handle_close (int, ACE_Reactor_Mask) +{ + return this->ACE_SOCK_Dgram::close (); +} diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_R_Stream.cpp b/examples/Service_Configurator/IPC-tests/server/Handle_R_Stream.cpp new file mode 100644 index 00000000000..91549a321e8 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_R_Stream.cpp @@ -0,0 +1,39 @@ +#include "Handle_R_Stream.h" +// @(#)Handle_R_Stream.cpp 1.1 10/18/96 + + +#if defined (SunOS4) +extern "C" +{ + int init (void); + int fini (void); + void __sti__Handle_R_Stream_C_recv_n_(); + void __std__Handle_R_Stream_C_recv_n_(); +} + +int +init (void) +{ + __sti__Handle_R_Stream_C_recv_n_(); + return 0; +} + +int +fini (void) +{ + __std__Handle_R_Stream_C_recv_n_(); + return 0; +} +#endif /* SunOS4 */ + +/* Static variables. */ + +unsigned short Handle_R_Stream::DEFAULT_PORT = ACE_DEFAULT_SERVER_PORT; +char *Handle_R_Stream::login_name = 0; + +#if !defined (__ACE_INLINE__) +#include "Handle_R_Stream.i" +#endif /* __ACE_INLINE__ */ + +Handle_R_Stream remote_stream; +ACE_Service_Object_Type rs (&remote_stream, "Remote_Stream"); diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_R_Stream.h b/examples/Service_Configurator/IPC-tests/server/Handle_R_Stream.h new file mode 100644 index 00000000000..a612eb29ad5 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_R_Stream.h @@ -0,0 +1,46 @@ +/* -*- C++ -*- */ +// @(#)Handle_R_Stream.h 1.1 10/18/96 + +/* Handle connections from remote INET connections. */ + +#if !defined (_HANDLE_R_STREAM_H) +#define _HANDLE_R_STREAM_H + +#include "ace/Service_Config.h" +#include "ace/Service_Record.h" +#include "ace/SOCK_Stream.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/INET_Addr.h" + +class Handle_R_Stream : public ACE_Service_Object, public ACE_SOCK_Acceptor +{ +public: + Handle_R_Stream (void); + virtual int init (int argc, char *argv[]); + virtual int info (char **, size_t) const; + virtual int fini (void); + +private: + int open (const ACE_INET_Addr &sia, int async = 0); + virtual int get_handle (void) const; + virtual int handle_input (int fd); + virtual int handle_close (int fd, ACE_Reactor_Mask); + + ACE_SOCK_Stream new_remote_stream; + static u_short DEFAULT_PORT; + static char *login_name; +}; + +extern ACE_Service_Object_Type rs; + +#if defined (__ACE_INLINE__) +#define ACE_INLINE inline +#include "Handle_R_Stream.i" +#else +#define ACE_INLINE +#endif /* __ACE_INLINE__ */ + +#endif /* _HANDLE_R_STREAM_H */ + + + diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_R_Stream.i b/examples/Service_Configurator/IPC-tests/server/Handle_R_Stream.i new file mode 100644 index 00000000000..ce605be5180 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_R_Stream.i @@ -0,0 +1,124 @@ +/* -*- C++ -*- */ +// @(#)Handle_R_Stream.i 1.1 10/18/96 + + +#include "ace/Get_Opt.h" + +ACE_INLINE +Handle_R_Stream::Handle_R_Stream (void) +{ + if (Handle_R_Stream::login_name == 0) + Handle_R_Stream::login_name = ACE_OS::cuserid (0); +} + +ACE_INLINE int +Handle_R_Stream::open (const ACE_INET_Addr &sia, int async) +{ + if (this->ACE_SOCK_Acceptor::open (sia) == -1) + return -1; + else if (async && this->ACE_SOCK_Acceptor::enable (SIGIO) == -1) + return -1; + else + return 0; +} + +ACE_INLINE int +Handle_R_Stream::info (char **strp, size_t length) const +{ + char buf[BUFSIZ]; + ACE_INET_Addr sa; + + if (this->get_local_addr (sa) == -1) + return -1; + + ACE_OS::sprintf (buf, "%d/%s %s", sa.get_port_number (), "tcp", "# tests remote stream\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +ACE_INLINE int +Handle_R_Stream::init (int argc, char *argv[]) +{ + ACE_INET_Addr sis (Handle_R_Stream::DEFAULT_PORT); + ACE_Get_Opt get_opt (argc, argv, "p:", 0); + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'p': + sis.set (ACE_OS::atoi (get_opt.optarg)); + break; + default: + break; + } + + if (this->open (sis) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + else if (ACE_Service_Config::reactor ()->register_handler (this, + ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "registering service with ACE_Reactor\n"), -1); + return 0; +} + +ACE_INLINE int +Handle_R_Stream::fini (void) +{ + return ACE_Service_Config::reactor ()->remove_handler (this, ACE_Event_Handler::READ_MASK); +} + +ACE_INLINE int +Handle_R_Stream::get_handle (void) const +{ + return ACE_SOCK_Acceptor::get_handle (); +} + +ACE_INLINE int +Handle_R_Stream::handle_input (int) +{ + char buf[BUFSIZ]; + int bytes; + + if (this->accept (this->new_remote_stream) == -1) + return -1; + else + ACE_DEBUG ((LM_INFO, "new_remote_stream fd = %d\n", + this->new_remote_stream.get_handle ())); + + ACE_INET_Addr sa; + + if (this->new_remote_stream.get_remote_addr (sa) == -1) + return -1; + + ACE_DEBUG ((LM_INFO, "accepted from host %s at port %d\n", + sa.get_host_name (), sa.get_port_number ())); + + ACE_OS::puts ("----------------------------------------"); + + while ((bytes = this->new_remote_stream.recv (buf, sizeof buf)) > 0) + ACE_OS::write (ACE_STDOUT, buf, bytes); + + ACE_OS::puts ("----------------------------------------"); + + time_t t = ACE_OS::time (0L); + char *cs = ACE_OS::ctime (&t); + + if (this->new_remote_stream.send (4, + Handle_R_Stream::login_name, ACE_OS::strlen (Handle_R_Stream::login_name), + cs, ACE_OS::strlen (cs)) == -1) + return -1; + + if (this->new_remote_stream.close () == -1) + return -1; + + return 0; +} + +ACE_INLINE int +Handle_R_Stream::handle_close (int, ACE_Reactor_Mask) +{ + return this->ACE_SOCK_Acceptor::close (); +} diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_Thr_Stream.cpp b/examples/Service_Configurator/IPC-tests/server/Handle_Thr_Stream.cpp new file mode 100644 index 00000000000..339ab3023b8 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_Thr_Stream.cpp @@ -0,0 +1,200 @@ +#if !defined (ACE_HANDLE_THR_STREAM_C) +// @(#)Handle_Thr_Stream.cpp 1.1 10/18/96 + +#define ACE_HANDLE_THR_STREAM_C + +#include "ace/Get_Opt.h" +#include "ace/INET_Addr.h" +#include "Handle_Thr_Stream.h" + +#if defined (ACE_HAS_THREADS) + +#if !defined (__ACE_INLINE__) +#include "Handle_Thr_Stream.i" +#endif /* __ACE_INLINE__ */ + +// Shorthand names. +#define SH SVC_HANDLER +#define PR_AC_1 ACE_PEER_ACCEPTOR_1 +#define PR_AC_2 ACE_PEER_ACCEPTOR_2 +#define PR_ST_1 ACE_PEER_STREAM_1 +#define PR_ST_2 ACE_PEER_STREAM_2 + +template +Handle_Thr_Stream::~Handle_Thr_Stream (void) +{ +} + +template +Handle_Thr_Stream::Handle_Thr_Stream (void) +#if defined (ACE_HAS_THREADS) + : thr_flags_ (THR_DETACHED | THR_NEW_LWP) +#else + : thr_flags_ (0) +#endif /* ACE_HAS_THREADS */ +{ +} + +template int +Handle_Thr_Stream::info (char **strp, + size_t length) const +{ + char buf[BUFSIZ]; + ACE_INET_Addr sa; + + if (this->acceptor ().get_local_addr (sa) == -1) + return -1; + + ACE_OS::sprintf (buf, "%d/%s %s", sa.get_port_number (), "tcp", + "# tests threaded remote stream\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +template int +Handle_Thr_Stream::init (int argc, char *argv[]) +{ + ACE_INET_Addr local_addr (inherited::DEFAULT_PORT_); + int n_threads = ACE_DEFAULT_THREADS; + + ACE_Get_Opt get_opt (argc, argv, "p:t:", 0); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'p': + local_addr.set (ACE_OS::atoi (get_opt.optarg)); + break; + case 't': + n_threads = ACE_OS::atoi (get_opt.optarg); + break; + default: + break; + } + } + + // Initialize the threading strategy. + if (this->thr_strategy_.open (&this->thr_mgr_, + this->thr_flags_, + n_threads) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + + // Initialize the Acceptor base class, passing in the desired + // concurrency strategy. + else if (this->open (local_addr, ACE_Service_Config::reactor (), + 0, 0, &this->thr_strategy_) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + else + return 0; +} + +template int +Handle_Thr_Stream::fini (void) +{ + return ACE_Service_Config::reactor ()->remove_handler + (this, ACE_Event_Handler::READ_MASK); +} + +template +CLI_Stream::CLI_Stream (ACE_Thread_Manager *thr_mgr) + : inherited (thr_mgr) +{ +} + +template int +CLI_Stream::close (u_long) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) client stream object closing down\n")); + this->peer ().close (); + + /* Must be allocated dynamically! */ + delete this; + return 0; +} + +template int +CLI_Stream::open (void *) +{ + ACE_INET_Addr sa; + + ACE_DEBUG ((LM_DEBUG, "(%t) client handle = %d\n", + this->peer ().get_handle ())); + + if (this->peer ().get_remote_addr (sa) == -1) + return -1; + + ACE_DEBUG ((LM_DEBUG, "(%t) accepted at port %d\n", + sa.get_port_number ())); + return 0; +} + +template int +CLI_Stream::svc (void) +{ + char buf[BUFSIZ]; + char login_name[L_cuserid]; + int bytes; + + ACE_OS::puts ("----------------------------------------"); + + while ((bytes = this->peer ().recv (buf, sizeof buf)) > 0) + ACE_OS::write (ACE_STDOUT, buf, bytes); + + ACE_OS::puts ("----------------------------------------"); + ACE_OS::fflush (stdout); + + long t = ACE_OS::time (0L); + ACE_OS::cuserid (login_name); + ACE_OS::sprintf (buf, "user %s %s", login_name, ACE_OS::ctime (&t)); + + if (this->peer ().send_n (buf, ACE_OS::strlen (buf) + 1) == -1) + return -1; + + ACE_DEBUG ((LM_DEBUG, "(%t) sent reply %s", buf)); + return 0; +} + +#undef SH +#undef PR_AC_1 +#undef PR_AC_2 +#undef PR_ST_1 +#undef PR_ST_2 + +//---------------------------------------- + +#if defined (ACE_HAS_TLI) +#include "ace/TLI_Stream.h" +#include "ace/TLI_Acceptor.h" +#define THR_STREAM ACE_TLI_STREAM +#define THR_ACCEPTOR ACE_TLI_ACCEPTOR +#else +#include "ace/SOCK_Stream.h" +#include "ace/SOCK_Acceptor.h" +#define THR_STREAM ACE_SOCK_STREAM +#define THR_ACCEPTOR ACE_SOCK_ACCEPTOR +#endif /* ACE_HAS_TLI */ +#include "ace/INET_Addr.h" + +typedef CLI_Stream CLI_STREAM; +typedef Handle_Thr_Stream HANDLE_THR_STREAM; + +/* Static class variables */ + +u_short HANDLE_THR_STREAM::DEFAULT_PORT_ = ACE_DEFAULT_THR_PORT; + +/* Service object */ +HANDLE_THR_STREAM remote_thr_stream; +ACE_Service_Object_Type rts (&remote_thr_stream, "Remote_Thr_Stream"); + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class CLI_Stream; +template class Handle_Thr_Stream, THR_ACCEPTOR>; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ + +#endif /* ACE_HAS_THREADS */ +#endif /* ACE_HANDLE_THR_STREAM_C */ diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_Thr_Stream.h b/examples/Service_Configurator/IPC-tests/server/Handle_Thr_Stream.h new file mode 100644 index 00000000000..9068fd1105d --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_Thr_Stream.h @@ -0,0 +1,76 @@ +/* -*- C++ -*- */ +// @(#)Handle_Thr_Stream.h 1.1 10/18/96 + +/* Handle connections from remote INET connections. */ + +#if !defined (_HANDLE_THR_STREAM_H) +#define _HANDLE_THR_STREAM_H + +#include "ace/Acceptor.h" +#include "ace/Service_Record.h" + +#if defined (ACE_HAS_THREADS) + +template +class Handle_Thr_Stream : public ACE_Strategy_Acceptor +{ +public: + // = Initialization and termination. + Handle_Thr_Stream (void); + ~Handle_Thr_Stream (void); + + // = Dynamic linking hooks. + virtual int init (int argc, char *argv[]); + virtual int info (char **, size_t) const; + virtual int fini (void); + +private: + typedef Handle_Thr_Stream inherited; + + static u_short DEFAULT_PORT_; + + ACE_Thread_Manager thr_mgr_; + // Thread manager. + + ACE_Thread_Strategy thr_strategy_; + // Threading strategy. + + int thr_flags_; + // Threading flags. +}; + +// This class interacts with the client, running in a separate +// thread... +template +class CLI_Stream : public ACE_Svc_Handler +{ +public: + CLI_Stream (ACE_Thread_Manager * = 0); + + virtual int open (void *); + // Open the service. + + virtual int close (u_long); + // Close down the service. + + virtual int svc (void); + // Execute the service. + +protected: + typedef ACE_Svc_Handler inherited; +}; + +extern ACE_Service_Object_Type rts; + +#if defined (__ACE_INLINE__) +#define ACE_INLINE inline +#include "Handle_Thr_Stream.i" +#else +#define ACE_INLINE +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "Handle_Thr_Stream.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ +#endif /* ACE_HAS_THREADS */ +#endif /* _HANDLE_THR_STREAM_H */ diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_Thr_Stream.i b/examples/Service_Configurator/IPC-tests/server/Handle_Thr_Stream.i new file mode 100644 index 00000000000..5f43e47c7ec --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_Thr_Stream.i @@ -0,0 +1 @@ +/* -*- C++ -*- */ diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_Timeout.cpp b/examples/Service_Configurator/IPC-tests/server/Handle_Timeout.cpp new file mode 100644 index 00000000000..bfb562185e6 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_Timeout.cpp @@ -0,0 +1,34 @@ +#include "Handle_Timeout.h" +// @(#)Handle_Timeout.cpp 1.1 10/18/96 + + +#if defined (SunOS4) +extern "C" +{ + int init (void); + int fini (void); + void __sti__Handle_Timeout_C_init_(); + void __std__Handle_Timeout_C_init_(); +} + +int +init (void) +{ + __sti__Handle_Timeout_C_init_(); + return 0; +} + +int +fini (void) +{ + __std__Handle_Timeout_C_init_(); + return 0; +} +#endif /* SunOS4 */ + +#if !defined (__ACE_INLINE__) +#include "Handle_Timeout.i" +#endif /* __ACE_INLINE__ */ + +Handle_Timeout timer_1; +ACE_Service_Object_Type t1 (&timer_1, "Timer_1"); diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_Timeout.h b/examples/Service_Configurator/IPC-tests/server/Handle_Timeout.h new file mode 100644 index 00000000000..efcb7575dad --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_Timeout.h @@ -0,0 +1,36 @@ +/* -*- C++ -*- */ +// @(#)Handle_Timeout.h 1.1 10/18/96 + +/* Handles timeouts. */ + +#if !defined (_HANDLE_TIMEOUT_H) +#define _HANDLE_TIMEOUT_H + +#include "ace/Service_Config.h" +#include "ace/Service_Record.h" + +class Handle_Timeout : public ACE_Service_Object +{ +public: + Handle_Timeout (void); + virtual int init (int argc, char *argv[]); + virtual int info (char **, size_t) const; + virtual int fini (void); + +private: + virtual int get_handle (void) const; + virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg); + + int count; +}; + +extern ACE_Service_Object_Type t1; + +#if defined (__ACE_INLINE__) +#define ACE_INLINE inline +#include "Handle_Timeout.i" +#else +#define ACE_INLINE +#endif /* __ACE_INLINE__ */ + +#endif /* _HANDLE_TIMEOUT_H */ diff --git a/examples/Service_Configurator/IPC-tests/server/Handle_Timeout.i b/examples/Service_Configurator/IPC-tests/server/Handle_Timeout.i new file mode 100644 index 00000000000..623efaf9437 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Handle_Timeout.i @@ -0,0 +1,74 @@ +/* -*- C++ -*- */ +// @(#)Handle_Timeout.i 1.1 10/18/96 + + +#include "ace/Service_Config.h" +#include "ace/Get_Opt.h" + +ACE_INLINE +Handle_Timeout::Handle_Timeout (void): count (0) +{ +} + +ACE_INLINE int +Handle_Timeout::info (char **strp, size_t length) const +{ + char buf[BUFSIZ]; + + ACE_OS::sprintf (buf, "%s", "# tests timeout facility\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +ACE_INLINE int +Handle_Timeout::init (int argc, char *argv[]) +{ + ACE_Time_Value delta (10); + ACE_Time_Value interval (1); + ACE_Get_Opt get_opt (argc, argv, "a:d:i:", 0); + int arg = 0; + + for (int c; (c = get_opt ()) != -1; ) + switch (c) + { + case 'd': + delta.sec (ACE_OS::atoi (get_opt.optarg)); + break; + case 'i': + interval.sec (ACE_OS::atoi (get_opt.optarg)); + break; + case 'a': + arg = atoi (get_opt.optarg); + break; + default: + break; + } + + return ACE_Service_Config::reactor ()->schedule_timer (this, (void *) arg, delta, interval); +} + +ACE_INLINE int +Handle_Timeout::fini (void) +{ + return 0; +} + +ACE_INLINE int +Handle_Timeout::get_handle (void) const +{ + return -1; +} + +ACE_INLINE int +Handle_Timeout::handle_timeout (const ACE_Time_Value &tv, const void *arg) +{ + if (this->count++ >= 10) + return -1; /* Automatically cancel periodic timer... */ + ACE_DEBUG ((LM_INFO, "time for this(%u) expired at (%d, %d) with arg = %d\n", + this, tv.sec (), tv.usec (), int (arg))); + return 0; +} diff --git a/examples/Service_Configurator/IPC-tests/server/Makefile b/examples/Service_Configurator/IPC-tests/server/Makefile new file mode 100644 index 00000000000..3f5a97aabb3 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/Makefile @@ -0,0 +1,1016 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the server-side of the primary Reactor tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = server_test +LIB = libServer.a +SHLIB = libServer.so + +FILES = Handle_L_Dgram \ + Handle_L_CODgram \ + Handle_L_FIFO \ + Handle_L_Pipe \ + Handle_L_Stream \ + Handle_R_Dgram \ + Handle_R_Stream \ + Handle_Timeout \ + Handle_Broadcast \ + Handle_L_SPIPE \ + Handle_Thr_Stream + +SRC = $(addsuffix .cpp,$(BIN)) +OBJ = $(SRC:%.cpp=$(VDIR)%.o) + +LSRC = $(addsuffix .cpp,$(FILES)) +LIBS = -lACE + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VLIB) $(VSHLIB) $(SHLIBA) $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +LDFLAGS += -L./ + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/Handle_L_Dgram.o .shobj/Handle_L_Dgram.so: Handle_L_Dgram.cpp Handle_L_Dgram.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Dgram.h \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.h \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.i \ + $(WRAPPER_ROOT)/ace/LSOCK.h \ + $(WRAPPER_ROOT)/ace/LSOCK.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Dgram.i \ + $(WRAPPER_ROOT)/ace/UNIX_Addr.h \ + Handle_L_Dgram.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/Handle_L_CODgram.o .shobj/Handle_L_CODgram.so: Handle_L_CODgram.cpp Handle_L_CODgram.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + $(WRAPPER_ROOT)/ace/LSOCK_CODgram.h \ + $(WRAPPER_ROOT)/ace/LSOCK.h \ + $(WRAPPER_ROOT)/ace/LSOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_CODgram.h \ + $(WRAPPER_ROOT)/ace/SOCK_CODgram.i \ + $(WRAPPER_ROOT)/ace/LSOCK_CODgram.i \ + $(WRAPPER_ROOT)/ace/UNIX_Addr.h \ + Handle_L_CODgram.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/Handle_L_FIFO.o .shobj/Handle_L_FIFO.so: Handle_L_FIFO.cpp Handle_L_FIFO.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + $(WRAPPER_ROOT)/ace/FIFO_Recv_Msg.h \ + $(WRAPPER_ROOT)/ace/FIFO_Recv.h \ + $(WRAPPER_ROOT)/ace/FIFO.h \ + $(WRAPPER_ROOT)/ace/FIFO_Recv.i \ + $(WRAPPER_ROOT)/ace/FIFO_Recv_Msg.i \ + Handle_L_FIFO.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/Handle_L_Pipe.o .shobj/Handle_L_Pipe.so: Handle_L_Pipe.cpp Handle_L_Pipe.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + $(WRAPPER_ROOT)/ace/UNIX_Addr.h \ + $(WRAPPER_ROOT)/ace/LSOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/LSOCK.h \ + $(WRAPPER_ROOT)/ace/LSOCK.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.i \ + Handle_L_Pipe.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/Handle_L_Stream.o .shobj/Handle_L_Stream.so: Handle_L_Stream.cpp Handle_L_Stream.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + $(WRAPPER_ROOT)/ace/UNIX_Addr.h \ + $(WRAPPER_ROOT)/ace/LSOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/LSOCK.h \ + $(WRAPPER_ROOT)/ace/LSOCK.i \ + $(WRAPPER_ROOT)/ace/LSOCK_Stream.i \ + Handle_L_Stream.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/Handle_R_Dgram.o .shobj/Handle_R_Dgram.so: Handle_R_Dgram.cpp Handle_R_Dgram.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.h \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.i \ + Handle_R_Dgram.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/Handle_R_Stream.o .shobj/Handle_R_Stream.so: Handle_R_Stream.cpp Handle_R_Stream.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + Handle_R_Stream.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/Handle_Timeout.o .shobj/Handle_Timeout.so: Handle_Timeout.cpp Handle_Timeout.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + Handle_Timeout.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/Handle_Broadcast.o .shobj/Handle_Broadcast.so: Handle_Broadcast.cpp Handle_Broadcast.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.h \ + $(WRAPPER_ROOT)/ace/SOCK_Dgram.i \ + Handle_Broadcast.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/Handle_L_SPIPE.o .shobj/Handle_L_SPIPE.so: Handle_L_SPIPE.cpp Handle_L_SPIPE.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + Handle_L_SPIPE.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/Handle_Thr_Stream.o .shobj/Handle_Thr_Stream.so: Handle_Thr_Stream.cpp \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + Handle_Thr_Stream.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Svc_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Dynamic.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.i \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Strategies.cpp \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/Acceptor.cpp \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + Handle_Thr_Stream.cpp Handle_Thr_Stream.i \ + $(WRAPPER_ROOT)/ace/TLI_Stream.h \ + $(WRAPPER_ROOT)/ace/TLI.h \ + $(WRAPPER_ROOT)/ace/TLI.i \ + $(WRAPPER_ROOT)/ace/TLI_Stream.i \ + $(WRAPPER_ROOT)/ace/TLI_Acceptor.h \ + $(WRAPPER_ROOT)/ace/TLI_Acceptor.i +.obj/server_test.o .shobj/server_test.so: server_test.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/Service_Configurator/IPC-tests/server/server_test.cpp b/examples/Service_Configurator/IPC-tests/server/server_test.cpp new file mode 100644 index 00000000000..3c93ca704f9 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/server_test.cpp @@ -0,0 +1,31 @@ +/* The main test driver for the dynamically configured server. */ +// @(#)server_test.cpp 1.1 10/18/96 + + +#include "ace/Service_Config.h" + +sig_atomic_t finished = 0; + +static void +handler (int) +{ + finished = 1; +} + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config server_test; + + ACE_Sig_Action sig ((ACE_SignalHandler) handler, SIGINT); + + if (server_test.open (argc, argv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "server_test.open"), -1); + + for (;;) + if (server_test.run_reactor_event_loop () == -1 && finished) + break; + + /* NOTREACHED */ + return 0; +} diff --git a/examples/Service_Configurator/IPC-tests/server/svc.conf b/examples/Service_Configurator/IPC-tests/server/svc.conf new file mode 100644 index 00000000000..47092c3d030 --- /dev/null +++ b/examples/Service_Configurator/IPC-tests/server/svc.conf @@ -0,0 +1,19 @@ +# To configure different services, simply uncomment the appropriate lines in this file! +#static ACE_Service_Manager "-d -p 3911" +dynamic Remote_Brdcast Service_Object * .shobj/Handle_Broadcast.so:remote_broadcast "-p 10001" +#dynamic Remote_Stream Service_Object * .shobj/Handle_R_Stream.so:remote_stream "-p 20002" +#dynamic Remote_Dgram Service_Object * .shobj/Handle_R_Dgram.so:remote_dgram "-p 15001" +#dynamic Timer_1 Service_Object * .shobj/Handle_Timeout.so:timer_1 "-d 5 -i 1 -a 100" +#dynamic Local_Stream Service_Object * .shobj/Handle_L_Stream.so:local_stream "-r /tmp/foo_stream" +#dynamic Local_Pipe Service_Object * .shobj/Handle_L_Pipe.so:local_pipe "-r /tmp/foo_pipe" +#dynamic Local_Fifo Service_Object * .shobj/Handle_L_FIFO.so:local_fifo "-r /tmp/foo_fifo" +#dynamic Local_Dgram Service_Object * .shobj/Handle_L_Dgram.so:local_dgram "-r /tmp/foo_dgram" +#dynamic Local_CODgram Service_Object * .shobj/Handle_L_CODgram.so:local_codgram "-r /tmp/foo_codgram" +#dynamic Local_Spipe Service_Object * .shobj/Handle_L_SPIPE.so:local_spipe "-r /tmp/foo_spipe" +#dynamic Remote_Thr_Stream Service_Object * .shobj/Handle_Thr_Stream.so:remote_thr_stream "-p 10001" +#suspend Remote_Stream +#resume Local_SPIPE +#resume Remote_Stream +#remove Remote_Stream +#remove Local_Stream + diff --git a/examples/Service_Configurator/Makefile b/examples/Service_Configurator/Makefile new file mode 100644 index 00000000000..86ad57b73ef --- /dev/null +++ b/examples/Service_Configurator/Makefile @@ -0,0 +1,22 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Service Configurator tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +DIRS = IPC-tests \ + Misc + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU diff --git a/examples/Service_Configurator/Misc/Makefile b/examples/Service_Configurator/Misc/Makefile new file mode 100644 index 00000000000..e9364dace7a --- /dev/null +++ b/examples/Service_Configurator/Misc/Makefile @@ -0,0 +1,105 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for a test of the miscellaneous Service_Config examples +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = main + +FILES = Timer_Service + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(addsuffix .o,$(FILES)) +SHOBJ = $(addsuffix .so,$(FILES)) + +LDLIBS = $(addprefix .shobj/,$(SHOBJ)) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/Timer_Service.o .shobj/Timer_Service.so: Timer_Service.cpp Timer_Service.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/Service_Configurator/Misc/Timer_Service.cpp b/examples/Service_Configurator/Misc/Timer_Service.cpp new file mode 100644 index 00000000000..8c377da53f5 --- /dev/null +++ b/examples/Service_Configurator/Misc/Timer_Service.cpp @@ -0,0 +1,40 @@ +#include "Timer_Service.h" +// @(#)Timer_Service.cpp 1.1 10/18/96 + + +int +Timer_Service::init (int argc, char *argv[]) +{ + char *prog = argc > 0 ? argv[0] : "Timer_Service"; + int interval = argc > 1 ? ACE_OS::atoi (argv[1]) : 4; + if (argc > 2) + ACE_Trace::start_tracing (); + else + ACE_Trace::stop_tracing (); + + ACE_DEBUG ((LM_DEBUG, "in Timer_Service::init, argv[0] = %s, argc == %d\n", + argv[0], argc)); + + + ACE_Service_Config::reactor ()->schedule_timer + (this, 0, ACE_Time_Value (1), ACE_Time_Value (interval)); + return 0; +} + +int +Timer_Service::handle_timeout (const ACE_Time_Value &tv, + const void *) +{ + ACE_DEBUG ((LM_DEBUG, "in Timer_Service::handle_timeout sec = %d, usec = %d\n", + tv.sec (), tv.usec ())); + return 0; +} + +// Define the factory function. +ACE_SVC_FACTORY_DEFINE (Timer_Service) + +// Define the object that describes the service. +ACE_STATIC_SVC_DEFINE (Timer_Service, + "Timer_Service", ACE_SVC_OBJ_T, &ACE_SVC_NAME (Timer_Service), + ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ, 0) + diff --git a/examples/Service_Configurator/Misc/Timer_Service.h b/examples/Service_Configurator/Misc/Timer_Service.h new file mode 100644 index 00000000000..b002cd6fddb --- /dev/null +++ b/examples/Service_Configurator/Misc/Timer_Service.h @@ -0,0 +1,16 @@ +/* -*- C++ -*- */ +// @(#)Timer_Service.h 1.1 10/18/96 + +#include "ace/Service_Config.h" + +class Timer_Service : public ACE_Service_Object +{ +public: + virtual int init (int argc, char *argv[]); + + virtual int handle_timeout (const ACE_Time_Value &, + const void *); +}; + +ACE_STATIC_SVC_DECLARE (Timer_Service) + diff --git a/examples/Service_Configurator/Misc/main.cpp b/examples/Service_Configurator/Misc/main.cpp new file mode 100644 index 00000000000..945465bf2ef --- /dev/null +++ b/examples/Service_Configurator/Misc/main.cpp @@ -0,0 +1,24 @@ +#include "ace/Service_Config.h" +// @(#)main.cpp 1.1 10/18/96 + +#include "Timer_Service.h" + +// Create an object that will insert the Timer_Service into the list +// of statically linked services that the ACE_Service_Config will +// process at run-time. +ACE_STATIC_SVC_REQUIRE(Timer_Service) + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config daemon; + + if (daemon.open (argc, argv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), 1); + + // Run forever, performing the configured services until we receive + // a SIGINT. + + daemon.run_reactor_event_loop (); + return 0; +} diff --git a/examples/Service_Configurator/Misc/svc.conf b/examples/Service_Configurator/Misc/svc.conf new file mode 100644 index 00000000000..c3eb2fc6cea --- /dev/null +++ b/examples/Service_Configurator/Misc/svc.conf @@ -0,0 +1 @@ +static Timer_Service "timer $TIME $TRACE" diff --git a/examples/Shared_Malloc/Makefile b/examples/Shared_Malloc/Makefile new file mode 100644 index 00000000000..002d0d7f06d --- /dev/null +++ b/examples/Shared_Malloc/Makefile @@ -0,0 +1,96 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for tests of the Shared_Malloc wrappers +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = test_malloc \ + test_persistence + +FILES = Malloc \ + Options + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(addsuffix .o,$(FILES)) +SHOBJ = $(addsuffix .so,$(FILES)) + +LDLIBS = $(addprefix .shobj/,$(SHOBJ)) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/Malloc.o .shobj/Malloc.so: Malloc.cpp Options.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h +.obj/Options.o .shobj/Options.so: Options.cpp \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + Options.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/Shared_Malloc/Malloc.cpp b/examples/Shared_Malloc/Malloc.cpp new file mode 100644 index 00000000000..f784e112124 --- /dev/null +++ b/examples/Shared_Malloc/Malloc.cpp @@ -0,0 +1,80 @@ +#include "Options.h" +// @(#)Malloc.cpp 1.1 10/18/96 + +#include "Malloc.h" + +// Determine the type of dynamic memory manager. +#if defined (ACE_HAS_THREADS) +typedef ACE_Thread_Mutex THREAD_MUTEX; +#else +typedef ACE_Null_Mutex THREAD_MUTEX; +#endif /* ACE_HAS_THREADS */ + +// ACE_Process_Mutex will work for non-MT platforms. +typedef ACE_Process_Mutex PROCESS_MUTEX; + +class MMAP_POOL : public ACE_MMAP_Memory_Pool + // = TITLE + // This class is an "adapter" that passes certain arguments to the + // constructor of ACE_MMAP_Memory_Pool. +{ +public: + MMAP_POOL (const char *); + + static const char BACKING_STORE[]; +}; + +const char MMAP_POOL::BACKING_STORE[] = "/tmp/test_malloc"; + +MMAP_POOL::MMAP_POOL (const char *) + : ACE_MMAP_Memory_Pool (BACKING_STORE, // Name of the backing store. + 1, // Use fixed addr. + 1) // Write each page of backing store. +{ +} + +// Strategic typedefs for memory allocation. + +typedef ACE_Malloc L_ALLOCATOR; + +#if !defined (ACE_WIN32) +typedef ACE_Malloc M_ALLOCATOR; +typedef ACE_Malloc SP_ALLOCATOR; +typedef ACE_Malloc ST_ALLOCATOR; +typedef ACE_Malloc SB_ALLOCATOR; +#else +typedef ACE_Malloc M_ALLOCATOR; +typedef ACE_Malloc SP_ALLOCATOR; +typedef ACE_Malloc ST_ALLOCATOR; +typedef ACE_Malloc SB_ALLOCATOR; +#endif /* ACE_WIN32 */ + +// Singleton +ACE_Allocator *Malloc::instance_ = 0; + +// This is a factory that decides what type of allocator to create. + +ACE_Allocator * +Malloc::instance (void) +{ + if (Malloc::instance_ == 0) + { + if (Options::instance ()->child ()) + Malloc::instance_ = new ACE_Allocator_Adapter; + else if (Options::instance ()->spawn_threads ()) + { + if (Options::instance ()->use_sbrk ()) + Malloc::instance_ = new ACE_Allocator_Adapter; + else if (Options::instance ()->use_shmem ()) + Malloc::instance_ = new ACE_Allocator_Adapter; + else + Malloc::instance_ = new ACE_Allocator_Adapter; + } + else if (Options::instance ()->use_mmap ()) + Malloc::instance_ = new ACE_Allocator_Adapter; + else // Use Shared_Memory_Pool. + Malloc::instance_ = new ACE_Allocator_Adapter; + } + + return Malloc::instance_; +} diff --git a/examples/Shared_Malloc/Malloc.h b/examples/Shared_Malloc/Malloc.h new file mode 100644 index 00000000000..b3f9d5fd516 --- /dev/null +++ b/examples/Shared_Malloc/Malloc.h @@ -0,0 +1,25 @@ +/* -*- C++ -*- */ +// @(#)Malloc.h 1.1 10/18/96 + +#if !defined (MY_MALLOC_H) +#define MY_MALLOC_H + +#include "ace/Malloc.h" + +class Malloc + // = TITLE + // Allocator Singleton. +{ +public: + static ACE_Allocator *instance (void); + // Returns static instance. + +private: + Malloc (void); + // Ensure Singleton. + + static ACE_Allocator *instance_; + // Malloc Singleton. +}; + +#endif /* MY_MALLOC_H */ diff --git a/examples/Shared_Malloc/Options.cpp b/examples/Shared_Malloc/Options.cpp new file mode 100644 index 00000000000..6a9467356a3 --- /dev/null +++ b/examples/Shared_Malloc/Options.cpp @@ -0,0 +1,186 @@ +#include "ace/Get_Opt.h" +// @(#)Options.cpp 1.1 10/18/96 + +#include "ace/Log_Msg.h" +#include "Options.h" + +// Static Singleton instance. +Options *Options::instance_ = 0; + +Options * +Options::instance (void) +{ + if (Options::instance_ == 0) + Options::instance_ = new Options (); + + return Options::instance_; +} + +char * +Options::program_name (void) +{ + return this->program_name_; +} + +const char * +Options::slave_name (void) +{ + return this->slave_name_; +} + +int +Options::debug (void) +{ + return this->debug_; +} + +int +Options::exec_slave (void) +{ + return this->exec_slave_; +} + +size_t +Options::iteration_count (void) +{ + return this->iteration_count_; +} + +int +Options::use_sbrk (void) +{ + return this->use_sbrk_; +} + +size_t +Options::max_msg_size (void) +{ + return this->max_msg_size_; +} + +size_t +Options::spawn_count (void) +{ + return this->spawn_count_; +} + +int +Options::spawn_threads (void) +{ + return this->spawn_threads_; +} + +int +Options::use_mmap (void) +{ + return this->use_mmap_; +} + +int +Options::use_shmem (void) +{ + return this->use_shmem_; +} + +int +Options::child (void) +{ + return this->child_; +} + +// Explain usage and exit. + +void +Options::print_usage_and_die (void) +{ + ACE_ERROR ((LM_ERROR, "usage: %n" + "\n[-d] (run in debugging mode)\n" + "[-e] (use exec(2) in addition to fork(2))\n" + "[-l] (use C++ new operator rather than sbrk(2)\n" + "[-L max_msg_size]\n" + "[-m] (use mmap rather than SysV shared memory)\n" + "[-p] (use processes rather than threads)\n" + "[-s] (use SysV shared memory rather than mmap)\n" + "[-t number of threads or processes to spawn]\n" + "[-n iteration_count]\n%a", -1)); + /* NOTREACHED */ +} + +Options::Options (void) + : slave_name_ ("slave"), + debug_ (0), + exec_slave_ (0), + iteration_count_ (100), + use_sbrk_ (0), + use_shmem_ (0), + max_msg_size_ (127), + spawn_count_ (1), + spawn_threads_ (1), + use_mmap_ (0), + child_ (0) +{ +} + +void +Options::parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, "dehlL:mn:pst:"); + + this->program_name_ = argv[0]; + ACE_LOG_MSG->open (this->program_name_); + + // Put in a special-case check for child process. + if (ACE_OS::strcmp (this->program_name_, slave_name_) == 0) + { + this->child_ = 1; + this->use_mmap_ = 1; + } + + int c; + + while ((c = get_opt ()) != -1) + { + switch (c) + { + case 'd': + this->debug_ = 1; + break; + case 'e': + this->exec_slave_ = 1; + break; + case 'h': + this->print_usage_and_die (); + /* NOTREACHED */ + break; + case 'l': + this->use_sbrk_ = 0; + break; + case 'L': + this->max_msg_size_ = ACE_OS::atoi (get_opt.optarg); + break; + case 'm': + this->use_mmap_ = 1; + break; + case 'n': + this->iteration_count_ = ACE_OS::atoi (get_opt.optarg); + break; + case 'p': // Spawn processes rather than threads + this->spawn_threads_ = 0; + break; + case 's': + // Use System V shared memory... + this->use_shmem_ = 1; + break; + case 't': + this->spawn_count_ = ACE_OS::atoi (get_opt.optarg); + break; + default: + this->print_usage_and_die (); + /* NOTREACHED */ + break; + } + } + // Switch to using MMAP when the -p and -e options are enabled. + if (this->exec_slave_ == 1 && this->spawn_threads_ == 0) + this->use_mmap_ = 1; +} diff --git a/examples/Shared_Malloc/Options.h b/examples/Shared_Malloc/Options.h new file mode 100644 index 00000000000..769e1a4db13 --- /dev/null +++ b/examples/Shared_Malloc/Options.h @@ -0,0 +1,81 @@ +/* -*- C++ -*- */ +// @(#)Options.h 1.1 10/18/96 + +#if !defined (_OPTIONS) +#define _OPTIONS + +#include "ace/OS.h" + +class Options + // = TITLE + // Options Singleton. +{ +public: + static Options *instance (void); + // Return Singleton. + + void parse_args (int argc, char *argv[]); + // Parse the arguments. + + // = Accessor methods. + char *program_name (void); + const char *slave_name (void); + int debug (void); + int exec_slave (void); + size_t iteration_count (void); + int use_sbrk (void); + int use_shmem (void); + size_t max_msg_size (void); + size_t spawn_count (void); + int spawn_threads (void); + int use_mmap (void); + int child (void); + +private: + Options (void); + // Ensure Singleton. + + static Options *instance_; + // Singleton. + + void print_usage_and_die (void); + // Explain usage and exit. + + char *program_name_; + // Name of the program. + + const char *slave_name_; + // Name of slave process. + + int debug_; + // Flag to indicate if we are debugging. + + int exec_slave_; + // Flag to indicate if we should exec after forking. + + size_t iteration_count_; + // Number of iterations to call malloc_recurse(). + + int use_sbrk_; + // Should we use sbrk(2)? + + int use_shmem_; + // Should we use Shared Memory? + + size_t max_msg_size_; + // Maximum number of bytes to malloc. + + size_t spawn_count_; + // Number of threads. + + int spawn_threads_; + // Spawn threads vs. processes. + + int use_mmap_; + // Use mmap() as the backing store. + + int child_; + // We're a child process. +}; + +#endif /* _OPTIONS */ diff --git a/examples/Shared_Malloc/test_malloc.cpp b/examples/Shared_Malloc/test_malloc.cpp new file mode 100644 index 00000000000..9a1d355701b --- /dev/null +++ b/examples/Shared_Malloc/test_malloc.cpp @@ -0,0 +1,195 @@ +// This program tests out all the various ACE_Malloc combinations and +// @(#)test_malloc.cpp 1.1 10/18/96 + +// the ACE_Allocator_Adapter. + +#include "ace/Thread.h" +#include "ace/Thread_Manager.h" +#include "Malloc.h" +#include "Options.h" + +// Global thread manager. +static ACE_Thread_Manager thread_manager; + +static int +gen_size (void) +{ +#if defined (ACE_HAS_THREADS) + ACE_RANDR_TYPE seed = ACE_RANDR_TYPE (&seed); + return (ACE_OS::rand_r (ACE_RANDR_TYPE (seed)) % Options::instance ()->max_msg_size ()) + 1; +#else + return (ACE_OS::rand () % Options::instance ()->max_msg_size ()) + 1; +#endif /* ACE_HAS_THREADS */ +} + +// Recursively allocate and deallocate dynamic memory. + +static int +malloc_recurse (int count) +{ + static char default_char = 0; + + if (count <= 0) + { + if (Options::instance ()->debug ()) + AMS (Malloc::instance ()->print_stats ()); + } + else + { + int alloc_size = gen_size (); + void *ptr = Malloc::instance ()->malloc (alloc_size); + + if (ptr == 0) + ACE_ERROR ((LM_ERROR, "(%P|%t) *** malloc of size %d failed, %p\n%a", + "malloc", alloc_size)); + else + { + ACE_OS::memset (ptr, default_char++, alloc_size); + + if (Options::instance ()->debug ()) + ACE_DEBUG ((LM_INFO, "(%P|%t) %u (alloc), size = %d\n", ptr, alloc_size)); + + // Call ourselves recursively + malloc_recurse (count - 1); + + if (Options::instance ()->debug ()) + ACE_DEBUG ((LM_INFO, "(%P|%t) %u (free), size = %d\n", ptr, alloc_size)); + + Malloc::instance ()->free (ptr); + } + } + return 0; +} + +static void * +worker (void *arg) +{ + // Allocate a thread control object, which automatically removes the + // thread from the thread manager on exit. + ACE_Thread_Control tc (&thread_manager); + + malloc_recurse (int (arg)); + return 0; +} + +// Create the appropriate type of process/thread. + +static void +spawn (void) +{ + if (Options::instance ()->spawn_threads ()) + { +#if defined (ACE_HAS_THREADS) + if (thread_manager.spawn (ACE_THR_FUNC (worker), + (void *) Options::instance ()->iteration_count (), + THR_BOUND) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "thread create failed")); +#else + if (Options::instance ()->spawn_count () > 1) + ACE_ERROR ((LM_ERROR, "only one thread may be run in a process on this platform\n%a", 1)); +#endif /* ACE_HAS_THREADS */ + } +#if !defined (ACE_WIN32) + else + { + if (ACE_OS::fork () == 0) + { + if (Options::instance ()->exec_slave ()) + { + char iterations[20]; + char msg_size[20]; + + ACE_OS::sprintf (iterations, "%d", Options::instance ()->iteration_count ()); + ACE_OS::sprintf (msg_size, "%d", Options::instance ()->max_msg_size ()); + + char *argv[8]; + argv[0] = (char *) Options::instance ()->slave_name (); + argv[1] = "-p"; + argv[2] = "-n"; + argv[3] = iterations; + argv[4] = "-L"; + argv[5] = msg_size; + argv[6] = Options::instance ()->debug () ? "-d" : ""; + argv[7] = (char *) 0; + + if (ACE_OS::execv (Options::instance ()->program_name (), argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "exec failed")); + ACE_OS::_exit (1); + } + else + { + ACE_LOG_MSG->sync (Options::instance ()->program_name ()); + + ACE_DEBUG ((LM_INFO, + "(%P|%t) about to recurse with iteration count = %d\n", + Options::instance ()->iteration_count ())); + + malloc_recurse (Options::instance ()->iteration_count ()); + ACE_OS::exit (0); + } + } + } +#endif /* ACE_WIN32 */ +} + +// Wait for all the child processes/threads to exit. + +static void +wait_for_children (void) +{ + if (Options::instance ()->spawn_threads ()) + { +#if defined (ACE_HAS_THREADS) + // Wait for the threads to terminate. + thread_manager.wait (); +#else + malloc_recurse (Options::instance ()->iteration_count ()); +#endif /* ACE_HAS_THREADS */ + } +#if !defined (ACE_WIN32) + else + { + pid_t pid; + + while ((pid = ACE_OS::wait (0)) != -1) + ACE_DEBUG ((LM_DEBUG, "(%P|%t) reaped pid = %d\n", pid)); + } +#endif /* ACE_WIN32 */ +} + +static void +handler (int) +{ + Malloc::instance ()->remove (); + ACE_ERROR ((LM_ERROR, "(%P|%t) removed handler\n%a", 0)); +} + +int +main (int argc, char *argv[]) +{ + signal (SIGINT, ACE_SignalHandler (handler)); + + Options::instance ()->parse_args (argc, argv); + +#if !defined (ACE_WIN32) + if (Options::instance ()->child ()) + { + ACE_DEBUG ((LM_INFO, + "(%P|%t) about to recurse with iteration count = %d, debug = %d\n", + Options::instance ()->iteration_count ())); + + // We've been forked... + malloc_recurse (Options::instance ()->iteration_count ()); + } + else +#endif /* ACE_WIN32 */ + { + for (size_t i = 0; i < Options::instance ()->spawn_count (); i++) + spawn (); + + wait_for_children (); + Malloc::instance ()->remove (); + } + return 0; +} + diff --git a/examples/Shared_Malloc/test_persistence.cpp b/examples/Shared_Malloc/test_persistence.cpp new file mode 100644 index 00000000000..8f499a6a01d --- /dev/null +++ b/examples/Shared_Malloc/test_persistence.cpp @@ -0,0 +1,246 @@ +// Test the persistence capabilities of the ACE shared memory manager. +// @(#)test_persistence.cpp 1.1 10/18/96 + + +#include "ace/Log_Msg.h" +#include "ace/Malloc.h" + +typedef ACE_Malloc MALLOC; +typedef ACE_Malloc_Iterator MALLOC_ITERATOR; + +// Shared memory manager. +static MALLOC *shmem_manager = 0; + +// Backing store name. +static char *backing_store = ACE_DEFAULT_BACKING_STORE; + +class Employee +{ +public: + Employee (void): name_ (0), id_ (0) {} + + Employee (char* name, u_long id) : id_ (id) + { + this->name_ = (char*) shmem_manager->malloc (ACE_OS::strlen (name) + 1); + ACE_OS::strcpy (this->name_, name ); + } + + ~Employee (void) { shmem_manager->free (this->name_); } + + char *name (void) const { return this->name_; } + + void name (char* name) + { + if (this->name_) + shmem_manager->free (this->name_); + this->name_ = (char*) shmem_manager->malloc (ACE_OS::strlen (name) + 1); + ACE_OS::strcpy (this->name_, name); + } + + u_long id (void) const { return id_; } + + void id (u_long id) { id_ = id; } + + friend ostream &operator<<(ostream &stream, const Employee &employee) + { + stream << endl; + stream << "Employee name: " << employee.name() << endl; + stream << "Employee id: " << employee.id() << endl; + stream << endl; + + return stream; + } + + void *operator new (size_t size) + { + return shmem_manager->malloc (sizeof (Employee)); + } + + void operator delete (void *pointer) { shmem_manager->free (pointer); } + +private: + char *name_; + // Employee name. + + u_long id_; + // Employee ID. +}; + +class GUI_Handler +{ +public: + GUI_Handler (void) { menu(); } + + ~GUI_Handler (void) + { + MALLOC::MEMORY_POOL &pool = shmem_manager->memory_pool(); + pool.sync (); + } + + int service(void) + { + char option[BUFSIZ]; + char buf1[BUFSIZ]; + char buf2[BUFSIZ]; + + if (::scanf ("%s", option) <= 0) + { + ACE_ERROR ((LM_ERROR, "try again\n")); + return 0; + } + + int result = 0; + switch (option[0]) + { + case 'I' : + case 'i' : + if (::scanf ("%s %s", buf1, buf2) <= 0) + break; + result = insert_employee (buf1, ACE_OS::atoi (buf2)); + break; + case 'F' : + case 'f' : + if (::scanf ("%s", buf1) <= 0) + break; + result = find_employee (buf1); + break; + case 'D' : + case 'd' : + if (::scanf ("%s", buf1) <= 0) + break; + result = delete_employee (buf1); + break; + case 'L' : + case 'l' : + result = list_employees (); + break; + case 'Q' : + case 'q' : + return -1; + break; + default : + cout << "unrecognized command" << endl; + } + if (result == 0) + cout << "Last operation was successful!!" << endl; + else + cout << "Last operation failed!! " << endl; + + menu (); + + return 0; + } + + void menu(void) + { + cout << endl; + cout << "\t************************** " << endl; + cout << "\tThe employee database menu " << endl; + cout << endl; + cout << "\t Insert " << endl; + cout << "\t Delete " << endl; + cout << "\t Find " << endl; + cout << endl; + cout << "\t List all employees " << endl; + cout << endl; + cout << "\t Quit " << endl; + cout << "\t************************** " << endl; + } + +private: + int insert_employee (char* name, u_long id) + { + if (find_employee (name) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "Employee already exists\n"), -1); + + Employee* new_employee = new Employee (name, id); + shmem_manager->bind (name, new_employee); + return 0; + } + + int find_employee (char* name) + { + void *temp; + if (shmem_manager->find (name, temp) == 0) + { + Employee *employee = (Employee *) temp; + + ACE_DEBUG ((LM_DEBUG, "The following employee was found.......\n\n")); + ACE_DEBUG ((LM_DEBUG, "Employee name: %s\nEmployee id: %d\n", + employee->name (), employee->id ())); + return 0; + } + + return -1; + } + + int list_employees (void) + { + MALLOC_ITERATOR iterator (*shmem_manager); + + ACE_DEBUG ((LM_DEBUG, "The following employees were found.......\n\n")); + + for (void* temp = 0; + iterator.next (temp) != 0; + iterator.advance ()) + { + Employee *employee = (Employee *) temp; + ACE_DEBUG ((LM_DEBUG, "Employee name: %s\nEmployee id: %d\n", + employee->name (), employee->id ())); + } + return 0; + } + + int delete_employee (char* name) + { + void *temp; + + if (shmem_manager->unbind (name, temp) == 0) + { + Employee *employee = (Employee *) temp; + + ACE_DEBUG ((LM_DEBUG, + "The following employee was found and deleted.......\n\n")); + + ACE_DEBUG ((LM_DEBUG, "Employee name: %s\nEmployee id: %d\n", + employee->name (), employee->id ())); + + delete employee; + return 0; + } + + ACE_DEBUG ((LM_DEBUG, "There is no employee with name %s", name)); + return -1; + } +}; + +void +parse_args (int argc, char *argv[]) +{ + if (argc > 1); + backing_store = argv[1]; +} + +int +main (int argc, char *argv[]) +{ + parse_args (argc, argv); + + shmem_manager = new MALLOC (backing_store); + + GUI_Handler handler; + + for(;;) + if (handler.service() == -1) + { + ACE_DEBUG ((LM_DEBUG, "closing down ....\n")); + break; + } + + return 0; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Malloc ; +template class ACE_Malloc_Iterator ; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/examples/Shared_Memory/Makefile b/examples/Shared_Memory/Makefile new file mode 100644 index 00000000000..d96a154ed6f --- /dev/null +++ b/examples/Shared_Memory/Makefile @@ -0,0 +1,76 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for tests of the Shared_Malloc wrappers +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = test_MM \ + test_SV + +LSRC = test_MM.cpp \ + test_SV.cpp + +LDLIBS = + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +INSTALL = + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/test_MM.o .shobj/test_MM.so: test_MM.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Shared_Memory_MM.h \ + $(WRAPPER_ROOT)/ace/Shared_Memory.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h +.obj/test_SV.o .shobj/test_SV.so: test_SV.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Shared_Memory_SV.h \ + $(WRAPPER_ROOT)/ace/Shared_Memory.h \ + $(WRAPPER_ROOT)/ace/SV_Shared_Memory.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/Shared_Memory/test_MM.cpp b/examples/Shared_Memory/test_MM.cpp new file mode 100644 index 00000000000..8cb304c8ac2 --- /dev/null +++ b/examples/Shared_Memory/test_MM.cpp @@ -0,0 +1,63 @@ +#include "ace/Log_Msg.h" +// @(#)test_MM.cpp 1.1 10/18/96 + +#include "ace/Shared_Memory_MM.h" + +#define SHMSZ 27 +char shm_key[] = "/tmp/fooXXXXXX"; + +static void +client (void) +{ + ACE_Shared_Memory *shm_client = new ACE_Shared_Memory_MM (shm_key); + char *shm = (char *) shm_client->malloc (); + + for (char *s = shm; *s != '\0'; s++) + putchar (*s); + + putchar ('\n'); + *shm = '*'; +} + +static void +server (void) +{ + ACE_Shared_Memory *shm_server = new ACE_Shared_Memory_MM (shm_key, SHMSZ); + char *shm = (char *) shm_server->malloc (); + char *s = shm; + + for (char c = 'a'; c <= 'z'; c++) + *s++ = c; + + *s = '\0'; + + // Perform a busy wait (ugh) + while (*shm != '*') + ACE_OS::sleep (1); + + if (shm_server->remove () < 0) + ACE_ERROR ((LM_ERROR, "%p\n", "remove")); + ACE_OS::unlink (shm_key); +} + +int +main (int, char *[]) +{ + if (ACE_OS::mktemp (shm_key) == 0 || (ACE_OS::unlink (shm_key) == -1 && errno == EPERM)) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", shm_key), 1); + + switch (ACE_OS::fork ()) + { + case -1: + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "fork"), 1); + case 0: + ACE_OS::sleep (1); + client (); + break; + default: + server (); + break; + } + return 0; +} + diff --git a/examples/Shared_Memory/test_SV.cpp b/examples/Shared_Memory/test_SV.cpp new file mode 100644 index 00000000000..f585318ea1a --- /dev/null +++ b/examples/Shared_Memory/test_SV.cpp @@ -0,0 +1,60 @@ +#include "ace/Log_Msg.h" +// @(#)test_SV.cpp 1.1 10/18/96 + +#include "ace/Shared_Memory_SV.h" + +#define SHMSZ 27 +#define SHM_KEY 5678 + +static void +client (void) +{ + ACE_Shared_Memory_SV shm_client (SHM_KEY, SHMSZ); + char *shm = (char *) shm_client.malloc (); + + for (char *s = shm; *s != '\0'; s++) + putchar (*s); + + putchar ('\n'); + *shm = '*'; +} + +static void +server (void) +{ + ACE_Shared_Memory_SV shm_server (SHM_KEY, SHMSZ, + ACE_Shared_Memory_SV::ACE_CREATE); + char *shm = (char *) shm_server.malloc (); + char *s = shm; + + for (char c = 'a'; c <= 'z'; c++) + *s++ = c; + + *s = '\0'; + + while (*shm != '*') + ACE_OS::sleep (1); + + if (shm_server.remove () < 0) + ACE_ERROR ((LM_ERROR, "%p\n", "remove")); +} + +int +main (int, char *[]) +{ + switch (ACE_OS::fork ()) + { + case -1: + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "fork"), 1); + case 0: + ACE_OS::sleep (1); + client (); + break; + default: + server (); + break; + } + + return 0; +} + diff --git a/examples/System_V_IPC/Makefile b/examples/System_V_IPC/Makefile new file mode 100644 index 00000000000..f799c16b5dc --- /dev/null +++ b/examples/System_V_IPC/Makefile @@ -0,0 +1,26 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the System V IPC directory +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +INFO = README + +DIRS = SV_Message_Queues \ + SV_Semaphores \ + SV_Shared_Memory + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + diff --git a/examples/System_V_IPC/README b/examples/System_V_IPC/README new file mode 100644 index 00000000000..c5ebde21a60 --- /dev/null +++ b/examples/System_V_IPC/README @@ -0,0 +1,13 @@ +This directory contains a number of examples that illustrate how to +use the following ACE library components: + + . SV_Message_Queues + Illustrates the ACE wrappers for System V Message + Queues. + + . SV_Semaphores + Illustrates the ACE wrappers for System V Semaphores. + + . SV_Shared_Memory + Illustrates the ACE wrappers for System V Shared Memory. + diff --git a/examples/System_V_IPC/SV_Message_Queues/MQ_Client.cpp b/examples/System_V_IPC/SV_Message_Queues/MQ_Client.cpp new file mode 100644 index 00000000000..31d56c23e6a --- /dev/null +++ b/examples/System_V_IPC/SV_Message_Queues/MQ_Client.cpp @@ -0,0 +1,29 @@ +#include "ace/SV_Message_Queue.h" +// @(#)MQ_Client.cpp 1.1 10/18/96 + +#include "test.h" + +int +main (void) +{ + long pid = long (ACE_OS::getpid ()); + ACE_SV_Message_Queue msgque (SRV_KEY); + ACE_Message_Block send_msg (SRV_ID, pid, ACE_OS::cuserid (0), "did you get this?"); + ACE_Message_Block recv_msg (pid); + + if (msgque.send (send_msg, send_msg.length ()) < 0) + ACE_OS::perror ("msgque.send"), ACE_OS::exit (1); + + if (msgque.recv (recv_msg, sizeof (Message_Data), recv_msg.type ()) < 0) + ACE_OS::perror ("msgrcv"), ACE_OS::exit (1); + + cout << "a message of length " + << recv_msg.length () + << " received from server " + << recv_msg.pid () + << " (user " + << recv_msg.user () << "): " + << recv_msg.text () << "\n"; + + return 0; +} diff --git a/examples/System_V_IPC/SV_Message_Queues/MQ_Server.cpp b/examples/System_V_IPC/SV_Message_Queues/MQ_Server.cpp new file mode 100644 index 00000000000..1f7729ad4e1 --- /dev/null +++ b/examples/System_V_IPC/SV_Message_Queues/MQ_Server.cpp @@ -0,0 +1,51 @@ +#include "ace/Signal.h" +// @(#)MQ_Server.cpp 1.1 10/18/96 + +#include "ace/SV_Message_Queue.h" +#include "test.h" + +/* Must be global for signal Message... */ +ACE_SV_Message_Queue msgque (SRV_KEY, ACE_SV_Message_Queue::ACE_CREATE); + +void +SIGNAL_handler (int) +{ + if (msgque.remove () < 0) + ACE_OS::perror ("msgque.close"), ACE_OS::exit (1); + ACE_OS::exit (0); +} + +int +main (void) +{ + long pid = long (ACE_OS::getpid ()); + ACE_Message_Block recv_msg (SRV_ID); + ACE_Message_Block send_msg (0, pid, ACE_OS::cuserid (0), + "I received your message."); + + ACE_Sig_Action sig ((ACE_SignalHandler) SIGNAL_handler, SIGINT); + + for (;;) + { + if (msgque.recv (recv_msg, sizeof (Message_Data), recv_msg.type ()) == -1) + ::perror ("msgque.recv"), ACE_OS::exit (1); + + cout << "a msg of length " + << recv_msg.length () + << " sent from client " + << recv_msg.pid () + << " (user " + << recv_msg.user () << "): " + << recv_msg.text () << "\n"; + cout.flush (); + + send_msg.type (recv_msg.pid ()); + + if (msgque.send (send_msg, send_msg.length ()) < 0) + ACE_OS::perror ("msgque.send"), ACE_OS::exit (1); + } + + /* NOTREACHED */ + return 0; +} + diff --git a/examples/System_V_IPC/SV_Message_Queues/Makefile b/examples/System_V_IPC/SV_Message_Queues/Makefile new file mode 100644 index 00000000000..cf5b28482e9 --- /dev/null +++ b/examples/System_V_IPC/SV_Message_Queues/Makefile @@ -0,0 +1,101 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for testing the typed and untyped Message Queue abstraction +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = MQ_Server \ + MQ_Client \ + TMQ_Server \ + TMQ_Client + +LSRC = $(addsuffix .cpp,$(BIN)) + +LDLIBS = + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/MQ_Server.o .shobj/MQ_Server.so: MQ_Server.cpp \ + $(WRAPPER_ROOT)/ace/SV_Message_Queue.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/SV_Message.h \ + $(WRAPPER_ROOT)/ace/SV_Message_Queue.i \ + test.h +.obj/MQ_Client.o .shobj/MQ_Client.so: MQ_Client.cpp \ + $(WRAPPER_ROOT)/ace/SV_Message_Queue.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/SV_Message.h \ + $(WRAPPER_ROOT)/ace/SV_Message_Queue.i \ + test.h +.obj/TMQ_Server.o .shobj/TMQ_Server.so: TMQ_Server.cpp \ + $(WRAPPER_ROOT)/ace/Typed_SV_Message_Queue.h \ + $(WRAPPER_ROOT)/ace/SV_Message_Queue.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/SV_Message.h \ + $(WRAPPER_ROOT)/ace/SV_Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Typed_SV_Message.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h test.h +.obj/TMQ_Client.o .shobj/TMQ_Client.so: TMQ_Client.cpp \ + $(WRAPPER_ROOT)/ace/Typed_SV_Message_Queue.h \ + $(WRAPPER_ROOT)/ace/SV_Message_Queue.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/SV_Message.h \ + $(WRAPPER_ROOT)/ace/SV_Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Typed_SV_Message.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h test.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/System_V_IPC/SV_Message_Queues/TMQ_Client.cpp b/examples/System_V_IPC/SV_Message_Queues/TMQ_Client.cpp new file mode 100644 index 00000000000..0961f92da6a --- /dev/null +++ b/examples/System_V_IPC/SV_Message_Queues/TMQ_Client.cpp @@ -0,0 +1,43 @@ +#include "ace/Typed_SV_Message_Queue.h" +// @(#)TMQ_Client.cpp 1.1 10/18/96 + +#include "ace/Log_Msg.h" +#include "test.h" + +int +main (void) +{ + long pid = long (ACE_OS::getpid ()); + + ACE_Typed_SV_Message_Queue msgque (key_t (SRV_KEY)); + + Message_Data msg_data (pid, ACE_OS::cuserid (0), "did you get this?"); + + ACE_Typed_SV_Message send_msg (msg_data, + SRV_ID, + msg_data.length ()), + recv_msg (pid); + + if (msgque.send (send_msg) < 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "msgque.send"), 1); + + if (msgque.recv (recv_msg) < 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "msgque.recv"), 1); + + Message_Data &recv_msg_data = recv_msg.data (); + + cout << "a message of length " + << recv_msg_data.length () + << " received from server " + << recv_msg_data.pid () + << " (user " + << recv_msg_data.user () << "): " + << recv_msg_data.text () << "\n"; + + return 0; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Typed_SV_Message_Queue; +template class ACE_Typed_SV_Message; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/examples/System_V_IPC/SV_Message_Queues/TMQ_Server.cpp b/examples/System_V_IPC/SV_Message_Queues/TMQ_Server.cpp new file mode 100644 index 00000000000..ab843c830d6 --- /dev/null +++ b/examples/System_V_IPC/SV_Message_Queues/TMQ_Server.cpp @@ -0,0 +1,59 @@ +#include "ace/Signal.h" +// @(#)TMQ_Server.cpp 1.1 10/18/96 + +#include "ace/Typed_SV_Message_Queue.h" +#include "ace/Log_Msg.h" +#include "test.h" + +// Must be global for signal Message... +ACE_Typed_SV_Message_Queue msgque + (SRV_KEY, ACE_Typed_SV_Message_Queue::ACE_CREATE); + +void +SIGNAL_handler (int) +{ + if (msgque.remove () < 0) + ACE_ERROR ((LM_ERROR, "%p\n%a", "msgque.recv", 1)); + ACE_OS::exit (0); +} + +int +main (void) +{ + char *username = ACE_OS::cuserid (0); + Message_Data msg_data ((int) ACE_OS::getpid (), username, "I received your message."); + ACE_Typed_SV_Message send_msg (msg_data, 0, msg_data.length ()); + ACE_Typed_SV_Message recv_msg (SRV_ID); + + ACE_Sig_Action sig2 ((ACE_SignalHandler) SIGNAL_handler, SIGINT); + + for (;;) + { + if (msgque.recv (recv_msg) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "msgque.recv"), 1); + + Message_Data &recv_msg_data = recv_msg.data (); + + cout << "a msg of length " + << recv_msg_data.length () + << " sent from client " + << recv_msg_data.pid () + << " (user " + << recv_msg_data.user () << "): " + << recv_msg_data.text () << "\n"; + cout.flush (); + + send_msg.type (recv_msg_data.pid ()); + + if (msgque.send (send_msg) < 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "msgque.send"), 1); + } + + /* NOTREACHED */ + return 0; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Typed_SV_Message_Queue; +template class ACE_Typed_SV_Message; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/examples/System_V_IPC/SV_Message_Queues/test.h b/examples/System_V_IPC/SV_Message_Queues/test.h new file mode 100644 index 00000000000..ebfbe3448ac --- /dev/null +++ b/examples/System_V_IPC/SV_Message_Queues/test.h @@ -0,0 +1,42 @@ +/* -*- C++ -*- */ +// @(#)test.h 1.1 10/18/96 + +#include "ace/OS.h" +#include "ace/SV_Message.h" + +#define MSGSZ 128 +#define SRV_KEY ACE_DEFAULT_SHM_KEY +#define SRV_ID 1 + +class Message_Data +{ +public: + Message_Data (long p = -1, const char user[] = "", char text[] = ""): pid_ (p) + { + ::strncpy (this->username_, user, 9); + ::strncpy (this->mtext_, text, MSGSZ); + } + + long pid (void) { return this->pid_; } + void pid (long p) { this->pid_ = p; } + char *user (void) { return this->username_; } + void user (char user[]) { ::strncpy (this->username_, user, 9); } + char *text (void) { return this->mtext_; } + void text (char text[]) { ::strncpy (this->mtext_, text, MSGSZ); } + int length (void) { return sizeof *this - sizeof this->mtext_ + ::strlen (this->mtext_) + 1; } + +protected: + long pid_; + char username_[9]; + char mtext_[MSGSZ]; +}; + +/* Note, this may not be 100 percent portable on all C++ compilers... */ +class ACE_Message_Block : public ACE_SV_Message, public Message_Data +{ +public: + ACE_Message_Block (long t, long p = 0, char login[] = "", char message[] = "") + : ACE_SV_Message (t), Message_Data (p, login, message) + {} +}; + diff --git a/examples/System_V_IPC/SV_Semaphores/Makefile b/examples/System_V_IPC/SV_Semaphores/Makefile new file mode 100644 index 00000000000..09ab2ef1359 --- /dev/null +++ b/examples/System_V_IPC/SV_Semaphores/Makefile @@ -0,0 +1,116 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for Semaphore wrapper class +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = Semaphore_Client \ + Semaphore_Server \ + Semaphores + +LSRC = $(addsuffix .cpp,$(BIN)) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/Semaphore_Client.o .shobj/Semaphore_Client.so: Semaphore_Client.cpp Semaphore_Test.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/SV_Shared_Memory.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i +.obj/Semaphore_Server.o .shobj/Semaphore_Server.so: Semaphore_Server.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/SV_Shared_Memory.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + Semaphore_Test.h +.obj/Semaphores.o .shobj/Semaphores.so: Semaphores.cpp \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + Semaphore_Test.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/System_V_IPC/SV_Semaphores/Semaphore_Client.cpp b/examples/System_V_IPC/SV_Semaphores/Semaphore_Client.cpp new file mode 100644 index 00000000000..69b414cef0c --- /dev/null +++ b/examples/System_V_IPC/SV_Semaphores/Semaphore_Client.cpp @@ -0,0 +1,31 @@ +#include "Semaphore_Test.h" +// @(#)Semaphore_Client.cpp 1.1 10/18/96 + +#include "ace/SV_Shared_Memory.h" +#include "ace/SV_Semaphore_Simple.h" + +int +main (void) +{ + ACE_SV_Shared_Memory shm_client (SHM_KEY, + SHMSZ, + ACE_SV_Shared_Memory::ACE_OPEN); + ACE_SV_Semaphore_Simple sem (SEM_KEY_1, + ACE_SV_Semaphore_Simple::ACE_OPEN, 0, 2); + + char *s = (char *) shm_client.get_segment_ptr (); + + if (sem.acquire (0) < 0) + ACE_OS::perror ("client sem.acquire"), ACE_OS::exit (1); + + while (*s != '\0') + putchar (*s++); + + putchar ('\n'); + + if (sem.release (1) < 0) + ACE_OS::perror ("client sem.release"), ACE_OS::exit (1); + + return 0; +} + diff --git a/examples/System_V_IPC/SV_Semaphores/Semaphore_Server.cpp b/examples/System_V_IPC/SV_Semaphores/Semaphore_Server.cpp new file mode 100644 index 00000000000..721bb07171e --- /dev/null +++ b/examples/System_V_IPC/SV_Semaphores/Semaphore_Server.cpp @@ -0,0 +1,41 @@ +#include "ace/Log_Msg.h" +// @(#)Semaphore_Server.cpp 1.1 10/18/96 + +#include "ace/SV_Shared_Memory.h" +#include "ace/SV_Semaphore_Simple.h" +#include "ace/Signal.h" +#include "Semaphore_Test.h" + +ACE_SV_Shared_Memory shm_server (SHM_KEY, SHMSZ, ACE_SV_Shared_Memory::ACE_CREATE); +ACE_SV_Semaphore_Simple sem (SEM_KEY_1, ACE_SV_Semaphore_Simple::ACE_CREATE, 0, 2); + +static void +cleanup (int = 0) +{ + if (shm_server.remove () < 0 || sem.remove () < 0) + ACE_ERROR ((LM_ERROR, "%p\n%a", "remove", 1)); + ACE_OS::exit (0); +} + +int +main (void) +{ + ACE_Sig_Action sig ((ACE_SignalHandler) cleanup, SIGINT); + + char *s = (char *) shm_server.get_segment_ptr (); + + for (char c = 'a'; c <= 'z'; c++) + *s++ = c; + + *s = '\0'; + + if (sem.release (0) < 0) + ESD ("server sem.release", done); + + if (sem.acquire (1) < 0) + ESD ("server sem.acquire", done); + +done: + cleanup (); + return 0; +} diff --git a/examples/System_V_IPC/SV_Semaphores/Semaphore_Test.h b/examples/System_V_IPC/SV_Semaphores/Semaphore_Test.h new file mode 100644 index 00000000000..07bc3e9ecec --- /dev/null +++ b/examples/System_V_IPC/SV_Semaphores/Semaphore_Test.h @@ -0,0 +1,11 @@ +/* -*- C++ -*- */ +// @(#)Semaphore_Test.h 1.1 10/18/96 + +#include "ace/Log_Msg.h" + +#define SHMSZ 27 +#define SEM_KEY_1 2345 +#define SEM_KEY_2 4321 +#define SHM_KEY 5678 + +#define ESD(MSG,LABEL) do { ACE_ERROR ((LM_ERROR, MSG)); goto LABEL; } while (0) diff --git a/examples/System_V_IPC/SV_Semaphores/Semaphores.cpp b/examples/System_V_IPC/SV_Semaphores/Semaphores.cpp new file mode 100644 index 00000000000..923bd142cc3 --- /dev/null +++ b/examples/System_V_IPC/SV_Semaphores/Semaphores.cpp @@ -0,0 +1,94 @@ +// Illustrates the use of the Semaphore_Complex class. Note that it +// @(#)Semaphores.cpp 1.1 10/18/96 + +// doesn't matter whether the parent or the child creates the +// semaphore since Semaphore_Complex will correctly serialize the +// intialization of the mutex and synch objects. +#include "ace/Malloc.h" +#include "ace/SV_Semaphore_Complex.h" +#include "Semaphore_Test.h" + +ACE_Malloc allocator; +ACE_SV_Semaphore_Complex *mutex = 0; +ACE_SV_Semaphore_Complex *synch = 0; + +/* Pointer to memory shared by both the client and server. */ +static char *shm; + +static int +do_parent (void) +{ + char *s = shm; + + mutex = new ACE_SV_Semaphore_Complex (SEM_KEY_1, ACE_SV_Semaphore_Complex::ACE_CREATE, 0); + synch = new ACE_SV_Semaphore_Complex (SEM_KEY_2, ACE_SV_Semaphore_Complex::ACE_CREATE, 0); + + for (char c = 'a'; c <= 'z'; c++) + *s++ = c; + + *s = '\0'; + + if (mutex->release () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p", "server mutex.release"), 1); + + if (synch->acquire () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p", "server synch.acquire"), 1); + return 0; +} + +static int +do_child (void) +{ + mutex = new ACE_SV_Semaphore_Complex (SEM_KEY_1, ACE_SV_Semaphore_Complex::ACE_CREATE, 0); + synch = new ACE_SV_Semaphore_Complex (SEM_KEY_2, ACE_SV_Semaphore_Complex::ACE_CREATE, 0); + + while (mutex->tryacquire () == -1) + if (errno == EAGAIN) + ACE_DEBUG ((LM_DEBUG, "spinning in client!\n")); + else + ACE_ERROR_RETURN ((LM_ERROR, "client mutex.tryacquire"), 1); + + for (char *s = (char *) shm; *s != '\0'; s++) + putchar (*s); + + putchar ('\n'); + + if (synch->release () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "client synch.release"), 1); + return 0; +} + +int +main (void) +{ + shm = (char *) allocator.malloc (27); + + switch (ACE_OS::fork ()) + { + case -1: + ACE_ERROR_RETURN ((LM_ERROR, "fork failed\n"), -1); + /* NOTREACHED */ + case 0: + return do_child (); + default: + { + int result = do_parent (); + + if (wait (0) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "wait"), -1); + + allocator.remove (); + + if (mutex->remove () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "mutex.remove"), -1); + else if (synch->remove () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "synch.remove"), -1); + return result; + } + } +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Malloc; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ + diff --git a/examples/System_V_IPC/SV_Shared_Memory/Makefile b/examples/System_V_IPC/SV_Shared_Memory/Makefile new file mode 100644 index 00000000000..a950c681250 --- /dev/null +++ b/examples/System_V_IPC/SV_Shared_Memory/Makefile @@ -0,0 +1,54 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for tests of the SV_Shared_Memory wrapper +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = SV_Shared_Memory_Test + +LSRC = $(addsuffix .cpp,$(BIN)) + +LDLIBS = + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +INSTALL = + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/SV_Shared_Memory_Test.o .shobj/SV_Shared_Memory_Test.so: SV_Shared_Memory_Test.cpp \ + $(WRAPPER_ROOT)/ace/SV_Shared_Memory.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + SV_Shared_Memory_Test.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/System_V_IPC/SV_Shared_Memory/SV_Shared_Memory_Test.cpp b/examples/System_V_IPC/SV_Shared_Memory/SV_Shared_Memory_Test.cpp new file mode 100644 index 00000000000..3b1fa48ceb5 --- /dev/null +++ b/examples/System_V_IPC/SV_Shared_Memory/SV_Shared_Memory_Test.cpp @@ -0,0 +1,60 @@ +#include "ace/SV_Shared_Memory.h" +// @(#)SV_Shared_Memory_Test.cpp 1.1 10/18/96 + +#include "SV_Shared_Memory_Test.h" + +static void +client (void) +{ + ACE_SV_Shared_Memory shm_client; + + if (shm_client.open_and_attach (SHM_KEY, SHMSZ) == -1) + ACE_OS::perror ("open"), ACE_OS::exit (1); + + for (char *s = (char *) shm_client.get_segment_ptr (); *s != '\0'; s++) + putchar (*s); + + putchar ('\n'); + *(char *) shm_client.get_segment_ptr () = '*'; + ACE_OS::exit (0); +} + +static void +server (void) +{ + ACE_SV_Shared_Memory shm_server; + + if (shm_server.open_and_attach (SHM_KEY, SHMSZ, ACE_SV_Shared_Memory::ACE_CREATE) == -1) + ACE_OS::perror ("open"), ACE_OS::exit (1); + + char *s = (char *) shm_server.get_segment_ptr (); + + for (char c = 'a'; c <= 'z'; c++) + *s++ = c; + + *s = '\0'; + + for (s = (char *) shm_server.get_segment_ptr (); *s != '*'; ) + ACE_OS::sleep (1); + + if (shm_server.remove () < 0) + ACE_OS::perror ("remove"), ACE_OS::exit (1); + ACE_OS::exit (0); +} + +int +main (int, char *argv[]) +{ + switch (ACE_OS::fork ()) + { + case -1: + ACE_OS::perror (argv[0]), ACE_OS::exit (1); + case 0: + ACE_OS::sleep (1); + client (); + default: + server (); + } + return 0; +} + diff --git a/examples/System_V_IPC/SV_Shared_Memory/SV_Shared_Memory_Test.h b/examples/System_V_IPC/SV_Shared_Memory/SV_Shared_Memory_Test.h new file mode 100644 index 00000000000..795e9180f65 --- /dev/null +++ b/examples/System_V_IPC/SV_Shared_Memory/SV_Shared_Memory_Test.h @@ -0,0 +1,7 @@ +/* -*- C++ -*- */ +// @(#)SV_Shared_Memory_Test.h 1.1 10/18/96 + +#include "ace/OS.h" +#define SHMSZ 27 +#define SEM_KEY 1234 +#define SHM_KEY 5678 diff --git a/examples/Threads/Makefile b/examples/Threads/Makefile new file mode 100644 index 00000000000..a518bf6c293 --- /dev/null +++ b/examples/Threads/Makefile @@ -0,0 +1,1004 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for tests of the ACE thread wrappers +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = test_auto_event \ + test_barrier1 \ + test_barrier2 \ + test_future1 \ + test_future2 \ + test_manual_event \ + test_process_mutex \ + test_process_semaphore \ + test_reader_writer \ + test_recursive_mutex \ + test_task \ + test_task_two \ + test_task_three \ + test_thread_manager \ + test_thread_pool \ + test_thread_specific \ + test_tss \ + test_token + +LSRC = $(addsuffix .cpp,$(BIN)) +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +LIBS += -lm +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/test_barrier1.o .shobj/test_barrier1.so: test_barrier1.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h +.obj/test_barrier2.o .shobj/test_barrier2.so: test_barrier2.cpp \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i +.obj/test_future1.o .shobj/test_future1.so: test_future1.cpp \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Future.h \ + $(WRAPPER_ROOT)/ace/Future.cpp \ + $(WRAPPER_ROOT)/ace/Method_Object.h \ + $(WRAPPER_ROOT)/ace/Activation_Queue.h \ + $(WRAPPER_ROOT)/ace/Auto_Ptr.h \ + $(WRAPPER_ROOT)/ace/Auto_Ptr.cpp \ + $(WRAPPER_ROOT)/ace/Auto_Ptr.i +.obj/test_future2.o .shobj/test_future2.so: test_future2.cpp \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Future.h \ + $(WRAPPER_ROOT)/ace/Future.cpp \ + $(WRAPPER_ROOT)/ace/Method_Object.h \ + $(WRAPPER_ROOT)/ace/Activation_Queue.h \ + $(WRAPPER_ROOT)/ace/Auto_Ptr.h \ + $(WRAPPER_ROOT)/ace/Auto_Ptr.cpp \ + $(WRAPPER_ROOT)/ace/Auto_Ptr.i +.obj/test_process_mutex.o .shobj/test_process_mutex.so: test_process_mutex.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i +.obj/test_process_semaphore.o .shobj/test_process_semaphore.so: test_process_semaphore.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i +.obj/test_reader_writer.o .shobj/test_reader_writer.so: test_reader_writer.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/test_recursive_mutex.o .shobj/test_recursive_mutex.so: test_recursive_mutex.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/test_task.o .shobj/test_task.so: test_task.cpp \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i +.obj/test_task_two.o .shobj/test_task_two.so: test_task_two.cpp \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i +.obj/test_task_three.o .shobj/test_task_three.so: test_task_three.cpp \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Task.i +.obj/test_thread_manager.o .shobj/test_thread_manager.so: test_thread_manager.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h +.obj/test_thread_pool.o .shobj/test_thread_pool.so: test_thread_pool.cpp \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i +.obj/test_thread_specific.o .shobj/test_thread_specific.so: test_thread_specific.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h +.obj/test_tss.o .shobj/test_tss.so: test_tss.cpp \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i +.obj/test_token.o .shobj/test_token.so: test_token.cpp \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.i + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/examples/Threads/test_auto_event.cpp b/examples/Threads/test_auto_event.cpp new file mode 100644 index 00000000000..24de2e9d230 --- /dev/null +++ b/examples/Threads/test_auto_event.cpp @@ -0,0 +1,106 @@ +// This test shows the use of an ACE_Auto_Event as a signaling +// @(#)test_auto_event.cpp 1.1 10/18/96 + +// mechanism. Two threads are created (one a reader, the other a +// writer). The reader waits till the writer has completed +// calculations. Upon waking up the reader prints the data calculated +// by the writer. The writer thread calculates the value and signals +// the reader when the calculation completes. + +#include "ace/Service_Config.h" +#include "ace/Synch.h" +#include "ace/Singleton.h" +#include "ace/Thread_Manager.h" + +// Shared event between reader and writer. The ACE_Thread_Mutex is +// necessary to make sure that only one ACE_Auto_Event is created. +// The default constructor for ACE_Auto_Event sets it initially into +// the non-signaled state. + +typedef ACE_Singleton EVENT; + +// work time for writer +static int work_time; + +// Reader thread. +static void * +reader (void *arg) +{ + // Shared data via a reference. + int& data = *(int *) arg; + + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + + // Wait for writer to complete. + + ACE_DEBUG ((LM_DEBUG, "(%t) reader: waiting...... \n")); + + if (EVENT::instance ()->wait () == -1) + { + ACE_ERROR ((LM_ERROR, "thread wait failed")); + ACE_OS::exit (0); + } + + // Read shared data. + ACE_DEBUG ((LM_DEBUG, "(%t) reader: value of data is: %d \n", data)); + + return 0; +} + +// Writer thread. +static void * +writer (void *arg) +{ + int result; + + int& data = *(int *) arg; + + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + + // Calculate (work). + ACE_DEBUG ((LM_DEBUG, "(%t) writer: working for %d secs\n", work_time)); + ACE_OS::sleep (work_time); + + // Write shared data. + data = 42; + + // Wake up reader. + ACE_DEBUG ((LM_DEBUG, "(%t) writer: calculation complete, waking reader\n")); + + if (EVENT::instance ()->signal () == -1) + { + ACE_ERROR ((LM_ERROR, "thread wait failed")); + ACE_OS::exit (0); + } + + return 0; +} + +int +main (int argc, char **argv) +{ + // Shared data: set by writer, read by reader. + int data; + + // Work time for writer. + work_time = argc == 2 ? atoi (argv[1]) : 5; + + // threads manager + ACE_Thread_Manager& tm = *ACE_Service_Config::thr_mgr (); + + // Create reader thread. + if (tm.spawn (reader, (void *) &data) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "thread create for reader failed"), -1); + + // Create writer thread. + if (tm.spawn (writer, (void *) &data) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "thread create for writer failed"), -1); + + // Wait for both. + if (tm.wait () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "thread wait failed"), -1); + else + ACE_DEBUG ((LM_ERROR, "graceful exit\n")); + + return 0; +} diff --git a/examples/Threads/test_barrier1.cpp b/examples/Threads/test_barrier1.cpp new file mode 100644 index 00000000000..2bd0b916b31 --- /dev/null +++ b/examples/Threads/test_barrier1.cpp @@ -0,0 +1,84 @@ +// This test program illustrates how the ACE barrier synchronization +// @(#)test_barrier1.cpp 1.1 10/18/96 + +// mechanisms work. + +#include "ace/Log_Msg.h" +#include "ace/Synch.h" +#include "ace/Thread_Manager.h" +#include "ace/Service_Config.h" + +#if defined (ACE_HAS_THREADS) + +struct Tester_Args + // = TITLE + // These arguments are passed into each test thread. +{ + Tester_Args (ACE_Barrier &tb, int i) + : tester_barrier_ (tb), + n_iterations_ (i) {} + + ACE_Barrier &tester_barrier_; + // Reference to the tester barrier. This controls each miteration of + // the tester function running in every thread. + + int n_iterations_; + // Number of iterations to run. +}; + +// Iterate time printing off a message and "waiting" +// for all other threads to complete this iteration. + +static void * +tester (Tester_Args *args) +{ + // Keeps track of thread exit. + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + + for (int iterations = 1; + iterations <= args->n_iterations_; + iterations++) + { + ACE_DEBUG ((LM_DEBUG, "(%t) in iteration %d\n", iterations)); + + // Block until all other threads have waited, then continue. + args->tester_barrier_.wait (); + } + + return 0; +} + +// Default number of threads to spawn. +static const int DEFAULT_ITERATIONS = 5; + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config daemon (argv[0]); + + int n_threads = argc > 1 ? ACE_OS::atoi (argv[1]) : ACE_DEFAULT_THREADS; + int n_iterations = argc > 2 ? ACE_OS::atoi (argv[2]) : DEFAULT_ITERATIONS; + + ACE_Barrier tester_barrier (n_threads); + + Tester_Args args (tester_barrier, n_iterations); + + if (ACE_Service_Config::thr_mgr ()->spawn_n + (n_threads, ACE_THR_FUNC (tester), + (void *) &args, THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn_n"), 1); + + // Wait for all the threads to reach their exit point. + ACE_Service_Config::thr_mgr ()->wait (); + + ACE_DEBUG ((LM_DEBUG, "(%t) done\n")); + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/Threads/test_barrier2.cpp b/examples/Threads/test_barrier2.cpp new file mode 100644 index 00000000000..11cb8e1da0b --- /dev/null +++ b/examples/Threads/test_barrier2.cpp @@ -0,0 +1,272 @@ +// generic_worker_task.cpp +// @(#)test_barrier2.cpp 1.1 10/18/96 + +// +// This test program illustrates how the ACE task workers/barrier +// synchronization mechanisms work in conjunction with the ACE_Task +// and the ACE_Thread_Manager. The manual flag not set simulates +// user input, if set input comes from stdin until RETURN only is +// entered which stops all workers via a message block of length +// 0. This is an alernative shutdown of workers compared to queue +// deactivate. The delay_put flag simulates a delay between the +// shutdown puts. All should work with this flag disabled! The +// BARRIER_TYPE is supposed to enable/disable barrier sync on each svc +// a worker has done. + +#include +#include "ace/Task.h" +#include "ace/Service_Config.h" +#include "ace/Log_Msg.h" + +#if defined (ACE_HAS_THREADS) + +#define BARRIER_TYPE ACE_Null_Barrier +//#define BARRIER_TYPE ACE_Barrier +//#ifdef delay_put +//#define manual + +template +class Worker_Task : public ACE_Task +{ +public: + + Worker_Task (ACE_Thread_Manager *thr_mgr, + int n_threads, + int inp_serialize = 1); + + virtual int Producer (void); + // produce input for workers + + virtual int input (ACE_Message_Block *mb); + // Fill one message block via a certain input strategy. + + virtual int output (ACE_Message_Block *mb); + // Forward one message block via a certain output strategy to the + // next task if any. + + virtual int service (ACE_Message_Block *mb, int iter); + // Perform one message block dependant service. + +private: + virtual int put (ACE_Message_Block *mb, ACE_Time_Value *tv=0); + + virtual int svc (void); + // Iterate time printing off a message and "waiting" + // for all other threads to complete this iteration. + + // = Not needed for this test. + virtual int open (void *) { return 0; } + virtual int close (u_long) {ACE_DEBUG ((LM_DEBUG,"(%t) in close of worker\n")); return 0; } + + int nt_; + // Number of worker threads to run. + int inp_serialize_; + + BARRIER barrier_; +}; + +template +Worker_Task::Worker_Task (ACE_Thread_Manager *thr_mgr, + int n_threads, + int inp_serialize) + : ACE_Task (thr_mgr), + barrier_ (n_threads) +{ + nt_ = n_threads; + // Create worker threads. + inp_serialize_ = inp_serialize; + + // Use the task's message queue for serialization (default) or run + // service in the context of the caller thread. + + if (nt_ > 0 && inp_serialize == 1) + if (this->activate (THR_NEW_LWP, n_threads) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "activate failed")); +} + + + +// Simply enqueue the Message_Block into the end of the queue. + +template int +Worker_Task::put (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + int result; + if (this->inp_serialize_) + result = this->putq (mb, tv); + else + { + static int iter = 0; + result = this->service (mb, iter++); + + if (this->output (mb) < 0) + ACE_DEBUG ((LM_DEBUG, "(%t) output not connected!\n")); + + delete mb; + } + return result; +} + +template int +Worker_Task::service (ACE_Message_Block *mb, int iter) +{ + int length = mb->length (); + + if (length > 0) + { + ACE_DEBUG ((LM_DEBUG,"(%t) in iteration %d len=%d text got:\n",iter,length)); + ACE_OS::write (ACE_STDOUT, mb->rd_ptr (), length); + ACE_DEBUG ((LM_DEBUG,"\n")); + } + return 0; +} + +// Iterate time printing off a message and "waiting" +// for all other threads to complete this iteration. + +template int +Worker_Task::svc (void) +{ + // Note that the ACE_Task::svc_run () method automatically adds us + // to the Thread_Manager when the thread begins. + + // Keep looping, reading a message out of the queue, until we get a + // message with a length == 0, which signals us to quit. + + for (int iter = 1; ;iter++) + { + ACE_Message_Block *mb = 0; + + int result = this->getq (mb); + + if (result == -1) + { + ACE_ERROR ((LM_ERROR, + "(%t) in iteration %d\n", "error waiting for message in iteration", iter)); + break; + } + + int length = mb->length (); + this->service (mb,iter); + + if (length == 0) + { + ACE_DEBUG ((LM_DEBUG, "(%t) in iteration %d got quit, exit!\n", iter)); + delete mb; + break; + } + + this->barrier_.wait (); + this->output (mb); + + delete mb; + } + + // Note that the ACE_Task::svc_run () method automatically removes + // us from the Thread_Manager when the thread exits. + + return 0; +} + +template int +Worker_Task::Producer (void) +{ + // Keep reading stdin, until we reach EOF. + + for (;;) + { + // Allocate a new message. + ACE_Message_Block *mb = new ACE_Message_Block (BUFSIZ); + + if (this->input (mb) == -1) + return -1; + } + + return 0; +} + +template int +Worker_Task::output (ACE_Message_Block *mb) +{ + return this->put_next (mb); +} + +template int +Worker_Task::input (ACE_Message_Block *mb) +{ + ACE_Message_Block *mb1; + +#ifndef manual + static int l= 0; + char str[]="kalle"; + strcpy (mb->rd_ptr (),str); + int n=strlen (str); + if (l==1000) + n=1; + l++; + if (l==0 || (l%100 == 0)) ACE_OS::sleep (5); + if (n <= 1) +#else + ACE_DEBUG ((LM_DEBUG,"(%t) press chars and enter to put a new message into task queue ...\n")); + if ((n = read (0, mb->rd_ptr (), mb->size ())) <= 1) +#endif // manual + { + // Send a shutdown message to the waiting threads and exit. + // cout << "\nvor loop, dump of task msg queue:\n" << endl; + // this->msg_queue ()->dump (); + for (int i=0;ilength (0); + if (this->put (mb1) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "put")); +#ifdef delay_put + ACE_OS::sleep (1); // this sleep helps to shutdown correctly -> was an error! +#endif delay_put + } + // cout << "\nnach loop, dump of task msg queue:\n" << endl; + // this->msg_queue ()->dump (); + return (-1); + } + else + { + // Send a normal message to the waiting threads and continue producing. + mb->wr_ptr (n); + if (this->put (mb) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "put")); + } + return 0; +} + +int +main (int argc, char *argv[]) +{ + int n_threads = argc > 1 ? ACE_OS::atoi (argv[1]) : ACE_DEFAULT_THREADS; + + ACE_DEBUG ((LM_DEBUG,"(%t) worker threads running=%d\n",n_threads)); + + + Worker_Task *worker_task = + new Worker_Task (ACE_Service_Config::thr_mgr (), + /*n_threads*/ 0,0); + + worker_task->Producer (); + + // Wait for all the threads to reach their exit point. + ACE_DEBUG ((LM_DEBUG,"(%t) waiting with thread manager ...\n")); + ACE_Service_Config::thr_mgr ()->wait (); + ACE_DEBUG ((LM_DEBUG,"(%t) delete worker task ...\n")); + + delete worker_task; + ACE_DEBUG ((LM_DEBUG,"(%t) done correct!\n")); + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/Threads/test_cancel.cpp b/examples/Threads/test_cancel.cpp new file mode 100644 index 00000000000..9d14e4684b0 --- /dev/null +++ b/examples/Threads/test_cancel.cpp @@ -0,0 +1,72 @@ +// Test out the cooperative thread cancellation mechanisms provided by +// @(#)test_cancel.cpp 1.1 10/18/96 + +// the ACE_Thread_Manager. + +#include "ace/Service_Config.h" +#include "ace/Thread_Manager.h" + +#if defined (ACE_HAS_THREADS) + +static void * +worker (int iterations) +{ + for (int i = 0; i < iterations; i++) + { + if ((i % 10) == 0 + && (ACE_Service_Config::thr_mgr ()->testcancel (ACE_Thread::self ()) != 0)) + { + ACE_DEBUG ((LM_DEBUG, "(%t) has been cancelled before iteration!\n", i)); + break; + } + } + + return 0; +} + +static const int DEFAULT_THREADS = ACE_DEFAULT_THREADS; +static const int DEFAULT_ITERATIONS = 100000; + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config daemon; + + daemon.open (argv[0]); + + int n_threads = argc > 1 ? ACE_OS::atoi (argv[1]) : DEFAULT_THREADS; + int n_iterations = argc > 2 ? ACE_OS::atoi (argv[2]) : DEFAULT_ITERATIONS; + + ACE_Thread_Manager *thr_mgr = ACE_Service_Config::thr_mgr (); + + int grp_id = thr_mgr->spawn_n (n_threads, ACE_THR_FUNC (worker), + (void *) n_iterations, + THR_NEW_LWP | THR_DETACHED); + + // Wait for 2 seconds and then suspend every thread in the group. + ACE_OS::sleep (2); + thr_mgr->suspend_grp (grp_id); + + // Wait for 2 more seconds and then resume every thread in the + // group. + ACE_OS::sleep (ACE_Time_Value (2)); + thr_mgr->resume_grp (grp_id); + + // Wait for 2 more seconds and then send a SIGINT to every thread in + // the group. + ACE_OS::sleep (ACE_Time_Value (2)); + thr_mgr->kill_grp (grp_id, SIGINT); + + // Wait for 2 more seconds and then exit (which should kill all the + // threads)! + ACE_OS::sleep (ACE_Time_Value (2)); + + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, "threads not supported on this platform\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/Threads/test_future1.cpp b/examples/Threads/test_future1.cpp new file mode 100644 index 00000000000..ad725ef5023 --- /dev/null +++ b/examples/Threads/test_future1.cpp @@ -0,0 +1,420 @@ +// ============================================================================ +// @(#)test_future1.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Test_Future.cpp +// +// = DESCRIPTION +// This example tests the ACE Future. +// +// = AUTHOR +// Andres Kruse and Douglas C. Schmidt +// +// +// ============================================================================ + +#include +#include "ace/Task.h" +#include "ace/Log_Msg.h" +#include "ace/Synch.h" +#include "ace/Message_Queue.h" +#include "ace/Future.h" +#include "ace/Method_Object.h" +#include "ace/Activation_Queue.h" +#include "ace/Auto_Ptr.h" + +#if defined (ACE_HAS_THREADS) + +typedef ACE_Atomic_Op ATOMIC_INT; + +// a counter for the tasks.. +static ATOMIC_INT task_count (0); + +// a counter for the futures.. +static ATOMIC_INT future_count (0); +static ATOMIC_INT future_no (0); + +// a counter for the capsules.. +static ATOMIC_INT capsule_count (0); +static ATOMIC_INT capsule_no (0); + +// a counter for the method objects... +static ATOMIC_INT methodobject_count (0); +static ATOMIC_INT methodobject_no (0); + +class Scheduler : public ACE_Task + // = TITLE + // Active Object Scheduler. +{ + friend class Method_ObjectWork; +public: + Scheduler (const char *, Scheduler * = 0); + ~Scheduler (void); + + virtual int open (void *args = 0); + virtual int close (u_long flags = 0); + virtual int put (ACE_Message_Block *mb, ACE_Time_Value *tv = 0); + virtual int svc (void); + + ACE_Future work (float param, int count); + ACE_Future name (void); + void end (void); + + float work_i (float, int); + const char *name_i (void); + +private: + const char *name_; + ACE_Activation_Queue activation_queue_; + Scheduler *scheduler_; + +}; + +class Method_Object_work : public ACE_Method_Object + // = TITLE + // Reification of the method. +{ +public: + Method_Object_work (Scheduler *, float, int, ACE_Future &); + ~Method_Object_work (void); + virtual int call (void); + +private: + Scheduler *scheduler_; + float param_; + int count_; + ACE_Future future_result_; +}; + +Method_Object_work::Method_Object_work (Scheduler* new_Scheduler, + float new_param, + int new_count, + ACE_Future &new_result) + : scheduler_ (new_Scheduler), + param_ (new_param), + count_ (new_count), + future_result_ (new_result) +{ + ACE_DEBUG ((LM_DEBUG, + "(%t) Method_Object_work created\n")); +} + +Method_Object_work::~Method_Object_work (void) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) Method_Object_work will be deleted.\n")); +} + + +int +Method_Object_work::call (void) +{ + return this->future_result_.set (this->scheduler_->work_i (this->param_, this->count_)); +} + +class Method_Object_name : public ACE_Method_Object + // = TITLE + // Reification of the method. +{ +public: + Method_Object_name (Scheduler *, ACE_Future &); + ~Method_Object_name (void); + virtual int call (void); + +private: + Scheduler *scheduler_; + ACE_Future future_result_; +}; + +Method_Object_name::Method_Object_name (Scheduler *new_scheduler, + ACE_Future &new_result) + : scheduler_ (new_scheduler), + future_result_ (new_result) +{ + ACE_DEBUG ((LM_DEBUG, + "(%t) Method_Object_name created\n")); +}; + +Method_Object_name::~Method_Object_name (void) +{ + ACE_DEBUG ((LM_DEBUG, + "(%t) Method_Object_name will be deleted.\n")); +} + +int +Method_Object_name::call (void) +{ + return future_result_.set (scheduler_->name_i ()); +} + +class Method_Object_end : public ACE_Method_Object + // = TITLE + // Reification of the method. +{ +public: + Method_Object_end (Scheduler *new_Scheduler): scheduler_ (new_Scheduler) {} + ~Method_Object_end (void) {} + virtual int call (void) { this->scheduler_->close (); return -1; } + +private: + Scheduler *scheduler_; +}; + +// constructor +Scheduler::Scheduler (const char *newname, Scheduler *new_Scheduler) +{ + ACE_NEW (this->name_, char[ACE_OS::strlen (newname) + 1]); + ACE_OS::strcpy ((char *) this->name_, newname); + this->scheduler_ = new_Scheduler; + ACE_DEBUG ((LM_DEBUG, "(%t) Scheduler %s created\n", this->name_)); +} + +// Destructor +Scheduler::~Scheduler (void) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) Scheduler %s will be destroyed\n", this->name_)); +} + +// open +int +Scheduler::open (void *args) +{ + task_count++; + ACE_DEBUG ((LM_DEBUG, "(%t) Scheduler %s open\n", this->name_)); + return this->activate (THR_BOUND); +} + +// close +int +Scheduler::close (u_long flags) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) Scheduler %s close\n", this->name_)); + task_count--; + return 0; +} + +// put... ?? +int +Scheduler::put (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + return 0; +} + +// service.. +int +Scheduler::svc (void) +{ + for (;;) + { + // Dequeue the next method object (we use an auto pointer in + // case an exception is thrown in the ). + auto_ptr mo (this->activation_queue_.dequeue ()); + + ACE_DEBUG ((LM_DEBUG, "(%t) calling method object\n")); + // Call it. + if (mo->call () == -1) + break; + // Destructor automatically deletes it. + } + + /* NOTREACHED */ + return 0; +} + +void +Scheduler::end (void) +{ + this->activation_queue_.enqueue (new Method_Object_end (this)); +} + + +// Here's where the Work takes place. +float +Scheduler::work_i (float param, + int count) +{ + float x = 0, y = 0; + + // @@ We should probably do something fun here, like compute the + // Fibonacci sequence or something. + + for (int j = 0; j < count; j++) + { + x = x + param; + y = y + ::sin (x); + } + + return y; +} + +const char * +Scheduler::name_i (void) +{ + char *the_name; + + the_name = new char[ACE_OS::strlen (this->name_) + 1]; + ACE_OS::strcpy (the_name, this->name_); + + return the_name; +} + +ACE_Future +Scheduler::name (void) +{ + if (this->scheduler_) + // Delegate to the Scheduler. + return this->scheduler_->name (); + else + { + ACE_Future new_future; + + // @@ What happens if new fails here? + this->activation_queue_.enqueue + (new Method_Object_name (this, new_future)); + + return new_future; + } +} + +ACE_Future +Scheduler::work (float newparam, int newcount) +{ + if (this->scheduler_) { + return this->scheduler_->work (newparam, newcount); + } + else { + ACE_Future new_future; + + this->activation_queue_.enqueue + (new Method_Object_work (this, newparam, newcount, new_future)); + return new_future; + } +} + +// @@ These values should be set by the command line options! + +// Total number of iterations to +static int n_iterations = 50000; + +// Total number of loops. +static int n_loops = 100; + +int +main (int argc, char *argv[]) +{ + Scheduler *andres, *peter, *helmut, *matias; + + // Create active objects.. + // @@ Should "open" be subsumed within the constructor of + // Scheduler()? + andres = new Scheduler ("andres"); + andres->open (); + peter = new Scheduler ("peter"); + peter->open (); + helmut = new Scheduler ("helmut"); + helmut->open (); + + // Matias passes all asynchronous method calls on to Andres... + matias = new Scheduler ("matias", andres); + matias->open (); + + for (int i = 0; i < n_loops; i++) + { + { + ACE_Future fresulta, fresultb, fresultc, fresultd, fresulte; + ACE_Future fname; + + ACE_DEBUG ((LM_DEBUG, "(%t) going to do a non-blocking call\n")); + + fresulta = andres->work (0.01, 100 + (n_iterations * (i % 2))); + fresultb = peter->work (0.01, 100 + (n_iterations * (i % 2))); + fresultc = helmut->work (0.01, 100 + (n_iterations * (i % 2))); + fresultd = matias->work (0.02, 100 + (n_iterations * (i % 2))); + fname = andres->name (); + + // see if the result is available... + if (fresulta.ready ()) + ACE_DEBUG ((LM_DEBUG, "(%t) wow.. work is ready.....\n")); + + ACE_DEBUG ((LM_DEBUG, "(%t) non-blocking call done... now blocking...\n")); + + // Save the result of fresulta. + + fresulte = fresulta; + + if (i % 3 == 0) + { + // Every 3rd time... disconnect the futures... + // but "fresulte" should still contain the result... + fresulta.cancel (10.0); + fresultb.cancel (20.0); + fresultc.cancel (30.0); + fresultd.cancel (40.0); + } + + float resulta = 0, resultb = 0, resultc = 0, resultd = 0, resulte = 0; + + fresulta.get (resulta); + fresultb.get (resultb); + fresultc.get (resultc); + fresultd.get (resultd); + fresulte.get (resulte); + + ACE_DEBUG ((LM_DEBUG, "(%t) result a %f\n", resulte)); + ACE_DEBUG ((LM_DEBUG, "(%t) result b %f\n", resulta)); + ACE_DEBUG ((LM_DEBUG, "(%t) result c %f\n", resultb)); + ACE_DEBUG ((LM_DEBUG, "(%t) result d %f\n", resultc)); + ACE_DEBUG ((LM_DEBUG, "(%t) result e %f\n", resultd)); + + const char *name; + + fname.get (name); + + ACE_DEBUG ((LM_DEBUG, "(%t) name %s\n", name)); + + } + + ACE_DEBUG ((LM_DEBUG, + "(%t) task_count %d future_count %d capsule_count %d methodobject_count %d\n", + (u_long) task_count, + (u_long) future_count, + (u_long) capsule_count, + (u_long) methodobject_count)); + } + + // Close things down. + andres->end (); + peter->end (); + helmut->end (); + matias->end (); + + ACE_OS::sleep (2); + + ACE_DEBUG ((LM_DEBUG, + "(%t) task_count %d future_count %d capsule_count %d methodobject_count %d\n", + (u_long) task_count, + (u_long) future_count, + (u_long) capsule_count, + (u_long) methodobject_count)); + + ACE_DEBUG ((LM_DEBUG,"(%t) th' that's all folks!\n")); + + ACE_OS::sleep (5); + return 0; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Atomic_Op; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ + +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/Threads/test_future2.cpp b/examples/Threads/test_future2.cpp new file mode 100644 index 00000000000..f565fbeb725 --- /dev/null +++ b/examples/Threads/test_future2.cpp @@ -0,0 +1,524 @@ +// ============================================================================ +// @(#)test_future2.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Test_Future.cpp +// +// = DESCRIPTION +// This example tests the ACE Future. +// +// = AUTHOR +// Andres Kruse and Douglas C. Schmidt +// +// +// Modification History +// Aug. 96; A.Kruse; dev. +// Aug. 96; D.Schmidt; complete workover +// 08/27/96; A.Kruse; - the friends of Scheduler are "Method_Object_name" +// and "Method_Object_work". +// - make the methods "work_i" and "name_i" private +// 09/2/96; D.Schmidt; Integrate with new ACE_Future API and rearrange +// the tests so they are more modular. +// ============================================================================ + +#include +#include "ace/Task.h" +#include "ace/Log_Msg.h" +#include "ace/Synch.h" +#include "ace/Message_Queue.h" +#include "ace/Future.h" +#include "ace/Method_Object.h" +#include "ace/Activation_Queue.h" +#include "ace/Auto_Ptr.h" + +#if defined (ACE_HAS_THREADS) + +typedef ACE_Atomic_Op ATOMIC_INT; + +// a counter for the tasks.. +static ATOMIC_INT scheduler_open_count (0); + +// forward declarations +class Method_Object_work; +class Method_Object_name; + +class Scheduler : public ACE_Task + // = TITLE + // Active Object Scheduler. +{ + // Every method object has to be able to access the private methods. + + friend class Method_Object_work; + friend class Method_Object_name; + friend class Method_Object_end; +public: + + Scheduler (const char *, Scheduler * = 0); + ~Scheduler (void); + + virtual int open (void *args = 0); + // The method that is used to start the active object. + + // = Here are the methods exported by the class. They return an + // . + ACE_Future work (float param, int count); + ACE_Future name (void); + void end (void); + +private: + virtual int close (u_long flags = 0); + // Should not be accessible from outside... (use end () instead). + + virtual int put (ACE_Message_Block *mb, ACE_Time_Value *tv = 0) + { return 0; }; + // Doesn't have any use for this example. + + virtual int svc (void); + // Here the actual servicing of all requests is happening.. + + // = Implementation methods. + float work_i (float, int); + char *name_i (void); + + const char *name_; + ACE_Activation_Queue activation_queue_; + Scheduler *scheduler_; +}; + +class Method_Object_work : public ACE_Method_Object + // = TITLE + // Reification of the method. +{ +public: + Method_Object_work (Scheduler *, float, int, ACE_Future &); + ~Method_Object_work (void); + virtual int call (void); + +private: + Scheduler *scheduler_; + float param_; + int count_; + ACE_Future future_result_; +}; + +Method_Object_work::Method_Object_work (Scheduler* new_Scheduler, + float new_param, + int new_count, + ACE_Future &new_result) + : scheduler_ (new_Scheduler), + param_ (new_param), + count_ (new_count), + future_result_ (new_result) +{ +} + +Method_Object_work::~Method_Object_work (void) +{ +} + +int +Method_Object_work::call (void) +{ + return this->future_result_.set (this->scheduler_->work_i (this->param_, this->count_)); +} + +class Method_Object_name : public ACE_Method_Object + // = TITLE + // Reification of the method. +{ +public: + Method_Object_name (Scheduler *, ACE_Future &); + ~Method_Object_name (void); + virtual int call (void); + +private: + Scheduler *scheduler_; + ACE_Future future_result_; +}; + + +Method_Object_name::Method_Object_name (Scheduler *new_scheduler, + ACE_Future &new_result) + : scheduler_ (new_scheduler), + future_result_ (new_result) +{ + ACE_DEBUG ((LM_DEBUG, + " (%t) Method_Object_name created\n")); +}; + +Method_Object_name::~Method_Object_name (void) +{ + ACE_DEBUG ((LM_DEBUG, + " (%t) Method_Object_name will be deleted.\n")); +} + +int +Method_Object_name::call (void) +{ + return future_result_.set (scheduler_->name_i ()); +} + +class Method_Object_end : public ACE_Method_Object + // = TITLE + // Reification of the method. +{ +public: + Method_Object_end (Scheduler *new_Scheduler): scheduler_ (new_Scheduler) {} + ~Method_Object_end (void) {} + virtual int call (void) { this->scheduler_->close (); return -1; } + +private: + Scheduler *scheduler_; +}; + +// constructor +Scheduler::Scheduler (const char *newname, Scheduler *new_Scheduler) +{ + ACE_NEW (this->name_, char[ACE_OS::strlen (newname) + 1]); + ACE_OS::strcpy ((char *) this->name_, newname); + this->scheduler_ = new_Scheduler; + ACE_DEBUG ((LM_DEBUG, " (%t) Scheduler %s created\n", this->name_)); +} + +// Destructor +Scheduler::~Scheduler (void) +{ + ACE_DEBUG ((LM_DEBUG, " (%t) Scheduler %s will be destroyed\n", this->name_)); +} + +int +Scheduler::open (void *args) +{ + scheduler_open_count++; + ACE_DEBUG ((LM_DEBUG, " (%t) Scheduler %s open\n", this->name_)); + return this->activate (THR_BOUND); +} + +int +Scheduler::close (u_long flags) +{ + ACE_DEBUG ((LM_DEBUG, " (%t) Scheduler %s close\n", this->name_)); + scheduler_open_count--; + return 0; +} + +int +Scheduler::svc (void) +{ + // Main event loop for this active object. + for (;;) + { + // Dequeue the next method object (we use an auto pointer in + // case an exception is thrown in the ). + auto_ptr mo (this->activation_queue_.dequeue ()); + + ACE_DEBUG ((LM_DEBUG, " (%t) calling method object\n")); + // Call it. + if (mo->call () == -1) + break; + // Smart pointer destructor automatically deletes mo. + } + + /* NOTREACHED */ + return 0; +} + +void +Scheduler::end (void) +{ + this->activation_queue_.enqueue (new Method_Object_end (this)); +} + +// Here's where the Work takes place. +float +Scheduler::work_i (float param, + int count) +{ + float x = 0, y = 0; + + for (int j = 0; j < count; j++) + { + x = x + param; + y = y + ::sin (x); + } + + return y; +} + +char * +Scheduler::name_i (void) +{ + char *the_name; + + the_name = new char[ACE_OS::strlen (this->name_) + 1]; + ACE_OS::strcpy (the_name, this->name_); + + return the_name; +} + +ACE_Future +Scheduler::name (void) +{ + if (this->scheduler_) + // Delegate to the other scheduler + return this->scheduler_->name (); + else + { + ACE_Future new_future; + + if (this->thr_count () == 0) + { + // This scheduler is inactive... so we execute the user + // request right away... + + auto_ptr mo (new Method_Object_name (this, new_future)); + + mo->call (); + // Smart pointer destructor automatically deletes mo. + } + else + // @@ What happens if new fails here? + this->activation_queue_.enqueue + (new Method_Object_name (this, new_future)); + + return new_future; + } +} + +ACE_Future +Scheduler::work (float newparam, int newcount) +{ + if (this->scheduler_) + return this->scheduler_->work (newparam, newcount); + else + { + ACE_Future new_future; + + if (this->thr_count () == 0) + { + auto_ptr mo + (new Method_Object_work (this, newparam, newcount, new_future)); + mo->call (); + // Smart pointer destructor automatically deletes it. + } + else + this->activation_queue_.enqueue + (new Method_Object_work (this, newparam, newcount, new_future)); + + return new_future; + } +} + +static int +determine_iterations (void) +{ + int n_iterations; + + ACE_DEBUG ((LM_DEBUG," (%t) determining the number of iterations...\n")); + Scheduler *worker_a = new Scheduler ("worker A"); + + ACE_Time_Value tstart (ACE_OS::gettimeofday ()); + ACE_Time_Value tend (ACE_OS::gettimeofday ()); + + // Determine the number of iterations... we want so many that the + // work () takes about 1 second... + + for (n_iterations = 1; + (tend.sec () - tstart.sec ()) < 1; + n_iterations *= 2) + { + tstart = ACE_OS::gettimeofday (); + + worker_a->work (0.1, n_iterations); + + tend = ACE_OS::gettimeofday (); + } + + ACE_DEBUG ((LM_DEBUG," (%t) n_iterations %d\n", + (u_long) n_iterations)); + + worker_a->end (); + // @@ Can we safely delete worker_a here? + return n_iterations; +} + +static void +test_active_object (int n_iterations) +{ + ACE_DEBUG ((LM_DEBUG," (%t) testing active object pattern...\n")); + // A simple example for the use of the active object pattern and + // futures to return values from an active object. + + Scheduler *worker_a = new Scheduler ("worker A"); + Scheduler *worker_b = new Scheduler ("worker B"); + + // Have worker_c delegate his work to worker_a. + Scheduler *worker_c = new Scheduler ("worker C", worker_a); + + // loop 0: + // test the Schedulers when they are not active. + // now the method objects will be created but since + // there is no active thread they will also be + // immediately executed, in the "main" thread. + // loop 1: + // do the same test but with the schedulers + // activated + for (int i = 0; i < 2; i++) + { + if (i == 1) + { + worker_a->open (); + worker_b->open (); + worker_c->open (); + } + + ACE_Future fresulta = worker_a->work (0.01, n_iterations); + ACE_Future fresultb = worker_b->work (0.02, n_iterations); + ACE_Future fresultc = worker_c->work (0.03, n_iterations); + + if (i == 0) + { + if (!fresulta.ready ()) + ACE_DEBUG ((LM_DEBUG," (%t) ERROR: worker A is should be ready!!!\n")); + if (!fresultb.ready ()) + ACE_DEBUG ((LM_DEBUG," (%t) ERROR: worker B is should be ready!!!\n")); + if (!fresultc.ready ()) + ACE_DEBUG ((LM_DEBUG," (%t) ERROR: worker C is should be ready!!!\n")); + } + + // When the workers are active we will block here until the + // results are available. + + float resulta = fresulta; + float resultb = fresultb; + float resultc = fresultc; + + ACE_Future fnamea = worker_a->name (); + ACE_Future fnameb = worker_b->name (); + ACE_Future fnamec = worker_c->name (); + + char *namea = fnamea; + char *nameb = fnameb; + char *namec = fnamec; + + ACE_DEBUG ((LM_DEBUG, " (%t) result from %s %f\n", + namea, resulta)); + ACE_DEBUG ((LM_DEBUG, " (%t) result from %s %f\n", + nameb, resultb)); + ACE_DEBUG ((LM_DEBUG, " (%t) result from %s %f\n", + namec, resultc)); + } + + ACE_DEBUG ((LM_DEBUG, " (%t) scheduler_open_count %d before end ()\n", + (u_long) scheduler_open_count)); + + worker_a->end (); + worker_b->end (); + worker_c->end (); + + ACE_DEBUG ((LM_DEBUG, " (%t) scheduler_open_count %d immediately after end ()\n", + (u_long) scheduler_open_count)); + + ACE_OS::sleep (2); + + ACE_DEBUG ((LM_DEBUG, " (%t) scheduler_open_count %d after waiting\n", + (u_long) scheduler_open_count)); + // @@ Can we safely delete worker_a, worker_b, and worker_c? +} + +static void +test_cancellation (int n_iterations) +{ + ACE_DEBUG ((LM_DEBUG," (%t) testing cancellation of a future...\n")); + + // Now test the cancelling a future. + + Scheduler *worker_a = new Scheduler ("worker A"); + worker_a->open (); + + ACE_Future fresulta = worker_a->work (0.01, n_iterations); + + // save the result by copying the future + ACE_Future fresultb = fresulta; + + // now we cancel the first future.. but the + // calculation will still go on... + fresulta.cancel (10.0); + + if (!fresulta.ready ()) + ACE_DEBUG ((LM_DEBUG," (%t) ERROR: future A is should be ready!!!\n")); + + float resulta = fresulta; + + ACE_DEBUG ((LM_DEBUG, " (%t) cancelled result %f\n", resulta)); + + if (resulta != 10.0) + ACE_DEBUG ((LM_DEBUG, " (%t) cancelled result should be 10.0!!\n", resulta)); + + resulta = fresultb; + + ACE_DEBUG ((LM_DEBUG, " (%t) true result %f\n", resulta)); + + worker_a->end (); + // @@ Can we safely delete worker_a here? +} + +static void +test_timeout (int n_iterations) +{ + ACE_DEBUG ((LM_DEBUG," (%t) testing timeout on waiting for the result...\n")); + Scheduler *worker_a = new Scheduler ("worker A"); + worker_a->open (); + + ACE_Future fresulta = worker_a->work (0.01, 2 * n_iterations); + + // Should immediately return... and we should see an error... + ACE_Time_Value *delay = new ACE_Time_Value (1); + + float resulta; + fresulta.get (resulta, delay); + + if (fresulta.ready ()) + ACE_DEBUG ((LM_DEBUG," (%t) ERROR: future A is should not be ready!!!\n")); + else + ACE_DEBUG ((LM_DEBUG," (%t) timed out on future A\n")); + + // now we wait until we are done... + fresulta.get (resulta); + ACE_DEBUG ((LM_DEBUG, " (%t) result %f\n", resulta)); + + worker_a->end (); + // @@ Can we safely delete worker_a here? +} + +int +main (int argc, char *argv[]) +{ + int n_iterations = determine_iterations (); + + test_active_object (n_iterations); + test_cancellation (n_iterations); + test_timeout (n_iterations); + + ACE_DEBUG ((LM_DEBUG," (%t) that's all folks!\n")); + + ACE_OS::sleep (5); + return 0; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Atomic_Op; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ + +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/Threads/test_manual_event.cpp b/examples/Threads/test_manual_event.cpp new file mode 100644 index 00000000000..51612d1fcab --- /dev/null +++ b/examples/Threads/test_manual_event.cpp @@ -0,0 +1,99 @@ +// The test shows the use of an ACE_Manual_Event to create a +// @(#)test_manual_event.cpp 1.1 10/18/96 + +// Pseudo_Barrier. Multiple threads are created which do the +// following: +// +// 1. work +// 2. synch with other threads +// 3. more work +// +// ACE_Manual_Event is use to synch with other +// threads. ACE_Manual_Event::signal() is used for broadcasting. + +#include "ace/Service_Config.h" +#include "ace/Synch.h" +#include "ace/Thread_Manager.h" + +static ACE_Atomic_Op amount_of_work = (u_long) 0; + +class Pseudo_Barrier + // = TITLE + // A barrier class using ACE manual-reset events. + // + // = DESCRIPTION + // This is *not* a real barrier. + // Pseudo_Barrier is more like a ``one shot'' barrier. + // All waiters after the Nth waiter are allowed to go. + // The barrier does not reset after the Nth waiter. + // For an example of a real barrier, please see class ACE_Barrier. +{ +public: + Pseudo_Barrier (u_long count); + + int wait (void); + +private: + ACE_Atomic_Op counter_; + ACE_Manual_Event event_; +}; + +Pseudo_Barrier::Pseudo_Barrier (u_long count) + : counter_ (count) +{ +} + +int +Pseudo_Barrier::wait (void) +{ + if (--this->counter_ == 0) + return this->event_.signal (); + else + return this->event_.wait (); +} + +static void * +worker (void *arg) +{ + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + Pseudo_Barrier &barrier = *(Pseudo_Barrier *) arg; + + // work + ACE_DEBUG ((LM_DEBUG, "(%t) working (%d secs)\n", ++::amount_of_work)); + ACE_OS::sleep (::amount_of_work); + + // synch with everybody else + ACE_DEBUG ((LM_DEBUG, "(%t) waiting to synch with others \n")); + barrier.wait (); + + // more work + ACE_DEBUG ((LM_DEBUG, "(%t) more work (%d secs)\n", ++::amount_of_work)); + ACE_OS::sleep (amount_of_work); + + ACE_DEBUG ((LM_DEBUG, "(%t) dying \n")); + + return 0; +} + +int +main (int argc, char **argv) +{ + int n_threads = argc == 2 ? atoi (argv[1]) : 5; + + ACE_Thread_Manager &tm = *ACE_Service_Config::thr_mgr (); + + // synch object shared by all threads + Pseudo_Barrier barrier (n_threads); + + // create workers + if (tm.spawn_n (n_threads, worker, &barrier) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "thread creates for worker failed"), -1); + + // wait for all workers to exit + if (tm.wait () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "thread wait failed"), -1); + else + ACE_DEBUG ((LM_ERROR, "graceful exit\n")); + + return 0; +} diff --git a/examples/Threads/test_process_mutex.cpp b/examples/Threads/test_process_mutex.cpp new file mode 100644 index 00000000000..1978e3601f0 --- /dev/null +++ b/examples/Threads/test_process_mutex.cpp @@ -0,0 +1,66 @@ +// This program tests ACE_Process_Mutexes. To run it, open 3 +// @(#)test_process_mutex.cpp 1.1 10/18/96 + +// or 4 windows and run this program in each window... + +#include "ace/Log_Msg.h" +#include "ace/Synch.h" +#include "ace/Signal.h" + +#if defined (ACE_HAS_THREADS) + +static sig_atomic_t done; + +static void +handler (int) +{ + done = 1; +} + +int +main (int argc, char *argv[]) +{ + char *name = argc == 1 ? "hello" : argv[1]; + + ACE_Process_Mutex pm (name); + ACE_Sig_Action handle ((ACE_SignalHandler) handler, SIGINT); + + for (int i = 0; i < 100 && !done; i++) + { + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = acquiring\n")); + if (pm.acquire () == -1) + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = %p\n", "acquire failed")); + else + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = acquired\n")); + + ACE_OS::sleep (3); + + if (pm.release () == -1) + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = %p\n", "release failed")); + else + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = released\n")); + + if (pm.tryacquire () == -1) + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = %p\n", "tryacquire failed")); + else + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = tryacquire\n")); + + if (pm.release () == -1) + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = %p\n", "release failed")); + else + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = released\n")); + } + + if (argc > 2) + pm.remove (); + return 0; +} +#else +int +main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "ACE doesn't support support threads on this platform (yet)\n"), + -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/Threads/test_process_semaphore.cpp b/examples/Threads/test_process_semaphore.cpp new file mode 100644 index 00000000000..ed9831ab627 --- /dev/null +++ b/examples/Threads/test_process_semaphore.cpp @@ -0,0 +1,56 @@ +// This program tests ACE_Process_Semaphore. To run it, open 3 +// @(#)test_process_semaphore.cpp 1.1 10/18/96 + +// or 4 windows and run this program in each window... + +#include "ace/Log_Msg.h" +#include "ace/Synch.h" +#include "ace/Signal.h" + +static sig_atomic_t done; + +static void +handler (int) +{ + done = 1; +} + +int +main (int argc, char *argv[]) +{ + char *name = argc == 1 ? "hello" : argv[1]; + + ACE_Process_Semaphore pm (1, name); + + ACE_Sig_Action handle ((ACE_SignalHandler) handler, SIGINT); + + for (int i = 0; i < 100 && !done; i++) + { + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = acquiring\n")); + if (pm.acquire () == -1) + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = %p\n", "acquire failed")); + else + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = acquired\n")); + + ACE_OS::sleep (3); + + if (pm.release () == -1) + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = %p\n", "release failed")); + else + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = released\n")); + + if (pm.tryacquire () == -1) + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = %p\n", "tryacquire failed")); + else + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = tryacquire\n")); + + if (pm.release () == -1) + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = %p\n", "release failed")); + else + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = released\n")); + } + + if (argc > 2) + pm.remove (); + return 0; +} diff --git a/examples/Threads/test_reader_writer.cpp b/examples/Threads/test_reader_writer.cpp new file mode 100644 index 00000000000..33d3e982bc6 --- /dev/null +++ b/examples/Threads/test_reader_writer.cpp @@ -0,0 +1,187 @@ +// This test program verifies the functionality of the ACE_OS +// @(#)test_reader_writer.cpp 1.1 10/18/96 + +// implementation of readers/writer locks on Win32 and Posix pthreads. + +#include "ace/Log_Msg.h" +#include "ace/Synch.h" +#include "ace/Thread.h" +#include "ace/Thread_Manager.h" +#include "ace/Get_Opt.h" + +#if defined (ACE_HAS_THREADS) + +// Default number of iterations. +static size_t n_iterations = 1000; + +// Default number of loops. +static size_t n_loops = 100; + +// Default number of readers. +static size_t n_readers = 6; + +// Default number of writers. +static size_t n_writers = 2; + +// Thread id of last writer. +volatile static int shared_data; + +// Lock for shared_data. +static ACE_RW_Mutex rw_mutex; + +// Count of the number of readers and writers. +ACE_Atomic_Op current_readers, current_writers; + +// Thread manager +static ACE_Thread_Manager thr_mgr; + +// Explain usage and exit. +static void +print_usage_and_die (void) +{ + ACE_DEBUG ((LM_DEBUG, + "usage: %n [-r n_readers] [-w n_writers] [-n iteration_count]\n")); + ACE_OS::exit (1); +} + +// Parse the command-line arguments and set options. +static void +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, "r:w:n:l:"); + + int c; + + while ((c = get_opt ()) != -1) + switch (c) + { + case 'r': + n_readers = ACE_OS::atoi (get_opt.optarg); + break; + case 'w': + n_writers = ACE_OS::atoi (get_opt.optarg); + break; + case 'n': + n_iterations = ACE_OS::atoi (get_opt.optarg); + break; + case 'l': + n_loops = ACE_OS::atoi (get_opt.optarg); + break; + default: + print_usage_and_die (); + break; + } +} + +// Iterate each time checking that nobody modifies the data +// while we have a read lock. + +static void * +reader (void *) +{ + ACE_Thread_Control tc (&thr_mgr); + ACE_DEBUG ((LM_DEBUG, "(%t) reader starting\n")); + + for (int iterations = 1; iterations <= n_iterations; iterations++) + { + ACE_Read_Guard g(rw_mutex); + int n = ++current_readers; + //ACE_DEBUG ((LM_DEBUG, "(%t) I'm reader number %d\n", n)); + + if (current_writers > 0) + ACE_DEBUG ((LM_DEBUG, "(%t) writers found!!!\n")); + + int data = shared_data; + + for (int loop = 1; loop <= n_loops; loop++) + { + ACE_Thread::yield(); + if (shared_data != data) + ACE_DEBUG ((LM_DEBUG, + "(%t) somebody changed %d to %d\n", + data, shared_data)); + } + + --current_readers; + //ACE_DEBUG ((LM_DEBUG, "(%t) done with reading guarded data\n")); + + ACE_Thread::yield (); + } + return 0; +} + +// Iterate each time modifying the global data +// and checking that nobody steps on it while we can write it. + +static void * +writer (void *) +{ + ACE_Thread_Control tc (&thr_mgr); + ACE_DEBUG ((LM_DEBUG, "(%t) writer starting\n")); + + for (int iterations = 1; iterations <= n_iterations; iterations++) + { + ACE_Write_Guard g(rw_mutex); + + ++current_writers; + //ACE_DEBUG ((LM_DEBUG, "(%t) writing to guarded data\n")); + + if (current_writers > 1) + ACE_DEBUG ((LM_DEBUG, "(%t) other writers found!!!\n")); + + if (current_readers > 0) + ACE_DEBUG ((LM_DEBUG, "(%t) readers found!!!\n")); + + int self = (int) ACE_Thread::self (); + shared_data = self; + + for (int loop = 1; loop <= n_loops; loop++) + { + ACE_Thread::yield(); + if (shared_data != self) + ACE_DEBUG ((LM_DEBUG, "(%t) somebody wrote on my data %d\n", shared_data)); + } + + --current_writers; + + //ACE_DEBUG ((LM_DEBUG, "(%t) done with guarded data\n")); + ACE_Thread::yield (); + } + return 0; +} + +// Spawn off threads. + +int main (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0]); + parse_args (argc, argv); + + current_readers = 0; // Possibly already done + current_writers = 0; // Possibly already done + + ACE_DEBUG ((LM_DEBUG, "(%t) main thread starting\n")); + + if (thr_mgr.spawn_n (n_readers, reader, 0, THR_NEW_LWP) == -1 || + thr_mgr.spawn_n (n_writers, writer, 0, THR_NEW_LWP) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn_n"), 1); + + thr_mgr.wait (); + + ACE_DEBUG ((LM_DEBUG, "(%t) exiting main thread\n")); + return 0; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Atomic_Op; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ + +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ + diff --git a/examples/Threads/test_recursive_mutex.cpp b/examples/Threads/test_recursive_mutex.cpp new file mode 100644 index 00000000000..e1c0b8353e9 --- /dev/null +++ b/examples/Threads/test_recursive_mutex.cpp @@ -0,0 +1,110 @@ +// This test program verifies the functionality of the ACE_OS +// @(#)test_recursive_mutex.cpp 1.1 10/18/96 + +// implementation of recursive mutexes on Win32 and Posix pthreads. + +#include "ace/Log_Msg.h" + +#if defined (ACE_HAS_THREADS) + +#include "ace/Service_Config.h" +#include "ace/Get_Opt.h" +#include "ace/Synch.h" + +// Total number of iterations. +static size_t n_iterations = 1000; +static size_t n_threads = 4; + +// Explain usage and exit. +static void +print_usage_and_die (void) +{ + ACE_DEBUG ((LM_DEBUG, + "usage: %n [-t n_threads] [-n iteration_count]\n")); + ACE_OS::exit (1); +} + +// Parse the command-line arguments and set options. + +static void +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, "n:t:"); + + int c; + + while ((c = get_opt ()) != -1) + switch (c) + { + case 'n': + n_iterations = ACE_OS::atoi (get_opt.optarg); + break; + case 't': + n_threads = ACE_OS::atoi (get_opt.optarg); + break; + default: + print_usage_and_die (); + break; + } +} + +static void +recursive_worker (size_t nesting_level, + ACE_Recursive_Thread_Mutex *rm) +{ + if (nesting_level < n_iterations) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) = trying to acquire, nesting = %d, thread id = %u\n", + rm->get_nesting_level (), rm->get_thread_id ())); + { + // This illustrates the use of the ACE_Guard with an + // ACE_Recursive_Thread_Mutex. + ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, *rm); + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) = acquired, nesting = %d, thread id = %u\n", + rm->get_nesting_level (), rm->get_thread_id ())); + + recursive_worker (nesting_level + 1, rm); + } + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) = released, nesting = %d, thread id = %u\n", + rm->get_nesting_level (), rm->get_thread_id ())); + } +} + +static void * +worker (void *arg) +{ + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + + ACE_Recursive_Thread_Mutex *rm = (ACE_Recursive_Thread_Mutex *) arg; + + recursive_worker (0, rm); + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config daemon (argv[0]); + + parse_args (argc, argv); + ACE_Recursive_Thread_Mutex rm; + + ACE_Service_Config::thr_mgr ()->spawn_n (n_threads, + ACE_THR_FUNC (worker), + (void *) &rm); + + ACE_Service_Config::thr_mgr ()->wait (); + return 0; +} +#else +int +main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "ACE doesn't support support process mutexes on this platform (yet)\n"), + -1); +} +#endif /* ACE_WIN32 */ diff --git a/examples/Threads/test_task.cpp b/examples/Threads/test_task.cpp new file mode 100644 index 00000000000..d0e8e124ead --- /dev/null +++ b/examples/Threads/test_task.cpp @@ -0,0 +1,104 @@ +// This test program illustrates how the ACE barrier synchronization +// @(#)test_task.cpp 1.1 10/18/96 + +// mechanisms work in conjunction with the ACE_Task and the +// ACE_Thread_Manager. It is instructive to compare this with the +// test_barrier.cpp test to see how they differ. + +#include "ace/Task.h" +#include "ace/Service_Config.h" +#include "ace/Log_Msg.h" + +#if defined (ACE_HAS_THREADS) + +#include "ace/Task.h" + +class Barrier_Task : public ACE_Task +{ +public: + Barrier_Task (ACE_Thread_Manager *thr_mgr, + int n_threads, + int n_iterations); + + virtual int svc (void); + // Iterate time printing off a message and "waiting" + // for all other threads to complete this iteration. + +private: + ACE_Barrier barrier_; + // Reference to the tester barrier. This controls each + // iteration of the tester function running in every thread. + + int n_iterations_; + // Number of iterations to run. + + // = Not needed for this test. + virtual int open (void *) { return 0; } + virtual int close (u_long) { return 0; } + virtual int put (ACE_Message_Block *, ACE_Time_Value *) { return 0; } +}; + +Barrier_Task::Barrier_Task (ACE_Thread_Manager *thr_mgr, + int n_threads, + int n_iterations) + : ACE_Task (thr_mgr), + barrier_ (n_threads), + n_iterations_ (n_iterations) +{ + // Create worker threads. + if (this->activate (THR_NEW_LWP, n_threads) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "activate failed")); +} + +// Iterate time printing off a message and "waiting" +// for all other threads to complete this iteration. + +int +Barrier_Task::svc (void) +{ + // Note that the ACE_Task::svc_run() method automatically adds us to + // the Thread_Manager when the thread begins. + + for (int iterations = 1; + iterations <= this->n_iterations_; + iterations++) + { + ACE_DEBUG ((LM_DEBUG, "(%t) in iteration %d\n", iterations)); + + // Block until all other threads have waited, then continue. + this->barrier_.wait (); + } + + // Note that the ACE_Task::svc_run() method automatically removes us + // from the Thread_Manager when the thread exits. + + return 0; +} + +// Default number of threads to spawn. +static const int DEFAULT_ITERATIONS = 5; + +int +main (int argc, char *argv[]) +{ + int n_threads = argc > 1 ? ACE_OS::atoi (argv[1]) : ACE_DEFAULT_THREADS; + int n_iterations = argc > 2 ? ACE_OS::atoi (argv[2]) : DEFAULT_ITERATIONS; + + Barrier_Task barrier_task (ACE_Service_Config::thr_mgr (), + n_threads, + n_iterations); + + // Wait for all the threads to reach their exit point. + ACE_Service_Config::thr_mgr ()->wait (); + + ACE_DEBUG ((LM_DEBUG, "(%t) done\n")); + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/Threads/test_task_three.cpp b/examples/Threads/test_task_three.cpp new file mode 100644 index 00000000000..348d8b0b7d0 --- /dev/null +++ b/examples/Threads/test_task_three.cpp @@ -0,0 +1,229 @@ +// Exercise more tests for the ACE Tasks. This also shows off some +// @(#)test_task_three.cpp 1.1 10/18/96 + +// interesting uses of the ACE Log_Msg's ability to print to ostreams. +// BTW, make sure that you set the out_stream in *every* thread that +// you want to have write to the output file, i.e.: +// +// +// if (out_stream) +// { +// ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM); +// ACE_LOG_MSG->msg_ostream (out_stream); +// } + +#include +#include "ace/Reactor.h" +#include "ace/Service_Config.h" +#include "ace/Task.h" +#include "ace/Log_Msg.h" + +#if defined (ACE_HAS_THREADS) + +static ofstream *out_stream = 0; + +static const int NUM_INVOCATIONS = 100; +static const int TASK_COUNT = 130; + +class Test_Task : public ACE_Task +{ +public: + Test_Task (void); + ~Test_Task (void); + + virtual int open (void *args = 0); + virtual int close (u_long flags = 0); + virtual int put (ACE_Message_Block *, ACE_Time_Value *tv = 0); + virtual int svc (void); + + virtual int handle_input (ACE_HANDLE fd); + + ACE_Reactor *r_; + int handled_; + static int current_count_; + static int done_cnt_; +}; + +int Test_Task::current_count_ = 0; +int Test_Task::done_cnt_ = 0; + +static ACE_Thread_Mutex lock_; + +Test_Task::Test_Task (void) +{ + ACE_GUARD (ACE_Thread_Mutex, ace_mon, lock_); + + this->handled_ = 0; + Test_Task::current_count_++; + ACE_DEBUG ((LM_DEBUG, + "Test_Task constructed, current_count_ = %d\n", + Test_Task::current_count_)); +} + +Test_Task::~Test_Task (void) +{ + ACE_GUARD (ACE_Thread_Mutex, ace_mon, lock_); + + ACE_DEBUG ((LM_DEBUG, "Test_Task destroyed, current_count_ = %d\n", + Test_Task::current_count_)); +} + +int +Test_Task::open (void *args) +{ + r_ = (ACE_Reactor *) args; + return ACE_Task::activate (THR_NEW_LWP); +} + +int +Test_Task::close (u_long flags) +{ + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, lock_, -1); + + Test_Task::current_count_--; + ACE_DEBUG ((LM_DEBUG, "Test_Task::close () current_count_ = %d.\n", + Test_Task::current_count_)); + return 0; +} + +int +Test_Task::put (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + return 0; +} + +int +Test_Task::svc (void) +{ + // Every thread must register the same stream to write to file. + if (out_stream) + { + ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM); + ACE_LOG_MSG->msg_ostream (out_stream); + } + + for (int index = 0; index < NUM_INVOCATIONS; index++) + { + ACE_OS::thr_yield (); + + if (r_->notify (this, ACE_Event_Handler::READ_MASK)) + { + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, lock_, -1); + + ACE_DEBUG ((LM_DEBUG, "Test_Task: error notifying reactor!\n")); + } + } + + ACE_DEBUG ((LM_DEBUG, " (%t) returning from svc ()\n")); + return 0; +} + +int +Test_Task::handle_input (ACE_HANDLE) +{ + this->handled_++; + + if (this->handled_ == NUM_INVOCATIONS) + { + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, lock_, -1); + Test_Task::done_cnt_++; + ACE_DEBUG ((LM_DEBUG, + " (%t) Test_Task: handle_input! done_cnt_ = %d.\n", + Test_Task::done_cnt_)); + } + + ACE_OS::thr_yield (); + return -1; +} + +void * +dispatch (void *arg) +{ + // every thread must register the same stream to write to file + if (out_stream) + { + ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM); + ACE_LOG_MSG->msg_ostream (out_stream); + } + + ACE_DEBUG ((LM_DEBUG, " (%t) Dispatcher Thread started!\n")); + ACE_Reactor *r = (ACE_Reactor *) arg; + int result; + + r->owner (ACE_OS::thr_self ()); + + while (1) + { + result = r->handle_events (); + if (result <= 0) + ACE_DEBUG ((LM_DEBUG, "Dispatch: handle_events (): %d", result)); + } + + return 0; +} + +static void +handler (int signum) +{ + *out_stream << flush; + out_stream->close (); + ACE_OS::exit (42); +} + +int +main (int argc, char **argv) +{ + if (argc > 1) + { + // Send output to file. + out_stream = new ofstream ("test_task_three.out", ios::trunc|ios::out); + ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM); + ACE_LOG_MSG->msg_ostream (out_stream); + signal (SIGINT, ACE_SignalHandler (handler)); + } + + ACE_Reactor *reactor1 = ACE_Service_Config::reactor (); + ACE_Reactor *reactor2 = new ACE_Reactor (); + + Test_Task t1[TASK_COUNT]; + Test_Task t2[TASK_COUNT]; + + ACE_Thread::spawn (dispatch, reactor2); + + reactor1->owner (ACE_OS::thr_self ()); + + for (int index = 0; index < TASK_COUNT; index++) + { + t1[index].open (reactor1); + t2[index].open (reactor2); + } + + ACE_OS::sleep (3); + + for (;;) + { + ACE_Time_Value timeout (2); + + if (reactor1->handle_events (timeout) <= 0) + { + if (errno == ETIME) + { + ACE_DEBUG ((LM_DEBUG, "no activity within 2 seconds, shutting down\n")); + break; + } + else + ACE_ERROR ((LM_ERROR, "%p error handling events\n", "main")); + } + } + + return 0; +} + +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/Threads/test_task_two.cpp b/examples/Threads/test_task_two.cpp new file mode 100644 index 00000000000..4ce201a74bc --- /dev/null +++ b/examples/Threads/test_task_two.cpp @@ -0,0 +1,156 @@ +// Exercise more tests for the ACE Tasks. This test can spawn off +// @(#)test_task_two.cpp 1.1 10/18/96 + +// zillions of tasks and then wait for them using both polling and the +// ACE Thread Manager. + +#include "ace/Task.h" +#include "ace/Log_Msg.h" +#include "ace/Service_Config.h" +#include "ace/Synch.h" + +#if defined (ACE_HAS_THREADS) + +typedef ACE_Atomic_Op ATOMIC_INT; + +static u_long zero = 0; +static ATOMIC_INT task_count (zero); +static ATOMIC_INT max_count (zero); +static ATOMIC_INT wait_count (zero); + +static u_long n_threads = 0; + +// Default number of tasks. +static const int default_threads = ACE_DEFAULT_THREADS; + +// Default number of times to run the test. +static const int default_iterations = 1000; + +class Task_Test : public ACE_Task +{ +public: + virtual int open (void *args = 0); + virtual int close (u_long flags = 0); + virtual int put (ACE_Message_Block *, ACE_Time_Value *tv = 0); + virtual int svc (void); + +private: + static ACE_Thread_Mutex lock_; +}; + +ACE_Thread_Mutex Task_Test::lock_; + +int +Task_Test::open (void *args) +{ + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, Task_Test::lock_, -1); + + task_count++; + ACE_DEBUG ((LM_DEBUG, "(%t) creating Task_Test, task count = %d\n", + (u_long) task_count)); + + return this->activate (THR_BOUND); +} + +int +Task_Test::close (u_long flags) +{ + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, Task_Test::lock_, -1); + + task_count--; + ACE_DEBUG ((LM_DEBUG, "(%t) destroying Task_Test, task count = %d\n", + (u_long) task_count)); + wait_count--; +// delete this; + return 0; +} + +int +Task_Test::put (ACE_Message_Block *mb, + ACE_Time_Value *tv) +{ + return 0; +} + +int +Task_Test::svc (void) +{ + wait_count++; + max_count++; + + ACE_DEBUG ((LM_DEBUG, "(%t) svc: waiting\n")); + + for (;;) + if (max_count >= n_threads) + break; + else + ACE_Thread::yield (); + + ACE_DEBUG ((LM_DEBUG, "(%t) svc: finished waiting\n")); + return 0; +} + +int +main (int argc, char *argv[]) +{ + int n_threads = argc > 1 ? ACE_OS::atoi (argv[1]) : default_threads; + int n_iterations = argc > 2 ? ACE_OS::atoi (argv[2]) : default_iterations; + + Task_Test **task_array = new Task_Test *[n_threads]; + + for (int i = 1; i <= n_iterations; i++) + { + ACE_DEBUG ((LM_DEBUG, "(%t) iteration = %d, max_count %d\n", + i, (u_long) max_count)); + max_count = 0; + + ACE_DEBUG ((LM_DEBUG, "(%t) starting %d task%s\n", + n_threads, n_threads == 1 ? "" : "s")); + + // Launch the new tasks. + for (int j = 0; j < n_threads; j++) + { + task_array[j] = new Task_Test; + // Activate the task, i.e., make it an active object. + task_array[j]->open (); + } + + // Wait for initialization to kick in. + while (max_count == 0) + ACE_Thread::yield (); + + ACE_DEBUG ((LM_DEBUG, "(%t) waiting for threads to finish\n")); + + // Wait for the threads to finish this iteration. + while (max_count != n_threads && wait_count != 0) + ACE_Thread::yield (); + + ACE_DEBUG ((LM_DEBUG, "(%t) iteration %d finished, max_count %d, wait_count %d, waiting for tasks to exit\n", + i, (u_long) max_count, (u_long) wait_count)); + + // Wait for all the tasks to exit. + ACE_Service_Config::thr_mgr ()->wait (); + + // Delete the existing tasks. + for (int k = 0; k < n_threads; k++) + delete task_array[k]; + } + + delete [] task_array; + + ACE_DEBUG ((LM_DEBUG, "(%t) shutting down the test\n")); + return 0; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Atomic_Op; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ + +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/Threads/test_thread_manager.cpp b/examples/Threads/test_thread_manager.cpp new file mode 100644 index 00000000000..efa5a2cc2a6 --- /dev/null +++ b/examples/Threads/test_thread_manager.cpp @@ -0,0 +1,105 @@ +// Test out the group management mechanisms provided by the +// @(#)test_thread_manager.cpp 1.1 10/18/96 + +// ACE_Thread_Manager, including the group signal handling, group +// suspension and resumption, and cooperative thread cancellation +// mechanisms. + +#include "ace/Service_Config.h" +#include "ace/Thread_Manager.h" + +#if defined (ACE_HAS_THREADS) + +static void +handler (int signum) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) received signal %d\n", signum)); +} + +static void * +worker (int iterations) +{ + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + + for (int i = 0; i < iterations; i++) + { + if ((i % 1000) == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%t) checking cancellation before iteration %d!\n", + i)); + + if (ACE_Service_Config::thr_mgr ()->testcancel (ACE_Thread::self ()) != 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%t) has been cancelled before iteration %d!\n", + i)); + break; + } + } + } + + // Destructor removes thread from Thread_Manager. + return 0; +} + +static const int DEFAULT_THREADS = ACE_DEFAULT_THREADS; +static const int DEFAULT_ITERATIONS = 100000; + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config daemon; + + daemon.open (argv[0]); + + // Register a signal handler + ACE_SignalHandler sh (handler); + ACE_Sig_Action sa (sh, SIGINT); + + int n_threads = argc > 1 ? ACE_OS::atoi (argv[1]) : DEFAULT_THREADS; + int n_iterations = argc > 2 ? ACE_OS::atoi (argv[2]) : DEFAULT_ITERATIONS; + + ACE_Thread_Manager *thr_mgr = ACE_Service_Config::thr_mgr (); + + int grp_id = thr_mgr->spawn_n (n_threads, ACE_THR_FUNC (worker), + (void *) n_iterations, + THR_NEW_LWP | THR_DETACHED); + + // Wait for 1 second and then suspend every thread in the group. + ACE_OS::sleep (1); + ACE_DEBUG ((LM_DEBUG, "(%t) suspending group\n")); + if (thr_mgr->suspend_grp (grp_id) == -1) + ACE_ERROR ((LM_DEBUG, "(%t) %p\n", "suspend_grp")); + + // Wait for 1 more second and then resume every thread in the + // group. + ACE_OS::sleep (ACE_Time_Value (1)); + ACE_DEBUG ((LM_DEBUG, "(%t) resuming group\n")); + if (thr_mgr->resume_grp (grp_id) == -1) + ACE_ERROR ((LM_DEBUG, "(%t) %p\n", "resume_grp")); + + // Wait for 1 more second and then send a SIGINT to every thread in + // the group. + ACE_OS::sleep (ACE_Time_Value (1)); + ACE_DEBUG ((LM_DEBUG, "(%t) signaling group\n")); + if (thr_mgr->kill_grp (grp_id, SIGINT) == -1) + ACE_ERROR ((LM_DEBUG, "(%t) %p\n", "kill_grp")); + + // Wait for 1 more second and then cancel all the threads. + ACE_OS::sleep (ACE_Time_Value (1)); + ACE_DEBUG ((LM_DEBUG, "(%t) cancelling group\n")); + if (thr_mgr->cancel_grp (grp_id) == -1) + ACE_ERROR ((LM_DEBUG, "(%t) %p\n", "cancel_grp")); + + // Perform a barrier wait until all the threads have shut down. + thr_mgr->wait (); + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, "threads not supported on this platform\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/Threads/test_thread_pool.cpp b/examples/Threads/test_thread_pool.cpp new file mode 100644 index 00000000000..28892ed9356 --- /dev/null +++ b/examples/Threads/test_thread_pool.cpp @@ -0,0 +1,214 @@ +// This test program illustrates how the ACE task synchronization +// @(#)test_thread_pool.cpp 1.1 10/18/96 + +// mechanisms work in conjunction with the ACE_Task and the +// ACE_Thread_Manager. If the manual flag is not set input comes from +// stdin until the user enters a return only. This stops all workers +// via a message block of length 0. This is an alternative shutdown of +// workers compared to queue deactivate. +// +// This code is original based on a test program written by Karlheinz +// Dorn. It was modified to utilize more "ACE" features by Doug Schmidt. + +#include "ace/Task.h" +#include "ace/Service_Config.h" +#include "ace/Log_Msg.h" +#include "ace/Task.h" + +#if defined (ACE_HAS_THREADS) + +// Number of iterations to run the test. +static size_t n_iterations = 100; + +class Thread_Pool : public ACE_Task +{ +public: + Thread_Pool (ACE_Thread_Manager *thr_mgr, int n_threads); + + virtual int svc (void); + // Iterate time printing off a message and "waiting" + // for all other threads to complete this iteration. + + virtual int put (ACE_Message_Block *mb, ACE_Time_Value *tv=0); + // This allows the producer to pass messages to the . + +private: + virtual int close (u_long); + + // = Not needed for this test. + virtual int open (void *) { return 0; } +}; + +int +Thread_Pool::close (u_long) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) close of worker\n")); + return 0; +} + +Thread_Pool::Thread_Pool (ACE_Thread_Manager *thr_mgr, + int n_threads) + : ACE_Task (thr_mgr) +{ + // Create worker threads. + if (this->activate (THR_NEW_LWP, n_threads) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "activate failed")); +} + +// Simply enqueue the Message_Block into the end of the queue. + +int +Thread_Pool::put (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + return this->putq (mb, tv); +} + +// Iterate time printing off a message and "waiting" +// for all other threads to complete this iteration. + +int +Thread_Pool::svc (void) +{ + // Note that the ACE_Task::svc_run () method automatically adds us to + // the Thread_Manager when the thread begins. + + int result = 0; + int count = 1; + + // Keep looping, reading a message out of the queue, until we get a + // message with a length == 0, which signals us to quit. + + for (;; count++) + { + ACE_Message_Block *mb; + + ACE_DEBUG ((LM_DEBUG, "(%t) in iteration %d before getq ()\n", count)); + + if (this->getq (mb) == -1) + { + ACE_ERROR ((LM_ERROR, + "(%t) in iteration %d, got result -1, exiting\n", count)); + break; + } + + int length = mb->length (); + + if (length > 0) + ACE_DEBUG ((LM_DEBUG, + "(%t) in iteration %d, length = %d, text = \"%*s\"\n", + count, length, length - 1, mb->rd_ptr ())); + + // We're responsible for deallocating this. + delete mb; + + if (length == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%t) in iteration %d, got NULL message, exiting\n", + count)); + break; + } + } + + // Note that the ACE_Task::svc_run () method automatically removes + // us from the Thread_Manager when the thread exits. + return 0; +} + +static void +produce (Thread_Pool &thread_pool) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) producer start, dumping the Thread_Pool\n")); + thread_pool.dump (); + + for (int n;;) + { + // Allocate a new message. + ACE_Message_Block *mb = new ACE_Message_Block (BUFSIZ); + +#if defined (manual) + ACE_DEBUG ((LM_DEBUG, + "(%t) press chars and enter to put a new message into task queue...")); + n = ACE_OS::read (ACE_STDIN, mb->rd_ptr (), mb->size ()); +#else // Automatically generate messages. + static int count = 0; + + ACE_OS::sprintf (mb->rd_ptr (), "%d\n", count); + + n = ACE_OS::strlen (mb->rd_ptr ()); + + if (count == n_iterations) + n = 1; // Indicate that we need to shut down. + else + count++; + + if (count == 0 || (count % 20 == 0)) + ACE_OS::sleep (1); +#endif /* manual */ + if (n > 1) + { + // Send a normal message to the waiting threads and continue + // producing. + mb->wr_ptr (n); + + // Pass the message to the Thread_Pool. + if (thread_pool.put (mb) == -1) + ACE_ERROR ((LM_ERROR, " (%t) %p\n", "put")); + } + else + { + // Send a shutdown message to the waiting threads and exit. + ACE_DEBUG ((LM_DEBUG, "\n(%t) start loop, dump of task:\n")); + thread_pool.dump (); + + for (int i = thread_pool.thr_count (); i > 0; i--) + { + ACE_DEBUG ((LM_DEBUG, + "(%t) EOF, enqueueing NULL block for thread = %d\n", + i)); + + // Enqueue a NULL message to flag each consumer to + // shutdown. + if (thread_pool.put (new ACE_Message_Block) == -1) + ACE_ERROR ((LM_ERROR, " (%t) %p\n", "put")); + } + + ACE_DEBUG ((LM_DEBUG, "\n(%t) end loop, dump of task:\n")); + thread_pool.dump (); + break; + } + } +} + +int +main (int argc, char *argv[]) +{ + int n_threads = argc > 1 ? ACE_OS::atoi (argv[1]) : ACE_DEFAULT_THREADS; + n_iterations = argc > 2 ? ACE_OS::atoi (argv[2]) : n_iterations; + + ACE_DEBUG ((LM_DEBUG, "(%t) argc = %d, threads = %d\n", + argc, n_threads)); + + // Create the worker tasks. + Thread_Pool thread_pool (ACE_Service_Config::thr_mgr (), + n_threads); + + // Create work for the worker tasks to process in their own threads. + produce (thread_pool); + + // Wait for all the threads to reach their exit point. + + ACE_DEBUG ((LM_DEBUG, "(%t) waiting with thread manager...\n")); + ACE_Service_Config::thr_mgr ()->wait (); + + ACE_DEBUG ((LM_DEBUG, "(%t) destroying worker tasks and exiting...\n")); + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/examples/Threads/test_thread_specific.cpp b/examples/Threads/test_thread_specific.cpp new file mode 100644 index 00000000000..ac0cc7ed5d1 --- /dev/null +++ b/examples/Threads/test_thread_specific.cpp @@ -0,0 +1,208 @@ +#include "ace/Service_Config.h" +// @(#)test_thread_specific.cpp 1.1 10/18/96 + +#include "ace/Synch.h" +#include "ace/Log_Msg.h" + +// Define a class that will be stored in thread-specific data. Note +// that as far as this class is concerned it's just a regular C++ +// class. The ACE_TSS wrapper transparently ensures that +// objects of this class will be placed in thread-specific storage. +// All calls on ACE_TSS::operator->() are delegated to the +// appropriate method in the Errno class. + +class Errno +{ +public: + int error (void) { return this->errno_; } + void error (int i) { this->errno_ = i; } + + int line (void) { return this->lineno_; } + void line (int l) { this->lineno_ = l; } + + // Errno::flags_ is a static variable, so we've got to protect it + // with a mutex since it isn't kept in thread-specific storage. + int flags (void) + { + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, Errno::lock_, -1); + + return Errno::flags_; + } + + void flags (int f) + { + ACE_GUARD (ACE_Thread_Mutex, ace_mon, Errno::lock_); + + Errno::flags_ = f; + } + +private: + // = errno_ and lineno_ will be thread-specific data so they don't + // need a lock. + int errno_; + int lineno_; + + static int flags_; +#if defined (ACE_HAS_THREADS) + // flags_ needs a lock. + static ACE_Thread_Mutex lock_; +#endif /* ACE_HAS_THREADS */ +}; + +// Static variables. +ACE_MT (ACE_Thread_Mutex Errno::lock_); +int Errno::flags_; + +// This is our thread-specific error handler... +static ACE_TSS TSS_Error; + +#if defined (ACE_HAS_THREADS) +// Serializes output via cout. +static ACE_Thread_Mutex lock; + +typedef ACE_TSS_Guard GUARD; +#else +// Serializes output via cout. +static ACE_Null_Mutex lock; + +typedef ACE_Guard GUARD; +#endif /* ACE_HAS_THREADS */ + +static void +cleanup (void *ptr) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) in cleanup, ptr = %x\n", ptr)); + + delete ptr; +} + +// This worker function is the entry point for each thread. + +static void * +worker (void *c) +{ + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + int count = int (c); + + ACE_thread_key_t key = 0; + int *ip = 0; + + // Make one key that will be available when the thread exits so that + // we'll have something to cleanup! + + if (ACE_OS::thr_keycreate (&key, cleanup) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_keycreate")); + + ip = new int; + + if (ACE_OS::thr_setspecific (key, (void *) ip) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_setspecific")); + + for (int i = 0; i < count; i++) + { + if (ACE_OS::thr_keycreate (&key, cleanup) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_keycreate")); + + ip = new int; + + ACE_DEBUG ((LM_DEBUG, "(%t) in worker 1, key = %d, ip = %x\n", key, ip)); + + if (ACE_OS::thr_setspecific (key, (void *) ip) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_setspecific")); + + if (ACE_OS::thr_getspecific (key, (void **) &ip) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_setspecific")); + + if (ACE_OS::thr_setspecific (key, (void *) 0) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_setspecific")); + + delete ip; + + if (ACE_OS::thr_keyfree (key) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_keyfree")); + + // Cause an error. + ACE_OS::read (ACE_INVALID_HANDLE, 0, 0); + + // The following two lines set the thread-specific state. + TSS_Error->error (errno); + TSS_Error->line (__LINE__); + + // This sets the static state (note how C++ makes it easy to do + // both). + TSS_Error->flags (count); + + { + // Use the guard to serialize access to cout... + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, lock, 0); + + cout << "(" << ACE_Thread::self () + << ") errno = " << TSS_Error->error () + << ", lineno = " << TSS_Error->line () + << ", flags = " << TSS_Error->flags () + << endl; + } + key = 0; + + if (ACE_OS::thr_keycreate (&key, cleanup) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_keycreate")); + + ip = new int; + + ACE_DEBUG ((LM_DEBUG, "(%t) in worker 2, key = %d, ip = %x\n", key, ip)); + + if (ACE_OS::thr_setspecific (key, (void *) ip) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_setspecific")); + + if (ACE_OS::thr_getspecific (key, (void **) &ip) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_setspecific")); + + if (ACE_OS::thr_setspecific (key, (void *) 0) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_setspecific")); + + delete ip; + + if (ACE_OS::thr_keyfree (key) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_keyfree")); + } + + ACE_DEBUG ((LM_DEBUG, "(%t) exiting\n")); + return 0; +} + +static void +handler (int signum) +{ + ACE_DEBUG ((LM_DEBUG, "signal = %S\n", signum)); + ACE_Service_Config::thr_mgr ()->exit (0); +} + +int +main (int argc, char *argv[]) +{ + // The Service_Config must *always* be the first object defined in + // main... + ACE_Service_Config daemon (argv[0]); + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + int threads = argc > 1 ? ACE_OS::atoi (argv[1]) : 4; + int count = argc > 2 ? ACE_OS::atoi (argv[2]) : 10000; + + signal (SIGINT, ACE_SignalHandler (handler)); + +#if defined (ACE_HAS_THREADS) + if (ACE_Service_Config::thr_mgr ()->spawn_n (threads, + ACE_THR_FUNC (&worker), + (void *) count, + THR_BOUND | THR_DETACHED) == -1) + ACE_OS::perror ("ACE_Thread_Manager::spawn_n"); + + ACE_Service_Config::thr_mgr ()->wait (); +#else + worker ((void *) count); +#endif /* ACE_HAS_THREADS */ + return 0; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_TSS; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/examples/Threads/test_token.cpp b/examples/Threads/test_token.cpp new file mode 100644 index 00000000000..bd8d399102f --- /dev/null +++ b/examples/Threads/test_token.cpp @@ -0,0 +1,76 @@ +// Test out the ACE Token class. +// @(#)test_token.cpp 1.1 10/18/96 + +#include "ace/Token.h" +#include "ace/Task.h" + +#if defined (ACE_HAS_THREADS) + +class My_Task : public ACE_Task +{ +public: + My_Task (int n); + virtual int open (void *) { return 0; } + virtual int close (u_long) { return 0; } + virtual int put (ACE_Message_Block *, ACE_Time_Value *tv) { return 0; } + virtual int svc (void); + + static void sleep_hook (void *); + +private: + ACE_Token token_; +}; + +My_Task::My_Task (int n) +{ + // Make this Task into an Active Object. + this->activate (THR_BOUND | THR_DETACHED, n); + + // Wait for all the threads to exit. + this->thr_mgr ()->wait (); +} + +void +My_Task::sleep_hook (void *) +{ + cerr << '(' << ACE_Thread::self () << ')' + << " blocking, My_Task::sleep_hook () called" << endl; +} + +// Test out the behavior of the ACE_Token class. + +int +My_Task::svc (void) +{ + for (int i = 0; i < 10000; i++) + { + // Wait for up to 1 millisecond past the current time to get the token. + ACE_Time_Value timeout (ACE_OS::time (0), 1000); + + if (this->token_.acquire (&My_Task::sleep_hook, 0, &timeout) == 1) + { + this->token_.acquire (); + this->token_.renew (); + this->token_.release (); + this->token_.release (); + } + else + ACE_Thread::yield (); + } + return 0; +} + +int +main (int argc, char *argv[]) +{ + My_Task tasks (argc > 1 ? atoi (argv[1]) : 4); + + return 0; +} +#else +int +main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "your platform doesn't support threads\n"), -1); +} +#endif /* */ diff --git a/examples/Threads/test_tss.cpp b/examples/Threads/test_tss.cpp new file mode 100644 index 00000000000..ed8cd32017e --- /dev/null +++ b/examples/Threads/test_tss.cpp @@ -0,0 +1,235 @@ +// Torture test ACE thread-specific storage... +// @(#)test_tss.cpp 1.1 10/18/96 + + +#include "ace/Task.h" +#include "ace/Token.h" + +#if defined (ACE_HAS_THREADS) + +class TSS_Obj +{ +public: + + TSS_Obj (void); + ~TSS_Obj (void); + +private: + static int count_; + static ACE_Thread_Mutex lock_; +}; + +int TSS_Obj::count_ = 0; +ACE_Thread_Mutex TSS_Obj::lock_; + +TSS_Obj::TSS_Obj (void) +{ + ACE_GUARD (ACE_Thread_Mutex, ace_mon, lock_); + + count_++; + cout << "TO+ : " << count_ << endl; +} + +TSS_Obj::~TSS_Obj (void) +{ + ACE_GUARD (ACE_Thread_Mutex, ace_mon, lock_); + + count_--; + cout << "TO- : " << count_ << endl; +} + +class Test_Task +{ +public: + + Test_Task (void); + ~Test_Task (void); + + int open (void *arg); + + static void* svc (void *arg); + + static int wait_count_; + static int max_count_; + +private: + static int count_; +}; + +int Test_Task::count_ = 0; +int Test_Task::wait_count_ = 0; +int Test_Task::max_count_ = 0; +int num_threads_ = 0; + +ACE_Token token; + +Test_Task::Test_Task (void) +{ + ACE_GUARD (ACE_Token, ace_mon, token); + + count_++; + cout << "Test_Task+ : " + << count_ << " (" + << ACE_OS::thr_self () + << ")" << endl; +} + +Test_Task::~Test_Task (void) +{ + ACE_GUARD (ACE_Token, ace_mon, token); + + count_--; + cout << "Test_Task- : " + << count_ << " (" + << ACE_OS::thr_self () + << ")" << endl; + + wait_count_--; +} + +int Test_Task::open (void *arg) +{ + + ACE_Thread::spawn (Test_Task::svc, arg); + + return 0; +} + + +void * +Test_Task::svc (void *arg) +{ + ACE_TSS tss (new TSS_Obj); + + { + ACE_GUARD_RETURN (ACE_Token, ace_mon, token, 0); + + wait_count_++; + max_count_++; + cout << "svc: waiting (" << ACE_OS::thr_self () << ")" << endl; + } + + while (1) + { + { + ACE_GUARD_RETURN (ACE_Token, ace_mon, token, 0); + + if (max_count_ >= num_threads_) + break; + else + { + ace_mon.release (); + ACE_Thread::yield (); + ace_mon.acquire (); + } + } + + { + ACE_GUARD_RETURN (ACE_Token, ace_mon, token, 0); + + cout << "svc: waiting (" << ACE_OS::thr_self () << ") finished" << endl; + } + } + + delete (Test_Task *) arg; + + return 0; +} + +int +main (int argc, char **argv) +{ + if (argc != 2) + { + cout << "Missing parameters!" << endl; + return 1; + } + + int num_Tasks = atoi (argv[1]); + + num_threads_ = num_Tasks; + + Test_Task **task_arr = (Test_Task**) new char[sizeof (Test_Task*) * num_Tasks]; + + while (1) + { + { + ACE_GUARD_RETURN (ACE_Token, ace_mon, token, -1); + + cout << "ReseTest_Tasking Test_Task::max_count_ from: " + << Test_Task::max_count_ << endl; + + Test_Task::max_count_ = 0; + } + + for (int i = 0; i < num_Tasks; i++) + { + task_arr[i] = new Test_Task; + task_arr[i]->open (task_arr[i]); + } + + cout << "Waiting for first thread started..." << endl; + + for (;;) + { + ACE_GUARD_RETURN (ACE_Token, ace_mon, token, -1); + + if (Test_Task::max_count_ != 0 ) + { + ace_mon.release (); + ACE_Thread::yield (); + ace_mon.acquire (); + break; + } + ace_mon.release (); + ACE_Thread::yield (); + ace_mon.acquire (); + } + + { + ACE_GUARD_RETURN (ACE_Token, ace_mon, token, -1); + + cout << "First thread started!" << endl + << "Waiting for all threads finished..." << endl; + } + + for (;;) + { + ACE_GUARD_RETURN (ACE_Token, ace_mon, token, -1); + + if (!(Test_Task::max_count_ == num_threads_ + && Test_Task::wait_count_ == 0)) + { + ace_mon.release (); + ACE_Thread::yield (); + ace_mon.acquire (); + continue; + } + + cout << "Test_Task::max_count_ = " + << Test_Task::max_count_ + << " Test_Task::wait_count_ = " + << Test_Task::wait_count_ + << endl; + break; + } + + { + ACE_GUARD_RETURN (ACE_Token, ace_mon, token, -1); + cout << "All threads finished..." << endl; + } + + ACE_OS::sleep (2); + } + + return 0; +} + +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/include/makeinclude/macros.GNU b/include/makeinclude/macros.GNU new file mode 100644 index 00000000000..8555d6b5818 --- /dev/null +++ b/include/makeinclude/macros.GNU @@ -0,0 +1,22 @@ +#---------------------------------------------------------------------------- +# @(#)macros.GNU 1.1 10/18/96 +# +# Local and nested target definitions +#---------------------------------------------------------------------------- + +TARGETS_LOCAL = \ + all.local \ + debug.local \ + profile.local \ + optimize.local \ + install.local \ + deinstall.local \ + clean.local \ + realclean.local \ + clobber.local \ + depend.local \ + rcs_info.local + +TARGETS_NESTED = \ + $(TARGETS_LOCAL:.local=.nested) + diff --git a/include/makeinclude/platform_aix.GNU b/include/makeinclude/platform_aix.GNU new file mode 100644 index 00000000000..058f464b2ad --- /dev/null +++ b/include/makeinclude/platform_aix.GNU @@ -0,0 +1,30 @@ +# AIX 4.1.3 +# *not* using Orbix +# This file assumes that the user has installed the AIX patch +# containing the dl*() APIs. To use these APIs, IBM has created a +# separate product (free to AIX licensees) called shared library +# hookable symbols (or slhs/6000). If they don't have this patch, the +# sv* commands for compiling and linking will not be present on the +# system. + +CC = xlC +CXX = xlC_r +DLD = makeC++SharedLib +CPPFLAGS += -qxcall -qtempinc +SHLIBA = $(SHLIB:lib%.so=lib%shr.a) +ifdef SHLIB +ACELIB = -lACEshr +endif +LLIBS = -lC_r -lC -lpthreads -lbsd -lsvld -ltli -lc_r -lm -lc $(ACELIB) +LIBS += $(filter-out $(SHLIBA:lib%.a=-l%), $(LLIBS)) +ARFLAGS = ruv +AR = ar +LDFLAGS += -bI:/lib/pse.exp +# Should be set to optimize for your particular computer. This +# is set to be optimized for RS/6000 43P +OCCFLAGS += -qarch=ppc -qtune=604 +RANLIB = ranlib +SOFLAGS = -p 0 +STATLIB = $(VLIB) +TEMPINCDIR = tempinc +SOBUILD = diff --git a/include/makeinclude/platform_hpux.GNU b/include/makeinclude/platform_hpux.GNU new file mode 100644 index 00000000000..8197edf7d16 --- /dev/null +++ b/include/makeinclude/platform_hpux.GNU @@ -0,0 +1,21 @@ +CC = /bin/cc +CXX = /usr/bin/CC +DLD = $(CXX) +PIC = +ARFLAGS = ruv +RANLIB = echo +CFLAGS = -Aa -z +z $(DCFLAGS) +LDFLAGS = -L$(WRAPPER_ROOT)/ace -Wl,+s +CCFLAGS = -Aa -z +z -pta -ptb +SOFLAGS = -b +SOBUILD = @echo ""; \ + echo "$(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<"; \ + $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<; \ + $(RM) -rf $(VSHDIR)pt$*; mkdir $(VSHDIR)pt$*; \ + echo "int main() { return 0; }" >dummy.C; \ + echo "$(CXX) $(CCFLAGS) $(PIC) $(CPPFLAGS) $(LDFLAGS) -ptr$(VSHDIR)pt$* -ptr./ptrepository dummy.C $<";\ + YYZ="`$(CXX) $(CCFLAGS) $(PIC) $(CPPFLAGS) $(LDFLAGS) -ptr$(VSHDIR)pt$* -ptr./ptrepository dummy.C $<`"; \ + $(RM) -rf a.out dummy.*; \ + YYZ="`echo $(VSHDIR)pt$*/*.o`"; \ + echo "$(SOLINK.cc) -o $@ ./$(VSHDIR)$*.o $(YYZ)"; \ + $(SOLINK.cc) -o $@ ./$(VSHDIR)$*.o $(YYZ) diff --git a/include/makeinclude/platform_hpux_orbix.GNU b/include/makeinclude/platform_hpux_orbix.GNU new file mode 100644 index 00000000000..e07a9cc993e --- /dev/null +++ b/include/makeinclude/platform_hpux_orbix.GNU @@ -0,0 +1,23 @@ +# Assume the existence of Orbix with HP/UX... +CC = /bin/cc +CXX = /usr/bin/CC +DLD = $(CXX) +INCLDIRS = -I$(ORBIX_ROOT)/include +PIC = +ARFLAGS = ruv +RANLIB = echo +CFLAGS = -Aa -z +z $(DCFLAGS) +LDFLAGS = -L$(ORBIX_ROOT)/lib -L$(WRAPPER_ROOT)/ace -Wl,+s +CCFLAGS = -Aa -z +z -pta -ptb +SOFLAGS = -b +SOBUILD = @echo ""; \ + echo "$(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<"; \ + $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<; \ + $(RM) -rf $(VSHDIR)pt$*; mkdir $(VSHDIR)pt$*; \ + echo "int main() { return 0; }" >dummy.C; \ + echo "$(CXX) $(CCFLAGS) $(PIC) $(CPPFLAGS) $(LDFLAGS) -ptr$(VSHDIR)pt$* -ptr./ptrepository dummy.C $<";\ + YYZ="`$(CXX) $(CCFLAGS) $(PIC) $(CPPFLAGS) $(LDFLAGS) -ptr$(VSHDIR)pt$* -ptr./ptrepository dummy.C $<`"; \ + $(RM) -rf a.out dummy.*; \ + YYZ="`echo $(VSHDIR)pt$*/*.o`"; \ + echo "$(SOLINK.cc) -o $@ ./$(VSHDIR)$*.o $(YYZ)"; \ + $(SOLINK.cc) -o $@ ./$(VSHDIR)$*.o $(YYZ) diff --git a/include/makeinclude/platform_irix5.2.GNU b/include/makeinclude/platform_irix5.2.GNU new file mode 100644 index 00000000000..f5edee5f16d --- /dev/null +++ b/include/makeinclude/platform_irix5.2.GNU @@ -0,0 +1,11 @@ +# Irix 5.2 with gcc 2.6.1 +MAKE = gmake +CC = gcc +CXX = g++ +DLD = $(CXX) +LDFLAGS += +LIBS += -ldl +PIC = -fpic +RANLIB = echo +SOFLAGS = +SOBUILD = diff --git a/include/makeinclude/platform_irix5.3_g++.GNU b/include/makeinclude/platform_irix5.3_g++.GNU new file mode 100644 index 00000000000..1d81ed6b7dd --- /dev/null +++ b/include/makeinclude/platform_irix5.3_g++.GNU @@ -0,0 +1,13 @@ +# Irix 5.3 with GNU C++ + +CC = gcc +CXX = gcc +DLD = $(CXX) +LDFLAGS += -L$(WRAPPER_ROOT)/ace +LIBS += -lstdc++ +PIC = -fpic +RANLIB = echo +SOFLAGS = -shared $(CPPFLAGS) +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<; \ + $(SOLINK.cc) -o $@ $(LDFLAGS) $(VSHDIR)$*.o + diff --git a/include/makeinclude/platform_irix5.3_sgic++.GNU b/include/makeinclude/platform_irix5.3_sgic++.GNU new file mode 100644 index 00000000000..9ea66283ce0 --- /dev/null +++ b/include/makeinclude/platform_irix5.3_sgic++.GNU @@ -0,0 +1,19 @@ +# Irix 5.3 with SGI C++ + +# This suppresses common compiler warnings which appear in the +# ACE code but should not matter. The warnings can be turned on +# again by removing the -woff clause in the CPPFLAGS definition. + +CC = cc +CXX = CC +DLD = $(CXX) +CPPFLAGS += -ptused -prelink +pp -woff 3203,3209,3161,3262,3665 +LDFLAGS += -rpath "$(WRAPPER_ROOT)/ace" +LIBS = +PIC = -KPIC +AR = ar +ARFLAGS = r +RANLIB = echo +SOFLAGS = -shared $(CPPFLAGS) -all +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<; \ + $(SOLINK.cc) -o $@ $(LDFLAGS) $(VSHDIR)$*.o diff --git a/include/makeinclude/platform_irix6.2_sgic++.GNU b/include/makeinclude/platform_irix6.2_sgic++.GNU new file mode 100644 index 00000000000..9bf0247f4f5 --- /dev/null +++ b/include/makeinclude/platform_irix6.2_sgic++.GNU @@ -0,0 +1,24 @@ +# Irix 6.2 with SGI C++ + +# This suppresses common compiler warnings which appear in the +# ACE code but should not matter. The warnings can be turned on +# again by removing the -woff clause in the CPPFLAGS definition. +# +# I (Gonzalo Diethelm ) also turned off warning 85 +# from the linker; otherwise there are a lot of warnings about symbols +# in the pthread library overriding symbols in the C library (which is +# OK), and added libpthread.so to the link phase. + +CC = cc +CXX = CC +DLD = $(CXX) +CPPFLAGS += -ptused -prelink +pp -D_SGI_MP_SOURCE -woff 3203,3209,3161,3262,3665 +LDFLAGS += -rpath "$(WRAPPER_ROOT)/ace" -Wl,-woff,85 +LIBS += -lpthread +PIC = -KPIC +AR = ar +ARFLAGS = r +RANLIB = echo +SOFLAGS = -shared $(CPPFLAGS) -all +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<; \ + $(SOLINK.cc) -o $@ $(LDFLAGS) $(VSHDIR)$*.o diff --git a/include/makeinclude/platform_linux.GNU b/include/makeinclude/platform_linux.GNU new file mode 100644 index 00000000000..cde3987019c --- /dev/null +++ b/include/makeinclude/platform_linux.GNU @@ -0,0 +1,18 @@ +# According to Bryon G. Rigg , this file +# should allow ACE to be built on Linux. + +CC = gcc -w +CXX = gcc -w -I. -fno-strict-prototypes -D__ACE_INLINE__ +DLD = $(CXX) +LIBS = -lstdc++ +PIC = -fPIC +AR = ar +ARFLAGS = ruv +RANLIB = ranlib + +SOFLAGS = $(CPPFLAGS) -shared +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.so $< +PRELIB = (echo "main() { }" > gcctemp.c && \ + $(COMPILE.cc) -o gcctemp.o gcctemp.c && \ + $(LINK.cc) -o gcctemp gcctemp.o $^ $(LDFLAGS) $(LIBS); \ + status=$$?; exit $$status) diff --git a/include/makeinclude/platform_linux_pthread.GNU b/include/makeinclude/platform_linux_pthread.GNU new file mode 100644 index 00000000000..f7103d1d84e --- /dev/null +++ b/include/makeinclude/platform_linux_pthread.GNU @@ -0,0 +1,24 @@ +# For pthreads support on Linux, you need +# -D_MIT_POSIX_THREADS +# -D_POSIX_THREADS +# -D_POSIX_THREAD_SAFE_FUNCTIONS +# in the CXX command line. Also, add -lpthreads to the LIBS. +# libpthreads.so comes with the sources of Linux libc-5.3.*, you need +# to compile it yourself (no binaries included) -- +# Jan Rychter + +CC = gcc -w +CXX = gcc -w -I. -fno-strict-prototypes -D__ACE_INLINE__ -D_MIT_POSIX_THREADS -D_POSIX_THREADS -D_POSIX_THREAD_SAFE_FUNCTIONS +DLD = $(CXX) +LIBS += -lpthreads -lstdc++ +PIC = -fPIC +AR = ar +ARFLAGS = ruv +RANLIB = ranlib + +SOFLAGS = $(CPPFLAGS) -shared +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.so $< +PRELIB = (echo "main() { }" > gcctemp.c && \ + $(COMPILE.cc) -o gcctemp.o gcctemp.c && \ + $(LINK.cc) -o gcctemp gcctemp.o $^ $(LDFLAGS) $(LIBS); \ + status=$$?; exit $$status) diff --git a/include/makeinclude/platform_m88k.GNU b/include/makeinclude/platform_m88k.GNU new file mode 100644 index 00000000000..87922980df0 --- /dev/null +++ b/include/makeinclude/platform_m88k.GNU @@ -0,0 +1,24 @@ +# SunOS 5.x (Solaris 2.x) with SunC++ 4.x +# *not* using Orbix +CC = gcc -w +#CXX = gcc -w -frepo -I. -fno-strict-prototypes -D__INLINE__ +CXX = gcc -w -I. -fno-strict-prototypes -D__INLINE__ +CXX += -D__m88k__ +DLD = $(CXX) +INCLDIRS += -I$(WRAPPER_ROOT) -I. +INCLDIRS += -I/devel/rmm/v1.0/local/src/threads/include +LDFLAGS += -L $(WRAPPER_ROOT)/ace -L ./ +LDFLAGS += -L/devel/rmm/v1.0/local/src/threads/lib +LIBS += -lsocket -ldl -lnsl -lgen -lstdc++ -lg++ +LIBS += -lgthreads -lgmalloc +PIC = -fpic +AR = ar +ARFLAGS = ruv +RANLIB = /bin/true +SOFLAGS = -G $(CPPFLAGS) +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<; \ + $(SOLINK.cc) -o $@ -h $@ $(LDFLAGS) $(VSHDIR)$*.o +PRELIB = (echo "main() { }" > gcctemp.c && \ + $(COMPILE.cc) -o gcctemp.o gcctemp.c && \ + $(LINK.cc) -o gcctemp gcctemp.o $^ $(LDFLAGS) $(LIBS); \ + status=$$?; rm -f gcctemp*; exit $$status) diff --git a/include/makeinclude/platform_osf1_3.2.GNU b/include/makeinclude/platform_osf1_3.2.GNU new file mode 100644 index 00000000000..478a4e072dd --- /dev/null +++ b/include/makeinclude/platform_osf1_3.2.GNU @@ -0,0 +1,13 @@ +# This platform macros file is intended to work with Digital UNIX 3.2 (OSF/1 3.2). + +CC = cxx -non_shared +CXX = cxx -x cxx -w0 -non_shared +#DLD = ld -non_shared +DLD = ld -shared +LIBS += -lpthreads -lmach -lsys5 -lxti -ltli -lcxx -lexc -lc +PIC = -pic +ARFLAGS = ruv +RANLIB = ranlib +SOFLAGS = -shared -assert +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<; \ + $(SOLINK.cc) -o $@ $(LDFLAGS) $(VSHDIR)$*.o -lcxx -ltask -lexc -lc diff --git a/include/makeinclude/platform_osf1_4.0.GNU b/include/makeinclude/platform_osf1_4.0.GNU new file mode 100644 index 00000000000..19b864127a9 --- /dev/null +++ b/include/makeinclude/platform_osf1_4.0.GNU @@ -0,0 +1,16 @@ +# This platform macros file is intended to work with Digital UNIX 4.0 (OSF/1 4.0). + +CC = cxx -g -pthread -ptr $(WRAPPER_ROOT)/ace/cxx_repository +CXX = cxx -w0 -g -pthread -ptr $(WRAPPER_ROOT)/ace/cxx_repository +DLD = $(CXX) +#LIBS += -lpthreads -lmach -lsys5 -lxti -ltli -lcxx -lexc -lc +LIBS += -ltli -lc_r +PIC = +ARFLAGS = ruvZ +# When libraries are archived, a hash index is automatically created so there +# is no need for ranlib +RANLIB = /usr/bin/true +SOFLAGS = -shared +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<; \ + $(SOLINK.cc) -o $@ $(LDFLAGS) $(VSHDIR)$*.o -lACE -ltli -lc_r +# $(SOLINK.cc) -o $@ $(LDFLAGS) $(VSHDIR)$*.o -lcxx -ltask -lexc -lc diff --git a/include/makeinclude/platform_sco-nothread.GNU b/include/makeinclude/platform_sco-nothread.GNU new file mode 100644 index 00000000000..e6bb5c810dc --- /dev/null +++ b/include/makeinclude/platform_sco-nothread.GNU @@ -0,0 +1,20 @@ +# According to Bryon G. Rigg , this file +# should allow ACE to be built on Linux. + +CC = gcc -w +# for threads +# for no threads +CXX = gcc -fno-implicit-templates -w -I. -fno-strict-prototypes -D__ACE_INLINE__ +DLD = $(CXX) +LIBS = -lstdc++ -lsocket +PIC = +AR = ar +ARFLAGS = ruv +RANLIB = /bin/true + +SOFLAGS = $(CPPFLAGS) +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.so $< +PRELIB = (echo "main() { }" > gcctemp.c && \ + $(COMPILE.cc) -o gcctemp.o gcctemp.c && \ + $(LINK.cc) -o gcctemp gcctemp.o $^ $(LDFLAGS) $(LIBS); \ + status=$$?; exit $$status) diff --git a/include/makeinclude/platform_sunos4_g++.GNU b/include/makeinclude/platform_sunos4_g++.GNU new file mode 100644 index 00000000000..e512caf5aea --- /dev/null +++ b/include/makeinclude/platform_sunos4_g++.GNU @@ -0,0 +1,22 @@ +# SunOS 4.x (Solaris 1.x) with g++ *not* using Orbix +# +# SOBUILD - compile into .so directly +# +CC = gcc +CXX = gcc -I. -fno-strict-prototypes -D__ACE_INLINE__ # -frepo +DLD = /bin/ld +# +# for G++ v2.6.0 +LIBS += -lstdc++ +# LIBS += -lnsl -lg++ +PIC = -fpic +AR = ar +ARFLAGS = ruv +RANLIB = ranlib +SOFLAGS = -assert pure-text +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.so $< +# SOLINK = $(SOLINK.cc) -o $@ $(LDFLAGS) $< +PRELIB = (echo "main() { }" > gcctemp.c && \ + $(COMPILE.cc) -o gcctemp.o gcctemp.c && \ + $(LINK.cc) -o gcctemp gcctemp.o $^ $(LDFLAGS) $(LIBS); \ + status=$$?; rm -f gcctemp*; exit $$status) diff --git a/include/makeinclude/platform_sunos4_lucid.GNU b/include/makeinclude/platform_sunos4_lucid.GNU new file mode 100644 index 00000000000..044f8764dd1 --- /dev/null +++ b/include/makeinclude/platform_sunos4_lucid.GNU @@ -0,0 +1,13 @@ +# SunOS 4.x (Solaris 1.x) with Lucid +CC = lcc +CXX = lcc +CFLAGS = -Xa # use ANSI c complier +CCFLAGS = -XF -Xpt- # use c++ ARM compiler with auto templates turned off +DLD = /bin/ld +LIBS += +PIC = -pic +ARFLAGS = ruv +RANLIB = ranlib +SOFLAGS = -assert pure-text +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<; \ + $(SOLINK.cc) -o $@ $(LDFLAGS) $(VSHDIR)$*.o diff --git a/include/makeinclude/platform_sunos4_sunc++3.x.GNU b/include/makeinclude/platform_sunos4_sunc++3.x.GNU new file mode 100644 index 00000000000..8e3909d090b --- /dev/null +++ b/include/makeinclude/platform_sunos4_sunc++3.x.GNU @@ -0,0 +1,17 @@ +# SunOS 4.x (Solaris 1.x) with SunC++ 3.x +CC = cc +CXX = CC +DLD = /bin/ld +LIBS += +PIC = -pic +AR = ar +ARFLAGS = ruv +RANLIB = ranlib +SOFLAGS = -assert pure-text +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<; \ + $(RM) -rf $(VSHDIR)pt$*; mkdir $(VSHDIR)pt$*; \ + YYZ="`$(CXX) $(CCFLAGS) $(CPPFLAGS) \ + -ptr$(VSHDIR)pt$* -ptr./ptrepository $<`"; \ + $(RM) -rf a.out; \ + YYZ="`echo $(VSHDIR)pt$*/*.o`"; \ + $(SOLINK.cc) -o $@ ./$(VSHDIR)$*.o $(YYZ) diff --git a/include/makeinclude/platform_sunos4_sunc++4.x.GNU b/include/makeinclude/platform_sunos4_sunc++4.x.GNU new file mode 100644 index 00000000000..250fd133a18 --- /dev/null +++ b/include/makeinclude/platform_sunos4_sunc++4.x.GNU @@ -0,0 +1,12 @@ +# SunOS 4.x (Solaris 1.x) with SunC++ 4.x +CC = cc +CXX = CC +DLD = $(CXX) +LIBS += +AR = CC +ARFLAGS = -xar -o +PIC = -pic +RANLIB = ranlib +SOFLAGS = -G $(CPPFLAGS) +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<; \ + $(SOLINK.cc) -o $@ $(LDFLAGS) $(VSHDIR)$*.o diff --git a/include/makeinclude/platform_sunos4_sunc++4.x_orbix.GNU b/include/makeinclude/platform_sunos4_sunc++4.x_orbix.GNU new file mode 100644 index 00000000000..6a282ff451b --- /dev/null +++ b/include/makeinclude/platform_sunos4_sunc++4.x_orbix.GNU @@ -0,0 +1,14 @@ +# SunOS 4.x (Solaris 1.x) with SunC++ 4.x and Orbix. +CC = cc +CXX = CC +DLD = $(CXX) +LIBS += +INCLDIRS = -I$(ORBIX_ROOT)/include +AR = CC +LDFLAGS += -L$(ORBIX_ROOT)/lib +ARFLAGS = -xar -o +PIC = -pic +RANLIB = ranlib +SOFLAGS = -G $(CPPFLAGS) +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<; \ + $(SOLINK.cc) -o $@ $(LDFLAGS) $(VSHDIR)$*.o diff --git a/include/makeinclude/platform_sunos5_centerline.GNU b/include/makeinclude/platform_sunos5_centerline.GNU new file mode 100644 index 00000000000..3bf22121c8b --- /dev/null +++ b/include/makeinclude/platform_sunos5_centerline.GNU @@ -0,0 +1,13 @@ +# SunOS 5.x (Solaris 2.x) with Centerline C++ +CC = cc +CXX = CC -mt +DLD = $(CXX) -mt +LIBS += -lsocket -ldl -lnsl -lgen +PIC = -PIC +#AR = CC +#ARFLAGS = -xar -o +ARFLAGS = ruv +RANLIB = echo +SOFLAGS = -G $(CPPFLAGS) $(PTDIRS) +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<; \ + $(SOLINK.cc) $(PIC) -o $@ $(LDFLAGS) $(VSHDIR)$*.o diff --git a/include/makeinclude/platform_sunos5_centerline_orbix.GNU b/include/makeinclude/platform_sunos5_centerline_orbix.GNU new file mode 100644 index 00000000000..cd68c89b609 --- /dev/null +++ b/include/makeinclude/platform_sunos5_centerline_orbix.GNU @@ -0,0 +1,14 @@ +# SunOS 5.x (Solaris 2.x) with Centerline C++ +CC = cc +CXX = CC -mt +DLD = $(CXX) -mt +INCLDIRS = -I$(ORBIX_ROOT)/include +LDFLAGS += -L$(ORBIX_ROOT)/lib +LIBS += -lITsrv -lsocket -ldl -lnsl -lgen +PIC = -PIC +AR = CC +ARFLAGS = -xar -o +RANLIB = echo +SOFLAGS = -G $(CPPFLAGS) $(PTDIRS) +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<; \ + $(SOLINK.cc) $(PIC) -o $@ $(LDFLAGS) $(VSHDIR)$*.o diff --git a/include/makeinclude/platform_sunos5_g++.GNU b/include/makeinclude/platform_sunos5_g++.GNU new file mode 100644 index 00000000000..195065cc641 --- /dev/null +++ b/include/makeinclude/platform_sunos5_g++.GNU @@ -0,0 +1,22 @@ +# SunOS 5.x (Solaris 2.x) with g++ *not* using Orbix +# +# SOBUILD - compile into .so directly +# +CC = gcc +CXX = gcc -I. -fno-strict-prototypes -D__ACE_INLINE__ # -frepo +DLD = $(CXX) +LDFLAGS += -L $(WRAPPER_ROOT)/ace -L ./ # -z muldefs +LIBS += -lsocket -ldl -lstdc++ -lgen -lnsl -lthread -lw +PIC = -fpic +AR = ar +ARFLAGS = ruv +RANLIB = /bin/true +SOFLAGS = -G $(CPPFLAGS) +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.so $< +# SOLINK = cp $< $@ +# SOLINK = ln -s $< $@ +# SOLINK = $(SOLINK.cc) -o $@ $(LDFLAGS) $< +PRELIB = (echo "main() { }" > gcctemp.c && \ + $(COMPILE.cc) -o gcctemp.o gcctemp.c && \ + $(LINK.cc) -o gcctemp gcctemp.o $^ $(LDFLAGS) $(LIBS); \ + status=$$?; rm -f gcctemp*; exit $$status) diff --git a/include/makeinclude/platform_sunos5_sunc++.GNU b/include/makeinclude/platform_sunos5_sunc++.GNU new file mode 100644 index 00000000000..45a69579117 --- /dev/null +++ b/include/makeinclude/platform_sunos5_sunc++.GNU @@ -0,0 +1,14 @@ +# SunOS 5.x (Solaris 2.x) with SunC++ 4.0.1 or earlier +# *not* using Orbix +CC = cc +CXX = CC -mt -pta -noex # This option should solve some evil problems with Solaris +DLD = $(CXX) +LDFLAGS += -R $(WRAPPER_ROOT)/ace +LIBS += -lsocket -ldl -lnsl -lgen # -lposix4 +PIC = -PIC +AR = CC +ARFLAGS = -xar -o +RANLIB = echo +SOFLAGS = -G $(CPPFLAGS) +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<; \ + $(SOLINK.cc) -o $@ -h $@ $(LDFLAGS) $(VSHDIR)$*.o diff --git a/include/makeinclude/platform_sunos5_sunc++_4.1.GNU b/include/makeinclude/platform_sunos5_sunc++_4.1.GNU new file mode 100644 index 00000000000..69e9895dfb7 --- /dev/null +++ b/include/makeinclude/platform_sunos5_sunc++_4.1.GNU @@ -0,0 +1,14 @@ +# SunOS 5.x (Solaris 2.x) with SunC++ 4.1 +# *not* using Orbix +CC = cc +CXX = CC -mt -noex -pta +DLD = $(CXX) +LDFLAGS += -R $(WRAPPER_ROOT)/ace +LIBS += -lsocket -ldl -lnsl -lgen +PIC = -PIC +AR = CC +ARFLAGS = -xar -o +RANLIB = echo +SOFLAGS = -G $(CPPFLAGS) +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<; \ + $(SOLINK.cc) -o $@ -h $@ $(LDFLAGS) $(VSHDIR)$*.o diff --git a/include/makeinclude/platform_sunos5_sunc++_orbix.GNU b/include/makeinclude/platform_sunos5_sunc++_orbix.GNU new file mode 100644 index 00000000000..f76fc318f99 --- /dev/null +++ b/include/makeinclude/platform_sunos5_sunc++_orbix.GNU @@ -0,0 +1,15 @@ +# SunOS 5.x (Solaris 2.x) with SunC++ 4.0.1 or earlier +# *using* Orbix +CC = cc +CXX = CC -mt -pta -noex +DLD = $(CXX) +INCLDIRS = -I$(ORBIX_ROOT)/include +PIC = -PIC +LDFLAGS += $(PIC) -L$(ORBIX_ROOT)/lib -R $(WRAPPER_ROOT)/ace -R $(ORBIX_ROOT)/lib +LIBS += -lITsrv -lsocket -ldl -lnsl -lthread -lgen +AR = CC +ARFLAGS = -xar -o +RANLIB = echo +SOFLAGS = -G $(CPPFLAGS) +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.o $<; \ + $(SOLINK.cc) $(PIC) -o $@ -h $@ $(LDFLAGS) $(VSHDIR)$*.o diff --git a/include/makeinclude/platform_sunos5_x86_g++.GNU b/include/makeinclude/platform_sunos5_x86_g++.GNU new file mode 100644 index 00000000000..195065cc641 --- /dev/null +++ b/include/makeinclude/platform_sunos5_x86_g++.GNU @@ -0,0 +1,22 @@ +# SunOS 5.x (Solaris 2.x) with g++ *not* using Orbix +# +# SOBUILD - compile into .so directly +# +CC = gcc +CXX = gcc -I. -fno-strict-prototypes -D__ACE_INLINE__ # -frepo +DLD = $(CXX) +LDFLAGS += -L $(WRAPPER_ROOT)/ace -L ./ # -z muldefs +LIBS += -lsocket -ldl -lstdc++ -lgen -lnsl -lthread -lw +PIC = -fpic +AR = ar +ARFLAGS = ruv +RANLIB = /bin/true +SOFLAGS = -G $(CPPFLAGS) +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.so $< +# SOLINK = cp $< $@ +# SOLINK = ln -s $< $@ +# SOLINK = $(SOLINK.cc) -o $@ $(LDFLAGS) $< +PRELIB = (echo "main() { }" > gcctemp.c && \ + $(COMPILE.cc) -o gcctemp.o gcctemp.c && \ + $(LINK.cc) -o gcctemp gcctemp.o $^ $(LDFLAGS) $(LIBS); \ + status=$$?; rm -f gcctemp*; exit $$status) diff --git a/include/makeinclude/platform_unixware_g++.GNU b/include/makeinclude/platform_unixware_g++.GNU new file mode 100644 index 00000000000..fdbd634653b --- /dev/null +++ b/include/makeinclude/platform_unixware_g++.GNU @@ -0,0 +1,21 @@ +# UnixWare V2.01 with g++ *not* using Orbix +# +# SOBUILD - compile into .so directly +# +CC = gcc -w +CXX = gcc -I. -D__ACE_INLINE__ # -w -fno-strict-prototypes +DLD = $(CXX) +LDFLAGS += -L$(WRAPPER_ROOT)/ace -L./ -L/usr/lib +LIBS += -lsocket -lnsl -lstdc++ -lgen -lthread +PIC = -fpic +AR = ar +ARFLAGS = ruv +RANLIB = /bin/true +#SOFLAGS = -assert pure-text +SOFLAGS = -shared +SOBUILD = $(COMPILE.cc) $(PIC) -o $(VSHDIR)$*.so $< +# SOLINK = $(SOLINK.cc) -o $@ $(LDFLAGS) $< +PRELIB = (echo "main() { }" > gcctemp.c && \ + $(COMPILE.cc) -o gcctemp.o gcctemp.c && \ + $(LINK.cc) -o gcctemp gcctemp.o $^ $(LDFLAGS) $(LIBS); \ + status=$$?; rm -f gcctemp*; exit $$status) diff --git a/include/makeinclude/rules.bin.GNU b/include/makeinclude/rules.bin.GNU new file mode 100644 index 00000000000..b546c9d43af --- /dev/null +++ b/include/makeinclude/rules.bin.GNU @@ -0,0 +1,12 @@ +#---------------------------------------------------------------------------- +# @(#)rules.bin.GNU 1.1 10/18/96 +# +# Build binaries +# GNU version +# Requires GNU make +#---------------------------------------------------------------------------- + +VBIN = $(BIN:%=%$(VAR)) + +$(BIN): %: $(VDIR)%.o $(VSHOBJS) + $(LINK.cc) -o $@ $< $(LDFLAGS) $(VLDLIBS) diff --git a/include/makeinclude/rules.common.GNU b/include/makeinclude/rules.common.GNU new file mode 100644 index 00000000000..c111b1996ea --- /dev/null +++ b/include/makeinclude/rules.common.GNU @@ -0,0 +1,17 @@ +#---------------------------------------------------------------------------- +# @(#)rules.common.GNU 1.1 10/18/96 +# +# Common targets +#---------------------------------------------------------------------------- + +all: all.nested all.local +debug: debug.nested debug.local +profile: profile.nested profile.local +install: install.nested install.local +deinstall: deinstall.nested deinstall.local +clean: clean.nested clean.local +realclean: realclean.nested realclean.local +clobber: clobber.nested clobber.local +depend: depend.nested depend.local +rcs_info: rcs_info.nested rcs_info.local + diff --git a/include/makeinclude/rules.lib.GNU b/include/makeinclude/rules.lib.GNU new file mode 100644 index 00000000000..f28213810a0 --- /dev/null +++ b/include/makeinclude/rules.lib.GNU @@ -0,0 +1,113 @@ +#---------------------------------------------------------------------------- +# @(#)rules.lib.GNU 1.1 10/18/96 +# +# Build libraries (i.e., contain no binary executables) +# GNU version +# Requires GNU make +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# The following targets arrange to build both unshared and shared libraries +#---------------------------------------------------------------------------- + +VSHLIB = $(SHLIB:%.so=%$(VAR).so) +VOBJS = $(LSRC:%.cpp=$(VDIR)%.o) + +ifdef TEMPINCDIR +VSHOBJS1 = +else +LSRC += $(LSRC2) +ifdef PRELIB +VSHOBJS = $(LSRC:%.cpp=$(VSHDIR)%.so) +VSHOBJS1 = $(VSHOBJS) +else +VSHOBJS = $(LSRC:%.cpp=$(VSHDIR)%.so) +VSHOBJS1 = $(LSRC:%.cpp=$(VSHDIR)%.o) +endif +endif + +# Comment out for now... +# $(DEFS:%=$(INSINC)/%) \ + +INSTALL = $(VLIB:%.a=$(INSLIB)/%.a) \ + $(VSHLIB:%.so=$(INSLIB)/%.so) + +ifdef PRELIB +# Unfortunately, gcc has to do a link of all of the objects (during which +# it may decide to recompile some of the objects), before we can safely build +# any libraries or shared objects. Comment this line if no shared +# libraries or objects are used. +$(VSHOBJS): $(VSHLIB) +endif + +# Comment these lines out if you want to build both *.a and *.so libraries... +#$(VSHLIB): $(VSHOBJS) $(STATLIB) +#ifdef PRELIB +# $(PRELIB) +#endif +# $(SOLINK.cc) -o $@ $(LDFLAGS) $(VSHDIR)*.o + +# Uncomment the remaining lines if you want to build both *.a and *.so libraries... +VLIB = $(LIB:%.a=%$(VAR).a) + +$(VLIB): $(VOBJS) +ifdef PRELIB + $(PRELIB) +endif + $(AR) $(ARFLAGS) $@ $? +ifdef TEMPINCDIR +# This is required for AIX!!! + if test -e xxx; \ + then \ + rm xxx; \ + fi + (if test -s ./$(TEMPINCDIR)/*.C; \ + then \ + while ! test -e xxx; \ + do \ + touch xxx; \ + cd ./$(TEMPINCDIR); \ + for temp in *.C; \ + do \ + if ! test -d ./$(TEMPINCDIR); \ + then \ + cd ..; \ + fi; \ + if $(COMPILE.cc) -o $(VDIR)$$temp.o ./$(TEMPINCDIR)/$$temp; \ + then \ + $(AR) $(ARFLAGS) $@ $(VDIR)$$temp.o;\ + else \ + rm $@; \ + rm xxx; \ + exit; \ + fi \ + done; \ + for temp in ./$(TEMPINCDIR)/*.C; \ + do \ + if test $$temp -nt xxx; \ + then \ + rm xxx; \ + break; \ + fi \ + done \ + done; \ + fi) + rm xxx +endif + -chmod a+r $@ + -$(RANLIB) $@ + +# Note that if you don't want to build shared libraries, just remove the $(VSHOBJS) +$(VSHLIB): $(VSHOBJS) $(STATLIB) +ifdef PRELIB + $(PRELIB) +endif + $(SOLINK.cc) -o $@ $(VSHOBJS1) $(LDFLAGS) $(LIBS) $(STATLIB) + -chmod a+rx $@ + +ifdef SHLIBA +$(SHLIBA): $(VSHLIB) + $(AR) $(ARFLAGS) $@ $? + -chmod a+rx $@ + -$(RANLIB) $@ +endif diff --git a/include/makeinclude/rules.local.GNU b/include/makeinclude/rules.local.GNU new file mode 100644 index 00000000000..1c3c30a44dd --- /dev/null +++ b/include/makeinclude/rules.local.GNU @@ -0,0 +1,151 @@ +#---------------------------------------------------------------------------- +# @(#)rules.local.GNU 1.1 10/18/96 +# +# Local targets +# GNU version +# Requires GNU make +#---------------------------------------------------------------------------- + +OBJDIRS = .obj .shobj # .obj_debug .obj_profile .obj_optimize + +all.local: build.objdirs build.local install.local + +#---------------------------------------------------------------------------- +# C/C++ compilation targets +#---------------------------------------------------------------------------- + +build.local: $(BUILD) + +# Set up the suffixes for C++ and IDL. +.SUFFIXES: +.SUFFIXES: .cpp .cc .C .idl $(SUFFIXES) + +# and here's how to compile C++ files from the IDL file. +# only ONE of these rules will be run at make-time, + +%S.cpp: %.idl + $(IDL) $(IDLFLAGS) $< + +%C.cpp: %.idl + $(IDL) $(IDLFLAGS) $< + +%.hh: %.idl + $(IDL) $(IDLFLAGS) $< + +# C++ related targets + +$(VDIR)%.o: %.c + $(COMPILE.c) -o $@ $< + +$(VDIR)%.o: %.cpp + $(COMPILE.cc) -o $@ $< + +#$(VDIR)%.o: %.C +# $(COMPILE.cc) -o $@ $< + +#$(VDIR)%.o: %.cc +# $(COMPILE.cc) -o $@ $< + +# If SOLINK is defined, then the .so file is built from the .o file via +# separate rules in the same directory. Otherwise, the .so and .o are +# built via the same rule. SOLINK is required for the repository under +# gcc. +ifndef SOLINK +$(VSHDIR)%.so: %.cpp + $(SOBUILD) +else +$(VSHDIR)%.o: %.cpp + $(COMPILE.cc) $(PIC) -o $@ $< +$(VSHDIR)%.o: %.cc + $(COMPILE.cc) $(PIC) -o $@ $< +$(VSHDIR)%.so: $(VSHDIR)%.o + $(SOLINK) +endif + +#---------------------------------------------------------------------------- +# Library generation targets +#---------------------------------------------------------------------------- + +.PRECIOUS: $(VLIB) + +#---------------------------------------------------------------------------- +# Installation targets +#---------------------------------------------------------------------------- + +install.local: $(INSTALL) + +deinstall.local: + $(RM) $(INSTALL) $(LIB:%.a=$(INSLIB)/%*.a) $(SHLIB:%.so=$(INSLIB)/%*.so) + +$(INSBIN)/%$(VAR) \ +$(INSINC)/ace% \ +$(INSLIB)/%$(VAR).a \ +$(INSLIB)/%$(VAR).so \ +$(INSMAN)/man1/% \ +$(INSMAN)/man2/% \ +$(INSMAN)/man3/% \ +$(INSMAN)/man4/% \ +$(INSMAN)/man5/% \ +$(INSMAN)/man6/% \ +$(INSMAN)/man7/% \ +$(INSMAN)/man8/% \ +$(INSMAN)/manl/% \ +$(INSMAN)/mann/% : + @if test -s $@ ; then \ + echo "$(@F) already installed" ; \ + else \ + echo "Installing $(@F) -> $(@D)" ; \ + ln -s $(shell pwd)/$(@F) $@ ; \ + fi + +#---------------------------------------------------------------------------- +# Cleanup targets +#---------------------------------------------------------------------------- + +clean.local: + -$(RM) -f *.o *~ *.bak *.rpo Makefile.old core + -$(RM) -rf $(OBJDIRS) $(TEMPINCDIR) ptrepository Templates.DB gcctemp.c + +realclean.local: clean.local + -$(RM) -f $(BIN:%=%) $(BIN:%=%_debug) $(BIN:%=%_profile) $(BIN:%=%_optimize) $(LIB:%=%) $(LIB:%=%_debug) $(LIB:%=%_profile) $(LIB:%=%_optimize) $(SHLIB:%=%) $(SHLIB:%=%_debug) $(SHLIB:%=%_profile) $(SHLIB:%=%_optimize) + +#---------------------------------------------------------------------------- +# Dependency generation target +#---------------------------------------------------------------------------- + +ifndef MAKEFILE +MAKEFILE=Makefile +endif + +depend.local: $(MAKEFILE) + @$(RM) -f $(MAKEFILE).old + @cp $(MAKEFILE) $(MAKEFILE).old + $(WRAPPER_ROOT)/bin/g++dep -f $(MAKEFILE) $(CPPFLAGS) $(LSRC) $(SRC) + @cat $(MAKEFILE) | \ + sed -e "s;$(WRAPPER_ROOT);\$$(WRAPPER_ROOT);g" \ + -e "s; /[-a-zA-Z0-9_./]*\.h;;g" \ + -e "/:$$/d" \ + -e "s;\([-a-zA-Z0-9._]*\)\.o:;.obj/\1.o .shobj/\1.so:;" \ + > $(MAKEFILE).new + @mv $(MAKEFILE).new $(MAKEFILE) + @if cmp -s $(MAKEFILE) $(MAKEFILE).old ;\ + then echo "Makefile dependencies unchanged." ;\ + else \ + echo "Makefile dependencies updated." ;\ + fi ;\ + $(RM) -f $(MAKEFILE).old ; +#---------------------------------------------------------------------------- +# RCS info target +#---------------------------------------------------------------------------- + +rcs_info.local: + @rcs info + +#---------------------------------------------------------------------------- +# Variant targets and conditional macros +#---------------------------------------------------------------------------- + +build.objdirs: $(OBJDIRS) + +$(OBJDIRS): + test -d $@ || mkdir $@ diff --git a/include/makeinclude/rules.nested.GNU b/include/makeinclude/rules.nested.GNU new file mode 100644 index 00000000000..bacf5604e8d --- /dev/null +++ b/include/makeinclude/rules.nested.GNU @@ -0,0 +1,15 @@ +#---------------------------------------------------------------------------- +# @(#)rules.nested.GNU 1.1 10/18/96 +# +# Nested directory targets makefile definitions +#---------------------------------------------------------------------------- + +$(TARGETS_NESTED): + @for dir in $(DIRS) ;\ + do \ + (cd $$dir ; \ + echo "" ; \ + echo " ========> Making $(@:.nested=) $(MAKEFLAGS): `pwd`"; \ + $(MAKE) $(@:.nested=) MAKEFLAGS=$(MAKEFLAGS) ; \ + echo "<======== End $(@:.nested=): `pwd`") \ + done diff --git a/include/makeinclude/rules.nolocal.GNU b/include/makeinclude/rules.nolocal.GNU new file mode 100644 index 00000000000..b71f6742c75 --- /dev/null +++ b/include/makeinclude/rules.nolocal.GNU @@ -0,0 +1,8 @@ +#---------------------------------------------------------------------------- +# @(#)rules.nolocal.GNU 1.1 10/18/96 +# +# Makefile for directories with no local build targets +#---------------------------------------------------------------------------- + +$(TARGETS_LOCAL): + diff --git a/include/makeinclude/rules.nonested.GNU b/include/makeinclude/rules.nonested.GNU new file mode 100644 index 00000000000..fc4f2b6de14 --- /dev/null +++ b/include/makeinclude/rules.nonested.GNU @@ -0,0 +1,8 @@ +#---------------------------------------------------------------------------- +# @(#)rules.nonested.GNU 1.1 10/18/96 +# +# Null nested targets +#---------------------------------------------------------------------------- + +$(TARGETS_NESTED): + diff --git a/include/makeinclude/wrapper_macros.GNU b/include/makeinclude/wrapper_macros.GNU new file mode 100644 index 00000000000..1a3c1cb6ab8 --- /dev/null +++ b/include/makeinclude/wrapper_macros.GNU @@ -0,0 +1,116 @@ +#---------------------------------------------------------------------------- +# @(#)wrapper_macros.GNU 1.1 10/18/96 +#---------------------------------------------------------------------------- +# +# Please see the README file in this directory to get a complete listing +# of all the platform compilation macros that may be defined to port ACE. + +# The following describes the ACE wrapper macros +# +# Variable Description +# -------- ----------- +# ARFLAGS Flags for the archive utility (ar) +# CC C compiler command +# CXX C++ compiler command +# COMPILE.c Flags for compiling with C +# COMPILE.cc Flags for compiling with C++ +# CPPFLAGS C pre-processor flags +# CFLAGS C compilation flags +# CCFLAGS C++ compilation flags +# DCFLAGS C compilation flags for debugging +# DCCFLAGS C++ compilation flags for debugging +# DEFFLAGS C++ preprocessor flag for defining symbols +# DLD Name of dynamic linker +# IDL Name of the CORBA IDL compiler +# INSBIN Binary (executable) installation directory +# INSINC Include file installation directory +# INSMAN Manpage installation directory +# INSLIB Library installation directory +# LDFLAGS ld linker flags +# LINK.c Flags for linking with C +# LINK.cc Flags for linking with C++ +# LINE_COMMAND A hook for passing commands to the linker, e.g., for Quantify +# MAKEFLAGS Flags that are passed into the compilation from the commandline +# OCFLAGS Optimizing C compilation flags +# OCCFLAGS Optimizing C++ compilation flags +# ORBIX_ROOT Root of IONA's Orbix CORBA implementation +# PCFLAGS C compilation flags for profiling +# PCCFLAGS C++ compilation flags for profiling +# PTDIRS Pathnames of directories containing template code +# RM Name of program to use to remove files +# SOFLAGS Flags used to build a shared library +# SOBUILD Link line necessary to build a share library +# VAR Variant identifier suffix +# VDIR Directory for object code +# VSHDIR Directory for shared object code +# WRAPPER_ROOT Pathname for the root of the build tree +# +#---------------------------------------------------------------------------- +# Platform-dependent macro definitions +# (link to the appropriate platform-specific config file). +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/platform_macros.GNU + +#---------------------------------------------------------------------------- +# Platform-independent macro definitions +#---------------------------------------------------------------------------- + +CPPFLAGS += $(DEFFLAGS) $(INCLDIRS) +DCFLAGS += -g +DCCFLAGS += -g +IDL = idl +IDLFLAGS = -s S.cpp -c C.cpp +INCLDIRS += -I$(WRAPPER_ROOT) -I. +INSBIN = $(WRAPPER_ROOT)/bin +INSINC = $(WRAPPER_ROOT)/ace +INSLIB = $(WRAPPER_ROOT)/ace +INSMAN = $(WRAPPER_ROOT)/man +LDFLAGS += -L$(WRAPPER_ROOT)/ace -L./ +LEX = flex +# LINK_COMMAND = quantify -cache-dir=/tmp/quantify +OCFLAGS += -O +OCCFLAGS += -O +PCFLAGS += # -p +PCCFLAGS += # -p +RM = /bin/rm +VAR = +VDIR = .obj/ +VSHDIR = .shobj/ +ifdef SHLIBA +VLDLIBS :=$(VLDLIBS) -lACEshr $(LIBS) +else +VLDLIBS :=$(VLDLIBS) -lACE $(LIBS) +endif +YACC = yacc + +#---------------------------------------------------------------------------- +# Conditional macro definitions +#---------------------------------------------------------------------------- + +ifdef debug +CFLAGS += $(DCFLAGS) +CCFLAGS += $(DCCFLAGS) + +else +ifdef profile +CFLAGS += $(PCFLAGS) +CCFLAGS += $(PCCFLAGS) + +else +ifdef optimize +CFLAGS += $(OCFLAGS) #-DNDEBUG +CCFLAGS += $(OCCFLAGS) #-DNDEBUG + +else # default settings +CFLAGS += $(DCFLAGS) #-DNDEBUG +CCFLAGS += $(DCCFLAGS) #-DNDEBUG +endif # optimize +endif # profile +endif # debug + +COMPILE.c =$(CC) $(CFLAGS) $(CPPFLAGS) -c +COMPILE.cc =$(CXX) $(CCFLAGS) $(CPPFLAGS) $(PTDIRS) -c +LINK.c =$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(LDLIBS) $(LIBS) +LINK.cc =$(CXX) $(CCFLAGS) $(CPPFLAGS) $(PTDIRS) +SOLINK.cc =$(LINK_COMMAND) $(DLD) $(SOFLAGS) diff --git a/netsvcs/ACE-netsvcs.html b/netsvcs/ACE-netsvcs.html new file mode 100644 index 00000000000..1fef080dc3e --- /dev/null +++ b/netsvcs/ACE-netsvcs.html @@ -0,0 +1,895 @@ + + + +Overview of the ACE Network Services + + + +


    +

    Overview of the ACE Network Services

    + +ACE provides a +standard library of network +services:

    + + + + + +
    + + + +
    + +These services play two roles in ACE:

    + +

    + +The heart of the ACE network services is the Service +Configurator, which is an object-oriented framework that automates +the configuration and reconfiguration of multi-service daemons. All +the ACE network services are configured using the Service +Configurator. Please refer to the online documentation for more +information on installing and testing the ACE network services.

    + +


    + +

    Overview of Naming Service

    + +A Naming Service associates names with values in a distributed +system. Clients can query these values using these names as keys. Such +a name-to-value association is called a Name Binding . Name +bindings are defined relative to a Naming Context . A naming +context is a collection that contains a set of name bindings in which +each name is unique. Different names can be bound to the same value in +the same or different naming contexts at the same time. There are +three types of naming contexts:

    + +

      +
    1. Process Local Naming Context: Name bindings are accessible from +processes with the same name running on the same host.

      +

    2. Node Local Naming Context: Name bindings are accessible from all +processes running on the same host.

      +

    3. Network Local Naming Context: Name bindings are accessible from +all processes running on any machine within a (sub)network.

      +

    + +

    +To bind a name is to create a name binding in a given context. +Querying a value using a name determines the value associated with the +name in a given context. Note that a name is always bound relative to +a context. Thus, there are no absolute names.

    + +The following are the key classes in the ACE Naming Service:

    + +

      +
    • Class Naming_Context

      + +This is the main class ``entry point'' into the Naming Service. It is +used both by client processes and by server process. It manages access +to the appropriate Name/Binding database (that is the file where +Name/Bindings are stored) and it also manages the communication +between a client process and the server (by using class Name_Proxy, +which is a private member of Naming_Context). If a client process +runs on the same host as the server no IPC is necessary because the +Naming_Context uses shared memory.

      + +

    • Class Name_Acceptor

      + +The Name_Acceptor allocates in its handle_input() routine a new +instance of class Name_Handler on the heap, and accepts connections +into this Name_Handler.

      + +

    • Class Name_Handler

      + +The class Name_Handler represents the server side of communication +between client and server. It interprets incoming requests to the +Net_Local namespace and delegates the requests to its own +Naming_Context (which is the Net_Local namespace on the current +host). For communication it uses the helper classes Name_Request and +Name_Reply.

      + +

    • Dependencies

      + +The ACE Naming Service uses ACE_WString String classes since it must +handle wide character strings in order to support +internationalization.

      +

    + +The following describes how to configure the Name_Server server and +client test applications.

    + +

      +
    • Startup configuration

      +Configuring a Name_Server server or client requires specifying all or +some of the following parameters. These parameters can be passed in to +main through command line as follows:

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + Option + + Description + + Default value +
      +-c <naming context>
      +
      +Naming Context to use. Can be either "PROC_LOCAL" or "NODE_LOCAL" or +"NET_LOCAL"
      +
      +PROC_LOCAL +
      +-h <hostname> + +Specify the server hostname (needed by Name Server clients for +PROC_LOCAL naming context) + +ACE_DEFAULT_SERVER_HOST +
      +-p <nameserver port>
      +
      +Port number where the server process expects requests
      +
      +ACE_DEFAULT_SERVER_PORT +
      +-l <namespace dir>
      +
      +Directory that holds the NameBinding databases
      +
      +ACE_DEFAULT_NAMESPACE_DIR +
      +-P <process name>
      +
      +Name of the client process + +argv[0] +
      +-s <database name>
      +
      +Name of the database. NameBindings for the appropriate naming context +are stored in file <namespace_dir>/<database name>. + + null +
      +-d <debug> + +Turn debugging on/off + +0 (off) +
      +-T <trace> + +Turn tracing on/off + +0 (off) +
      +-v <verbose> + +Turn verbose on/off + +0 (off) +
      +

      + +

    • Examples

      +

        +
      1. Here is what a config file would look like for starting up a +server at port 20222 using NET_LOCAL naming context with database +called MYDATABSE located in directory /tmp: + +
         
        +dynamic Naming_Service Service_Object * 
        +  ../lib/libnetsvcs.so:_make_ACE_Name_Acceptor() 
        +  "-p 20222 -c NET_LOCAL -l /tmp -s MYDATABASE"
        +
        + +
      2. Here is what a config file would look like for starting up a +client that connects to a Name Server running on host +tango.cs.wustl.edu at port 20222: + +
         
        +dynamic Naming_Service_Client Service_Object * 
        +  ../lib/libnetsvcs.so:_make_Client_Test() 
        +  "-h tango.cs.wustl.edu -p 20222"
        +
        +
      + +Note:

      +

        +
      • These files would vary if the services are run on NT. For +example, instead of using *.so, we would have to use *.dll.

        +

      • Values for parameters can also be passed in using environment +variables. For example, instead of specifying absolute hostname or +port numbers in the config file, we can use $HOST and $PORT, +respectively, in the file (assuming that these environment variables +have been set).

        +

      • If the environment variable LD_LIBRARY_PATH (in the case of UNIX) +or PATH (in the case of Win32) contains the path to the shared object +files or dll, then the config file can be further simplified. Instead +of specifying an absolute path to the shared object or dll, only the +name of the shared object or dll would suffice. That is, the Service +Configurator makes use of LD_LIBRARY_PATH (on UNIX) or PATH (on Win32) +to look for the shared object files or dlls. +
      + +
    + +


    + +

    Overview of Time Service

    + +Time Service provides accurate, fault-tolerant clock synchronization +for computers collaborating in local area networks and wide area +networks. Synchronized time services are important in distributed +systems that require multiple hosts to maintain accurate global +time. The architecture of the distributed time service contains the +following Time Server, Clerk, and Client components:

    + +

      +
    • Time Server answers queries about the time made by +Clerks.

      + +

    • Clerk queries one or more Time Servers to determine +the correct time, calculates the approximate correct time using one of +several distributed time algorithms and updates its own local system +time.

      + +

    • Client uses the global time information maintained by +a Clerk to provide consistency with the notion of time used by clients +on other hosts.

      +

    +

    +The following are the key classes in the ACE Time Service:

    + +

      +
    • Class TS_Server_Handler

      + +TS_Server_Handler represents the server side of communication between +clerk and server. It interprets incoming requests for time updates, +gets the system time, creates a reply in response to the request and +then sends the reply to the clerk from which it received the request. +For communication it uses the helper class Time_Request.

      + +

    • Class TS_Server_Acceptor

      + +TS_Server_Acceptor allocates in its handle_input routine a new instance +of class TS_Server_Handler on the heap, and accepts connections into this +TS_Server_Handler.

      + +

    • Class TS_Clerk_Handler

      + +TS_Clerk_Handler represents the clerk side of communication between +clerk and server. It generates requests for time updates every timeout +period and then sends these requests to all the servers it is +connected to asynchronously. It receives the replies to these requests +from the servers through its handle_input method and then adjusts the +time using the roundtrip estimate. It caches this time, which is +subsequently retrieved by TS_Clerk_Processor.

      + +

    • Class TS_Clerk_Processor

      + +TS_Clerk_Processor creates a new instance of TS_Clerk_Handler for +every server connection it needs to create. It periodically calls +send_request() of every TS_Clerk_Handler to send a request for time +update to all the servers. In the process, it retrieves the latest +time cached by each TS_Clerk_Handler and then uses it to compute its +notion of the local system time.

      + +

    • Algorithms

      + +Currently, updating the system time involves taking the average of all +the times received from the servers.

      +

    + +The following is a description of how to configure the Time Server +clerk and server services:

    + +

      + +
    • Startup configuration

      + +Configuring a server requires specifying the port number of the +server. This can be specified as a command line argument as follows:

      + + -p <port number> + +

      +A clerk communicates with one or more server processes. To communicate +with the server process, a client needs to know the INET_Addr, where +the server offers its service. The configuration parameters namely the +server port and server host are passed as command line arguments when +starting up the clerk service as follows:

      + + -h <server host1>:<server port1> -h <server host2>:<server port2> ... +

      +Note that multiple servers can be specified in this manner for the +clerk to connect to when it starts up. The server name and the port +number need to be concatenated and separated by a ":". In addition, +the timeout value can also be specified as a command line argument as +follows: +

      + + -t timeout + +

      +The timeout value specifies the time interval at which the clerk +should query the servers for time updates. +

      +By default a Clerk does a non-blocking connect to a server. This can +be overridden and a Clerk can be made to do a blocking connect by +using the -b flag. +

      + +

    • Examples

      +

        +
      1. Here is what a config file would look like for starting up a +server at port 20202: + +
         
        +dynamic Time_Service Service_Object * 
        +  ../lib/libnetsvcs.so:_make_ACE_TS_Server_Acceptor() 
        +  "-p 20202"
        +
        + +
      2. Here is what a config file would look like for starting up a +clerk that needs to connect to two servers, one at tango and one at +lambada: + +
         
        +dynamic Time_Server_test Service_Object *
        +  ../lib/libnetsvcs.so:_make_ACE_TS_Clerk_Connector () 
        +  "-h tango:20202 -h lambada:20202 -t 4"
        +
        +
      + +Note:

      +

        +
      • These files would vary if the services are run on NT. For +example, instead of using *.so, we would have to use *.dll.

        +

      • Values for parameters can also be passed in using environment +variables. For example, instead of specifying absolute hostname or +port numbers in the config file, we can use $HOST and $PORT, +respectively, in the file (assuming that these environment variables +have been set).

        +

      • If the environment variable LD_LIBRARY_PATH (in the case of UNIX) +or PATH (in the case of Win32) contains the path to the shared object +files or dll, then the config file can be further simplified. Instead +of specifying an absolute path to the shared object or dll, only the +name of the shared object or dll would suffice. That is, the Service +Configurator makes use of LD_LIBRARY_PATH (on UNIX) or PATH (on Win32) +to look for the shared object files or dlls. +
      +

      + +

    + +


    +

    Token Service

    + +The ACE Token Service provides local and remove mutexes and +readers/writer locks. For information regarding the deadlock +detection algorithm, check out ACE_Token_Manager.h. For information +about an implementation of the Composite Pattern for Tokens, check out +Token_Collection.h. The classes which implement the local and remote +synchronization primitives are listed below:

    + +

      +
    • ACE_Local_Mutex

      + + This class is a more general-purpose synchronization mechanism + than SunOS 5.x mutexes. For example, it implements "recursive + mutex" semantics, where a thread that owns the token can + reacquire it without deadlocking. In addition, threads that + are blocked awaiting the token are serviced in strict FIFO + order as other threads release the token (SunOS 5.x mutexes + don't strictly enforce an acquisition order). Lastly, + ACE_Local_Mutex performs deadlock detection on acquire + calls.

      + +

    • ACE_Remote_Mutex

      + + This is the remote equivalent to ACE_Local_Mutex. The + Remote_Mutex class offers methods for acquiring, renewing, and + releasing a distributed synchronization mutex. Similar to + ACE_Local_Mutex, ACE_Remote_Token_Proxy offers recursive + acquisition, FIFO waiter ordering, and deadlock detection. It + depends on the Token Server for its distributed synchronization + semantics.

      + +

    • ACE_Local_RLock

      + + This class implements the reader interface to canonical + readers/writer locks. Multiple readers can hold the lock + simultaneously when no writers have the lock. Alternatively, + when a writer holds the lock, no other participants (readers or + writers) may hold the lock. This class is a more + general-purpose synchronization mechanism than SunOS 5.x + RLocks. For example, it implements "recursive RLock" + semantics, where a thread that owns the token can reacquire it + without deadlocking. In addition, threads that are blocked + awaiting the token are serviced in strict FIFO order as other + threads release the token (SunOS 5.x RLockes don't strictly + enforce an acquisition order).

      + +

    • ACE_Local_WLock

      + + This class implements the writer interface to canonical + readers/writer locks. Multiple readers can hold the lock + simultaneously when no writers have the lock. Alternatively, + when a writer holds the lock, no other participants (readers or + writers) may hold the lock. This class is a more + general-purpose synchronization mechanism than SunOS 5.x WLock. + For example, it implements "recursive WLock" semantics, where a + thread that owns the token can reacquire it without + deadlocking. In addition, threads that are blocked awaiting + the token are serviced in strict FIFO order as other threads + release the token (SunOS 5.x WLocks don't strictly enforce an + acquisition order).

      + +

    • ACE_Remote_RLock

      + + This is the remote equivalent to ACE_Local_RLock. Multiple + readers can hold the lock simultaneously when no writers have + the lock. Alternatively, when a writer holds the lock, no + other participants (readers or writers) may hold the lock. + ACE_Remote_RLock depends on the ACE Token Server for its + distributed synchronization semantics.

      + +

    • ACE_Remote_RLock

      + + This is the remote equivalent to ACE_Local_WLock.

      +

    + +The Token Server provides distributed mutex and readers/writer lock +semantics to the ACE Token library. ACE_Remote_Mutex, +ACE_Remote_RLock, and ACE_Remote_WLock, are proxies to the Token +Server. The following are the key classes in the ACE Token +Server:

    + +

      +
    • class Token_Acceptor

      + + The Token_Acceptor is a Token_Handler factory. It accepts + connections and passes the service responsibilities off to a + new Token_Handler.

      + +

    • class Token_Handler

      + + This class is the main class ``entry point'' of the ACE Token service. It + receives token operation requests from remote clients and turns + them into calls on local tokens (acquire, release, renew, and + remove). In OMG CORBA terminology, it is an ``Object Adapter.'' It also + schedules and handles timeouts that are used to support "timed + waits." Clients used timed waits to bound the amount of time + they block trying to get a token.

      +

    + +The following describes how to configure the Token Server:

    +

      +
    • Startup configuration

      + + The only parameter that the Token Server takes is a listen port + number. You can specify a port number by passing a "-p + " to the application. This can be done via the + svc.conf file.

      + +

    • Examples

      + + Here is an example NT svc.conf entry that dynamically loads the + Token Server specifying port number to listen on for client + connections:

      + +

      +        dynamic Token_Service Service_Object * 
      +          ../../ace/libnet_svcs.dll:_make_ACE_Token_Acceptor() 
      +          "-p 10202"
      +       
      +

      + + Here is an example UNIX svc.conf entry that dynamically loads the + Token Server specifying port number to listen on for client + connections. Notice that only the name of the library file + changed:

      + +

      +          dynamic Token_Service Service_Object * 
      +            ../../ace/netsvcs.so:_make_ACE_Token_Acceptor() 
      +            "-p 10202"
      +      
      +
    +Note:

    +

      +
    • These files would vary if the services are run on NT. For +example, instead of using *.so, we would have to use *.dll.

      +

    • Values for parameters can also be passed in using environment +variables. For example, instead of specifying absolute hostname or +port numbers in the config file, we can use $HOST and $PORT, +respectively, in the file (assuming that these environment variables +have been set).

      +

    • If the environment variable LD_LIBRARY_PATH (in the case of UNIX) +or PATH (in the case of Win32) contains the path to the shared object +files or dll, then the config file can be further simplified. Instead +of specifying an absolute path to the shared object or dll, only the +name of the shared object or dll would suffice. That is, the Service +Configurator makes use of LD_LIBRARY_PATH (on UNIX) or PATH (on Win32) +to look for the shared object files or dlls. +
    + + +


    + +

    Overview of Server Logging Service

    + +The Server Logging Service provides a concurrent, multi-service daemon +that processes logging records received from one or more client hosts +simultaneously. The object-oriented design of the Server Logging +Service is decomposed into several modular components that perform +well-defined tasks.

    + +The following are the key classes in the Server Logging Service:

    +

      +
    • Server_Logging_Handler

      +The Server_Logging_Handler class is a parameterized type that is +responsible for processing logging records sent to the Server from +participating client hosts. When logging records arrive from the +client host associated with a particular Logging Handler object, the +handle_input() method of the Server_Logging_Handler class is called +which in turn formats and displays the records on one or more output +devices (such as the printer, persistent storage, and/or console +devices.

      + +

    • Server_Logging_Acceptor

      +The class Server_Logging_Acceptor allocates in its handle_input() +routine a new instance of class Server_Logging_Handler on the heap, +and accepts connections into this Server_Logging_Handler.

      +

    + +The following describes how to configure the Logging Server:

    +

      +
    • Startup configuration

      + + The only parameter that the Logging Server takes is a listen + port number. You can specify a port number by passing a "-p + " to the application. This can be done via the + svc.conf file.

      + +

    • Examples

      + + Here is an example NT svc.conf entry that dynamically loads the + Logging Server specifying port number to listen on for client + connections:

      + +

       
      +      dynamic Server_Logging_Service Service_Object * 
      +        ../../ace/libnet_svcs.dll:_make_ACE_Server_Logging_Acceptor() 
      +        "-p 10202"
      +      
      +

      + + Here is an example UNIX svc.conf entry that dynamically loads the + Logging Server specifying port number to listen on for client + connections. Notice that only the name of the library file + changed:

      + +

       
      +      dynamic Server_Logging_Service Service_Object * 
      +        ../../ace/netsvcs.so:_make_ACE_Server_Logging_Acceptor() 
      +        "-p 10202"
      +      
      +
    +Note:

    +

      +
    • These files would vary if the services are run on NT. For +example, instead of using *.so, we would have to use *.dll.

      +

    • Values for parameters can also be passed in using environment +variables. For example, instead of specifying absolute hostname or +port numbers in the config file, we can use $HOST and $PORT, +respectively, in the file (assuming that these environment variables +have been set).

      +

    • If the environment variable LD_LIBRARY_PATH (in the case of UNIX) +or PATH (in the case of Win32) contains the path to the shared object +files or dll, then the config file can be further simplified. Instead +of specifying an absolute path to the shared object or dll, only the +name of the shared object or dll would suffice. That is, the Service +Configurator makes use of LD_LIBRARY_PATH (on UNIX) or PATH (on Win32) +to look for the shared object files or dlls. +
    + +


    + +

    Overview of Client Logging Service

    + +The Client Logging Service multiplexes messages recevied from +different applications to the Server Logging Daemon running on a +designated host in a network/internetwork. + + +The following are the key classes in the Client Logging Service:

    +

      +
    • Client_Logging_Handler

      +The Client_Logging_Handler class is a parameterized type that is +responsible for setting up a named pipe and using it to communicate +with different user processes on the same host. Once logging records +arrive from these processes, the handler reads these records in +priority order, performs network-byte order conversions on +multiple-header fields, and then transmits these records to the Server +Logging daemon across the network.

      + +

    • Client_Logging_Connector

      +The class Client_Logging_Connector connects to the Server Logging +daemon and then in its handle_input() routine it allocates a new +instance of the Client_Logging_Handler on the heap.

      +

    + +The following describes how to configure the Logging Client:

    +

      +
    • Startup configuration

      + +Configuring a Logging Client requires specifying all or some of the +following parameters. These parameters can be passed in to main +through command line as follows:

      + + + + + + + + + + + + + + + + + +
      + Option + + Description + + Default value +
      +-h &hostname>
      +
      +Hostname of the Server Logging Daemon
      +
      +ACE_DEFAULT_SERVER_HOST +
      +-p <port number> + +Port number of the Server Logging Daemon
      +
      +ACE_DEFAULT_LOGGING_SERVER_PORT +
      +-p <rendezvous key> + +Rendezvous key used to create named pipe + +ACE_DEFAULT_RENDEZVOUS +
      +

      + +

    • Examples

      + + Here is an example NT svc.conf entry that dynamically loads the + Logging Client specifying host name and port number of the + Logging Server:

      + +

       
      +      dynamic Client_Logging_Service Service_Object * 
      +        ../../ace/libnet_svcs.dll:_make_ACE_Client_Logging_Connector() 
      +        "-h tango.cs.wustl.edu -p 10202"
      +      
      +

      + + Here is an example UNIX svc.conf entry that dynamically loads the + Logging Client specifying host name and port number of the + Logging Server. Notice that only the name of the library file + changed:

      + +

       
      +      dynamic Client_Logging_Service Service_Object * 
      +        ../../ace/netsvcs.so:_make_ACE_Client_Logging_Connector() 
      +        "-h tango.cs.wustl.edu -p 10202"
      +      
      +
    +Note:

    +

      +
    • These files would vary if the services are run on NT. For +example, instead of using *.so, we would have to use *.dll.

      +

    • Values for parameters can also be passed in using environment +variables. For example, instead of specifying absolute hostname or +port numbers in the config file, we can use $HOST and $PORT, +respectively, in the file (assuming that these environment variables +have been set).

      +

    • If the environment variable LD_LIBRARY_PATH (in the case of UNIX) +or PATH (in the case of Win32) contains the path to the shared object +files or dll, then the config file can be further simplified. Instead +of specifying an absolute path to the shared object or dll, only the +name of the shared object or dll would suffice. That is, the Service +Configurator makes use of LD_LIBRARY_PATH (on UNIX) or PATH (on Win32) +to look for the shared object files or dlls. +
    + +


    + +

    Overview of Logging Strategy Service

    + +The Logging Strategy Service can be used to control the output of all the +network services. It can be invoked with certain flags that determine +where the output of all the services should go. The Logging Strategy +Service sets the flags in ACE_Log_Msg, which controls all the streams +through macros such as ACE_DEBUG, ACE_ERROR, and ACE_ERROR_RETURN. If +default behavior is required, the Logging Strategy Service need not be +invoked or it can be invoked with no parameters.

    + +The following describes how to configure the Logging Strategy +Service:

    + +

      +
    • Startup configuration

      + +Here are the command line arguments that can be given to the Logging +Strategy Service:

      + + -f <flag1>|<flag2>|<flag3> (etc...)

      + + where a flag can be any of the following:

      + + + + + + + + + + + + + + + + + + + + +
      + Flags + + Description +
      + STDERR
      +
      + Write messages to stderr.
      +
      + LOGGER
      +
      + Write messages to the local client logger deamon.
      +
      + OSTREAM
      +
      + Write messages to the ostream that gets created by specifying a + filename (see below)
      +
      + VERBOSE
      +
      + Display messages in a verbose manner
      +
      + SILENT
      +
      + Do not print messages at all
      +
      +

      + +Note: If more than one flag is specified, the flags need to be 'OR'ed +as above syntax shows. Make sure there is no space in between the flag +and '|'.

      + + -s filename +

      + +If the OSTREAM flag is set, this can be used to specify the filename +where the output should be directed. Note that if the OSTREAM flag is +set and no filename is specified, ACE_DEFAULT_LOGFILE will be used to +write the output to.

      + +

    • Examples:

      +

        +
      1. To direct output only to STDERR, specify command line arguments as:

        + "-f STDERR" +

        + +

      2. To direct output to both STDERR and a file called "mylog", specify +command line arguments as:

        + "-f STDERR|OSTREAM -s mylog" +

      +Note:

      +

        +
      • These files would vary if the services are run on NT. For +example, instead of using *.so, we would have to use *.dll.

        +

      • Values for parameters can also be passed in using environment +variables. For example, instead of specifying absolute hostname or +port numbers in the config file, we can use $HOST and $PORT, +respectively, in the file (assuming that these environment variables +have been set).

        +

      • If the environment variable LD_LIBRARY_PATH (in the case of UNIX) +or PATH (in the case of Win32) contains the path to the shared object +files or dll, then the config file can be further simplified. Instead +of specifying an absolute path to the shared object or dll, only the +name of the shared object or dll would suffice. That is, the Service +Configurator makes use of LD_LIBRARY_PATH (on UNIX) or PATH (on Win32) +to look for the shared object files or dlls. +
      +
    + +


    +Back to the +ACE home page. diff --git a/netsvcs/Makefile b/netsvcs/Makefile new file mode 100644 index 00000000000..c9e4b544788 --- /dev/null +++ b/netsvcs/Makefile @@ -0,0 +1,27 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the ACE network services +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +INFO = README + +# lib must come first! +DIRS = lib \ + clients \ + servers + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + diff --git a/netsvcs/README b/netsvcs/README new file mode 100644 index 00000000000..e9dff4c7dfc --- /dev/null +++ b/netsvcs/README @@ -0,0 +1,20 @@ +This directory contains the ACE network service implementations and +sample driver programs for dynamically configuring them into client +and server processes. The subdirectories include the following: + + . lib -- contains implementations of the ACE network services. + These services include a logging service, a name service, + a distributed locking service, and a distributed time service. + These can be built as shared libraries (i.e., DLLs), which + are then linked into applications either statically or + dynamically. + + . servers -- contains the driver program that links the various + services together, either statically or dynamically, to + form complete server programs. + + . clients -- contains a number of test programs that illustrate + how to write clients for the various ACE network services. + +Please see the ACE-netsvcs.html file for an overview of the various +services. diff --git a/netsvcs/clients/Logger/Makefile b/netsvcs/clients/Logger/Makefile new file mode 100644 index 00000000000..bc9a34890f3 --- /dev/null +++ b/netsvcs/clients/Logger/Makefile @@ -0,0 +1,77 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for client logging applications +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = direct_logging \ + indirect_logging + +LSRC = $(addsuffix .cpp,$(BIN)) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/direct_logging.o .shobj/direct_logging.so: direct_logging.cpp \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i +.obj/indirect_logging.o .shobj/indirect_logging.so: indirect_logging.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/clients/Logger/README b/netsvcs/clients/Logger/README new file mode 100644 index 00000000000..87e324ab0d8 --- /dev/null +++ b/netsvcs/clients/Logger/README @@ -0,0 +1,18 @@ +This directory contains two sample logging applications that implement +and test the ACE distributed logging service. + + . indirect_logging.cpp + + This program talks to the ACE Client Logging Daemon on + the localhost, which forwards the messages to Server + Logging Daemon. The Client Logging Daemon and Server + Logging Daemon both must be started before you can run + this test. + + . direct_logging.cpp + + This program talks directly to the Server Logging + Daemon. The Server Logging Daemon must be started + before you can run this test. + +To start these daemons, please check out the ../../servers/ directory. diff --git a/netsvcs/clients/Logger/direct_logging.cpp b/netsvcs/clients/Logger/direct_logging.cpp new file mode 100644 index 00000000000..26b63657efd --- /dev/null +++ b/netsvcs/clients/Logger/direct_logging.cpp @@ -0,0 +1,42 @@ +// This program sends logging records directly to the server, rather +// @(#)direct_logging.cpp 1.1 10/18/96 + +// than going through the client logging daemon. + +#include "ace/SOCK_Connector.h" +#include "ace/Log_Msg.h" +#include "ace/Log_Record.h" + +static u_short LOGGER_PORT = ACE_DEFAULT_SERVER_PORT; +static const char *const LOGGER_HOST = ACE_DEFAULT_SERVER_HOST; +static const char *const DATA = "hello world\n"; + +int +main (int argc, char *argv[]) +{ + u_short logger_port = argc > 1 ? atoi (argv[1]) : LOGGER_PORT; + const char *logger_host = argc > 2 ? argv[2] : LOGGER_HOST; + + ACE_SOCK_Stream logger; + ACE_SOCK_Connector connector; + ACE_INET_Addr addr (logger_port, logger_host); + ACE_Log_Record log_record (LM_DEBUG, + ACE_OS::time ((time_t *) 0), + ACE_OS::getpid ()); + + if (connector.connect (logger, addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + + log_record.msg_data (DATA); + size_t len = log_record.length (); + size_t encoded_len = htonl (len); + + log_record.encode (); + + if (logger.send (4, &encoded_len, sizeof encoded_len, + (char *) &log_record, len) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), -1); + else if (logger.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), -1); + return 0; +} diff --git a/netsvcs/clients/Logger/indirect_logging.cpp b/netsvcs/clients/Logger/indirect_logging.cpp new file mode 100644 index 00000000000..8b1ac5841f7 --- /dev/null +++ b/netsvcs/clients/Logger/indirect_logging.cpp @@ -0,0 +1,34 @@ +// This is a simple test that sends logging records to the Client +// @(#)indirect_logging.cpp 1.1 10/18/96 + +// Logging Daemon running on the localhost. This daemon then forwards +// them to the Server Logging Daemon. If there is no Server Logging +// Daemon, the logging records will be written to stderr. + +#include "ace/Log_Msg.h" + +int +main (int argc, char *argv[]) +{ + char *prog_name = argv[0]; + int iterations = argc < 2 ? 10 : ACE_OS::atoi (argv[1]); + char *logger_key = argc < 3 ? ACE_DEFAULT_RENDEZVOUS : argv[2]; + + ACE_OS::srand ((u_int) ACE_OS::time (0)); + + ACE_LOG_MSG->open (prog_name, ACE_Log_Msg::LOGGER, logger_key); + + ACE_DEBUG ((LM_STARTUP, "starting up the test\n")); + + for (int i = 0; i < iterations; i++) + { + int priority = ACE_OS::rand () % int (LM_MAX); + ACE_POW (priority); + ACE_DEBUG ((ACE_Log_Priority (priority), + "random message %d...\n", + priority)); + } + + ACE_DEBUG ((LM_SHUTDOWN, "closing down the test\n")); + return 0; +} diff --git a/netsvcs/clients/Makefile b/netsvcs/clients/Makefile new file mode 100644 index 00000000000..9e5d9d5025a --- /dev/null +++ b/netsvcs/clients/Makefile @@ -0,0 +1,24 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the client programs that test the ACE network services +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +DIRS = Logger \ + Naming \ + Tokens + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + diff --git a/netsvcs/clients/Naming/Client/Client_Test.cpp b/netsvcs/clients/Naming/Client/Client_Test.cpp new file mode 100644 index 00000000000..da1c4c0836c --- /dev/null +++ b/netsvcs/clients/Naming/Client/Client_Test.cpp @@ -0,0 +1,561 @@ +#define ACE_BUILD_SVC_DLL +// @(#)Client_Test.cpp 1.1 10/18/96 + +#include "ace/Service_Config.h" +#include "ace/Naming_Context.h" +#include "ace/Dynamic_Service.h" +#include "Client_Test.h" + +class ACE_Svc_Export Client_Test : public ACE_Service_Object +{ +public: + Client_Test (void); + + int open (void); + // Cache reactor and then register self with reactor + + int close (void); + // Close things down and free up resources. + + virtual int handle_input (ACE_HANDLE handle); + // Handle user entered commands + + virtual int init (int argc, char *argv[]); + // Initialize name options and naming context when dynamically + // linked. + + virtual int fini (void); + // Close down the test when dynamically unlinked. + + void list_options (void); + // Print name options + + int bind (char *key, char *value, char *type = ""); + // Bind a key to a value + + int unbind (char *key); + // Unbind a name binding + + int rebind (char *key, char *value, char *type = ""); + // Rebind a name binding + + int find (char *key); + // Find the value associated with a key + + int list_names (char *pattern); + // Find all names that match pattern + + int list_values (char *pattern); + // Find all values that match pattern + + int list_types (char *pattern); + // Find all types that match pattern + + int list_name_entries (char *pattern); + // Find all names that match pattern + + int list_value_entries (char *pattern); + // Find all values that match pattern + + int list_type_entries (char *pattern); + // Find all types that match pattern + +private: + ACE_Name_Options *name_options_; + // Name Options associated with the Naming Context + + void display_menu (void); + // Display user menu + + int set_proc_local (void); + // Set options to use PROC_LOCAL naming context + + int set_node_local (void); + // Set options to use NODE_LOCAL naming context + + int set_host (char *hostname, int port); + // Set options to use NET_LOCAL naming context + // specifying host name and port number + + int quit (void); + // Gracefully exit +}; + +// The following Factory is used by the ACE_Service_Config and +// svc.conf file to dynamically initialize the state of the client +// test. + +ACE_SVC_FACTORY_DEFINE (Client_Test) + +// Get the instance of Name_Service using Dynamic_Service + +//inline Name_Service * +//NAME_SERVICE (void) + +inline ACE_Naming_Context * +NAMING_CONTEXT (void) +{ + return ACE_Dynamic_Service::instance ("ACE_Naming_Context"); +} + +Client_Test::Client_Test (void) +{ + ACE_DEBUG ((LM_DEBUG, "Client_Test::Client_Test\n")); +} + +int +Client_Test::init (int argc, char *argv[]) +{ + ACE_DEBUG ((LM_DEBUG, "Client_Test::init\n")); + + // Cache the name options. + this->name_options_ = NAMING_CONTEXT ()->name_options (); + return this->open (); +} + +int +Client_Test::open (void) +{ + this->display_menu (); + + if (ACE::register_stdin_handler (this, + ACE_Service_Config::reactor (), + ACE_Service_Config::thr_mgr ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "register_stdin_handler"), -1); +} + + +int +Client_Test::close (void) +{ + // Deregister this handler with the ACE_Reactor. + return ACE_Service_Config::reactor ()->remove_handler + (ACE_STDIN, + ACE_Event_Handler::DONT_CALL | ACE_Event_Handler::READ_MASK); +} + +int +Client_Test::fini (void) +{ + ACE_DEBUG ((LM_DEBUG, "Client_Test::fini\n")); + return this->close (); +} + +int +Client_Test::handle_input (ACE_HANDLE) +{ + char option[BUFSIZ]; + char buf1[BUFSIZ]; + char buf2[BUFSIZ]; + char buf3[BUFSIZ]; + char *temp_buf; + int port; + char input[256]; + + if (::scanf ("%s", option) <= 0) + { + ACE_ERROR_RETURN ((LM_ERROR, "%p Try again!\n", + "Client_Test::handle_input"), 0); + } + + int result = -1; + + switch (isupper (option[0]) ? tolower (option[0]) : option[0]) + { + case 'p' : + result = this->set_proc_local (); + break; + case 'n' : + result = this->set_node_local (); + break; + case 'h' : + if (::scanf ("%s %d", buf1, &port) <= 0) + break; + result = this->set_host (buf1, port); + break; + case 'b' : + // get the input from stdin + ACE_OS::gets (input); + + // get the key + if (temp_buf = ACE_OS::strtok (input, " ")) + { + ACE_OS::strcpy (buf1, temp_buf); + + // get the value + if (temp_buf = ACE_OS::strtok (0, " ")) + { + ACE_OS::strcpy (buf2, temp_buf); + + // get the type (if entered) + if (temp_buf = ACE_OS::strtok (0, " ")) + { + ACE_OS::strcpy (buf3, temp_buf); + result = this->bind (buf1, buf2, buf3); + } + else + result = this->bind (buf1, buf2); + } + else + ACE_ERROR ((LM_ERROR, "Bind Failed! Value not entered.\n")); + } + else + ACE_ERROR ((LM_ERROR, "Bind Failed! Key and Value not entered.\n")); + break; + case 'u' : + if (::scanf ("%s", buf1) <= 0) + break; + result = this->unbind (buf1); + break; + case 'r' : + // get the input from stdin + ACE_OS::gets (input); + + // get the key + if (temp_buf = ACE_OS::strtok (input, " ")) + { + ACE_OS::strcpy (buf1, temp_buf); + + // get the value + if (temp_buf = ACE_OS::strtok (0, " ")) + { + ACE_OS::strcpy (buf2, temp_buf); + + // get the type (if entered) + if (temp_buf = ACE_OS::strtok (0, " ")) + { + ACE_OS::strcpy (buf3, temp_buf); + result = this->rebind (buf1, buf2, buf3); + } + else + result = this->rebind (buf1, buf2); + } + else + ACE_ERROR ((LM_ERROR, "Rebind Failed! Value not entered.\n")); + } + else + ACE_ERROR ((LM_ERROR, "Reind Failed! Key and value not entered.\n")); + break; + case 'f' : + if (::scanf ("%s", buf1) <= 0) + break; + result = this->find (buf1); + break; + case 'j' : + if (::scanf ("%s", buf1) <= 0) + break; + else + result = this->list_names (buf1); + break; + case 'k' : + if (::scanf ("%s", buf1) <= 0) + break; + else + result = this->list_values (buf1); + break; + case 'l' : + if (::scanf ("%s", buf1) <= 0) + break; + else + result = this->list_types (buf1); + break; + case 'c' : + if (::scanf ("%s", buf1) <= 0) + break; + else + result = this->list_name_entries (buf1); + break; + case 'd' : + if (::scanf ("%s", buf1) <= 0) + break; + else + result = this->list_value_entries (buf1); + break; + case 'e' : + if (::scanf ("%s", buf1) <= 0) + break; + else + result = this->list_type_entries (buf1); + break; + case 'q' : + result = this->quit (); + break; + default : + ACE_DEBUG ((LM_DEBUG, "Unrecognized command.\n")); + } + + this->display_menu (); + return result; +} + +void +Client_Test::display_menu (void) +{ + ACE_DEBUG ((LM_DEBUG, "\n")); + this->list_options (); + ACE_DEBUG ((LM_DEBUG, " Name Service Main Menu\n")); + ACE_DEBUG ((LM_DEBUG, " ----------------------\n")); + ACE_DEBUG ((LM_DEBUG, "

    Use Process Local Database\n")); + ACE_DEBUG ((LM_DEBUG, " Use Node Local Database\n"));; + ACE_DEBUG ((LM_DEBUG, " Set Remote Name server and \n\n")); + ACE_DEBUG ((LM_DEBUG, " Bind []\n")); + ACE_DEBUG ((LM_DEBUG, " Unbind \n")); + ACE_DEBUG ((LM_DEBUG, " Rebind []\n")); + ACE_DEBUG ((LM_DEBUG, " Find \n")); + ACE_DEBUG ((LM_DEBUG, " Lookup keys matching \n")); + ACE_DEBUG ((LM_DEBUG, " Lookup values matching \n")); + ACE_DEBUG ((LM_DEBUG, " Lookup types matching \n")); + ACE_DEBUG ((LM_DEBUG, " Complete lookup keys matching \n")); + ACE_DEBUG ((LM_DEBUG, " Complete lookup values matching \n")); + ACE_DEBUG ((LM_DEBUG, " Complete lookup types matching \n")); + + ACE_DEBUG ((LM_DEBUG, " or ^C (exit)\n")); +} + +void +Client_Test::list_options (void) +{ +// ACE_DEBUG ((LM_DEBUG, " *** Process Name is %s ***\n", +// this->name_options_->process_name ())); + switch (this->name_options_->context ()) + { + case ACE_Naming_Context::PROC_LOCAL: + ACE_DEBUG ((LM_DEBUG, " *** Using Process Local Database\n")); + break; + case ACE_Naming_Context::NODE_LOCAL: + ACE_DEBUG ((LM_DEBUG, " *** Using Node Local Database\n")); + break; + case ACE_Naming_Context::NET_LOCAL: + ACE_DEBUG ((LM_DEBUG, " *** Hostname: %s\n", + this->name_options_->nameserver_host ())); + ACE_DEBUG ((LM_DEBUG, " *** Port Number: %d\n", + this->name_options_->nameserver_port ())); + break; + default: + assert (!"shouldn't occur!\n"); + /* NOTREACHED */ + } + ACE_DEBUG ((LM_DEBUG, " *** Namespace directory is %s ***\n", + this->name_options_->namespace_dir ())); +} + +int +Client_Test::set_proc_local (void) +{ + // Close down original name space + NAMING_CONTEXT ()->close (); + this->name_options_->nameserver_host ("localhost"); + this->name_options_->context (ACE_Naming_Context::PROC_LOCAL); + return NAMING_CONTEXT ()->open (ACE_Naming_Context::PROC_LOCAL); +} + +int +Client_Test::set_node_local (void) +{ + // Close down original name space + NAMING_CONTEXT ()->close (); + this->name_options_->nameserver_host ("localhost"); + this->name_options_->context (ACE_Naming_Context::NODE_LOCAL); + return NAMING_CONTEXT ()->open (ACE_Naming_Context::NODE_LOCAL); +} + +int +Client_Test::set_host (char* hostname, int port) +{ + // Close down original name space + NAMING_CONTEXT ()->close (); + + this->name_options_->context (ACE_Naming_Context::NET_LOCAL); + // Set Name Options + this->name_options_->nameserver_host (hostname); + this->name_options_->nameserver_port (port); + + return NAMING_CONTEXT ()->open (ACE_Naming_Context::NET_LOCAL); +} + +int +Client_Test::quit (void) +{ + // Send ourselves a SIGINT! + return ACE_OS::kill (ACE_OS::getpid (), SIGINT); +} + +int +Client_Test::bind (char* key, char* value, char* type) +{ + if (NAMING_CONTEXT ()->bind (key, value, type) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p Bind failed! Key %s exists\n", + "Client_Test::bind", key), 0); + return 0; +} + +int +Client_Test::unbind (char* key) +{ + if (NAMING_CONTEXT ()->unbind (key) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p Unbind failed! Key %s not found\n", + "Client_Test::unbind", key), 0); + return 0; +} + +int +Client_Test::rebind (char* key, char* value, char* type) +{ + int result = NAMING_CONTEXT ()->rebind (key, value, type ); + return result == 1 ? 0 : result; +} + +int +Client_Test::list_names (char *pattern) +{ + ACE_PWSTRING_SET set; + + if (NAMING_CONTEXT ()->list_names (set, pattern) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p Pattern matching failed!\n", + "Client_Test::list_names"), 0); + else + { + ACE_PWSTRING_ITERATOR set_iterator (set); + + for (ACE_WString *name = 0; + set_iterator.next (name) !=0; + set_iterator.advance()) + ACE_DEBUG ((LM_DEBUG, "%s\n", name->char_rep ())); + } + return 0; +} + +int +Client_Test::list_values (char *pattern) +{ + ACE_PWSTRING_SET set; + + if (NAMING_CONTEXT ()->list_values (set, pattern) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p Pattern matching failed!\n", + "Client_Test::list_values"), 0); + else + { + ACE_PWSTRING_ITERATOR set_iterator (set); + + for (ACE_WString *value = 0; + set_iterator.next (value) !=0; + set_iterator.advance()) + ACE_DEBUG ((LM_DEBUG, "%s\n", value->char_rep ())); + } + return 0; +} + +int +Client_Test::list_types (char *pattern) +{ + ACE_PWSTRING_SET set; + + if (NAMING_CONTEXT ()->list_types (set, pattern) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p Pattern matching failed!\n", + "Client_Test::list_types"), 0); + else + { + ACE_PWSTRING_ITERATOR set_iterator (set); + + for (ACE_WString *type = 0; + set_iterator.next (type) !=0; + set_iterator.advance()) + ACE_DEBUG ((LM_DEBUG, "%s\n", type->char_rep ())); + } + return 0; +} + +int +Client_Test::list_name_entries (char *pattern) +{ + ACE_BINDING_SET set; + + if (NAMING_CONTEXT ()->list_name_entries (set, pattern) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p Pattern matching failed!\n", + "Client_Test::list_names"), 0); + else + { + ACE_BINDING_ITERATOR set_iterator (set); + + for (ACE_Name_Binding *entry = 0; + set_iterator.next (entry) !=0; + set_iterator.advance()) + { + ACE_DEBUG ((LM_DEBUG, "%s\t", entry->name_.char_rep ())); + ACE_DEBUG ((LM_DEBUG, "%s\t", entry->value_.char_rep ())); + if (entry->type_) + ACE_DEBUG ((LM_DEBUG, "%s\n", entry->type_)); + } + } + return 0; +} + +int +Client_Test::list_value_entries (char *pattern) +{ + ACE_BINDING_SET set; + + if (NAMING_CONTEXT ()->list_value_entries (set, pattern) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p Pattern matching failed!\n", + "Client_Test::list_values"), 0); + else + { + ACE_BINDING_ITERATOR set_iterator (set); + for (ACE_Name_Binding *entry = 0; + set_iterator.next (entry) !=0; + set_iterator.advance()) + { + ACE_DEBUG ((LM_DEBUG, "%s\t", entry->name_.char_rep ())); + ACE_DEBUG ((LM_DEBUG, "%s\t", entry->value_.char_rep ())); + if (entry->type_) + ACE_DEBUG ((LM_DEBUG, "%s\n", entry->type_)); + } + } + return 0; +} + +int +Client_Test::list_type_entries (char *pattern) +{ + ACE_BINDING_SET set; + + if (NAMING_CONTEXT ()->list_type_entries (set, pattern) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p Pattern matching failed!\n", + "Client_Test::list_types"), 0); + else + { + ACE_BINDING_ITERATOR set_iterator (set); + + for (ACE_Name_Binding *entry = 0; + set_iterator.next (entry) !=0; + set_iterator.advance()) + { + ACE_DEBUG ((LM_DEBUG, "%s\t", entry->name_.char_rep ())); + ACE_DEBUG ((LM_DEBUG, "%s\t", entry->value_.char_rep ())); + ACE_DEBUG ((LM_DEBUG, "%s\n", entry->type_)); + } + } + return 0; +} + + +int +Client_Test::find (char *key) +{ + char *value = 0; + char *type = 0; + + if (NAMING_CONTEXT ()->resolve (key, value, type) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p Find failed! Key %s not found\n", + "Client_Test::list_find", key), 0); + else + { + ACE_DEBUG ((LM_DEBUG, + "Binding for %s : value = %s\ttype = %s\n", + key, value, type)); + if (type) + delete [] type; + return 0; + } +} + diff --git a/netsvcs/clients/Naming/Client/Client_Test.h b/netsvcs/clients/Naming/Client/Client_Test.h new file mode 100644 index 00000000000..825ca528f87 --- /dev/null +++ b/netsvcs/clients/Naming/Client/Client_Test.h @@ -0,0 +1,9 @@ +/* -*- C++ -*- */ +// @(#)Client_Test.h 1.1 10/18/96 + + +#include "ace/OS.h" + +// Define the external Client_Test interface. + +ACE_SVC_FACTORY_DECLARE (Client_Test) diff --git a/netsvcs/clients/Naming/Client/Makefile b/netsvcs/clients/Naming/Client/Makefile new file mode 100644 index 00000000000..1c4a908feb0 --- /dev/null +++ b/netsvcs/clients/Naming/Client/Makefile @@ -0,0 +1,175 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the ACE client-side Name_Server test +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = main +LIB = libClient_Test.a +SHLIB = libClient_Test.so + +FILES = Client_Test + +SRC = $(addsuffix .cpp,$(BIN)) +OBJ = $(SRC:%.cpp=$(VDIR)%.o) + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +LDLIBS = -lClient_Test +LIBS = -lACE + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VLIB) $(VSHLIB) $(SHLIBA) $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/Client_Test.o .shobj/Client_Test.so: Client_Test.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Naming_Context.h \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/Name_Proxy.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Name_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Name_Space.h \ + $(WRAPPER_ROOT)/ace/Dynamic_Service.h \ + Client_Test.h +.obj/main.o .shobj/main.so: main.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Naming_Context.h \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/Name_Proxy.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Name_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Name_Space.h \ + Client_Test.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/clients/Naming/Client/main.cpp b/netsvcs/clients/Naming/Client/main.cpp new file mode 100644 index 00000000000..20e8c53ef7e --- /dev/null +++ b/netsvcs/clients/Naming/Client/main.cpp @@ -0,0 +1,42 @@ +// Test the client-side of the ACE Name Server... +// @(#)main.cpp 1.1 10/18/96 + + +#include "ace/Service_Config.h" +#include "ace/Naming_Context.h" +#include "Client_Test.h" + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config daemon; + + if (daemon.open (argc, argv) == -1) + { + if (errno != ENOENT) + ACE_ERROR ((LM_ERROR, "%p\n%a", "open", 1)); + else // Use static binding. + { + char *l_argv[3]; + l_argv[0] = argv[0]; + l_argv[1] = "-p 10011"; + l_argv[2] = 0; + ACE_Service_Object *so = ACE_SVC_INVOKE (ACE_Naming_Context); + + if (so->init (2, l_argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "ACE_Naming_Context", 1)); + + so = ACE_SVC_INVOKE (Client_Test); + + if (so->init (0, l_argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "Client_Test", 1)); + } + } + + // Run forever, performing the configured services until we are shut + // down by a SIGINT/SIGQUIT signal. + + ACE_Service_Config::run_reactor_event_loop (); + + return 0; +} diff --git a/netsvcs/clients/Naming/Client/svc.conf b/netsvcs/clients/Naming/Client/svc.conf new file mode 100644 index 00000000000..7625547e8d8 --- /dev/null +++ b/netsvcs/clients/Naming/Client/svc.conf @@ -0,0 +1,6 @@ +# Note that $DB and $PORT are environment variables that are +# automatically interpreted and substituted by ACE! +static ACE_Naming_Context "main -s $DB -p $PORT -h tango" +dynamic Name_Server_test Service_Object * ./libClient_Test.so:_make_Client_Test () +# Note: Client_Test must come after ACE_Naming_Context since it relies +# on the ACE_Naming_Context having been linked... diff --git a/netsvcs/clients/Naming/Client/svc2.conf b/netsvcs/clients/Naming/Client/svc2.conf new file mode 100644 index 00000000000..41075e1bf29 --- /dev/null +++ b/netsvcs/clients/Naming/Client/svc2.conf @@ -0,0 +1,9 @@ +# Note that $DB and $PORT are environment variables that are +# automatically interpreted and substituted by ACE! In addition, note +# how you can give a relative name for the libACE_svcs.so and ACE will +# locate this for you automatically by reading your LD search path! +dynamic ACE_Naming_Context Service_Object * libACE.so:_make_ACE_Naming_Context () "main -s $DB" +dynamic ACE_Naming_Context2 Service_Object * libACE.so:_make_ACE_Naming_Context () "main -s $DB" +dynamic Name_Server_test Service_Object * .shobj/Client_Test.so:_make_Client_Test () +# Note: Client_Test must come after ACE_Naming_Context since it relies +# on the ACE_Naming_Context having been dynamically linked. diff --git a/netsvcs/clients/Naming/Dump_Restore/Dump_Restore.cpp b/netsvcs/clients/Naming/Dump_Restore/Dump_Restore.cpp new file mode 100644 index 00000000000..91617d11662 --- /dev/null +++ b/netsvcs/clients/Naming/Dump_Restore/Dump_Restore.cpp @@ -0,0 +1,388 @@ +#include +// @(#)Dump_Restore.cpp 1.1 10/18/96 + +#include "ace/Service_Config.h" +#include "ace/Read_Buffer.h" +#include "Dump_Restore.h" + +Dump_Restore::Dump_Restore (int argc, char *argv[]) + : infile_ (0) +{ + ACE_NEW (this->ns_context_, ACE_Naming_Context); + + // Cache the name options + this->name_options_ = this->ns_context_->name_options (); + this->name_options_->parse_args (argc, argv); + + //determine name context + if (ACE_OS::strcmp (this->name_options_->nameserver_host (), "localhost") == 0) + { + if (ns_context_->open (ACE_Naming_Context::PROC_LOCAL) == -1) + ACE_ERROR ( (LM_ERROR, "%p\n", "ns_context_->open")); + } + else + { + // Don't really need to do this but it's a hack to fix + // the problme of Display () not printing the right hostname + ACE_OS::strcpy (this->hostname_, + this->name_options_->nameserver_host ()); + this->port_ = this->name_options_->nameserver_port (); + + if (this->ns_context_->open (ACE_Naming_Context::NET_LOCAL) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ns_context_->open")); + } + + this->display_menu (); + + if (ACE::register_stdin_handler (this, + ACE_Service_Config::reactor (), + ACE_Service_Config::thr_mgr ()) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "register_stdin_handler")); +} + +Dump_Restore::~Dump_Restore (void) +{ + // Deregister this handler with the ACE_Reactor. + ACE_Service_Config::reactor ()->remove_handler + (ACE_STDIN, + ACE_Event_Handler::DONT_CALL | ACE_Event_Handler::READ_MASK); + + ACE_OS::fclose (this->infile_); +} + +int +Dump_Restore::handle_input (ACE_HANDLE) +{ + char option[BUFSIZ]; + char buf1[BUFSIZ]; + char buf2[BUFSIZ]; + char buf3[BUFSIZ]; + char *temp_buf; + int port; + char input[256]; + + if (::scanf ("%s", option) <= 0) + { + cerr << "try again" << endl; + return 0; + } + + int result = -1; + switch (option[0]) + { + case 'P' : + case 'p' : + result = set_proc_local (); + break; + case 'N' : + case 'n' : + result = set_node_local (); + break; + case 'H' : + case 'h' : + if (::scanf ("%s %d", buf1, &port) <= 0) + break; + result = set_host (buf1, port); + break; + case 'F': + case 'f': + if (::scanf ("%s", filename_) <= 0) + break; + if (this->infile_) + ACE_OS::fclose (this->infile_); + this->infile_ = fopen(filename_,"r"); + break; + case 'B' : + case 'b' : + result = populate (Dump_Restore::BIND); + break; + case 'U' : + case 'u' : + result = populate (Dump_Restore::UNBIND); + break; + case 'R' : + case 'r' : + result = populate (Dump_Restore::REBIND); + break; + case 'D': + case 'd': + if (::scanf ("%s", dump_filename_) <= 0) + break; + this->dump (); + break; + case 'Q' : + case 'q' : + result = quit (); + break; + default : + cout << "Unrecognized command." << endl; + } +// if (result == 0) +// cout << "Last operation was successful!" << endl; +// else +// cout << "Last operation returned: " << result << endl; + + display_menu (); + return 0; +} + +void +Dump_Restore::display_menu (void) +{ + cout << endl; + cout << " Name Service Main Menu" << endl; + cout << " ----------------------" << endl; + + // Check if using local name space or remote name space + if (ACE_OS::strcmp (this->name_options_->nameserver_host (), "localhost") == 0) + { + if (this->ns_scope_ == ACE_Naming_Context::PROC_LOCAL) + cout << " *** Using Process Local Database ***" << endl << endl; + else + cout << " *** Using Node Local Database ***" << endl << endl; + } + else + { + cout << " Hostname: " << this->hostname_; + cout << " Port Number: " << this->port_ << endl << endl; + } + if (this->infile_) + cout << "Input File: " << filename_ << endl << endl; + else + cout << "** No Input File Specified **" << endl; + cout << "

    Use Process Local Database" << endl; + cout << " Use Node Local Database" << endl; + cout << " Set Remote Name server and " << endl; + cout << " Set Input File " << endl << endl; + cout << " Bind" << endl; + cout << " Unbind" << endl; + cout << " Rebind" << endl; + cout << " Dump " << endl; + cout << " or ^C (exit) " << endl; +} + + +int +Dump_Restore::set_proc_local (void) +{ + // Set Name Options + this->name_options_->nameserver_host ("localhost"); + this->name_options_->nameserver_port (0); + + // Set Naming Context scope + this->ns_scope_ = ACE_Naming_Context::PROC_LOCAL; + + // Remove old naming context + delete this->ns_context_; + + // Create new Naming Context + ACE_NEW_RETURN (this->ns_context_, ACE_Naming_Context, -1); + + if (this->ns_context_->open (ACE_Naming_Context::PROC_LOCAL) == -1) + ACE_ERROR_RETURN ( (LM_ERROR, "%p\n", "ns_context_->open"), -1); + + return 0; +} + +int +Dump_Restore::set_node_local (void) +{ + // Set Name Options + this->name_options_->nameserver_host ("localhost"); + this->name_options_->nameserver_port (0); + + // Set Naming Context scope + this->ns_scope_ = ACE_Naming_Context::NODE_LOCAL; + + // Remove old naming context + delete this->ns_context_; + + // Create new Naming Context + ACE_NEW_RETURN (this->ns_context_, ACE_Naming_Context, -1); + + if (ns_context_->open (ACE_Naming_Context::NODE_LOCAL) == -1) + ACE_ERROR_RETURN ( (LM_ERROR, "%p\n", "ns_context_->open"), -1); + return 0; +} + +int +Dump_Restore::set_host (char* hostname, int port) +{ + // Set Name Options + this->name_options_->nameserver_host (hostname); + this->name_options_->nameserver_port (port); + + // don't really need to do this but it's a hack to fix + // the problme of Display () not printing the right hostname + ACE_OS::strcpy (this->hostname_, hostname); + this->port_ = port; + this->ns_scope_ = ACE_Naming_Context::NET_LOCAL; + + // remove old naming context + delete this->ns_context_; + + // Create new Naming Context + ACE_NEW_RETURN (this->ns_context_, ACE_Naming_Context, -1); + + // assume net_local context + if (ns_context_->open (ACE_Naming_Context::NET_LOCAL) == -1) + ACE_ERROR_RETURN ( (LM_ERROR, "%p\n", "ns_context_->open"), -1); + + return 0; +} + +int +Dump_Restore::doit (Dump_Restore::Operation_Type op, + char *name, + char* value, + char* type) +{ + int result = -1; + + switch (op) + { + case Dump_Restore::BIND: + { + result = this->bind (name, value, type); + break; + } + case Dump_Restore::UNBIND: + { + result = this->unbind (name); + break; + } + case Dump_Restore::REBIND: + { + result = this->rebind (name, value, type); + break; + } + } + + return result; +} + +int +Dump_Restore::populate (Dump_Restore::Operation_Type op) +{ + if (this->infile_) + { + int result = -1; + enum State { NAME, VALUE, TYPE }; + + State state = NAME; + // reset file pointer + ACE_OS::rewind (this->infile_); + + ACE_Allocator *allocator = ACE_Service_Config::allocator (); + ACE_Read_Buffer read_buffer (this->infile_, 0, allocator); + + for (char *temp; (temp = read_buffer.read ('\n')) != 0; ) + { + char *name = 0; + char *actual_name = 0; + char *value = 0; + char *actual_value = 0; + char *type = 0; + char *actual_type = 0; + + switch (state) + { + case NAME: + name = temp; + ACE_OS::strtok (name, "="); + actual_name = ACE_OS::strtok (0, "="); + state = VALUE; + break; + case VALUE: + value = temp; + ACE_OS::strtok (value, "="); + actual_value = ACE_OS::strtok (0, "="); + state = TYPE; + break; + case TYPE: + type = temp; + ACE_OS::strtok (type, "="); + actual_type = ACE_OS::strtok (0, "="); + + if (actual_type) + result = this->doit (op, + actual_name, + actual_value, + actual_type); + else + result = this->doit (op, + actual_name, + actual_value); + if (name) + allocator->free(name); + if (value) + allocator->free(value); + if (type) + allocator->free(type); + state = NAME; + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "populate"), -1); + break; + } + } + + return result; + } + else + return -1; +} + +int +Dump_Restore::bind (char* key, char* value, char* type) +{ + int result = ns_context_->bind (key, value, type); + + if (result == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ns_context_->bind"), -1); + else if (result == 1) + ACE_ERROR_RETURN ((LM_ERROR, "%s%s%s\n", "key <", key, "> already bound"), 1); + return 0; +} + +int +Dump_Restore::unbind (char* key) +{ + int result = ns_context_->unbind (key); + + if (result == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ns_context_->unbind"), -1); + + return 0; +} + +int +Dump_Restore::rebind (char* key, char* value, char* type) +{ + if (ns_context_->rebind (key, value, type) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ns_context_->rebind"), -1); + + return 0; +} + +int +Dump_Restore::quit (void) +{ + return ACE_OS::kill (ACE_OS::getpid (), SIGINT); +} + +void +Dump_Restore::dump (void) +{ + ofstream output_file (dump_filename_); + + ostream *orig_stream = ACE_Log_Msg::instance ()->msg_ostream (); + ACE_Log_Msg::instance ()->msg_ostream (&output_file); + ACE_Log_Msg::instance ()->clr_flags (ACE_Log_Msg::STDERR | ACE_Log_Msg::LOGGER ); + ACE_Log_Msg::instance ()->set_flags (ACE_Log_Msg::OSTREAM); + + ns_context_->dump (); + + ACE_Log_Msg::instance ()->msg_ostream (orig_stream); + ACE_Log_Msg::instance ()->clr_flags (ACE_Log_Msg::STDERR); +} diff --git a/netsvcs/clients/Naming/Dump_Restore/Dump_Restore.h b/netsvcs/clients/Naming/Dump_Restore/Dump_Restore.h new file mode 100644 index 00000000000..218e842f2e9 --- /dev/null +++ b/netsvcs/clients/Naming/Dump_Restore/Dump_Restore.h @@ -0,0 +1,74 @@ +/* -*- C++ -*- */ +// @(#)Dump_Restore.h 1.1 10/18/96 + +#include "ace/Event_Handler.h" +#include "ace/Reactor.h" +#include "ace/Naming_Context.h" + +class Dump_Restore : public ACE_Event_Handler +{ +public: + enum Operation_Type + { + BIND, + UNBIND, + REBIND + }; + Dump_Restore (int argc, char *argv[]); + // Initialize name options and naming context + + ~Dump_Restore (void); + + virtual int handle_input (ACE_HANDLE handle); + // Handle user entered commands + + void dump (void); + +private: + char hostname_[MAXHOSTNAMELEN + 1]; + // Cache the hostname and port number for remote case + + void display_menu (void); + // Display user menu. + + int set_proc_local (void); + // Set options to use PROC_LOCAL naming context. + + int set_node_local (void); + // Set options to use NODE_LOCAL naming context. + + int set_host (char* hostname, int port); + // Set options to use NET_LOCAL naming context specifying host name + // and port number. + + int quit (void); + // Gracefully exit. + + int populate (Dump_Restore::Operation_Type op); + + int doit (Dump_Restore::Operation_Type op, + char *name, + char *value, + char *type = ""); + int bind (char* key, char* value, char* type = ""); + int unbind (char* key); + int rebind (char* key, char* value, char* type = ""); + + char filename_[MAXPATHLEN]; + char dump_filename_[MAXPATHLEN]; + + u_short port_; + // port server is listening on + + ACE_Naming_Context *ns_context_; + // Current naming context + + ACE_Naming_Context::Context_Scope_Type ns_scope_; + // Defines the scope of the naming context + + FILE *infile_; + // input file + + ACE_Name_Options *name_options_; + // Name Options associated with the Naming Context +}; diff --git a/netsvcs/clients/Naming/Dump_Restore/Makefile b/netsvcs/clients/Naming/Dump_Restore/Makefile new file mode 100644 index 00000000000..62b517b4e40 --- /dev/null +++ b/netsvcs/clients/Naming/Dump_Restore/Makefile @@ -0,0 +1,176 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the ACE Dump-Restore Name_Server utility +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = main +LIB = libDump_Restore.a +SHLIB = libDump_Restore.so + +FILES = Dump_Restore + +SRC = $(addsuffix .cpp,$(BIN)) +OBJ = $(SRC:%.cpp=$(VDIR)%.o) + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +LDLIBS = -lDump_Restore +LIBS += -lACE + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VLIB) $(VSHLIB) $(SHLIBA) $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/Dump_Restore.o .shobj/Dump_Restore.so: Dump_Restore.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Read_Buffer.h \ + $(WRAPPER_ROOT)/ace/Read_Buffer.i \ + Dump_Restore.h \ + $(WRAPPER_ROOT)/ace/Naming_Context.h \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/Name_Proxy.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Name_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Name_Space.h +.obj/main.o .shobj/main.so: main.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + Dump_Restore.h \ + $(WRAPPER_ROOT)/ace/Naming_Context.h \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/Name_Proxy.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Name_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Name_Space.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/clients/Naming/Dump_Restore/README b/netsvcs/clients/Naming/Dump_Restore/README new file mode 100644 index 00000000000..3bb13935d87 --- /dev/null +++ b/netsvcs/clients/Naming/Dump_Restore/README @@ -0,0 +1,67 @@ +This file describes the usage of the Dump-Restore utility for the ACE +Name Server. + +Similar to the test application provided in the Client-Server +directory, a simple ASCII menu-driven interface is provided to the +user: + + Name Service Main Menu + ---------------------- + *** Using Process Local Database *** + +** No Input File Specified ** +

    Use Process Local Database + Use Node Local Database + Set Remote Name server and + Set Input File + + Bind + Unbind + Rebind + Dump + or ^C (exit) + +Initially, the user can select the type of database from the menu: + +

    uses the process local database (i.e., the + database is called the same name as the process + and stored in /tmp). + uses the node local database (which defaults + to /tmp/localnames). + uses the net local database by specifying host and port + number (by default this is stored in a file called + /tmp/globalnames on the server). + Sets the name of the input file that will be used by the + test application to populate the database. The format of + the file should be: + + name= + value= + type=[] + name= + value= + type=[] + . + . + . + + Note that the type field is optional. However, if no type + information is associated with a name binding, a null entry still + needs to be present (i.e., type=). + +Once the input file has been specified, the user can then do one of +the following: + + Bind -- bind all the bindings in the file to the database. + This can be used to "restore" the state of the + Name Server. + Unbind -- unbind all the bindings in the file from the database. + Rebind -- rebind all the bindings in the file to the database. + Dump -- dump the state of the database to . + or ^C (exit) -- exit gracefully, saving the contents of the + Name Server in persistent shared memory. + +Note that the dump file is stored in ASCII with exactly the same +format as the input file. Also, one can easily change the test +application so that a call to Dump results in the state of the +database dumped to standard output instead of a file. diff --git a/netsvcs/clients/Naming/Dump_Restore/createfile.cpp b/netsvcs/clients/Naming/Dump_Restore/createfile.cpp new file mode 100644 index 00000000000..4880cfe7883 --- /dev/null +++ b/netsvcs/clients/Naming/Dump_Restore/createfile.cpp @@ -0,0 +1,32 @@ +#include +// @(#)createfile.cpp 1.1 10/18/96 + +#include +#include + +int +main (int argc, char **argv) +{ + FILE *infile, *outfile; + char buf[BUFSIZ]; + + if ((infile = fopen (argv[1], "r")) == NULL) + return -1; + + if ((outfile = fopen (argv[2], "w")) == NULL) + return -1; + + int count = 0; + while (::fgets (buf, BUFSIZ, infile)) + { + buf[::strlen(buf) - 1] = '\0'; + fputs (buf, outfile); + if (count % 2 == 0) + fputs (" ", outfile); + else + fputs ("\n", outfile); + count++; + } + fclose (outfile); + fclose (infile); +} diff --git a/netsvcs/clients/Naming/Dump_Restore/main.cpp b/netsvcs/clients/Naming/Dump_Restore/main.cpp new file mode 100644 index 00000000000..a30b94c6cd3 --- /dev/null +++ b/netsvcs/clients/Naming/Dump_Restore/main.cpp @@ -0,0 +1,22 @@ +// Test the client-side of the ACE Name Server... +// @(#)main.cpp 1.1 10/18/96 + +#include "ace/Service_Config.h" +#include "Dump_Restore.h" + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config daemon (argv[0]); + + ACE_DEBUG ((LM_DEBUG, "entering main\n")); + + // Get a handler + Dump_Restore client_handler (argc, argv); + + for (;;) + daemon.run_reactor_event_loop (); + + ACE_DEBUG ((LM_DEBUG, "leaving main\n")); + return 0; +} diff --git a/netsvcs/clients/Naming/Dump_Restore/nametest.cpp b/netsvcs/clients/Naming/Dump_Restore/nametest.cpp new file mode 100644 index 00000000000..d5347b7206a --- /dev/null +++ b/netsvcs/clients/Naming/Dump_Restore/nametest.cpp @@ -0,0 +1,112 @@ +#include "ace/Naming_Context.h" +// @(#)nametest.cpp 1.1 10/18/96 + +#include "ace/Name_Options.h" +#include "nametest.h" + +void +Nametest::listopt (void) +{ + cout << "serverport is " + << ACE_Name_Options::instance ()->nameserver_port() + << endl; + cout << "serverhost is " + << ACE_Name_Options::instance ()->nameserver_host() + << endl; + cout << "process_name is " + << ACE_Name_Options::instance ()->process_name() + << endl; + cout << "namespace_dir is " + << ACE_Name_Options::instance ()->namespace_dir() + << endl; +} + +int +Nametest::init (int argc, char *argv[]) +{ + ACE_Server_Record *sr; + ACE_Service_Config::svc_rep ()->find ("Name_Server_Proxy", &sr); + ACE_Service_Type *st = sr->type (); + ACE_Server_Object *so = st->object (); +dynamic_cast (so); + + ACE_Name_Server_Proxy *ns_proxy = ACE_Service_Config::name_server_proxy (); + + ns_proxy->bind (...); + + this->listopt (); + + ACE_Naming_Context ns_context; + + if (ns_context.open (ACE_Naming_Context::NET_LOCAL) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ns_context.open"), -1); + + const char *mykey = argv[0]; + char *myvalue = argv[1]; + char *ns_value = 0; + char *ns_type = 0; + + if (ns_context.bind (mykey, myvalue, "ottotype") == -1) + cout << "bind failed" << endl; + else + cout << "bind succeeded" << endl; + + + if (ns_context.resolve (mykey, ns_value, ns_type) == -1) + cout << "resolve of " << mykey << " failed" << endl; + else + cout << "resolve of " << mykey << " succeeded, value = " + << ns_value << ", type = " << ns_type << endl; + + delete [] ns_value; + delete [] ns_type; + ns_value = 0; + ns_type = 0; + + if (ns_context.rebind (mykey, myvalue, "newottotype") == -1) + cout << "rebind failed" << endl; + else + cout << "rebind succeeded" << endl; + + if (ns_context.resolve (mykey, ns_value, ns_type) == -1) + cout << "resolve of " << mykey << " failed" << endl; + else + cout << "resolve of " << mykey << " succeeded, value = " + << ns_value << ", type = " << ns_type << endl; + + delete [] ns_value; + delete [] ns_type; + ns_value = 0; + ns_type = 0; + + if (ns_context.unbind (mykey) == -1) + cout << "unbind failed" << endl; + else + cout << "unbind succeeded" << endl; + + return 0; +} + +int +Nametest::fini (void) +{ + cout << "Nametest::fini called" << endl; + return 0; +} + +int +Nametest::info (char **, unsigned) const +{ + cout << "Nametest::info called" << endl; + return 0; +} + +extern "C" ACE_Service_Object *_alloc(void); + +// Factory function that is called automatically when the ACE +// framework dynamically links this shared object file. + +ACE_Service_Object *_alloc (void) +{ + return new Nametest; +} diff --git a/netsvcs/clients/Naming/Dump_Restore/nametest.h b/netsvcs/clients/Naming/Dump_Restore/nametest.h new file mode 100644 index 00000000000..423f2ea1a5c --- /dev/null +++ b/netsvcs/clients/Naming/Dump_Restore/nametest.h @@ -0,0 +1,15 @@ +/* -*- C++ -*- */ +// @(#)nametest.h 1.1 10/18/96 + +#include "ace/Service_Object.h" + +class Nametest : public ACE_Service_Object +{ +public: + virtual int init (int argc, char *argv[]); + virtual int fini (void); + virtual int info (char **, size_t) const; + + void listopt (void); +}; + diff --git a/netsvcs/clients/Naming/Makefile b/netsvcs/clients/Naming/Makefile new file mode 100644 index 00000000000..db15cce1cf5 --- /dev/null +++ b/netsvcs/clients/Naming/Makefile @@ -0,0 +1,25 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Name Server test applications +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +INFO = README + +DIRS = Client \ + Dump_Restore + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + diff --git a/netsvcs/clients/Naming/README b/netsvcs/clients/Naming/README new file mode 100644 index 00000000000..7249a2b23c0 --- /dev/null +++ b/netsvcs/clients/Naming/README @@ -0,0 +1,124 @@ +This directory contains a set of tests for the ACE_Name_Server +library. There are two directories -- client and server, which test +the client and server, respectively. In addition, these tests +illustrate how to use the ACE Service_Config mechanism, which enables +the client and server code to be dynamically linked into the process +at installation-time or run-time! + +The client test is an application that allows the user to vary the +test parameters through the following menu driven interface: + + Name Service Main Menu + ---------------------- + *** Using Process Local Database *** + +

    Use Process Local Database + Use Node Local Database + Set Remote Name server and + + Bind [] + Unbind + Rebind [] + Find + Lookup keys matching + Lookup values matching + Lookup types matching + Complete lookup keys matching + Complete lookup values matching + Complete lookup types matching + + or ^C (exit) + +Initially, the user can select the type of database -- process local, +node local, or net local -- from the menu. + +

    uses the process local database (i.e., the database is called the + same name as the process and stored in /tmp). + uses the node local database (which defaults to /tmp/localnames). + uses the net local database by specifying host and port number (by + default this is stored in a file called /tmp/globalnames on the server). + +The user can then create new bindings, delete existing bindings, or +rebind bindings: + + Bind [] + -- binds the key to the value and adds the + binding to the database. Note that type + information is optional. + Unbind -- unbind a binding whose key is + Rebind [] + -- rebind to . Once again is optional. + Find -- find the binding associated with key + or ^C (exit) -- exit gracefully, saving the contents of the + Name Server in persistent shared memory. + +In addition, the user can do pattern matching for keys, values, and +types. Note that pattern matching is supported using regular expressions. + + Lookup keys matching + -- find all keys that match + Lookup values matching + -- find all values that match + Lookup types matching + -- find all types that match + + Complete lookup keys matching + -- find all bindings whose keys match + Complete lookup values matching + -- find all bindings whose values match + Complete lookup types matching + -- find all bindings whose types match + +------------------------- +Running the tests: + +Both the client and the server test programs use DLL supported by +svc.conf which allows them to configure the client-side and the +server-side (respectively) dynamically. The client test program +accomplishes this by making use of a Singleton proxy object +(Name_Service) to provide an interface to the client-side. + +The test programs rely on svc.conf to provide the necessary parameters +for dynamically linking the Name Service library and then +executing. In the absence of svc.conf, the test programs would use +static binding. + +client: + +The client test can be started without any parameters. However, if the +user wants to use the net local database, the hostname and the port +number of the server containing the net local database can be given at +"command line" in the svc.conf file, e.g.: + +dynamic ACE_Naming_Context Service_Object * libACE.so:_make_ACE_Naming_Context () + "main -h tango.cs -p 7891" +dynamic Name_Server_test Service_Object * .shobj/Client_Test.so:_make_Client_Test () "" + +The above example starts the client test application and sets up a +connection to port 7891 to a Name Server running on tango.cs, which +has the net local database. The Client_Test directive must come after +ACE_Naming_Context since it relies on the ACE_Naming_Context having +been dynamically linked. + +Note that you can also use environment variables in the "command +line", as follows: + +dynamic ACE_Naming_Context Service_Object * libACE.so:_make_ACE_Naming_Context () + "main -s $DB -p $PORT -h tango" +dynamic Name_Server_test Service_Object * .shobj/Client_Test.so:_make_Client_Test () "" + +In this example, $DB and $PORT are environment variables that are +automatically interpreted and substituted by ACE. In addition, note +how you can give a relative name for the libACE_svcs.so and ACE will +locate this for you automatically by reading your LD search path. + +server: + +The name server is needed only in the case where the net local +database needs to be accessed. The server test needs to run on the +machine that contains the net local database. To execute the server +test, the user has to specify the port number at which the server will +be listening in the svc.conf file. An implementation of a name +service for ACE is available in the $WRAPPER_ROOT/netsvcs/bin +directory. Please see the README file there for an explanation of how +to run the server. diff --git a/netsvcs/clients/README b/netsvcs/clients/README new file mode 100644 index 00000000000..d47c9bfe7ff --- /dev/null +++ b/netsvcs/clients/README @@ -0,0 +1,8 @@ +This directory contains a number of test programs that illustrate how +to write clients for the various ACE network services. + + . Logger -- client programs that illustrate the ACE logging service. + + . Naming -- client programs that illustrate the ACE name service. + + . Tokens -- client programs that illustrate the ACE token service. diff --git a/netsvcs/clients/Tokens/Makefile b/netsvcs/clients/Tokens/Makefile new file mode 100644 index 00000000000..051e0b90dae --- /dev/null +++ b/netsvcs/clients/Tokens/Makefile @@ -0,0 +1,26 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Token tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +DIRS = collection \ + deadlock \ + invariant \ + manual \ + mutex \ + rw_lock + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU diff --git a/netsvcs/clients/Tokens/README b/netsvcs/clients/Tokens/README new file mode 100644 index 00000000000..3b6313a1df7 --- /dev/null +++ b/netsvcs/clients/Tokens/README @@ -0,0 +1,34 @@ +This directory contains a set of tests for the ACE Tokens library. + + . mutex + + Runs a few tests on ACE_Local_Mutex and + ACE_Remote_Mutex. Tests recursive acquisition and + global vs local proxies. + + . rw_locks + + App for testing ACE_Local_RLock, ACE_Local_WLock, + ACE_Remote_RLock, and ACE_Remote_WLock. + + . deadlock + + Tests the deadlock detection algorithm of the token + manager using ACE_Local_Mutex and ACE_Remote_Mutex. + + . collection + + Tests the ACE_Token_Collection utility. Uses local + and remote tokens and readers/writer locks. + + . invariant + + Tests the token Invariant testing utilities. Yes, + this tests a testing utility. + + . manual + + Gives users a text-based interactive interface to + local or remote tokens. This is extremely useful for + manually testing the token server and setting up + deadlock scenarios. diff --git a/netsvcs/clients/Tokens/collection/Makefile b/netsvcs/clients/Tokens/collection/Makefile new file mode 100644 index 00000000000..76090600a11 --- /dev/null +++ b/netsvcs/clients/Tokens/collection/Makefile @@ -0,0 +1,108 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for repeating token client application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = collection + +FILES = collection + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/collection.o .shobj/collection.so: collection.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Stack.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Token_Collection.h \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/Remote_Tokens.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Token_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/clients/Tokens/collection/README b/netsvcs/clients/Tokens/collection/README new file mode 100644 index 00000000000..4c25a1f729e --- /dev/null +++ b/netsvcs/clients/Tokens/collection/README @@ -0,0 +1,25 @@ + +Shows how applications can use the ACE_Token_Collection utility. This +example creates three collections and spawns a thread to operate on +each. The threads use the collective acquire, renew, and release +features of ACE_Token_Collection. + +Here are the command-line parameters for collection: + +./collection: +[-h ] +[-p ] +[-n ] +[-d debug] + +To run the collection locally with debugging info, type + +% ./collection -d + +To run the collection remotely with debugging info, first start a +token server and the type: + +% ./collection -d -h -p + +The -n option is to control how often each thread +iterates on the acquire, renew, release cycle. diff --git a/netsvcs/clients/Tokens/collection/collection.cpp b/netsvcs/clients/Tokens/collection/collection.cpp new file mode 100644 index 00000000000..797546f3f92 --- /dev/null +++ b/netsvcs/clients/Tokens/collection/collection.cpp @@ -0,0 +1,217 @@ +// ============================================================================ +// @(#)collection.cpp 1.1 10/18/96 + +// +// = LIBRARY +// examples +// +// = FILENAME +// collection.cpp +// +// = DESCRIPTION +// Shows how applications can use the ACE_Token_Collection +// utility. This example creates three collections and spawns a +// thread to operate on each. The threads use the collective +// acquire, renew, and release features of ACE_Token_Collection. +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#include "ace/OS.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/Local_Tokens.h" +#include "ace/Token_Collection.h" +#include "ace/Remote_Tokens.h" +#include "ace/Thread_Manager.h" +#include "ace/Service_Config.h" + +#if defined (ACE_HAS_THREADS) + +static char *server_host = ACE_DEFAULT_SERVER_HOST; +static int server_port = ACE_DEFAULT_SERVER_PORT; +static int threads = 2; +static int iterations = 50; +static int debug = 0; +static int remote = 0; +static int tokens = 5; + +static void * +run_thread (void *vp) +{ + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + ACE_Token_Proxy *collection = (ACE_Token_Proxy *) vp; + + int count = iterations; + while (count--) + { + if (collection->acquire () == -1) + { + if (ACE_OS::last_error () == EDEADLK) + { + ACE_DEBUG ((LM_DEBUG, "deadlock detected in acquire")); + continue; + } + ACE_ERROR ((LM_ERROR, "(%t) %p acquire failed\n","run_thread")); + return (void *) -1; + } + + ACE_DEBUG ((LM_DEBUG, "(%t) %s acquired.\n", collection->name ())); + + if (collection->renew () == -1) + { + if (ACE_OS::last_error () == EDEADLK) + { + ACE_DEBUG ((LM_DEBUG, "deadlock detected")); + goto deadlock; + } + ACE_ERROR ((LM_ERROR, "(%t) %p renew failed\n","run_thread")); + return (void *) -1; + } + + ACE_DEBUG ((LM_DEBUG, "(%t) %s renewed.\n", collection->name ())); + + deadlock: + if (collection->release () == -1) + { + ACE_ERROR ((LM_ERROR, "(%t) %p release failed\n","run_thread")); + return (void *) -1; + } + + ACE_DEBUG ((LM_DEBUG, "(%t) %s released.\n", collection->name ())); + } + + + ACE_DEBUG ((LM_DEBUG, "(%t) thread exiting.\n")); + return 0; +} + +static int +parse_args (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0], ACE_Log_Msg::STDERR); // | ACE_Log_Msg::VERBOSE); + + ACE_Get_Opt get_opt (argc, argv, "un:dp:h:", 1); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'h': // specify the host machine on which the server is running + server_host = get_opt.optarg; + remote = 1; + break; + case 'p': // specify the port on which the server is running + server_port = ACE_OS::atoi (get_opt.optarg); + remote = 1; + break; + case 'd': + debug = 1; + break; + case 'n': + iterations = ACE_OS::atoi (get_opt.optarg); + break; + case 'u': + // usage: fallthrough + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n" + "[-h ]\n" + "[-p ]\n" + "[-n ]\n" + "[-d debug]\n", 1), -1); + break; + } + } + + return 0; +} + +#if defined (ACE_HAS_PTHREADS) +#define SUSPEND 0 +#else +#define SUSPEND THR_SUSPENDED +#endif + +int +main (int argc, char* argv[]) +{ + if (parse_args (argc, argv) == -1) + return -1; + + ACE_Token_Proxy *A; // Mutex *A*. + ACE_Token_Proxy *B; // Mutex *B*. + ACE_Token_Proxy *R; // *R*eader Lock. + ACE_Token_Proxy *W; // *W*riter Lock. + + // Depending on the command line arguments, we will create local or + // remote tokens. The names of the tokens are not important as long + // as they are unique. + if (remote) + { + ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port, server_host)); + A = new ACE_Remote_Mutex ("R Mutex A", 0, debug); + B = new ACE_Remote_Mutex ("R Mutex B", 0, debug); + R = new ACE_Remote_RLock ("R Reader Lock", 0, debug); + W = new ACE_Remote_WLock ("R Writer Lock", 0, debug); + } + else + { + A = new ACE_Local_Mutex ("L Mutex A", 0, debug); + B = new ACE_Local_Mutex ("L Mutex B", 0, debug); + R = new ACE_Local_RLock ("L Reader Lock", 0, debug); + W = new ACE_Local_WLock ("L Writer Lock", 0, debug); + } + + // These collections will be treated as Tokens by the threads. + ACE_Token_Collection collectionAR (debug, "A and Reader"); + ACE_Token_Collection collectionAW (debug, "A and Writer"); + ACE_Token_Collection collectionBR (debug, "B and Reader"); + + // AR and BR can run concurrently. Neither AR or BR can run when AW + // is running. + collectionAR.insert (*A); + collectionAR.insert (*R); + + collectionAW.insert (*A); + collectionAW.insert (*W); + + collectionBR.insert (*B); + collectionBR.insert (*R); + + // Spawn off three threads. + ACE_Thread_Manager *mgr = ACE_Service_Config::thr_mgr (); + + if (mgr->spawn (ACE_THR_FUNC (run_thread), + (void *) &collectionAR, THR_BOUND | SUSPEND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn 1 failed"), -1); + + if (mgr->spawn (ACE_THR_FUNC (run_thread), + (void *) &collectionAW, THR_BOUND | SUSPEND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn 2 failed"), -1); + + if (mgr->spawn (ACE_THR_FUNC (run_thread), + (void *) &collectionBR, THR_BOUND | SUSPEND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn 3 failed"), -1); + +#if ! defined (ACE_HAS_PTHREADS) + if (mgr->resume_all () == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "resume failed"), -1); +#endif + + // Wait for all threads to exit. + mgr->wait (); + + return 42; +} + +#else +int +main (int, char *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "threads not supported on this platform\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/netsvcs/clients/Tokens/collection/rw_locks.cpp b/netsvcs/clients/Tokens/collection/rw_locks.cpp new file mode 100644 index 00000000000..8717c7687b6 --- /dev/null +++ b/netsvcs/clients/Tokens/collection/rw_locks.cpp @@ -0,0 +1,175 @@ +#include "ace/OS.h" +// @(#)rw_locks.cpp 1.1 10/18/96 + +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/Local_Tokens.h" +#include "ace/Remote_Tokens.h" +#include "ace/Thread_Manager.h" + +#if defined (ACE_HAS_THREADS) + +static ACE_Token_Proxy *global_rlock; +static ACE_Token_Proxy *global_wlock; + +static char *server_host = ACE_DEFAULT_SERVER_HOST; +static int server_port = ACE_DEFAULT_SERVER_PORT; +static int ignore_deadlock = 0; +static int threads = 2; +static int iterations = 50; +static int debug = 0; +static int remote = 0; +static int reads = 4; +static int write_sleep = 0; + +static void * +run_thread (void *vp) +{ + ACE_Thread_Manager *thr_mgr = (ACE_Thread_Manager*) vp; + ACE_Thread_Control tc (thr_mgr); + + for (int x = 0; x < iterations; x++) + { + int y = 0; + for (; y < reads; y++) + { + if (global_rlock->acquire () == -1) + { + if (ACE_Log_Msg::instance ()->errnum () == EDEADLK) + { + ACE_DEBUG ((LM_DEBUG, "rlock deadlock detected\n")); + goto READ_DEADLOCK; + } + else return 0; + } + + ACE_DEBUG ((LM_DEBUG, "(%t) rlock acquired.\n")); + } + + READ_DEADLOCK: + + for (; y > 0; y--) + { + if (global_rlock->release () == 0) + ACE_DEBUG ((LM_DEBUG, "(%t) r-released.\n")); + } + + if (global_wlock->acquire () == -1) + { + ACE_DEBUG ((LM_DEBUG, "wlock deadlock detected\n")); + } + else + { + if (write_sleep) + ACE_OS::sleep (1); + ACE_DEBUG ((LM_DEBUG, "\t\t(%t) wlock acquired.\n")); + if (global_wlock->release () == 0) + ACE_DEBUG ((LM_DEBUG, "\t\t(%t) w-released.\n")); + } + } + + ACE_DEBUG ((LM_DEBUG, "(%t) thread exiting.\n")); + return 0; +} + +static int +parse_args (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0], ACE_Log_Msg::STDERR); // | ACE_Log_Msg::VERBOSE); + + ACE_Get_Opt get_opt (argc, argv, "t:iun:drR:sp:h:", 1); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'h': // specify the host machine on which the server is running + server_host = get_opt.optarg; + break; + case 'p': // specify the port on which the server is running + server_port = ACE_OS::atoi (get_opt.optarg); + break; + case 't': + threads = ACE_OS::atoi (get_opt.optarg); + break; + case 'R': + reads = ACE_OS::atoi (get_opt.optarg); + break; + case 'd': + debug = 1; + break; + case 'r': + remote = 1; + break; + case 's': + write_sleep = 1; + break; + case 'n': + iterations = ACE_OS::atoi (get_opt.optarg); + break; + case 'i': + ignore_deadlock = 1; + break; + case 'u': + // usage: fallthrough + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n" + "[-i ignore deadlock]\n" + "[-n ]\n" + "[-R ]\n" + "[-r use remote locks]\n" + "[-d debug]\n" + "[-s sleep during writes]\n" + "[-t \n", 1), -1); + break; + } + } + + return 0; +} + +int +main (int argc, char* argv[]) +{ + if (parse_args (argc, argv) == -1) + return -1; + + if (remote) + { + ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port, server_host)); + global_rlock = (ACE_Token_Proxy *) new + ACE_Remote_RLock ("THE_TOKEN", ignore_deadlock, debug); + global_wlock = (ACE_Token_Proxy *) new + ACE_Remote_WLock ("THE_TOKEN", ignore_deadlock, debug); + } + else + { + global_rlock = (ACE_Token_Proxy *) new + ACE_Local_RLock ("THE_TOKEN", ignore_deadlock, debug); + global_wlock = (ACE_Token_Proxy *) new + ACE_Local_WLock ("THE_TOKEN", ignore_deadlock, debug); + } + + ACE_Thread_Manager mgr; + + if (mgr.spawn_n (threads, ACE_THR_FUNC (run_thread), + (void *) &mgr, THR_BOUND | THR_SUSPENDED) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn failed"), -1); + + if (mgr.resume_all () == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "resume failed"), -1); + + mgr.wait (); + + return 42; +} + +#else +int +main (int, char *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "threads not supported on this platform\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/netsvcs/clients/Tokens/deadlock/Makefile b/netsvcs/clients/Tokens/deadlock/Makefile new file mode 100644 index 00000000000..27dfd2a4253 --- /dev/null +++ b/netsvcs/clients/Tokens/deadlock/Makefile @@ -0,0 +1,87 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for repeating token client application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = deadlock_detection_test + +FILES = deadlock_detection_test + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/deadlock_detection_test.o .shobj/deadlock_detection_test.so: deadlock_detection_test.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Token_Manager.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Stack.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Remote_Tokens.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Token_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Token_Invariants.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/clients/Tokens/deadlock/README b/netsvcs/clients/Tokens/deadlock/README new file mode 100644 index 00000000000..74fffde05cd --- /dev/null +++ b/netsvcs/clients/Tokens/deadlock/README @@ -0,0 +1,98 @@ + +deadlock_detection_test + +This example contains two deadlock tests, mutex and rwlock tests. +% ./deadlock_detection_test -u +./deadlock_detection_test: +[-r test readers/writer locks] +[-n ] +[-h ] +[-p ] +[-i ignore deadlock] + +For both mutex and rwlock tests, -h and -p specify to use remote +mutexes. -i specifies to ignore deadlock. -n is repetitions through +the respective algorithms (default 100). Both tests also use Token +Invariants to ensure correctness of the mutexes and readers/writer +locks. + +------------------------------------------------------------ + +If you run ./deadlock_detection_test without -r, then the following +mutex test is run. + +The mutex test spawns two threads which attempt to deadlock. +Logically, there are two tokens A and B. Here is what both threads +try to do: + +Thread 1 Thread 2 +-------- -------- +Repeat 100 times Repeat 100 times + acquire A acquire B + acquire B acquire A + release A and B release A and B +repeat repeat + +Notice that A and B are reversed in 1 and 2. If the token manager +(which is not in the public interface, but hidden behind +ACE_Local_Mutex) works properly, they should detect the deadlock. If +a thread detects deadlock, the resources held are released, and it +starts the whole process over again. + +What can be confusing about the test program is all the other tricks +I'm pulling to test other aspects of the library. For instance, I'm +using both "global" and "local" ACE_Local_Mutexes. This is to test +the ability to have multiple threads using one token proxy as well as +multiple threads each using their own proxies. All the while, the +same logical token is being used. If this doesn't make sense, don't +worry about it. Just use the ACE_Local_Mutex any way you want. + +Another confusing trick is that I'm testing recursive acquisition. +(Two acquires in a row.) I have to make sure that the token manager +doesn't detect a recursive acquire as deadlock. + +To run a test, simply type: +% ./deadlock_detection_test + +This should run 100 times through the above pseudo code. If the +application halts, then we have trouble. It should never ever halt. +I've included a little flag with the ACE_Local_Mutex class to allow +deadlock detection to be ignored. So, if you run the test as follows, +deadlock detection will be ignored. + +% ./deadlock_detection_test -i + +In this case, the application should only run about a second before +deadlock occurs and the application halts. This is good. + +------------------------------------------------------------ + +If you run ./deadlock_detection_test *with* -r, then the following +rwlock test is run: + +There are four tokens and four threads in the rwlock test. The +readers/writer tokens are: + +reader first +writer first 1 +writer first 2 +writer first 3 + +There are three reader threads that only acquire reader locks on the +above tokens. Each of the reader threads first acquire "reader first" +and then one "writer first " (where is the corresponding +thread's id). So reader thread 1 acquires "reader first" and then +"writer first 1". + +There is a single writer thread that uses the following algorithm: + +repeat 100 + acquire "writer first 1" + acquire "reader first" + acquire "writer first 2" + acquire "reader first" + acquire "writer first 3" + acquire "reader first" + +This strange mix of readers and writer create an interesting graph of +tokens that the deadlock detection algorithm must traverse. diff --git a/netsvcs/clients/Tokens/deadlock/deadlock_detection_test.cpp b/netsvcs/clients/Tokens/deadlock/deadlock_detection_test.cpp new file mode 100644 index 00000000000..7f03ec512ae --- /dev/null +++ b/netsvcs/clients/Tokens/deadlock/deadlock_detection_test.cpp @@ -0,0 +1,342 @@ +// ============================================================================ +// @(#)deadlock_detection_test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// examples +// +// = FILENAME +// deadlock_detection_test.cpp +// +// = DESCRIPTION +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#include "ace/OS.h" +#include "ace/Log_Msg.h" +#include "ace/Token_Manager.h" +#include "ace/Remote_Tokens.h" +#include "ace/Thread.h" +#include "ace/Thread_Manager.h" +#include "ace/Get_Opt.h" +#include "ace/Token_Invariants.h" + +#if defined (ACE_HAS_THREADS) + +typedef ACE_Token_Invariant_Manager ACE_TOKEN_INVARIANTS; + +static ACE_Token_Proxy *global_mutex; + +struct Two_Tokens +{ +public: + Two_Tokens (ACE_Thread_Manager *tm): thr_mgr_ (tm) {} + ACE_Token_Proxy *first_; + ACE_Token_Proxy *second_; + ACE_Thread_Manager *thr_mgr_; +}; + +struct Four_Tokens +{ +public: + Four_Tokens (ACE_Thread_Manager *tm): thr_mgr_ (tm) {} + ACE_Token_Proxy *first1_; + ACE_Token_Proxy *first2_; + ACE_Token_Proxy *first3_; + ACE_Token_Proxy *second_; + ACE_Thread_Manager *thr_mgr_; +}; + +static int ignore_deadlock = 0; +static int remote_mutexes = 0; +static char *server_host = ACE_DEFAULT_SERVER_HOST; +static int server_port = ACE_DEFAULT_SERVER_PORT; +static int iterations = 100; +static int rwlocks = 0; + +static void * +two_token_thread (void *vp) +{ + Two_Tokens* tm = (Two_Tokens*) vp; + ACE_Thread_Control (tm->thr_mgr_); + + for (int x = 0; x < iterations; x++) + { + if (tm->first_->acquire () == -1) + { + ACE_DEBUG ((LM_DEBUG, "Deadlock detected\n")); + continue; + } + + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (tm->first_) == 0) + { + tm->first_->dump (); + ACE_ERROR_RETURN ((LM_ERROR, "violated invariant.\n"), 0); + } + + if (tm->second_->acquire () == -1) + { + ACE_DEBUG ((LM_DEBUG, "Deadlock Detected\n")); + goto G1; + } + + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (tm->second_) == 0) + { + tm->second_->dump (); + ACE_ERROR_RETURN ((LM_ERROR, "violated invariant.\n"), 0); + } + + ACE_TOKEN_INVARIANTS::instance ()->releasing (tm->second_); + + tm->second_->release (); + G1: + ACE_TOKEN_INVARIANTS::instance ()->releasing (tm->first_); + + tm->first_->release (); + } + + ACE_DEBUG ((LM_DEBUG, "thread %t exiting\n")); + return 0; +} + +static void * +run_writer (void *vp) +{ + Four_Tokens* ft = (Four_Tokens *) vp; + ACE_Thread_Control (ft->thr_mgr_); + int acquire_number = 0; + + for (int x = 0; x < iterations; x++) + { + // Cycle through each of the first three tokens. + ACE_Token_Proxy *t; + switch (acquire_number) + { + case 0: + t = ft->first1_; + break; + case 1: + t = ft->first2_; + break; + case 2: + t = ft->first3_; + break; + } + + acquire_number = (acquire_number + 1) % 3; + + if (t->acquire () == -1) + { + ACE_ASSERT (errno == EDEADLK); + ACE_DEBUG ((LM_DEBUG, "Deadlock detected.\n")); + continue; + } + + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (t) == 0) + { + t->dump (); + ACE_ERROR_RETURN ((LM_ERROR, "violated invariant.\n"), 0); + } + + if (ft->second_->acquire () == -1) + { + ACE_ASSERT (errno == EDEADLK); + ACE_DEBUG ((LM_DEBUG, "Deadlock Detected..\n")); + goto G1; + } + + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (ft->second_) == 0) + { + ft->second_->dump (); + ACE_ERROR_RETURN ((LM_ERROR, "violated invariant.\n"), 0); + } + + ACE_TOKEN_INVARIANTS::instance ()->releasing (ft->second_); + + ft->second_->release (); + G1: + ACE_TOKEN_INVARIANTS::instance ()->releasing (t); + + t->release (); + } + + ACE_DEBUG ((LM_DEBUG, "thread %t exiting\n")); + return 0; +} + +static int +parse_args (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0]); + + ACE_Get_Opt get_opt (argc, argv, "iuh:rp:n:", 1); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'r': + rwlocks = 1; + break; + case 'i': + ignore_deadlock = 1; + break; + case 'h': + server_host = get_opt.optarg; + remote_mutexes = 1; + break; + case 'p': + server_port = ACE_OS::atoi (get_opt.optarg); + remote_mutexes = 1; + break; + case 'n': + iterations = ACE_OS::atoi (get_opt.optarg); + break; + case 'u': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n" + "[-r test readers/writer locks]\n" + "[-n ]\n" + "[-h ]\n" + "[-p ]\n" + "[-i ignore deadlock]\n%a", 1), -1); + break; + } + } + + return 0; +} + +int +mutex_test (void) +{ + ACE_Thread_Manager thr_mgr; + + Two_Tokens one (&thr_mgr), two (&thr_mgr); + + if (remote_mutexes == 0) + { + global_mutex = new ACE_Local_Mutex ("global proxy", ignore_deadlock, 1); + one.first_ = new ACE_Local_Mutex ("local proxy", ignore_deadlock, 1); + two.second_ = new ACE_Local_Mutex ("local proxy", ignore_deadlock, 1); + } + else + { + ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port, server_host)); + global_mutex = new ACE_Remote_Mutex ("global proxy", ignore_deadlock, 1); + one.first_ = new ACE_Remote_Mutex ("local proxy", ignore_deadlock, 1); + two.second_ = new ACE_Remote_Mutex ("local proxy", ignore_deadlock, 1); + } + + one.second_ = global_mutex; + two.first_ = global_mutex; + + // Tell the token manager to be verbose when reporting deadlock. + ACE_Token_Manager::instance ()->debug (1); + + if (thr_mgr.spawn (ACE_THR_FUNC (two_token_thread), + (void *) &one, THR_BOUND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "first spawn"), -1); + + if (thr_mgr.spawn (ACE_THR_FUNC (two_token_thread), + (void *) &two, THR_BOUND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "second spawn"), -1); + + // Wait for all threads to exit. + thr_mgr.wait (); + + return 0; +} + +int +rwlock_test (void) +{ + ACE_Thread_Manager thr_mgr; + + Two_Tokens reader1 (&thr_mgr); + Two_Tokens reader2 (&thr_mgr); + Two_Tokens reader3 (&thr_mgr); + Four_Tokens writer (&thr_mgr); + + if (remote_mutexes == 0) + { + reader1.first_ = new ACE_Local_RLock ("reader first", ignore_deadlock, 1); + reader1.second_ = new ACE_Local_RLock ("writer first 1", ignore_deadlock, 1); + reader2.first_ = new ACE_Local_RLock ("reader first", ignore_deadlock, 1); + reader2.second_ = new ACE_Local_RLock ("writer first 2", ignore_deadlock, 1); + reader3.first_ = new ACE_Local_RLock ("reader first", ignore_deadlock, 1); + reader3.second_ = new ACE_Local_RLock ("writer first 3", ignore_deadlock, 1); + + writer.first1_ = new ACE_Local_WLock ("writer first 1", ignore_deadlock, 1); + writer.first2_ = new ACE_Local_WLock ("writer first 2", ignore_deadlock, 1); + writer.first3_ = new ACE_Local_WLock ("writer first 3", ignore_deadlock, 1); + writer.second_ = new ACE_Local_WLock ("reader first", ignore_deadlock, 1); + } + else + { + ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port, server_host)); + + reader1.first_ = new ACE_Remote_RLock ("writer first 1", ignore_deadlock, 1); + reader1.second_ = new ACE_Remote_RLock ("reader first", ignore_deadlock, 1); + reader2.first_ = new ACE_Remote_RLock ("writer first 2", ignore_deadlock, 1); + reader2.second_ = new ACE_Remote_RLock ("reader first", ignore_deadlock, 1); + reader3.first_ = new ACE_Remote_RLock ("writer first 3", ignore_deadlock, 1); + reader3.second_ = new ACE_Remote_RLock ("reader first", ignore_deadlock, 1); + + writer.first1_ = new ACE_Remote_WLock ("writer first 1", ignore_deadlock, 1); + writer.first2_ = new ACE_Remote_WLock ("writer first 2", ignore_deadlock, 1); + writer.first3_ = new ACE_Remote_WLock ("writer first 3", ignore_deadlock, 1); + writer.second_ = new ACE_Remote_WLock ("reader first", ignore_deadlock, 1); + } + + // Tell the token manager to be verbose when reporting deadlock. + ACE_Token_Manager::instance ()->debug (1); + + if (thr_mgr.spawn (ACE_THR_FUNC (two_token_thread), + (void *) &reader1, THR_BOUND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "first spawn"), -1); + + if (thr_mgr.spawn (ACE_THR_FUNC (two_token_thread), + (void *) &reader2, THR_BOUND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "first spawn"), -1); + + if (thr_mgr.spawn (ACE_THR_FUNC (two_token_thread), + (void *) &reader3, THR_BOUND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "first spawn"), -1); + + if (thr_mgr.spawn (ACE_THR_FUNC (run_writer), + (void *) &writer, THR_BOUND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "second spawn"), -1); + + // Wait for all threads to exit. + thr_mgr.wait (); + + return 0; +} + +int +main (int argc, char* argv[]) +{ + if (parse_args (argc, argv) == -1) + return -1; + + if (rwlocks) + rwlock_test (); + else + mutex_test (); + + ACE_DEBUG ((LM_DEBUG, "test exiting.\n")); + return 42; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "threads not supported on this platform\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/netsvcs/clients/Tokens/invariant/Makefile b/netsvcs/clients/Tokens/invariant/Makefile new file mode 100644 index 00000000000..8f1c727d6c9 --- /dev/null +++ b/netsvcs/clients/Tokens/invariant/Makefile @@ -0,0 +1,72 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for repeating token client application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = invariant + +FILES = invariant + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/invariant.o .shobj/invariant.so: invariant.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Token_Invariants.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Stack.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/clients/Tokens/invariant/README b/netsvcs/clients/Tokens/invariant/README new file mode 100644 index 00000000000..f078c2d6be4 --- /dev/null +++ b/netsvcs/clients/Tokens/invariant/README @@ -0,0 +1,27 @@ + +invariants.cpp tests the ACE Token Invariant utilities. The ACE Token +Invariant utilities allow an application to test the correctness of +mutex and readers/writer locks. + +invariants.cpp takes no command-line arguments. invariants.cpp first +tests readers/writer locks. This is done by spawning two threads +which simulate reader and writer acquire/renew/release loops. +However, the loops are performed without actual locks, so the +competing threads quickly reach and invalid state. The test should +report this violation of readers/writer lock invariants and both +threads should exit. + +The second test is for mutexes. Similar to the readers/writer lock +test, this test spawns two threads which perform acquire/renew/release +loops. When to two threads reach an invalid mutex state, the error +should be reported and the threads should exit. + +For these two previous tests, it is theoretically possible that the +threads never reach an invalid token state. However, it is highly +unlikely since the threads would have to execute the same code +simultaneously for the duration of the test. Nevertheless, it is +possible. + +The last test hardwires invalid token states. It runs two mutex and +two readers/writer lock tests. It should report "succeeded" for the +four tests. diff --git a/netsvcs/clients/Tokens/invariant/invariant.cpp b/netsvcs/clients/Tokens/invariant/invariant.cpp new file mode 100644 index 00000000000..85dfd0885dc --- /dev/null +++ b/netsvcs/clients/Tokens/invariant/invariant.cpp @@ -0,0 +1,199 @@ +// ============================================================================ +// @(#)invariant.cpp 1.1 10/18/96 + +// +// = LIBRARY +// examples +// +// = FILENAME +// invariant.cpp +// +// = DESCRIPTION +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#include "ace/OS.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/Thread_Manager.h" +#include "ace/Token_Invariants.h" + +#if defined (ACE_HAS_THREADS) + +typedef ACE_Token_Invariant_Manager ACE_TOKEN_INVARIANTS; + +static char * rwname = "reader/writer"; +static char * mutexname = "mutex"; + +static void * +run_reader_writer (void *vp) +{ + ACE_Thread_Manager *thr_mgr = (ACE_Thread_Manager*) vp; + ACE_Thread_Control tc (thr_mgr); + + for (int x = 0; x < 50; x++) + { + int y = 0; + for (; y < 5; y++) + { + if (ACE_TOKEN_INVARIANTS::instance ()->reader_acquired (rwname) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "reader acquire violated invariant.\n"), 0); + + ACE_DEBUG ((LM_DEBUG, "(%t) rlock acquired.\n")); + } + + ACE_TOKEN_INVARIANTS::instance ()->rwlock_releasing (rwname); + + if (ACE_TOKEN_INVARIANTS::instance ()->reader_acquired (rwname) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "reader renew violated invariant.\n"), 0); + + ACE_DEBUG ((LM_DEBUG, "(%t) rlock renewed.\n")); + + for (; y > 0; y--) + { + ACE_TOKEN_INVARIANTS::instance ()->rwlock_releasing (rwname); + ACE_DEBUG ((LM_DEBUG, "(%t) r-released.\n")); + } + + if (ACE_TOKEN_INVARIANTS::instance ()->writer_acquired (rwname) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "writer acquire violated invariant.\n"), 0); + + ACE_DEBUG ((LM_DEBUG, "\t\t(%t) wlock acquired.\n")); + + ACE_TOKEN_INVARIANTS::instance ()->rwlock_releasing (rwname); + + if (ACE_TOKEN_INVARIANTS::instance ()->writer_acquired (rwname) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "writer renew violated invariant.\n"), 0); + + ACE_DEBUG ((LM_DEBUG, "(%t) rlock renewed.\n")); + + ACE_TOKEN_INVARIANTS::instance ()->rwlock_releasing (rwname); + } + + ACE_DEBUG ((LM_DEBUG, "(%t) thread exiting.\n")); + return 0; +} + +static void * +run_mutex (void *vp) +{ + ACE_Thread_Manager *thr_mgr = (ACE_Thread_Manager*) vp; + ACE_Thread_Control tc (thr_mgr); + + for (int x = 0; x < 50; x++) + { + if (ACE_TOKEN_INVARIANTS::instance ()->mutex_acquired (mutexname) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "mutex acquire violated invariant.\n"), 0); + + ACE_DEBUG ((LM_DEBUG, "(%t) mutex acquired.\n")); + + ACE_TOKEN_INVARIANTS::instance ()->mutex_releasing (mutexname); + + if (ACE_TOKEN_INVARIANTS::instance ()->mutex_acquired (mutexname) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "mutex renew violated invariant.\n"), 0); + + ACE_DEBUG ((LM_DEBUG, "(%t) mutex renewed.\n")); + + ACE_TOKEN_INVARIANTS::instance ()->mutex_releasing (mutexname); + ACE_DEBUG ((LM_DEBUG, "(%t) mutex released.\n")); + } + + ACE_DEBUG ((LM_DEBUG, "(%t) thread exiting.\n")); + return 0; +} + +static int +run_final_test (void) +{ + ACE_DEBUG ((LM_DEBUG, "starting mutex tests 1 & 2\n")); + + // Mutex tests. + if (ACE_TOKEN_INVARIANTS::instance ()->mutex_acquired ("testing mutex") == 0) + ACE_ERROR_RETURN ((LM_ERROR, "mutex test 1 failed.\n"), 0); + if (ACE_TOKEN_INVARIANTS::instance ()->mutex_acquired ("testing mutex2") == 0) + ACE_ERROR_RETURN ((LM_ERROR, "mutex test 2 failed.\n"), 0); + if (ACE_TOKEN_INVARIANTS::instance ()->mutex_acquired ("testing mutex") == 0) + ACE_DEBUG ((LM_DEBUG, "mutex test 1 succeeded.\n")); + else + ACE_ERROR_RETURN ((LM_ERROR, "mutex test 1 failed..\n"), 0); + + if (ACE_TOKEN_INVARIANTS::instance ()->mutex_acquired ("testing mutex2") == 0) + ACE_DEBUG ((LM_DEBUG, "mutex test 2 succeeded.\n")); + else + ACE_ERROR_RETURN ((LM_ERROR, "mutex test 2 failed..\n"), 0); + + // RW tests. + ACE_DEBUG ((LM_DEBUG, "starting rwlock tests 1 & 2\n")); + + // Multiple readers. + if (ACE_TOKEN_INVARIANTS::instance ()->reader_acquired ("testing rwlock") == 0) + ACE_ERROR_RETURN ((LM_ERROR, "rwlock test 1 failed.\n"), 0); + if (ACE_TOKEN_INVARIANTS::instance ()->reader_acquired ("testing rwlock 2") == 0) + ACE_ERROR_RETURN ((LM_ERROR, "rwlock test 2 failed.\n"), 0); + if (ACE_TOKEN_INVARIANTS::instance ()->reader_acquired ("testing rwlock") == 0) + ACE_ERROR_RETURN ((LM_ERROR, "rwlock test 1 failed..\n"), 0); + if (ACE_TOKEN_INVARIANTS::instance ()->reader_acquired ("testing rwlock 2") == 0) + ACE_ERROR_RETURN ((LM_ERROR, "rwlock test 2 failed..\n"), 0); + + // Writer. + if (ACE_TOKEN_INVARIANTS::instance ()->writer_acquired ("testing rwlock") == 0) + ACE_DEBUG ((LM_ERROR, "rwlock test 1 succeded.\n")); + else + ACE_ERROR_RETURN ((LM_ERROR, "rwlock test 1 failed...\n"), 0); + + // Releasing reader. + ACE_TOKEN_INVARIANTS::instance ()->rwlock_releasing ("testing rwlock 2"); + ACE_TOKEN_INVARIANTS::instance ()->rwlock_releasing ("testing rwlock 2"); + + // Writer. + if (ACE_TOKEN_INVARIANTS::instance ()->writer_acquired ("testing rwlock 2") == 0) + ACE_ERROR_RETURN ((LM_ERROR, "rwlock test 2 failed....\n"), 0); + + // Reader. + if (ACE_TOKEN_INVARIANTS::instance ()->reader_acquired ("testing rwlock 2") == 0) + ACE_DEBUG ((LM_DEBUG, "rwlock test 2 succeeded.\n")); + else + ACE_ERROR_RETURN ((LM_ERROR, "rwlock test 2 failed.....\n"), 0); + + return 0; +} + +int +main (int argc, char* argv[]) +{ + ACE_Thread_Manager mgr; + + // Run reader/writer test + if (mgr.spawn_n (2, ACE_THR_FUNC (run_reader_writer), + (void *) &mgr, THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn failed"), -1); + + mgr.wait (); + + ACE_OS::sleep (2); + + // Run mutex test. + if (mgr.spawn_n (2, ACE_THR_FUNC (run_mutex), + (void *) &mgr, THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn failed"), -1); + + mgr.wait (); + + ACE_OS::sleep (2); + + run_final_test (); + + return 42; +} + +#else +int +main (int, char *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "threads not supported on this platform\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/netsvcs/clients/Tokens/manual/Makefile b/netsvcs/clients/Tokens/manual/Makefile new file mode 100644 index 00000000000..bc38106c2f8 --- /dev/null +++ b/netsvcs/clients/Tokens/manual/Makefile @@ -0,0 +1,109 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for repeating token client application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = manual + +FILES = manual + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/manual.o .shobj/manual.so: manual.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Stack.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Remote_Tokens.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Token_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Token_Invariants.h \ + $(WRAPPER_ROOT)/ace/Token_Collection.h \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/clients/Tokens/manual/README b/netsvcs/clients/Tokens/manual/README new file mode 100644 index 00000000000..09b9b9a365a --- /dev/null +++ b/netsvcs/clients/Tokens/manual/README @@ -0,0 +1,67 @@ + +./manual gives users a text-based interactive interface to local or +remote tokens. This is extremely useful for manually testing the +token server and setting up deadlock scenarios. + +Run it as follows + +% ./manual -u +./manual: +[-h ] +[-p ] +[-i ignore deadlock] +[-d debug] + +./manual gives you the following prompt. + + + This is the client id of the current operation. This is set + manually by ./manual for every operation. Be careful when + using multiple 's during a remote session (see BUGS + below). + + This is the name of the token for the operation. + + This is the type of the token. This can be: + M - Corresponds to a Mutex lock. + R - Corresponds to Readers/Writer lock. + W - Corresponds to Readers/Writer lock. + Obviously, a single can be M or it can R and/or W. If + you perform and operation like this "tid1 tokenA M A" then + don't do this "tid1 tokenA R A". This doesn't make sense. + + This is the operation to perform on the + -- proxy. These include: + A - acquire. + N - renew. + R - release. + T - tryacquire. + +BUGS!!!! + +When performing remote tests, be careful when using a single running +./manual to impersonate two 's. The Token Server client +connection policy is currently, one per thread. The Token Server +assumes that the same is always on the other end of a +connection. If you do something like the following, you will break +it: + +lambada:Tokens/manual> ./manual -h tango -p 20202 + +tid1 tokenA M A +ACE_TSS_Connection new connection +(1) acquired tokenA remotely. +Succeeded. + +tid2 tokenA M A +(1) acquired tokenA remotely. <------ This is remote BADness!!! +Succeeded. +Violated invariant. <------ Locally detected badness. + + + +Notice that the local side discovered that this was incorrect. +However, the Token Server thinks it was a recursive acquisition for +tid1. Keep in mind that this is not a problem with the Token library. +It is just a problem with how this primitive ./manual application maps +STDIN to the ACE Token API. diff --git a/netsvcs/clients/Tokens/manual/manual.cpp b/netsvcs/clients/Tokens/manual/manual.cpp new file mode 100644 index 00000000000..664d9017f66 --- /dev/null +++ b/netsvcs/clients/Tokens/manual/manual.cpp @@ -0,0 +1,347 @@ +// ============================================================================ +// @(#)manual.cpp 1.1 10/18/96 + +// +// = LIBRARY +// examples +// +// = FILENAME +// manual.cpp +// +// = DESCRIPTION +// Allows manual operations on local and remote tokens. +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#include "ace/OS.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/Local_Tokens.h" +#include "ace/Remote_Tokens.h" +#include "ace/Thread_Manager.h" +#include "ace/Token_Invariants.h" +#include "ace/Token_Collection.h" +#include "ace/Map_Manager.h" +#include "ace/Service_Config.h" + +typedef ACE_Token_Invariant_Manager ACE_TOKEN_INVARIANTS; + +class STDIN_Token : public ACE_Event_Handler + // = TITLE + // STDIN Token + // + // = DESCRIPTION + // Translates STDIN commands to ACE Token commands. +{ +public: + STDIN_Token (void); + // Construction. + + int parse_args (int argc, char *argv[]); + // Parse command-line arguments. + + int open (int argc, char *argv[]); + // Register with whatever event dispatcher is needed and run. + + // = Event_Handler methods. + int handle_input (ACE_HANDLE); + handle_exception (ACE_HANDLE); + +private: + + void display_menu (void); + // Display options. + + ACE_Token_Proxy *get_proxy (const char *tid, const char *token, char type); + // Get or make a proxy to with a client id. + + ACE_Token_Proxy *create_proxy (const char *token, char type); + // Create a proxy to with a client id. + + typedef ACE_CString TID; + + // = Mapping from tid to Token_Collection. + typedef ACE_Map_Manager + COLLECTIONS; + // COLLECTION maintains a mapping from tid to a collection. + + typedef ACE_Map_Iterator + COLLECTIONS_ITERATOR; + // Allows iterations through collections_. + + typedef ACE_Map_Entry + COLLECTIONS_ENTRY; + // Allows iterations through collections_. + + COLLECTIONS collections_; + // A collection for each . + + char *server_host_; + int server_port_; + int ignore_deadlock_; + int debug_; + int remote_; +}; + +STDIN_Token::STDIN_Token (void) +: server_host_ (ACE_DEFAULT_SERVER_HOST), + server_port_ (ACE_DEFAULT_SERVER_PORT), + ignore_deadlock_ (0), + debug_ (0), + remote_ (0) +{ +} + +int +STDIN_Token::parse_args (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0], ACE_Log_Msg::STDERR); + + ACE_Get_Opt get_opt (argc, argv, "h:p:diu", 1); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'h': // specify the host machine on which the server is running + server_host_ = get_opt.optarg; + remote_ = 1; + break; + case 'p': // specify the port on which the server is running + server_port_ = ACE_OS::atoi (get_opt.optarg); + remote_ = 1; + break; + case 'd': + debug_ = 1; + break; + case 'i': + ignore_deadlock_ = 1; + break; + case 'u': + // usage: fallthrough + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n" + "[-h ]\n" + "[-p ]\n" + "[-i ignore deadlock]\n" + "[-d debug]\n", 1), -1); + break; + } + } + + if (remote_) + ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port_, server_host_)); + + return 0; +} + +int +STDIN_Token::open (int argc, char *argv[]) +{ + if (this->parse_args (argc, argv) == -1) + return -1; + + // Register for signals. + if (ACE_Service_Config::reactor ()->register_handler + (SIGINT, this) == -1) + ACE_DEBUG ((LM_DEBUG, "Can't register signal handler\n")); + +#if (ACE_WIN32) + +#else + // Register for STDIN events with Reactor. + if (ACE_Service_Config::reactor ()->register_handler + (ACE_STDIN, this, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "Can't register signal handler\n"), 0); + + +#endif /* ACE_WIN32 */ + + + this->display_menu (); + +#if (ACE_WIN32) + +#else + ACE_Service_Config::run_reactor_event_loop (); +#endif /* ACE_WIN32 */ + + ACE_OS::printf ("Exiting...\n"); + return 0; +} + +int +STDIN_Token::handle_input (ACE_HANDLE fd) +{ + char tid[BUFSIZ]; + char token[BUFSIZ]; + char type[16]; + char operation[16]; + + if (::scanf ("%s %s %s %s", tid, token, type, operation) <= 0) + { + ACE_OS::printf ("Try again.\n"); + return 0; + } + + ACE_Token_Proxy *proxy = + this->get_proxy (tid, token, type[0]); + + if (proxy == 0) + return -1; + + switch (operation[0]) + { + case 'a': + case 'A': + if (proxy->acquire () == 0) + { + ACE_OS::printf ("Succeeded.\n"); + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (proxy) == 0) + ACE_OS::printf ("Violated invariant.\n"); + } + else + ACE_ERROR ((LM_ERROR, "%p.\n", "Acquire failed")); + break; + + case 'n': + case 'N': + ACE_TOKEN_INVARIANTS::instance ()->releasing (proxy); + if (proxy->renew () == 0) + { + ACE_OS::printf ("Succeeded.\n"); + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (proxy) == 0) + ACE_OS::printf ("Violated invariant.\n"); + } + else + ACE_ERROR ((LM_ERROR, "%p.\n", "Renew failed")); + break; + + case 'r': + case 'R': + ACE_TOKEN_INVARIANTS::instance ()->releasing (proxy); + if (proxy->release () == 0) + ACE_OS::printf ("Succeeded.\n"); + else + ACE_ERROR ((LM_ERROR, "%p.\n", "Release failed")); + break; + + case 't': + case 'T': + if (proxy->tryacquire () == 0) + { + ACE_OS::printf ("Succeeded.\n"); + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (proxy) == 0) + ACE_OS::printf ("Violated invariant.\n"); + } + else + ACE_ERROR ((LM_ERROR, "%p.\n", "Tryacquire failed")); + break; + } + + this->display_menu (); + return 0; +} + +void +STDIN_Token::display_menu (void) +{ + ACE_OS::printf (" \n"); +} + +int +STDIN_Token::handle_exception (ACE_HANDLE fd) +{ + ACE_Service_Config::run_reactor_event_loop (); + return -1; +} + +ACE_Token_Proxy * +STDIN_Token::get_proxy (const char *_tid, const char *token, char type) +{ + ACE_Token_Collection *proxy_collection; + + TID tid (_tid); + + if (collections_.find (tid, proxy_collection) == -1) + // We did not find a proxy_collection. + { + // Make one. + proxy_collection = new ACE_Token_Collection (debug_, "no name collection"); + + // Put it in the collections. + if (collections_.bind (tid, proxy_collection) == -1) + { + delete proxy_collection; + return 0; + } + } + + // Either way, we have a proxy_collection now. + + // See if the proxy already exists in the collection. + ACE_Token_Proxy *proxy = proxy_collection->is_member (token); + + // If not, create one. + if (proxy == 0) + { + proxy = this->create_proxy (token, type); + + // Put the new_proxy in this tid's collection. + if (proxy_collection->insert (*proxy) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "insert failed\n"), 0); + + // Delete our copy (one was created in the collection). + delete proxy; + proxy = proxy_collection->is_member (token); + + if (proxy == 0) + ACE_ERROR_RETURN ((LM_ERROR, "is_member failed\n"), 0); + + // Set the client_id (it was set to 1 since we're + // single-threaded. + proxy->client_id (_tid); + } + + return proxy; +} + +ACE_Token_Proxy * +STDIN_Token::create_proxy (const char *token, char type) +{ + switch (type) + { + case 'm': + case 'M': + if (remote_) + return new ACE_Remote_Mutex (token, ignore_deadlock_, debug_); + else + return new ACE_Local_Mutex (token, ignore_deadlock_, debug_); + + case 'r': + case 'R': + if (remote_) + return new ACE_Remote_RLock (token, ignore_deadlock_, debug_); + else + return new ACE_Local_RLock (token, ignore_deadlock_, debug_); + + case 'w': + case 'W': + if (remote_) + return new ACE_Remote_WLock (token, ignore_deadlock_, debug_); + else + return new ACE_Local_WLock (token, ignore_deadlock_, debug_); + } +} + + +int +main (int argc, char* argv[]) +{ + STDIN_Token st; + return st.open (argc, argv); +} diff --git a/netsvcs/clients/Tokens/mutex/Makefile b/netsvcs/clients/Tokens/mutex/Makefile new file mode 100644 index 00000000000..fbd5fd4c597 --- /dev/null +++ b/netsvcs/clients/Tokens/mutex/Makefile @@ -0,0 +1,85 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for repeating token client application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = test_mutex + +FILES = test_mutex + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/test_mutex.o .shobj/test_mutex.so: test_mutex.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Stack.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Remote_Tokens.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Token_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/clients/Tokens/mutex/README b/netsvcs/clients/Tokens/mutex/README new file mode 100644 index 00000000000..cbd1e9c7d6c --- /dev/null +++ b/netsvcs/clients/Tokens/mutex/README @@ -0,0 +1,23 @@ + +test_mutex + +test_mutex tests ACE_Local_Mutex and ACE_Remote_Mutex with both local +and global proxies. "Local proxies" mean that each thread uses its +own proxy (but same logical token.) "Global proxy" means that all +threads access the same proxy (and, of course, the same logical +token.) + +test_mutex can take the number of threads to run from the +command-line. Thus, to run the test with one thread and local +mutexes, type: + +% ./test_mutex + +To run the test with 10 threads and local mutexes, type: + +% ./test_mutex -t 10 + +To run the test with 10 threads and remote mutexes, type: + +% ./test_mutex -t 10 -r + diff --git a/netsvcs/clients/Tokens/mutex/test_mutex.cpp b/netsvcs/clients/Tokens/mutex/test_mutex.cpp new file mode 100644 index 00000000000..3b7b94dba0d --- /dev/null +++ b/netsvcs/clients/Tokens/mutex/test_mutex.cpp @@ -0,0 +1,144 @@ +// ============================================================================ +// @(#)test_mutex.cpp 1.1 10/18/96 + +// +// = LIBRARY +// examples +// +// = FILENAME +// test_mutex.cpp +// +// = DESCRIPTION +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#include "ace/OS.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/Local_Tokens.h" +#include "ace/Remote_Tokens.h" +#include "ace/Thread.h" +#include "ace/Thread_Manager.h" + +#if defined (ACE_HAS_THREADS) + +static ACE_Token_Proxy *mutex; +static int remote_mutexes = 0; +static char *server_host = ACE_DEFAULT_SERVER_HOST; +static int server_port = ACE_DEFAULT_SERVER_PORT; +static int iterations = 100; +static int spawn_count = 2; + +static void * +run_test (void *vp) +{ + ACE_Thread_Manager *thr_mgr = (ACE_Thread_Manager*) vp; + ACE_Thread_Control tc (thr_mgr); + + int count = iterations; + // test recursive acquisition of a global proxy + while (count--) + { + if (mutex->acquire () == -1) + { + ACE_ERROR ((LM_ERROR, "(%t) %p acquire failed\n","test_mutex")); + return (void *) -1; + } + +// mutex->acquire (); + if (mutex->renew () == -1) + { + ACE_ERROR ((LM_ERROR, "(%t) %p renew failed\n","test_mutex")); + return (void *) -1; + } + + if (mutex->release () == -1) + { + ACE_ERROR ((LM_ERROR, "(%t) %p release failed\n","test_mutex")); + return (void *) -1; + } + +// mutex->release (); + } + + return 0; +} + +static int +parse_args (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0]); + + ACE_Get_Opt get_opt (argc, argv, "t:uh:p:n:", 1); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 't': + spawn_count = ACE_OS::atoi (get_opt.optarg); + break; + case 'h': // specify the host machine on which the server is running + server_host = get_opt.optarg; + remote_mutexes = 1; + break; + case 'p': // specify the port on which the server is running + server_port = ACE_OS::atoi (get_opt.optarg); + remote_mutexes = 1; + break; + case 'n': // specify the port on which the server is running + iterations = ACE_OS::atoi (get_opt.optarg); + break; + case 'u': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n" + "[-h ]\n" + "[-p ]\n" + "[-n ]\n" + "[-t ]\n" + "[-h ]\n" + "[-p ]\n", 1), -1); + break; + } + } + + return 0; +} + +int +main (int argc, char* argv[]) +{ + ACE_Thread_Manager thread_mgr; + + if (parse_args (argc, argv) == -1) + return -1; + + if (remote_mutexes) + { + ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port, server_host)); + mutex = new ACE_Remote_Mutex ("Remote TOKEN", 0, 1); + } + else + { + mutex = new ACE_Local_Mutex ("Local TOKEN", 0, 1); + } + + if (thread_mgr.spawn_n (spawn_count, + ACE_THR_FUNC (run_test), + (void *) &thread_mgr, THR_BOUND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn"), -1); + + thread_mgr.wait (); + + return 42; +} +#else +int main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "you must have threads to run this test program\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/netsvcs/clients/Tokens/rw_lock/Makefile b/netsvcs/clients/Tokens/rw_lock/Makefile new file mode 100644 index 00000000000..3bf51a6fa51 --- /dev/null +++ b/netsvcs/clients/Tokens/rw_lock/Makefile @@ -0,0 +1,86 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for repeating token client application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = rw_locks + +FILES = rw_locks + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/rw_locks.o .shobj/rw_locks.so: rw_locks.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Stack.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Remote_Tokens.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Token_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Token_Invariants.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/clients/Tokens/rw_lock/README b/netsvcs/clients/Tokens/rw_lock/README new file mode 100644 index 00000000000..dabc0a3741d --- /dev/null +++ b/netsvcs/clients/Tokens/rw_lock/README @@ -0,0 +1,40 @@ + +test_rw_locks shows how to use ACE_Local_RLock, ACE_Local_WLock, +ACE_Remote_RLock, and ACE_Remote_WLock. + +Here are the options to test_rw_locks: +% ./test_rw_lock -u + -i ignore deadlock + -n + -r + -d debug + -s sleep during writes + -t + +test_rw_locks spawns number of threads which perform the +following algorithm: + +for + { + for + acquire read lock + for + release read lock + + acquire write lock + if (sleep during writes) + sleep for 1 second + release write lock + } + + +The output should show that multiple readers can acquire the lock for +reading simultaneously (note that this also tests recursive +acquisition.) When a writer lock is acquired, the output should show +that no thread holds a reader lock. + +To run a test, simply type: +% ./test_rw_lock + +This should show output as described above. + diff --git a/netsvcs/clients/Tokens/rw_lock/rw_locks.cpp b/netsvcs/clients/Tokens/rw_lock/rw_locks.cpp new file mode 100644 index 00000000000..3c6295ce0a5 --- /dev/null +++ b/netsvcs/clients/Tokens/rw_lock/rw_locks.cpp @@ -0,0 +1,255 @@ +// ============================================================================ +// @(#)rw_locks.cpp 1.1 10/18/96 + +// +// = LIBRARY +// examples +// +// = FILENAME +// rw_locks.cpp +// +// = DESCRIPTION +// test_rw_locks shows how to use ACE_Local_RLock, ACE_Local_WLock, +// ACE_Remote_RLock, and ACE_Remote_WLock. +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#include "ace/OS.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/Local_Tokens.h" +#include "ace/Remote_Tokens.h" +#include "ace/Thread_Manager.h" +#include "ace/Token_Invariants.h" + +#if defined (ACE_HAS_THREADS) + +typedef ACE_Token_Invariant_Manager ACE_TOKEN_INVARIANTS; + +static ACE_Token_Proxy *global_rlock; +static ACE_Token_Proxy *global_wlock; + +static char *server_host = ACE_DEFAULT_SERVER_HOST; +static int server_port = ACE_DEFAULT_SERVER_PORT; +static int ignore_deadlock = 0; +static int threads = 2; +static int iterations = 50; +static int debug = 0; +static int remote = 0; +static int reads = 4; +static int write_sleep = 0; +static int renew = 0; + +static void * +run_thread (void *vp) +{ + ACE_Thread_Manager *thr_mgr = (ACE_Thread_Manager*) vp; + ACE_Thread_Control tc (thr_mgr); + + for (int x = 0; x < iterations; x++) + { + int y = 0; + for (; y < reads; y++) + { + if (global_rlock->acquire () == -1) + { + if (ACE_Log_Msg::instance ()->errnum () == EDEADLK) + { + ACE_DEBUG ((LM_DEBUG, "rlock deadlock detected\n")); + goto READ_DEADLOCK; + } + else return 0; + } + + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (global_rlock) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "reader acquire violated invariant.\n"), 0); + + ACE_DEBUG ((LM_DEBUG, "(%t) rlock acquired.\n")); + } + + if (renew) + { + ACE_TOKEN_INVARIANTS::instance ()->releasing (global_rlock); + + if (global_rlock->renew () == -1) + { + if (ACE_Log_Msg::instance ()->errnum () == EDEADLK) + { + ACE_DEBUG ((LM_DEBUG, "rlock deadlock detected during renew\n")); + goto READ_DEADLOCK; + } + else return 0; + } + + ACE_DEBUG ((LM_DEBUG, "(%t) rlock renewed.\n")); + + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (global_rlock) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "reader renew violated invariant.\n"), 0); + } + + READ_DEADLOCK: + + for (; y > 0; y--) + { + ACE_TOKEN_INVARIANTS::instance ()->releasing (global_rlock); + if (global_rlock->release () == 0) + ACE_DEBUG ((LM_DEBUG, "(%t) r-released.\n")); + } + + if (global_wlock->acquire () == -1) + ACE_DEBUG ((LM_DEBUG, "wlock deadlock detected\n")); + else + { + if (write_sleep) + ACE_OS::sleep (1); + ACE_DEBUG ((LM_DEBUG, "\t\t(%t) wlock acquired.\n")); + + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (global_wlock) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "writer acquire violated invariant.\n"), 0); + + if (renew) + { + ACE_TOKEN_INVARIANTS::instance ()->releasing (global_wlock); + + if (global_wlock->renew () == -1) + { + if (ACE_Log_Msg::instance ()->errnum () == EDEADLK) + { + ACE_DEBUG ((LM_DEBUG, "wlock deadlock detected during renew\n")); + } + else return 0; + } + + ACE_DEBUG ((LM_DEBUG, "(%t) rlock renewed.\n")); + + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (global_wlock) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "writer renew violated invariant.\n"), 0); + } + + ACE_TOKEN_INVARIANTS::instance ()->releasing (global_wlock); + + if (global_wlock->release () == 0) + ACE_DEBUG ((LM_DEBUG, "\t\t(%t) w-released.\n")); + } + } + + ACE_DEBUG ((LM_DEBUG, "(%t) thread exiting.\n")); + return 0; +} + +static int +parse_args (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0], ACE_Log_Msg::STDERR); // | ACE_Log_Msg::VERBOSE); + + ACE_Get_Opt get_opt (argc, argv, "t:iun:dr:sp:h:R", 1); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'h': // specify the host machine on which the server is running + server_host = get_opt.optarg; + remote = 1; + break; + case 'p': // specify the port on which the server is running + server_port = ACE_OS::atoi (get_opt.optarg); + remote = 1; + break; + case 't': + threads = ACE_OS::atoi (get_opt.optarg); + break; + case 'R': + renew = 1; + break; + case 'r': + reads = ACE_OS::atoi (get_opt.optarg); + break; + case 'd': + debug = 1; + break; + case 's': + write_sleep = 1; + break; + case 'n': + iterations = ACE_OS::atoi (get_opt.optarg); + break; + case 'i': + ignore_deadlock = 1; + break; + case 'u': + // usage: fallthrough + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n" + "[-h ]\n" + "[-p ]\n" + "[-i ignore deadlock]\n" + "[-n ]\n" + "[-R perform renews]\n" + "[-r ]\n" + "[-d debug]\n" + "[-s sleep during writes]\n" + "[-t \n", 1), -1); + break; + } + } + + return 0; +} + +#if defined (ACE_HAS_PTHREADS) +#define SUSPEND 0 +#else +#define SUSPEND THR_SUSPENDED +#endif + +int +main (int argc, char* argv[]) +{ + if (parse_args (argc, argv) == -1) + return -1; + + if (remote) + { + ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port, server_host)); + global_rlock = (ACE_Token_Proxy *) new + ACE_Remote_RLock ("THE_TOKEN", ignore_deadlock, debug); + global_wlock = (ACE_Token_Proxy *) new + ACE_Remote_WLock ("THE_TOKEN", ignore_deadlock, debug); + } + else + { + global_rlock = (ACE_Token_Proxy *) new + ACE_Local_RLock ("THE_TOKEN", ignore_deadlock, debug); + global_wlock = (ACE_Token_Proxy *) new + ACE_Local_WLock ("THE_TOKEN", ignore_deadlock, debug); + } + + ACE_Thread_Manager mgr; + + if (mgr.spawn_n (threads, ACE_THR_FUNC (run_thread), + (void *) &mgr, THR_BOUND | SUSPEND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn failed"), -1); + +#if ! defined (ACE_HAS_PTHREADS) + if (mgr.resume_all () == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "resume failed"), -1); +#endif + + mgr.wait (); + + return 42; +} + +#else +int +main (int, char *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "threads not supported on this platform\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/netsvcs/lib/Client_Logging_Handler.cpp b/netsvcs/lib/Client_Logging_Handler.cpp new file mode 100644 index 00000000000..9ef906172b5 --- /dev/null +++ b/netsvcs/lib/Client_Logging_Handler.cpp @@ -0,0 +1,373 @@ +// Client_Logging_Handler.cpp +// @(#)Client_Logging_Handler.cpp 1.1 10/18/96 + +#define ACE_BUILD_SVC_DLL +#include "ace/Service_Config.h" +#include "ace/Connector.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/SOCK_Connector.h" +#include "ace/SOCK_Stream.h" +#include "ace/FIFO_Recv_Msg.h" +#include "Client_Logging_Handler.h" + +class ACE_Svc_Export ACE_Client_Logging_Handler : public ACE_Svc_Handler + // = TITLE + // This client logging daemon is a mediator that receives logging + // records from local applications processes and forwards them to + // the server logging daemon running on another host. + // + // = DESCRIPTION + // +{ +public: + // = Initialization and termination. + + ACE_Client_Logging_Handler (const char rendezvous[]); + // Default constructor. + + virtual int open (void * = 0); + // Activate this instance of the + // (called by the ). + + virtual ACE_HANDLE get_handle (void) const; + // Return the handle of the message_fifo_; + + virtual int close (u_long); + // Called when object is removed from the ACE_Reactor + +protected: + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + // Handle SIGINT. + + virtual int handle_input (ACE_HANDLE); + // Receive logging records from applications. + + virtual int handle_exception (ACE_HANDLE); + // Receive logging records from applications. This is necessary to handle + // madness with UNIX select, which can't deal with MSG_BAND data easily due + // to its overly simple interface... This just calls . + + virtual int handle_output (ACE_HANDLE); + // Called back when it's ok to send. + + int send (ACE_Log_Record &log_record); + // Send the to the logging server. + + ACE_FIFO_Recv_Msg message_fifo_; + // Message queue we use to receive logging records from clients. + + ACE_HANDLE logging_output_; + // This is either a SOCKET (if we're connected to a logging server) + // or ACE_STDOUT. + + static void stderr_output (int = 0); +}; + +ACE_Client_Logging_Handler::ACE_Client_Logging_Handler (const char rendezvous[]) + : logging_output_ (ACE_STDOUT) +{ + if (ACE_OS::unlink (rendezvous) == -1 && errno == EACCES) + ACE_ERROR ((LM_ERROR, "%p\n", "unlink")); + else if (this->message_fifo_.open (rendezvous) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "open")); + // Register message FIFO to receive input from clients. Note that we need to + // put the EXCEPT_MASK here to deal with SVR4 MSG_BAND data correctly... + else if (ACE_Service_Config::reactor ()->register_handler + (this->message_fifo_.get_handle (), this, + ACE_Event_Handler::READ_MASK | ACE_Event_Handler::EXCEPT_MASK) == -1) + ACE_ERROR ((LM_ERROR, "%n: %p\n", + "register_handler (message_fifo)")); + ACE_DEBUG ((LM_DEBUG, + "opened fifo at %s on handle %d\n", + rendezvous, + this->message_fifo_.get_handle ())); +} + +// This is called when a to the logging server fails... + +int +ACE_Client_Logging_Handler::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + ACE_TRACE ("ACE_Client_Logging_Connector::handle_signal"); +// return 0; + return -1; +} + +int +ACE_Client_Logging_Handler::open (void *) +{ + ACE_INET_Addr server_addr; + + this->logging_output_ = this->peer ().get_handle (); + + // Register ourselves to receive SIGPIPE so we can attempt + // reconnections. + if (ACE_Service_Config::reactor ()->register_handler (SIGPIPE, this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n", + "register_handler (SIGPIPE)"), -1); + + // Figure out what remote port we're really bound to. + else if (this->peer ().get_remote_addr (server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "get_remote_addr"), -1); + + ACE_DEBUG ((LM_DEBUG, + "starting up Client Logging Daemon, " + "connected to port %d on handle %d\n", + server_addr.get_port_number (), + this->peer ().get_handle ())); + return 0; +} + +/* VIRTUAL */ ACE_HANDLE +ACE_Client_Logging_Handler::get_handle (void) const +{ + ACE_TRACE ("ACE_Client_Logging_Handler::get_handle"); + return this->message_fifo_.get_handle (); +} + + +// Receive a logging record from an application. + +int +ACE_Client_Logging_Handler::handle_input (ACE_HANDLE handle) +{ + if (handle == this->message_fifo_.get_handle ()) + { + // We're getting a logging message from a local application. + + ACE_Log_Record log_record; + ACE_Str_Buf msg ((void *) &log_record, + 0, sizeof log_record); + + ACE_DEBUG ((LM_DEBUG, "in handle_input\n")); + if (this->message_fifo_.recv (msg) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ACE_FIFO_Recv_Msg::recv"), -1); + else if (this->send (log_record) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), 0); + return 0; + } + else if (handle == this->peer ().get_handle ()) + { + // We're getting a message from the logging server! + ACE_ASSERT (!"this shouldn't happen yet...\n"); + } + return 0; +} + +// Receive a logging record from an application send via a non-0 MSG_BAND... +// This just calls handle_input(). + +int +ACE_Client_Logging_Handler::handle_exception (ACE_HANDLE handle) +{ + return this->handle_input (handle); +} + +// Called when object is removed from the ACE_Reactor + +int +ACE_Client_Logging_Handler::close (u_long) +{ + ACE_DEBUG ((LM_DEBUG, "shutting down!!!\n")); + this->message_fifo_.close (); + return 0; +} + +int +ACE_Client_Logging_Handler::handle_output (ACE_HANDLE handle) +{ + return 0; +} + +// Encodes the contents of log_record object using network byte-order +// and sends it to the logging server. + +int +ACE_Client_Logging_Handler::send (ACE_Log_Record &log_record) +{ + if (this->logging_output_ == ACE_STDOUT) + log_record.print ("", 0, stderr); + else + { + long len = log_record.length (); + long encoded_len = htonl (len); + + log_record.encode (); + + if (this->peer ().send (4, &encoded_len, sizeof encoded_len, + (char *) &log_record, len) == -1) + // Switch over to logging to stdout for now. In the long + // run, we'll need to queue up the message, try to + // reestablish a connection, and then send the queued data + // once we've reconnect to the logging server. + this->logging_output_ = ACE_STDOUT; + } + + return 0; +} + + +class ACE_Client_Logging_Connector : public ACE_Connector + // = TITLE + // This class contains the service-specific methods that can't + // easily be factored into the . +{ +protected: + // = Dynamic linking hooks. + virtual int init (int argc, char *argv[]); + // Called when service is linked. + + virtual int fini (void); + // Called when service is unlinked. + + virtual int info (char **strp, size_t length) const; + // Called to determine info about the service. + + // = Scheduling hooks. + virtual int suspend (void); + virtual int resume (void); + + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + // Handle SIGINT. + +private: + int parse_args (int argc, char *argv[]); + // Parse svc.conf arguments. + + const char *server_host_; + // Host where the logging server is located. + + u_short server_port_; + // Port number where the logging server is listening for + // connections. + + ACE_INET_Addr server_addr_; + // Address of the logging server. + + const char *rendezvous_key_; + // Filename where the FIFO will listen for application logging + // records. + + ACE_Client_Logging_Handler *handler_; + // Pointer to the handler that does the work. +}; + +int +ACE_Client_Logging_Connector::fini (void) +{ + this->handler_->destroy (); + return 0; +} + +int +ACE_Client_Logging_Connector::info (char **strp, size_t length) const +{ + char buf[BUFSIZ]; + + ACE_OS::sprintf (buf, "%d/%s %s", + this->server_addr_.get_port_number (), "tcp", + "# client logging daemon\n"); + + if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0) + return -1; + else + ACE_OS::strncpy (*strp, buf, length); + return ACE_OS::strlen (buf); +} + +int +ACE_Client_Logging_Connector::init (int argc, char *argv[]) +{ + ACE_LOG_MSG->open ("Client Logging Service"); + + // Use the options hook to parse the command line arguments and set + // options. + this->parse_args (argc, argv); + + // Register ourselves to receive SIGINT so we can shutdown + // gracefully. + if (ACE_Service_Config::reactor ()->register_handler (SIGINT, this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n", + "register_handler (SIGINT)"), -1); + + ACE_NEW_RETURN (this->handler_, + ACE_Client_Logging_Handler (this->rendezvous_key_), + -1); + + // Establish connection with the server. + if (this->connect (this->handler_, + this->server_addr_, + ACE_Synch_Options::synch) == -1) + ACE_ERROR ((LM_ERROR, "%p, using stdout\n", + "can't connect to logging server")); + return 0; +} + +int +ACE_Client_Logging_Connector::parse_args (int argc, char *argv[]) +{ + this->rendezvous_key_ = ACE_DEFAULT_RENDEZVOUS; + this->server_port_ = ACE_DEFAULT_LOGGING_SERVER_PORT; + this->server_host_ = ACE_DEFAULT_SERVER_HOST; + + ACE_Get_Opt get_opt (argc, argv, "h:k:p:", 0); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'h': + this->server_host_ = get_opt.optarg; + break; + case 'k': + this->rendezvous_key_ = get_opt.optarg; + break; + case 'p': + this->server_port_ = ACE_OS::atoi (get_opt.optarg); + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n[-p server-port]\n%a", 1), + -1); + break; + } + } + + this->server_addr_.set (this->server_port_, this->server_host_); + return 0; +} + +int +ACE_Client_Logging_Connector::suspend (void) +{ + // To be done... + return 0; +} + +int +ACE_Client_Logging_Connector::resume (void) +{ + // To be done... + return 0; +} + +// Signal the server to shutdown gracefully. + +int +ACE_Client_Logging_Connector::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + ACE_TRACE ("ACE_Client_Logging_Connector::handle_signal"); + ACE_Service_Config::end_reactor_event_loop (); + return 0; +} + +// The following is a "Factory" used by the ACE_Service_Config and +// svc.conf file to dynamically initialize the state of the +// single-threaded logging server. + +ACE_SVC_FACTORY_DEFINE (ACE_Client_Logging_Connector) + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Connector; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/netsvcs/lib/Client_Logging_Handler.h b/netsvcs/lib/Client_Logging_Handler.h new file mode 100644 index 00000000000..7d18a7af6e7 --- /dev/null +++ b/netsvcs/lib/Client_Logging_Handler.h @@ -0,0 +1,25 @@ +/* -*- C++ -*- */ +// @(#)Client_Logging_Handler.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Client_Logging_Handler.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_CLIENT_LOGGER_H) +#define ACE_CLIENT_LOGGER_H + +#include "ace/OS.h" + +ACE_SVC_FACTORY_DECLARE (ACE_Client_Logging_Connector) + +#endif /* ACE_CLIENT_LOGGER_H */ diff --git a/netsvcs/lib/Client_Logging_Handler.i b/netsvcs/lib/Client_Logging_Handler.i new file mode 100644 index 00000000000..e5cdb810e6b --- /dev/null +++ b/netsvcs/lib/Client_Logging_Handler.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// @(#)Client_Logging_Handler.i 1.1 10/18/96 + + diff --git a/netsvcs/lib/Logging_Strategy.cpp b/netsvcs/lib/Logging_Strategy.cpp new file mode 100644 index 00000000000..af2a0fc5f31 --- /dev/null +++ b/netsvcs/lib/Logging_Strategy.cpp @@ -0,0 +1,145 @@ +// Logging_Strategy.cpp +// @(#)Logging_Strategy.cpp 1.1 10/18/96 + +#define ACE_BUILD_SVC_DLL +#include "iostream.h" +#include "fstream.h" +#include "ace/Get_Opt.h" +#include "ace/Log_Msg.h" +#include "ace/Service_Object.h" +#include "Logging_Strategy.h" + +class ACE_Logging_Strategy : public ACE_Service_Object + // = TITLE + // This class provides the hooks to control the output produced + // by any of the network services. + // + // = DESCRIPTION + // Depending upon when this service is invoked and with what + // flags, the output of other network services can be + // controlled. The output can be streamed to stderr, to a file, + // to a logging daemon, or it can be set to be "silent". +{ +public: + virtual int init (int argc, char *argv[]); + // Dynamic linking hook. + + int parse_args (int argc, char *argv[]); + // Parse svc.conf arguments. +private: + void tokenize (char *flag_string); + // Tokenize to set all the flags + u_long flags_; + char *filename_; +}; + +// Parse the string containing all the flags and set the flags accordingly +void +ACE_Logging_Strategy::tokenize (char *flag_string) +{ + char *flag; + if ((flag = ACE_OS::strtok (flag_string, "|")) != NULL) + { + while (flag) + { + if (ACE_OS::strcmp (flag, "STDERR") == 0) + ACE_SET_BITS (this->flags_, ACE_Log_Msg::STDERR); + else if (ACE_OS::strcmp (flag, "LOGGER") == 0) + ACE_SET_BITS (this->flags_, ACE_Log_Msg::LOGGER); + else if (ACE_OS::strcmp (flag, "OSTREAM") == 0) + ACE_SET_BITS (this->flags_, ACE_Log_Msg::OSTREAM); + else if (ACE_OS::strcmp (flag, "VERBOSE") == 0) + ACE_SET_BITS (this->flags_, ACE_Log_Msg::VERBOSE); + else if (ACE_OS::strcmp (flag, "SILENT") == 0) + ACE_SET_BITS (this->flags_, ACE_Log_Msg::SILENT); + + // Get the next flag + flag = ACE_OS::strtok(0, "|"); + } + } +} + +int +ACE_Logging_Strategy::parse_args (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_Logging_Strategy::parse_args"); + char *temp; + u_long flag = 0; + + this->flags_ = 0; + this->filename_ = ACE_DEFAULT_LOGFILE; + + ACE_LOG_MSG->open ("Logging_Strategy"); + + ACE_Get_Opt get_opt (argc, argv, "f:s:", 0); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'f': + temp = get_opt.optarg; + // Now tokenize the string to get all the flags + this->tokenize (temp); + break; + case 's': + // Ensure that the OSTREAM flag is set + ACE_SET_BITS (this->flags_, ACE_Log_Msg::OSTREAM); + this->filename_ = get_opt.optarg; + break; + default: + break; + } + } + return 0; +} + +int +ACE_Logging_Strategy::init (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_Logging_Strategy::init"); + + // Use the options hook to parse the command line arguments. + this->parse_args (argc, argv); + + // Check if any flags were specified. If none were specified, let + // the default behavior take effect. + if (this->flags_ != 0) + { + // Clear all flags + ACE_Log_Msg::instance()->clr_flags (ACE_Log_Msg::STDERR | + ACE_Log_Msg::LOGGER | + ACE_Log_Msg::OSTREAM | + ACE_Log_Msg::VERBOSE | + ACE_Log_Msg::SILENT); + // Check if OSTREAM bit is set + if (ACE_BIT_ENABLED (this->flags_, ACE_Log_Msg::OSTREAM)) + { + // Create a new ofstream to direct output to the file + ofstream *output_file = new ofstream (this->filename_); + ACE_Log_Msg::instance()->msg_ostream (output_file); + } + // Now set the flags for Log_Msg + ACE_Log_Msg::instance()->set_flags (this->flags_); + } + return 0; +} + +// The following is a "Factory" used by the ACE_Service_Config and +// svc.conf file to dynamically initialize the state of the Logging_Strategy. + +ACE_SVC_FACTORY_DEFINE (ACE_Logging_Strategy) + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Strategy_Acceptor; +template class ACE_Schedule_All_Reactive_Strategy; +#if defined (ACE_HAS_THREADS) +template class ACE_Svc_Handler; +template class ACE_Task; +template class ACE_Message_Queue; +template class ACE_Module; +template class ACE_Task_Exit; +template class ACE_TSS >; +template class ACE_Thru_Task; +#endif +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/netsvcs/lib/Logging_Strategy.h b/netsvcs/lib/Logging_Strategy.h new file mode 100644 index 00000000000..c1d94f48313 --- /dev/null +++ b/netsvcs/lib/Logging_Strategy.h @@ -0,0 +1,25 @@ +/* -*- C++ -*- */ +// @(#)Logging_Strategy.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Logging_Strategy.h +// +// = AUTHOR +// Prashant Jain +// +// ============================================================================ + +#if !defined (ACE_LOGGING_STRATEGY_H) +#define ACE_LOGGING_STRATEGY_H + +#include "ace/OS.h" + +ACE_SVC_FACTORY_DECLARE (ACE_Logging_Strategy) + +#endif /* ACE_LOGGING_STRATEGY_H */ diff --git a/netsvcs/lib/Makefile b/netsvcs/lib/Makefile new file mode 100644 index 00000000000..05b70cdbab2 --- /dev/null +++ b/netsvcs/lib/Makefile @@ -0,0 +1,465 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the server-side ACE network services +#---------------------------------------------------------------------------- + +#LIB = libnet_svcs.a +SHLIB = libnet_svcs.so + +FILES = TS_Server_Handler \ + TS_Clerk_Handler \ + Client_Logging_Handler \ + Name_Handler \ + Server_Logging_Handler \ + Token_Handler \ + Logging_Strategy + +DEFS = $(addsuffix .h,$(FILES)) +LSRC = $(addsuffix .cpp,$(FILES)) + +LIBS += -lACE + +BUILD = $(VLIB) $(VSHLIB) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/TS_Server_Handler.o .shobj/TS_Server_Handler.so: TS_Server_Handler.cpp \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/Time_Request_Reply.h \ + TS_Server_Handler.h +.obj/TS_Clerk_Handler.o .shobj/TS_Clerk_Handler.so: TS_Clerk_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Connector.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Connector.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Time_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/SString.h \ + TS_Clerk_Handler.h +.obj/Client_Logging_Handler.o .shobj/Client_Logging_Handler.so: Client_Logging_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Connector.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Connector.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/FIFO_Recv_Msg.h \ + $(WRAPPER_ROOT)/ace/FIFO_Recv.h \ + $(WRAPPER_ROOT)/ace/FIFO.h \ + $(WRAPPER_ROOT)/ace/FIFO_Recv.i \ + $(WRAPPER_ROOT)/ace/FIFO_Recv_Msg.i \ + Client_Logging_Handler.h +.obj/Name_Handler.o .shobj/Name_Handler.so: Name_Handler.cpp \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Naming_Context.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Name_Proxy.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Name_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Name_Space.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + Name_Handler.h +.obj/Server_Logging_Handler.o .shobj/Server_Logging_Handler.so: Server_Logging_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/TLI_Acceptor.h \ + $(WRAPPER_ROOT)/ace/TLI.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/TLI.i \ + $(WRAPPER_ROOT)/ace/TLI_Stream.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/TLI_Stream.i \ + $(WRAPPER_ROOT)/ace/TLI_Acceptor.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + Server_Logging_Handler.h +.obj/Token_Handler.o .shobj/Token_Handler.so: Token_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/Token_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Stack.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Token_Collection.h \ + $(WRAPPER_ROOT)/ace/SString.h \ + Token_Handler.h +.obj/Logging_Strategy.o .shobj/Logging_Strategy.so: Logging_Strategy.cpp \ + /pkg/gnu/lib/g++-include/iostream.h \ + /pkg/gnu/lib/g++-include/fstream.h \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + Logging_Strategy.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/lib/Name_Handler.cpp b/netsvcs/lib/Name_Handler.cpp new file mode 100644 index 00000000000..e036f42b68b --- /dev/null +++ b/netsvcs/lib/Name_Handler.cpp @@ -0,0 +1,738 @@ +// Name_Handler.cpp +// @(#)Name_Handler.cpp 1.1 10/18/96 + +#define ACE_BUILD_SVC_DLL +#include "ace/SString.h" +#include "ace/Set.h" +#include "ace/Get_Opt.h" +#include "ace/Naming_Context.h" +#include "ace/Acceptor.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/SOCK_Stream.h" +#include "ace/Name_Request_Reply.h" +#include "Name_Handler.h" + +// Simple macro that does bitwise AND -- useful in table lookup +#define ACE_TABLE_MAP(INDEX, MASK) (INDEX & MASK) + +// Simple macro that does bitwise AND and then right shift bits by 3 +#define ACE_LIST_MAP(INDEX, MASK) (((unsigned long) (INDEX & MASK)) >> 3) + +// Forward declaration. +class ACE_Naming_Context; + +class ACE_Svc_Export ACE_Name_Handler : public ACE_Svc_Handler + // = TITLE + // Product object created by . An + // exchanges messages with a + // object on the client-side. + // + // = DESCRIPTION + // This class is the main workhorse of the . It + // handles client requests to bind, rebind, resolve, and unbind + // names. It also schedules and handles timeouts that are used to + // support "timed waits." Clients used timed waits to bound the + // amount of time they block trying to get a name. +{ + friend class ACE_Shutup_GPlusPlus; // Turn off g++ warning +public: + typedef int (ACE_Name_Handler::*OPERATION) (void); + // Pointer to a member function of ACE_Name_Handler returning int + + typedef int (ACE_Naming_Context::*LIST_OP) (ACE_PWSTRING_SET &, const ACE_WString &); + // Pointer to a member function of ACE_Naming_Context returning int + + typedef ACE_Name_Request (ACE_Name_Handler::*REQUEST) (ACE_WString *); + // Pointer to a member function of ACE_Name_Handler returning ACE_Name_Request + + // = Initialization and termination. + + ACE_Name_Handler (ACE_Thread_Manager * = 0); + // Default constructor. + + virtual int open (void * = 0); + // Activate this instance of the (called by the + // ). + +protected: + // = Helper routines for the operations exported to clients. + + virtual int abandon (void); + // Give up waiting (e.g., when a timeout occurs or a client shuts + // down unexpectedly). + + // = Low level routines for framing requests, dispatching + // operations, and returning replies. + + virtual int recv_request (void); + // Receive, frame, and decode the client's request. + + virtual int dispatch (void); + // Dispatch the appropriate operation to handle the client's + // request. + + virtual int send_reply (ACE_UINT32 status, ACE_UINT32 errnum = 0); + // Create and send a reply to the client. + + virtual int send_request (ACE_Name_Request &); + // Special kind of reply + + // = Demultiplexing hooks. + virtual ACE_HANDLE get_handle (void) const; + // Return the underlying . + + virtual int handle_input (ACE_HANDLE); + // Callback method invoked by the when client events + // arrive. + + // = Timer hook. + virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg); + // Enable clients to limit the amount of time they wait for a name. + +private: + + OPERATION op_table_[ACE_Name_Request::MAX_ENUM]; + // Table of pointers to member functions + + struct LIST_ENTRY + { + LIST_OP operation_; + // A member function pointer that performs the appropriate + // operation (e.g., LIST_NAMES, LIST_VALUES, or LIST_TYPES). + + REQUEST request_factory_; + // A member function pointer that serves as a factory to create a + // request that is passed back to the client. + + char *description_; + // Name of the operation we're dispatching (used for debugging). + }; + + LIST_ENTRY list_table_[ACE_Name_Request::MAX_LIST]; + // This is the table of pointers to functions that we use to + // simplify the handling of list requests. + + ACE_Naming_Context *naming_context_; + // ACE_Naming_Context of this Handler. + + ACE_Name_Request name_request_; + // Cache request from the client. + + ACE_Name_Request name_request_back_; + // Special kind of reply for resolve and listnames. + + ACE_Name_Reply name_reply_; + // Cache reply to the client. + + ACE_INET_Addr addr_; + // Address of client we are connected with. + + ~ACE_Name_Handler (void); + // Ensure dynamic allocation... + + int bind (void); + // Handle binds. + + int rebind (void); + // Handle rebinds. + + int shared_bind (int rebind); + // Handle binds and rebinds. + + int resolve (void); + // Handle find requests. + + int unbind (void); + // Handle unbind requests. + + int lists (void); + // Handle LIST_NAMES, LIST_VALUES, and LIST_TYPES requests. + + int lists_entries (void); + // Handle LIST_NAME_ENTRIES, LIST_VALUE_ENTRIES, and + // LIST_TYPE_ENTRIES requests. + + ACE_Name_Request name_request (ACE_WString *one_name); + // Create a name request. + + ACE_Name_Request value_request (ACE_WString *one_name); + // Create a value request. + + ACE_Name_Request type_request (ACE_WString *one_name); + // Create a type request. +}; + +class ACE_Name_Acceptor : public ACE_Strategy_Acceptor + // = TITLE + // This class contains the service-specific methods that can't + // easily be factored into the . +{ +public: + virtual int init (int argc, char *argv[]); + // Dynamic linking hook. + + int parse_args (int argc, char *argv[]); + // Parse svc.conf arguments. + + int handle_signal (int, siginfo_t *, ucontext_t *); + +private: + ACE_Schedule_All_Reactive_Strategy scheduling_strategy_; + // The scheduling strategy is designed for Reactive services. +}; + +int +ACE_Name_Acceptor::handle_signal (int, siginfo_t *, ucontext_t *) +{ + ACE_DEBUG ((LM_DEBUG, "ACE_Name_Acceptor::handle_signal got called\n")); + return 0; +} + +int +ACE_Name_Acceptor::parse_args (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_Name_Acceptor::parse_args"); + + this->service_port_ = ACE_DEFAULT_SERVER_PORT; + + ACE_LOG_MSG->open ("Name Service"); + + ACE_Get_Opt get_opt (argc, argv, "p:", 0); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'p': + this->service_port_ = ACE_OS::atoi (get_opt.optarg); + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n[-p server-port]\n%a", 1), + -1); + break; + } + } + + this->service_addr_.set (this->service_port_); + return 0; +} + +int +ACE_Name_Acceptor::init (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_Name_Acceptor::init"); + + // Use the options hook to parse the command line arguments and set + // options. + this->parse_args (argc, argv); + + // Set the acceptor endpoint into listen mode (use the Singleton + // global Reactor...). + if (this->open (this->service_addr_, ACE_Service_Config::reactor (), + 0, 0, 0, + &this->scheduling_strategy_, + "Name Server", "ACE naming service") == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p on port %d\n", + "acceptor::open failed", + this->service_addr_.get_port_number ()), -1); + + // Register ourselves to receive SIGINT so we can shutdown + // gracefully. + if (this->reactor ()->register_handler (SIGINT, this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n", + "register_handler (SIGINT)"), -1); + + // Ignore SIGPIPE so that each can handle this on its + // own. + ACE_Sig_Action sig (ACE_SignalHandler (SIG_IGN), SIGPIPE); + + ACE_INET_Addr server_addr; + + // Figure out what port we're really bound to. + if (this->acceptor ().get_local_addr (server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "get_local_addr"), -1); + + ACE_DEBUG ((LM_DEBUG, + "starting up Name Server at port %d on handle %d\n", + server_addr.get_port_number (), + this->acceptor ().get_handle ())); + return 0; +} + +// The following is a "Factory" used by the ACE_Service_Config and +// svc.conf file to dynamically initialize the state of the Naming +// Server. + +ACE_SVC_FACTORY_DEFINE (ACE_Name_Acceptor) + +// Default constructor. +ACE_Name_Handler::ACE_Name_Handler (ACE_Thread_Manager *tm) + : ACE_Svc_Handler (tm) +{ + ACE_TRACE ("ACE_Name_Handler::ACE_Name_Handler"); + + // Set up pointers to member functions for the top-level dispatching + // of client requests. + this->op_table_[ACE_Name_Request::BIND] = &ACE_Name_Handler::bind; + this->op_table_[ACE_Name_Request::REBIND] = &ACE_Name_Handler::rebind; + this->op_table_[ACE_Name_Request::RESOLVE] = &ACE_Name_Handler::resolve; + this->op_table_[ACE_Name_Request::UNBIND] = &ACE_Name_Handler::unbind; + this->op_table_[ACE_Name_Request::LIST_NAMES] = &ACE_Name_Handler::lists; + this->op_table_[ACE_Name_Request::LIST_NAME_ENTRIES] = &ACE_Name_Handler::lists_entries; + + // Assign references to simplify subsequent code. + LIST_ENTRY &list_names_ref = this->list_table_[ACE_LIST_MAP (ACE_Name_Request::LIST_NAMES, + ACE_Name_Request::LIST_OP_MASK)]; + LIST_ENTRY &list_values_ref = this->list_table_[ACE_LIST_MAP (ACE_Name_Request::LIST_VALUES, + ACE_Name_Request::LIST_OP_MASK)]; + LIST_ENTRY &list_types_ref = this->list_table_[ACE_LIST_MAP (ACE_Name_Request::LIST_TYPES, + ACE_Name_Request::LIST_OP_MASK)]; + + // Set up pointers to member functions for dispatching within the + // LIST_{NAMES,VALUES,TYPES} methods. + + list_names_ref.operation_ = &ACE_Naming_Context::list_names; + list_names_ref.request_factory_ = &ACE_Name_Handler::name_request; + list_names_ref.description_ = "request for LIST_NAMES\n"; + + list_values_ref.operation_ = &ACE_Naming_Context::list_values; + list_values_ref.request_factory_ = &ACE_Name_Handler::value_request; + list_values_ref.description_ = "request for LIST_VALUES\n"; + + list_types_ref.operation_ = &ACE_Naming_Context::list_types; + list_types_ref.request_factory_ = &ACE_Name_Handler::type_request; + list_types_ref.description_ = "request for LIST_TYPES\n"; +} + +// Activate this instance of the ACE_Name_Handler (called by the +// ACE_Name_Acceptor). + +/* VIRTUAL */ int +ACE_Name_Handler::open (void *) +{ + ACE_TRACE ("ACE_Name_Handler::open"); + + // Call down to our parent to register ourselves with the Reactor. + if (ACE_Svc_Handler::open (0) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + + // Instantiate our associated ACE_Naming_Context + ACE_NEW_RETURN (naming_context_, ACE_Naming_Context (ACE_Naming_Context::NET_LOCAL), -1); + + return 0; +} + +// Create and send a reply to the client. + +/* VIRTUAL */ int +ACE_Name_Handler::send_reply (ACE_UINT32 status, ACE_UINT32 err) +{ + ACE_TRACE ("ACE_Name_Handler::send_reply"); + void *buf; + this->name_reply_.msg_type (status); + this->name_reply_.errnum (err); + + this->name_reply_.init (); + int len = this->name_reply_.encode (buf); + + if (len == -1) + return -1; + + ssize_t n = this->peer ().send (buf, len); + + if (n != len) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n, expected len = %d, actual len = %d", + "send failed", len, n), -1); + else + return 0; +} + +/* VIRTUAL */ int +ACE_Name_Handler::send_request (ACE_Name_Request &request) +{ + ACE_TRACE ("ACE_Name_Handler::send_request"); + void *buffer; + ssize_t length = request.encode (buffer); + + if (length == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "encode failed"), -1); + + // Transmit request via a blocking send. + + if (this->peer ().send_n (buffer, length) != length) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send_n failed"), -1); + + return 0; +} + +// Give up waiting (e.g., when a timeout occurs or a client shuts down +// unexpectedly). + +/* VIRTUAL */ int +ACE_Name_Handler::abandon (void) +{ + ACE_TRACE ("ACE_Name_Handler::abandon"); + int failure_reason = errno; + return this->send_reply (ACE_Name_Reply::FAILURE, failure_reason); +} + +// Enable clients to limit the amount of time they'll wait + +/* VIRTUAL */ int +ACE_Name_Handler::handle_timeout (const ACE_Time_Value &, const void *) +{ + ACE_TRACE ("ACE_Name_Handler::handle_timeout"); + return this->abandon (); +} + +// Return the underlying ACE_HANDLE. + +/* VIRTUAL */ ACE_HANDLE +ACE_Name_Handler::get_handle (void) const +{ + ACE_TRACE ("ACE_Name_Handler::get_handle"); + return this->peer ().get_handle (); +} + +// Dispatch the appropriate operation to handle the client request. + +/* VIRTUAL */ int +ACE_Name_Handler::dispatch (void) +{ + ACE_TRACE ("ACE_Name_Handler::dispatch"); + // Dispatch the appropriate request. + int index = this->name_request_.msg_type (); + + // Invoke the appropriate member function obtained by indexing into + // the op_table_. ACE_TABLE_MAP returns the same index (by bitwise + // AND) for list_names, list_values, and list_types since they are + // all handled by the same method. Similarly, it returns the same + // index for list_name_entries, list_value_entries, and + // list_type_entries. + return (this->*op_table_[ACE_TABLE_MAP (index, ACE_Name_Request::OP_TABLE_MASK)]) (); +} + +// Receive, frame, and decode the client's request. Note, this method +// should use non-blocking I/O. + +/* VIRTUAL */ int +ACE_Name_Handler::recv_request (void) +{ + ACE_TRACE ("ACE_Name_Handler::recv_request"); + // Read the first 4 bytes to get the length of the message This + // implementation assumes that the first 4 bytes are the length of + // the message. + ssize_t n = this->peer ().recv ((void *) &this->name_request_, sizeof (ACE_UINT32)); + + switch (n) + { + case -1: + /* FALLTHROUGH */ + ACE_DEBUG ((LM_DEBUG, "****************** recv_request returned -1\n")); + default: + ACE_ERROR ((LM_ERROR, "%p got %d bytes, expected %d bytes\n", + "recv failed", n, sizeof (ACE_UINT32))); + /* FALLTHROUGH */ + case 0: + // We've shutdown unexpectedly, let's abandon the connection. + this->abandon (); + return -1; + /* NOTREACHED */ + case sizeof (ACE_UINT32): + { + // Transform the length into host byte order. + ssize_t length = ntohl (this->name_request_.length ()); + + // Do a sanity check on the length of the message. + if (length > sizeof this->name_request_) + { + ACE_ERROR ((LM_ERROR, "length %d too long\n", length)); + return this->abandon (); + } + + // Receive the rest of the request message. + // @@ beware of blocking read!!!. + n = this->peer ().recv ((void *) (((char *) &this->name_request_) + + sizeof (ACE_UINT32)), + length - sizeof (ACE_UINT32)); + + // Subtract off the size of the part we skipped over... + if (n != (length - sizeof (ACE_UINT32))) + { + ACE_ERROR ((LM_ERROR, "%p expected %d, got %d\n", + "invalid length", length, n)); + return this->abandon (); + } + + // Decode the request into host byte order. + if (this->name_request_.decode () == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "decode failed")); + return this->abandon (); + } + } + } + return 0; +} + +// Callback method invoked by the ACE_Reactor when events arrive from +// the client. + +/* VIRTUAL */ int +ACE_Name_Handler::handle_input (ACE_HANDLE) +{ + ACE_TRACE ("ACE_Name_Handler::handle_input"); + + if (this->recv_request () == -1) + return -1; + else + return this->dispatch (); +} + +int +ACE_Name_Handler::bind (void) +{ + ACE_TRACE ("ACE_Name_Handler::bind"); + return this->shared_bind (0); +} + +int +ACE_Name_Handler::rebind (void) +{ + ACE_TRACE ("ACE_Name_Handler::rebind"); + int result = this->shared_bind (1); + return result == 1 ? 0 : result; +} + +int +ACE_Name_Handler::shared_bind (int rebind) +{ + ACE_TRACE ("ACE_Name_Handler::shared_bind"); + ACE_WString a_name (this->name_request_.name (), + this->name_request_.name_len () / sizeof (ACE_USHORT16)); + ACE_WString a_value (this->name_request_.value (), + this->name_request_.value_len () / sizeof (ACE_USHORT16)); + int result; + if (rebind == 0) + { + ACE_DEBUG ((LM_DEBUG, "request for BIND \n")); + result = this->naming_context_->bind (a_name, a_value, + this->name_request_.type ()); + } + else + { + ACE_DEBUG ((LM_DEBUG, "request for REBIND \n")); + result = this->naming_context_->rebind (a_name, a_value, + this->name_request_.type ()); + if (result == 1) + result = 0; + } + if (result == 0) + return this->send_reply (ACE_Name_Reply::SUCCESS); + else return this->send_reply (ACE_Name_Reply::FAILURE); +} + +int +ACE_Name_Handler::resolve (void) +{ + ACE_TRACE ("ACE_Name_Handler::resolve"); + ACE_DEBUG ((LM_DEBUG, "request for RESOLVE \n")); + ACE_WString a_name (this->name_request_.name (), + this->name_request_.name_len () / sizeof (ACE_USHORT16)); + + // The following will deliver our reply back to client we + // pre-suppose success (indicated by type RESOLVE). + + ACE_WString avalue; + char *atype; + if (this->naming_context_->resolve (a_name, avalue, atype) == 0) + { + ACE_Name_Request nrq (ACE_Name_Request::RESOLVE, + NULL, 0, + avalue.rep (), + avalue.length () * sizeof (ACE_USHORT16), + atype, ACE_OS::strlen (atype)); + return this->send_request (nrq); + } + + ACE_Name_Request nrq (ACE_Name_Request::BIND, NULL, 0, NULL, 0, NULL, 0); + this->send_request (nrq); + return 0; +} + +int +ACE_Name_Handler::unbind (void) +{ + ACE_TRACE ("ACE_Name_Handler::unbind"); + ACE_DEBUG ((LM_DEBUG, "request for UNBIND \n")); + ACE_WString a_name (this->name_request_.name (), + this->name_request_.name_len () / sizeof (ACE_USHORT16)); + if (this->naming_context_->unbind (a_name) == 0) + return this->send_reply (ACE_Name_Reply::SUCCESS); + else return this->send_reply (ACE_Name_Reply::FAILURE); +} + +ACE_Name_Request +ACE_Name_Handler::name_request (ACE_WString *one_name) +{ + ACE_TRACE ("ACE_Name_Handler::name_request"); + return ACE_Name_Request (ACE_Name_Request::LIST_NAMES, + one_name->rep (), + one_name->length () * sizeof (ACE_USHORT16), + NULL, 0, + NULL, 0); +} + +ACE_Name_Request +ACE_Name_Handler::value_request (ACE_WString *one_value) +{ + ACE_TRACE ("ACE_Name_Handler::value_request"); + return ACE_Name_Request (ACE_Name_Request::LIST_VALUES, + NULL, 0, + one_value->rep (), + one_value->length () * sizeof (ACE_USHORT16), + NULL, 0); +} + +ACE_Name_Request +ACE_Name_Handler::type_request (ACE_WString *one_type) +{ + ACE_TRACE ("ACE_Name_Handler::type_request"); + return ACE_Name_Request (ACE_Name_Request::LIST_TYPES, + NULL, 0, + NULL, 0, + one_type->char_rep (), + one_type->length ()); +} + +int +ACE_Name_Handler::lists (void) +{ + ACE_TRACE ("ACE_Name_Handler::lists"); + + ACE_PWSTRING_SET set; + ACE_WString pattern (this->name_request_.name (), + this->name_request_.name_len () / sizeof (ACE_USHORT16)); + + // Get the index into the list table + int index = ACE_LIST_MAP (this->name_request_.msg_type (), + ACE_Name_Request::LIST_OP_MASK); + + // Print the message type + ACE_DEBUG ((LM_DEBUG, list_table_[index].description_)); + + // Call the appropriate method + if ((this->naming_context_->*list_table_[index].operation_) (set, pattern) != 0) + { + // None found so send blank request back + ACE_Name_Request end_rq (ACE_Name_Request::MAX_ENUM, NULL, 0, NULL, 0, NULL, 0); + + if (this->send_request (end_rq) == -1) + return -1; + } + else + { + ACE_WString *one_entry = 0; + + for (ACE_Unbounded_Set_Iterator set_iterator (set); + set_iterator.next (one_entry) !=0; + set_iterator.advance()) + { + ACE_Name_Request nrq ((this->*list_table_[index].request_factory_) (one_entry)); + + // Create a request by calling the appropriate method obtained + // by accessing into the table. Then send the request across. + if (this->send_request (nrq) == -1) + return -1; + } + + // Send last message indicator. + ACE_Name_Request nrq (ACE_Name_Request::MAX_ENUM, + NULL, 0, + NULL, 0, + NULL, 0); + return this->send_request (nrq); + } + return 0; +} + +int +ACE_Name_Handler::lists_entries (void) +{ + ACE_TRACE ("ACE_Name_Handler::lists_entries"); + ACE_BINDING_SET set; + ACE_WString pattern (this->name_request_.name (), + this->name_request_.name_len () / sizeof (ACE_USHORT16)); + + int (ACE_Naming_Context::*ptmf) (ACE_BINDING_SET &, const ACE_WString &); + + switch (this->name_request_.msg_type ()) + { + case ACE_Name_Request::LIST_NAME_ENTRIES: + ACE_DEBUG ((LM_DEBUG, "request for LIST_NAME_ENTRIES \n")); + ptmf = &ACE_Naming_Context::list_name_entries; + break; + case ACE_Name_Request::LIST_VALUE_ENTRIES: + ACE_DEBUG ((LM_DEBUG, "request for LIST_VALUE_ENTRIES \n")); + ptmf = &ACE_Naming_Context::list_value_entries; + break; + case ACE_Name_Request::LIST_TYPE_ENTRIES: + ACE_DEBUG ((LM_DEBUG, "request for LIST_TYPE_ENTRIES \n")); + ptmf = &ACE_Naming_Context::list_type_entries; + break; + default: + return -1; + } + + if ((this->naming_context_->*ptmf) (set, pattern) != 0) + { + // None found so send blank request back. + ACE_Name_Request end_rq (ACE_Name_Request::MAX_ENUM, NULL, 0, NULL, 0, NULL, 0); + + if (this->send_request (end_rq) == -1) + return -1; + } + else + { + ACE_Name_Binding *one_entry = 0; + + for (ACE_Unbounded_Set_Iterator set_iterator (set); + set_iterator.next (one_entry) !=0; + set_iterator.advance()) + { + ACE_Name_Request mynrq (this->name_request_.msg_type (), + one_entry->name_.rep (), + one_entry->name_.length () * sizeof (ACE_USHORT16), + one_entry->value_.rep (), + one_entry->value_.length () * sizeof (ACE_USHORT16), + one_entry->type_, + ACE_OS::strlen (one_entry->type_)); + + if (this->send_request (mynrq) == -1) + return -1; + } + + // send last message indicator + ACE_Name_Request nrq (ACE_Name_Request::MAX_ENUM, NULL, 0, NULL, 0, NULL, 0); + + if (this->send_request (nrq) == -1) + return -1; + } + return 0; +} + +ACE_Name_Handler::~ACE_Name_Handler (void) +{ + ACE_TRACE ("ACE_Name_Handler::~ACE_Name_Handler"); + ACE_DEBUG ((LM_DEBUG, "closing down Handle %d\n", + this->get_handle ())); + + // Delete associated Naming Context. + delete this->naming_context_; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Strategy_Acceptor; +template class ACE_Schedule_All_Reactive_Strategy; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/netsvcs/lib/Name_Handler.h b/netsvcs/lib/Name_Handler.h new file mode 100644 index 00000000000..0de9b44ca77 --- /dev/null +++ b/netsvcs/lib/Name_Handler.h @@ -0,0 +1,24 @@ +/* -*- C++ -*- */ +// @(#)Name_Handler.h 1.1 10/18/96 + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Name_Handler.h +// +// = AUTHOR +// Prashant Jain, Gerhard Lenzer and Douglas C. Schmidt +// +// ============================================================================ + +#if !defined (ACE_NAME_HANDLER_H) +#define ACE_NAME_HANDLER_H + +#include "ace/OS.h" + +ACE_SVC_FACTORY_DECLARE (ACE_Name_Acceptor) + +#endif /* ACE_NAME_HANDLER_H */ diff --git a/netsvcs/lib/README b/netsvcs/lib/README new file mode 100644 index 00000000000..a85ce77b82f --- /dev/null +++ b/netsvcs/lib/README @@ -0,0 +1,270 @@ +This directory provides a number of network services that utilize the +ACE wrapper features. + + . Logging_Strategy -- Controls the output of all services that are + invoked along with the Logging_Strategy service. Please see below for + details on how to control the output. + + . [Thr_]Server_Logging_Handler.* -- Implements server portion + of the ACE distributed logging service. Both multi-threaded + and single-threaded implementations are provided. + + . Client_Logging_Handler.* -- Implements the client portion + of the ACE distributed logging service. + + . Name_Handler.* -- Implements a distributed name service that + allows applications to bind, find, and unbind names in + a distributed system. + + . Token_Handler.* -- Implements a distributed token service + that allows distributed applications to acquire and release + locks in a distributed system. + + . Time_Handler.* -- Implements a distributed time service that + allows distributed applications to synchronize their + time. + +The remainder of this README file explains how these services work. + +==================== Logging_Strategy Service ==================== +The Logging_Strategy Service can be used to control the output of all the +network services. It can be invoked with certain flags that determine +where the output of all the services should go. + +The Logging_Strategy Service sets the flags in ACE_Log_Msg which in turn +controls all the streams through macros such as ACE_DEBUG, ACE_ERROR, +and ACE_ERROR_RETURN. + +If default behavior is required, the Logging_Strategy Service need not be +invoked or it can be invoked with no paramaters. Here are the command +line arguments that can be given to the Logging_Strategy Service: + + + -f || (etc...) + + where a flag can be any of the following: + + STDERR -- Write messages to stderr. + LOGGER -- Write messages to the local client logger deamon. + OSTREAM -- Write messages to the ostream that gets created by + specifying a filename (see below) + VERBOSE -- Display messages in a verbose manner + SILENT -- Do not print messages at all + +Note: If more than one flag is specified, the flags need to be 'OR'ed +as above syntax shows. Make sure there is no space in between the flag +and '|'. + + -s filename + + If the OSTREAM flag is set, this can be used to specify the +filename where the output should be directed. Note that if the OSTREAM +flag is set and no filename is specified, ACE_DEFAULT_LOGFILE will be +used to write the output to. + +Examples: + +To direct output only to STDERR, specify command line arguments as: + "-f STDERR" + +To direct output to both STDERR and a file called "mylog", specify +command line arguments as: + "-f STDERR|OSTREAM -s mylog" + +==================== Name Service ==================== + +This file describes the principles of the Name_Server server test +application. + +1. Startup configuration + --------------------- + +To communicate with the server process, a client needs to know the +INET_Addr, where the server offers its service. Class Name_Options +holds all the configuration information of the Name Service. This +consists of : + + - nameserver_port : Port number where the server process expects requests + - nameserver_host : hostname where the server process resides + - namespace_dir : directory that holds the NameBinding databases + - process_name : name of the client process (argv[0]), NameBindings of + a ProcessLocal namespace are stored in file + "namespace_dir/process_name". NameBindings of NodeGlobal + namespace are stored in "namespace_dir/localnames". + NameBindings of Net_Local namespace are stored in file + "namespace_dir/globalnames" on the server host. + These configuration parameters are passed to the process as commandline + arguments to main: + -p nameserver port + -h nameserver host + -l namespace directory + + The main program _must_ initialize an instance of Name_Options with name + name_options (since the shared libraries depend on this). Main should + look like : + + #include "ace/Name_Options.h" + + Name_Options name_options; + + int main(int argc, char **argv) + { + name_options.process_name(argv[0]); + name_options.parse_args (argc, argv); + ...... + } + +See the examples in the tests subdirectory of +...Name_Server/Client-Server/client and +...Name_Server/Client-Server/server + + +2. Class Naming_Context + ------------------- + +This is the main workhorse of the Name Service. It is used by client +processes as well as by the server process. It manages all accesses to +the appropriate NameBinding database (that is the file where +NameBindings are stored) and it also manages the communication between +a client process and the server (by using class Name_Proxy, which is a +private member of Naming_Context). (Note: no IPC is necessary, if a +client process runs on the same host as the server). + +The strategy for all public methods of Naming_Context is common : + +1. Transform the format of the arguments to ACE_SString (which is + internally used) if necessary. + +2. check if work can be done locally : -> call the appropriate local_* method + otherwise call the appropriate global_* method. + +Removing Name_Bindings from the database (either with unbind or +rebind) uses the ACE_Malloc class configured with the +ACE_MMAP_Memory_Pool. This allows memory to be reclaimed when +name/value tuples are unbound. + +3. Class Name_Server + ---------------- + +The Name_Server registers in its run method its Name_Acceptor +(instantiated with the INET_Addr) at the Reactor, to receive incoming +requests. + +4. Class Name_Acceptor + ------------------ + +The Name_Acceptor allocates in its handle_input routine a new instance +of class Name_Handler on the heap, and accepts connections into this +Name_Handler. + +5. Class Name_Handler + ----------------- + +The Name_Handler represents the server side of communication between +client and server. It interprets incoming requests to the Net_Local +namespace and dele- gates the requests to its own Naming_Context +(which is the Net_Local namespace on the current host). For +communication it uses the helper classes Name_Request (which up to now +needs not only contain the request from the client, but also the +appropriate reply from the server) and Name_Reply. Note that I want +to change the usage of these classes to make the structure of the +software clearer. + +6. Dependencies + ------------ + +As the Name service must be able to handle wide character strings, it +uses ACE_WString String classes. + + +==================== Time Service ==================== + +The following is a description of the Time Server clerk and server +services: + +1. Startup configuration + --------------------- + +Configuring a server requires specifying the port number of the +server. This can be specified as a command line argument as follows: + + -p + +A clerk communicates with one or more server processes. To communicate +with the server process, a client needs to know the INET_Addr, where +the server offers its service. The configuration parameters namely the +server port and server host are passed as command line arguments when +starting up the clerk service as follows: + + -h : -h : ... + +Note that multiple servers can be specified in this manner for the +clerk to connect to when it starts up. The server name and the port +number need to be concatenated and separated by a ":". In addition, +the timeout value can also be specified as a command line argument as +follows: + + -t timeout + +The timeout value specifies the time interval at which the clerk +should query the servers for time updates. + +By default a Clerk does a non-blocking connect to a server. This can +be overridden and a Clerk can be made to do a blocking connect by +using the -b flag. + +Here is what a config file would look like for starting up a server at +port 20202: + +dynamic Time_Service Service_Object * ../lib/libnet_svcs.so:_make_ACE_TS_Server_Acceptor() "-p 20202" + +Here is what a config file would look like for starting up a clerk +that needs to connect to two servers, one at tango and one at lambada: + +dynamic Time_Server_test Service_Object *../lib/libnet_svcs.so:_make_ACE_TS_Clerk_Connector () "-h tango:20202 -h lambada:20202 -t 4" + +[Note: these files would vary if the services are run on NT] + + +2. Class TS_Server_Handler + ----------------------- + +TS_Server_Handler represents the server side of communication between +clerk and server. It interprets incoming requests for time updates, +gets the system time, creates a reply in response to the request and +then sends the reply to the clerk from which it received the request. +For communication it uses the helper class Time_Request. + +3. Class TS_Server_Acceptor + ------------------------ + +TS_Server_Acceptor allocates in its handle_input routine a new instance +of class TS_Server_Handler on the heap, and accepts connections into this +TS_Server_Handler. + +4. Class TS_Clerk_Handler + ---------------------- + +TS_Clerk_Handler represents the clerk side of communication between +clerk and server. It generates requests for time updates every timeout +period and then sends these requests to all the servers it is +connected to asynchronously. It receives the replies to these requests +from the servers through its handle_input method and then adjusts the +time using the roundtrip estimate. It caches this time which is later +retrieved by TS_Clerk_Processor. + +5. Class TS_Clerk_Processor + ------------------------ + +TS_Clerk_Processor creates a new instance of TS_Clerk_Handler for +every server connection it needs to create. It periodically calls +send_request() of every TS_Clerk_Handler to send a request for time +update to all the servers. In the process, it retrieves the latest +time cached by each TS_Clerk_Handler and then uses it to compute its +notion of the local system time. + +6. Algorithms + ---------- + +Currently, updating the system time involves taking the average of all +the times received from the servers. \ No newline at end of file diff --git a/netsvcs/lib/Server_Logging_Handler.cpp b/netsvcs/lib/Server_Logging_Handler.cpp new file mode 100644 index 00000000000..d784cb6af37 --- /dev/null +++ b/netsvcs/lib/Server_Logging_Handler.cpp @@ -0,0 +1,453 @@ +// Server_Logging_Handler.cpp +// @(#)Server_Logging_Handler.cpp 1.1 10/18/96 + +#define ACE_BUILD_SVC_DLL +#include "ace/Synch.h" +#include "ace/TLI_Acceptor.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/Acceptor.h" +#include "Server_Logging_Handler.h" + +template +class ACE_Server_Logging_Handler : public ACE_Svc_Handler +{ + // = TITLE + // Product object created by an . An + // receives, frames, and processes logging + // records. + // + // = DESCRIPTION + // Defines the classes that perform server logging daemon + // functionality. +public: + ACE_Server_Logging_Handler (ACE_Thread_Manager * = 0); + + virtual int open (void * = 0); + // Hook called by Server_Logging_Acceptor when connection is + // established. + + virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE); + // Process remote logging records. + +protected: + int handle_logging_record (void); + // Receive the logging record from a client. + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + static COUNTER request_count_; + // Count the number of logging records that arrive. +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ + + char host_name_[MAXHOSTNAMELEN + 1]; + // Name of the host we are connected to. +}; + +#if !defined (ACE_HAS_TLI) +#define LOGGING_PEER_ACCEPTOR ACE_SOCK_ACCEPTOR +#define LOGGING_PEER_STREAM ACE_SOCK_STREAM +#else /* use sockets */ +#define LOGGING_PEER_ACCEPTOR ACE_TLI_ACCEPTOR +#define LOGGING_PEER_STREAM ACE_TLI_STREAM +#endif /* ACE_HAS_TLI */ + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) +// Track number of requests. +template +COUNTER ACE_Server_Logging_Handler::request_count_ = 0L; +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ + +typedef ACE_Server_Logging_Handler + SERVER_LOGGING_HANDLER; + +class ACE_Server_Logging_Acceptor : public ACE_Strategy_Acceptor + // = TITLE + // This class implements the ACE single-threaded logging service. + // + // = DESCRIPTION + // This class contains the service-specific methods that can't + // easily be factored into the . +{ +public: + virtual int init (int argc, char *argv[]); + // Dynamic linking hook. + + int parse_args (int argc, char *argv[]); + // Parse svc.conf arguments. + +private: + ACE_Schedule_All_Reactive_Strategy scheduling_strategy_; + // The scheduling strategy is designed for Reactive services. +}; + +int +ACE_Server_Logging_Acceptor::parse_args (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_Server_Logging_Acceptor::parse_args"); + + this->service_port_ = ACE_DEFAULT_SERVER_PORT; + + ACE_LOG_MSG->open ("Logging Service"); + + ACE_Get_Opt get_opt (argc, argv, "p:", 0); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'p': + this->service_port_ = ACE_OS::atoi (get_opt.optarg); + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n[-p server-port]\n%a", 1), + -1); + break; + } + } + + this->service_addr_.set (this->service_port_); + return 0; +} + +int +ACE_Server_Logging_Acceptor::init (int argc, + char *argv[]) +{ + ACE_TRACE ("ACE_Server_Logging_Acceptor::init"); + + // Use the options hook to parse the command line arguments and set + // options. + this->parse_args (argc, argv); + + // Set the acceptor endpoint into listen mode (use the Singleton + // global Reactor...). + if (this->open (this->service_addr_, ACE_Service_Config::reactor (), + 0, 0, 0, + &this->scheduling_strategy_, + "Logging Server", "ACE single-threaded logging service") == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p on port %d\n", + "acceptor::open failed", + this->service_addr_.get_port_number ()), -1); + + // Register ourselves to receive SIGINT so we can shutdown + // gracefully. + if (this->reactor ()->register_handler (SIGINT, this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n", + "register_handler (SIGINT)"), -1); + + // Ignore SIGPIPE so that each can handle this on its + // own. + ACE_Sig_Action sig (ACE_SignalHandler (SIG_IGN), SIGPIPE); + + ACE_INET_Addr server_addr; + + // Figure out what port we're really bound to. + if (this->acceptor ().get_local_addr (server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "get_local_addr"), -1); + + ACE_DEBUG ((LM_DEBUG, + "starting up Logging Server at port %d on handle %d\n", + server_addr.get_port_number (), + this->acceptor ().get_handle ())); + return 0; +} + +template +ACE_Server_Logging_Handler::ACE_Server_Logging_Handler (ACE_Thread_Manager *) +{ + this->host_name_[0] = '\0'; // Initialize to a known state. +} + +template int +ACE_Server_Logging_Handler::handle_logging_record (void) +{ + ssize_t n; + size_t len; + // Lock used to serialize access to std output + // (this should be in the class, but the SunC++ compiler is broken...) + static ACE_SYNCH_MUTEX lock; + + // Perform two recv's to emulate record-oriented semantiCLS. + // Note that this code is not entirely portable since it + // relies on the fact that sizeof (ssize_t) is the same + // on both the sender and receiver side. To correctly + // handle this is painful, and we leave it as an exercise + // for the reader ;-). + + switch (n = this->peer ().recv (&len, sizeof len)) + { + case -1: + ACE_ERROR_RETURN ((LM_ERROR, "%p at host %s\n", + "server logger", this->host_name_), -1); + /* NOTREACHED */ + case 0: + ACE_ERROR_RETURN ((LM_ERROR, "closing log daemon at host %s\n", + this->host_name_), -1); + /* NOTREACHED */ + case sizeof (ssize_t): + { + ACE_Log_Record lp; + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + u_long count = ++this->request_count_; + ACE_DEBUG ((LM_DEBUG, "request count = %d\n", count)); +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ + + len = ntohl (len); + if ((n = this->peer ().recv_n ((void *) &lp, len)) != len) + ACE_ERROR_RETURN ((LM_ERROR, "len = %d, %p at host %s\n", + n, "server logger", this->host_name_), -1); + /* NOTREACHED */ + + lp.decode (); + + if (lp.length () == n) + { + // Serialize output, if necessary (i.e., if we are running + // in separate threads). + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, lock, -1); + + lp.print (this->host_name_, 0, stderr); + } + else + ACE_ERROR ((LM_ERROR, "error, lp.length = %d, n = %d\n", + lp.length (), n)); + break; + } + default: + ACE_ERROR_RETURN ((LM_ERROR, "%p at host %s\n", + "server logger", this->host_name_), -1); + /* NOTREACHED */ + } + + return n; +} + +// Hook called by Server_Logging_Acceptor when connection is +// established. + +template int +ACE_Server_Logging_Handler::open (void *arg) +{ + // Register ourselves with the Reactor to enable subsequent + // dispatching. + if (ACE_Service_Config::reactor ()->register_handler + (this, ACE_Event_Handler::READ_MASK) == -1) + return -1; + + ACE_PEER_STREAM_ADDR client_addr; + + // Determine the address of the client and display it. + if (this->peer ().get_remote_addr (client_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "get_remote_addr"), -1); + + ACE_OS::strncpy (this->host_name_, client_addr.get_host_name (), MAXHOSTNAMELEN + 1); + + ACE_DEBUG ((LM_DEBUG, "(%t) accepted connection from host %s on fd %d\n", + client_addr.get_host_name (), this->peer ().get_handle ())); + + // Shut off non-blocking IO if it was enabled... + if (this->peer ().disable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "disable"), -1); + + return 0; +} + +// Callback routine for handling the reception of remote logging +// transmissions. + +template int +ACE_Server_Logging_Handler::handle_input (ACE_HANDLE) +{ + return this->handle_logging_record () > 0 ? 0 : -1; +} + +#if !defined (ACE_HAS_THREADS) +typedef u_long COUNTER; +#define ACE_LOGGER_SYNCH ACE_NULL_SYNCH +#else +typedef ACE_Atomic_Op COUNTER; +#define ACE_LOGGER_SYNCH ACE_MT_SYNCH +#endif /* ACE_HAS_THREADS */ + +class ACE_Svc_Export ACE_Thr_Server_Logging_Handler : public ACE_Server_Logging_Handler + // = TITLE + // Product object created by a . An + // receives, frames, and processes + // logging records. + // + // = DESCRIPTION + // Each client is handled in its own separate thread. +{ +public: + ACE_Thr_Server_Logging_Handler (ACE_Thread_Manager * = 0); + + virtual int open (void * = 0); + // Override activation definition in the ACE_Svc_Handler class (will + // spawn a new thread if we've got threads). + + virtual int svc (void); + // Process remote logging records. +}; + +class ACE_Thr_Server_Logging_Acceptor : public ACE_Strategy_Acceptor + // = TITLE + // This class implements the ACE multi-threaded logging service. + // + // = DESCRIPTION + // This class contains the service-specific methods that can't + // easily be factored into the . +{ +public: + virtual int init (int argc, char *argv[]); + // Dynamic linking hook. + + int parse_args (int argc, char *argv[]); + // Parse svc.conf arguments. + +private: + ACE_Schedule_All_Threaded_Strategy scheduling_strategy_; + // The scheduling strategy is designed for multi-threaded services. +}; + +int +ACE_Thr_Server_Logging_Acceptor::parse_args (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_Thr_Server_Logging_Acceptor::parse_args"); + + this->service_port_ = ACE_DEFAULT_SERVER_PORT; + + ACE_LOG_MSG->open ("Logging Service"); + + ACE_Get_Opt get_opt (argc, argv, "p:", 0); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'p': + this->service_port_ = ACE_OS::atoi (get_opt.optarg); + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n[-p server-port]\n%a", 1), + -1); + break; + } + } + + this->service_addr_.set (this->service_port_); + return 0; +} + +int +ACE_Thr_Server_Logging_Acceptor::init (int argc, + char *argv[]) +{ + ACE_TRACE ("ACE_Thr_Server_Logging_Acceptor::init"); + + // Use the options hook to parse the command line arguments and set + // options. + this->parse_args (argc, argv); + + // Set the acceptor endpoint into listen mode (use the Singleton + // global Reactor...). + if (this->open (this->service_addr_, ACE_Service_Config::reactor (), + 0, 0, 0, + &this->scheduling_strategy_, + "Thr Logging Server", "ACE multi-threaded logging service") == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p on port %d\n", + "acceptor::open failed", + this->service_addr_.get_port_number ()), -1); + + // Register ourselves to receive SIGINT so we can shutdown + // gracefully. + if (this->reactor ()->register_handler (SIGINT, this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n", + "register_handler (SIGINT)"), -1); + + // Ignore SIGPIPE so that each can handle this on its + // own. + ACE_Sig_Action sig (ACE_SignalHandler (SIG_IGN), SIGPIPE); + + ACE_INET_Addr server_addr; + + // Figure out what port we're really bound to. + if (this->acceptor ().get_local_addr (server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "get_local_addr"), -1); + + ACE_DEBUG ((LM_DEBUG, + "starting up Threaded Logging Server at port %d on handle %d\n", + server_addr.get_port_number (), + this->acceptor ().get_handle ())); + return 0; +} + +// The following are "Factories" used by the ACE_Service_Config and +// svc.conf file to dynamically initialize the state of the +// single-threaded and multi-threaded logging server. + +ACE_SVC_FACTORY_DEFINE (ACE_Server_Logging_Acceptor) +ACE_SVC_FACTORY_DEFINE (ACE_Thr_Server_Logging_Acceptor) + +// No-op... + +ACE_Thr_Server_Logging_Handler::ACE_Thr_Server_Logging_Handler (ACE_Thread_Manager *) +{ +} + +// Override definition in the ACE_Svc_Handler class (spawn a new +// thread if we're configured with ACE_HAS_THREADS!). + +ACE_INLINE int +ACE_Thr_Server_Logging_Handler::open (void *) +{ + // Shut off non-blocking IO since now we can block in our own + // thread! + if (this->peer ().disable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "disable"), -1); + + ACE_INET_Addr client_addr; + + // Determine the address of the client and display it. + if (this->peer ().get_remote_addr (client_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "get_remote_addr"), -1); + + ACE_OS::strncpy (this->host_name_, client_addr.get_host_name (), MAXHOSTNAMELEN + 1); + + ACE_DEBUG ((LM_DEBUG, "(%t) accepted connection from host %s on fd %d\n", + client_addr.get_host_name (), this->peer ().get_handle ())); + + // Spawn a new thread of control to handle logging records with the + // client. Note that this implicitly uses the + // ACE_Service_Config::thr_mgr () to control all the threads. + if (this->activate (THR_BOUND | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), -1); + return 0; +} + +// Process remote logging records. + +ACE_INLINE int +ACE_Thr_Server_Logging_Handler::svc (void) +{ + int result = 0; + + // Loop until the client terminates the connection or an error occurs. + + while ((result = this->handle_input ()) > 0) + continue; + + return result; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Strategy_Acceptor; +template class ACE_Schedule_All_Threaded_Strategy; +template class ACE_Strategy_Acceptor, LOGGING_PEER_ACCEPTOR>; +template class ACE_Schedule_All_Reactive_Strategy >; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ + + diff --git a/netsvcs/lib/Server_Logging_Handler.h b/netsvcs/lib/Server_Logging_Handler.h new file mode 100644 index 00000000000..b73ba1eb8bb --- /dev/null +++ b/netsvcs/lib/Server_Logging_Handler.h @@ -0,0 +1,26 @@ +/* -*- C++ -*- */ +// @(#)Server_Logging_Handler.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Server_Logging_Handler.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SERVER_LOGGING_HANDLER_H) +#define ACE_SERVER_LOGGING_HANDLER_H + +#include "ace/OS.h" + +ACE_SVC_FACTORY_DECLARE (ACE_Server_Logging_Acceptor) +ACE_SVC_FACTORY_DECLARE (ACE_Thr_Server_Logging_Acceptor) + +#endif /* ACE_SERVER_LOGGING_HANDLER_H */ diff --git a/netsvcs/lib/Server_Logging_Handler.i b/netsvcs/lib/Server_Logging_Handler.i new file mode 100644 index 00000000000..91a235b2847 --- /dev/null +++ b/netsvcs/lib/Server_Logging_Handler.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// @(#)Server_Logging_Handler.i 1.1 10/18/96 + + diff --git a/netsvcs/lib/TS_Clerk_Handler.cpp b/netsvcs/lib/TS_Clerk_Handler.cpp new file mode 100644 index 00000000000..6a4b181fd47 --- /dev/null +++ b/netsvcs/lib/TS_Clerk_Handler.cpp @@ -0,0 +1,826 @@ +// TS_Clerk_Handler.cpp +// @(#)TS_Clerk_Handler.cpp 1.1 10/18/96 + +#define ACE_BUILD_SVC_DLL +#include "ace/Service_Config.h" +#include "ace/Connector.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/SOCK_Connector.h" +#include "ace/SOCK_Stream.h" +#include "ace/Svc_Handler.h" +#include "ace/Time_Value.h" +#include "ace/Time_Request_Reply.h" +#include "ace/OS.h" +#include "ace/Malloc.h" +#include "TS_Clerk_Handler.h" + +// A simple struct containing delta time and a sequence number +struct ACE_Time_Info +{ + long delta_time_; + ACE_UINT32 sequence_num_; +}; + +class ACE_TS_Clerk_Processor; // forward declaration + +class ACE_Svc_Export ACE_TS_Clerk_Handler : public ACE_Svc_Handler + // = TITLE + // The Clerk Handler provides the interface that is used by the + // Clerk Processor to send time update requests to all the + // servers. It obtains these updates from the servers and passes + // the updates to the Clerk Processor + // + // = DESCRIPTION + // The Clerk Processor uses send_request() to send a request for + // time update to a server. The Clerk Handler internally computes + // the round trip delay for the reply to come back. Once it gets + // the reply back from the server (handle_input), it adjusts the + // system time using the round trip delay estimate and then + // passes the delta time by reference back to the Clerk Processor. +{ +public: + ACE_TS_Clerk_Handler (ACE_TS_Clerk_Processor *processor, + ACE_INET_Addr &addr); + // Default constructor. + + // = Set/get the current state + enum State + { + IDLE = 1, // Prior to initialization. + CONNECTING, // During connection establishment. + ESTABLISHED, // Connection is established and active. + DISCONNECTING, // In the process of disconnecting. + FAILED // Connection has failed. + }; + + // = Set/get the current state. + State state (void); + void state (State); + + // = Set/get the current retry timeout delay. + int timeout (void); + void timeout (int); + + // = Set/get the maximum retry timeout delay. + int max_timeout (void); + void max_timeout (int); + + virtual int open (void * = 0); + // Activate this instance of the + // (called by the ). + + virtual ACE_HANDLE get_handle (void) const; + // Return the handle of the message_fifo_; + + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::RWE_MASK); + // Called when object is removed from the ACE_Reactor + + virtual int handle_input (ACE_HANDLE); + // Receive time update from a server. + + virtual int handle_timeout (const ACE_Time_Value &tv, + const void *arg); + // Restart connection asynchronously when timeout occurs. + + void remote_addr (ACE_INET_Addr &addr); + ACE_INET_Addr &remote_addr (void); + // Get/Set remote addr + + int send_request (ACE_UINT32 sequence_num, ACE_Time_Info &time_info); + // Send request for time update to the server as well as return the + // current time info by reference. + +protected: + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + // Handle SIGINT. + + static void stderr_output (int = 0); + + enum + { + MAX_RETRY_TIMEOUT = 300 // 5 minutes is the maximum timeout. + }; +private: + int recv_reply (ACE_Time_Request &reply); + // Receive a reply from a server containing time update + + int reinitiate_connection (void); + // Reinitiate connection with the server + + State state_; + // The current state of the connection + + int timeout_; + // Amount of time to wait between reconnection attempts + + int max_timeout_; + // Maximum amount of time to wait between reconnection attempts + + ACE_INET_Addr remote_addr_; + // Remote Addr used for connecting to the server + + ACE_TS_Clerk_Processor *processor_; + // Instance of Clerk Processor used for re-establishing connections + + ACE_UINT32 start_time_; + // Time at which request was sent (used to compute round trip delay) + + ACE_UINT32 cur_sequence_num_; + // Next sequence number of time request (waiting for this update from + // the server). + + ACE_Time_Info time_info_; + // Record of current delta time and current sequence number +}; + +class ACE_TS_Clerk_Processor : public ACE_Connector + // = TITLE + // This class manages all the connections to the servers along + // with querying them periodically for time updates. + // = DESCRIPTION + // The Clerk Processor creates connections to all the servers and + // creates an ACE_TS_Clerk_Handler for each connection to handle + // the requests and replies. It periodically sends a request for + // time update through each of the handlers and uses the replies for + // computing a synchronized system time. +{ +public: + ACE_TS_Clerk_Processor (); + // Default constructor + + virtual int handle_timeout (const ACE_Time_Value &tv, + const void *arg); + // Query servers for time periodically (timeout value) + + int initiate_connection (ACE_TS_Clerk_Handler *, ACE_Synch_Options &); + // Set up connections to all servers + +protected: + // = Dynamic linking hooks. + virtual int init (int argc, char *argv[]); + // Called when service is linked. + + virtual int fini (void); + // Called when service is unlinked. + + virtual int info (char **strp, size_t length) const; + // Called to determine info about the service. + + // = Scheduling hooks. + virtual int suspend (void); + virtual int resume (void); + + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + // Handle SIGINT. + +private: + int parse_args (int argc, char *argv[]); + // Parse svc.conf arguments. + + void alloc (void); + // Allocate entry in shared memory for system time + + int update_time (); + // Update delta_time using times obtained from all servers + + typedef ACE_Malloc MALLOC; + typedef ACE_Allocator_Adapter ALLOCATOR; + ALLOCATOR *shmem_; + // Allocator (used for reading/writing system time from/to shared memory) + + typedef ACE_Unbounded_Set HANDLER_SET; + typedef ACE_Unbounded_Set_Iterator HANDLER_SET_ITERATOR; + HANDLER_SET handler_set_; + // Set of TS_Clerk_Handlers and iterator over the set. + + struct System_Time + { + long *delta_time_; // Difference between system time and local time + long *last_local_time_; // Last local time + }; + + System_Time system_time_; + // Clerk system time containing pointers to entries in shared memory + + int timer_id_; + // Timer id returned by Reactor + + int timeout_; + // Time period for updating system time + + const char *poolname_; + // Pool name for backing store + + int blocking_semantics_; + // Do a blocking/non-blocking connect + + ACE_UINT32 cur_sequence_num_; + // Sequence number of next expected update from servers +}; + + +ACE_TS_Clerk_Handler::ACE_TS_Clerk_Handler (ACE_TS_Clerk_Processor *processor, + ACE_INET_Addr &addr) +: processor_ (processor), + remote_addr_ (addr), + state_ (ACE_TS_Clerk_Handler::IDLE), + timeout_ (ACE_DEFAULT_TIMEOUT), + max_timeout_ (ACE_TS_Clerk_Handler::MAX_RETRY_TIMEOUT) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::ACE_TS_Clerk_Handler"); + this->time_info_.delta_time_ = 0; + this->time_info_.sequence_num_ = 0; +} + +// This is called when a to a server fails... +int +ACE_TS_Clerk_Handler::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::handle_signal"); + return 0; +} + +// Set the connection state +void +ACE_TS_Clerk_Handler::state (ACE_TS_Clerk_Handler::State state) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::state"); + this->state_ = state; +} + +// Get the connection state +ACE_TS_Clerk_Handler::State +ACE_TS_Clerk_Handler::state (void) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::state"); + return this->state_; +} + +// Sets the timeout delay. +void +ACE_TS_Clerk_Handler::timeout (int to) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::timeout"); + if (to > this->max_timeout_) + to = this->max_timeout_; + + this->timeout_ = to; +} + +// Recalculate the current retry timeout delay using exponential +// backoff. Returns the original timeout (i.e., before the +// recalculation). +int +ACE_TS_Clerk_Handler::timeout (void) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::timeout"); + int old_timeout = this->timeout_; + this->timeout_ *= 2; + + if (this->timeout_ > this->max_timeout_) + this->timeout_ = this->max_timeout_; + + return old_timeout; +} + +// Set the max timeout delay. +void +ACE_TS_Clerk_Handler::max_timeout (int mto) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::max_timeout"); + this->max_timeout_ = mto; +} + +// Gets the max timeout delay. +int +ACE_TS_Clerk_Handler::max_timeout (void) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::max_timeout"); + return this->max_timeout_; +} + +int +ACE_TS_Clerk_Handler::open (void *) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::open"); + ACE_INET_Addr server_addr; + + // Set connection state as established + this->state (ACE_TS_Clerk_Handler::ESTABLISHED); + + // Register ourselves to receive SIGPIPE so we can attempt + // reconnections. +#if !defined (ACE_WIN32) + if (ACE_Service_Config::reactor ()->register_handler (SIGPIPE, this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n", + "register_handler (SIGPIPE)"), -1); +#endif + + // Register ourselves with the reactor to receive input + if (ACE_Service_Config::reactor ()->register_handler (this->get_handle (), + this, + ACE_Event_Handler::READ_MASK | + ACE_Event_Handler::EXCEPT_MASK) == -1) + ACE_ERROR ((LM_ERROR, "%n: %p\n", "register_handler (this)")); + + // Figure out what remote port we're really bound to. + else if (this->peer ().get_remote_addr (server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "get_remote_addr"), -1); + + ACE_DEBUG ((LM_DEBUG, + "TS Clerk Daemon connected to port %d on handle %d\n", + server_addr.get_port_number (), + this->peer ().get_handle ())); + + return 0; +} + +ACE_HANDLE +ACE_TS_Clerk_Handler::get_handle (void) const +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::get_handle"); + return this->peer().get_handle (); +} + +int +ACE_TS_Clerk_Handler::handle_close (ACE_HANDLE, + ACE_Reactor_Mask) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::handle_close"); + ACE_DEBUG ((LM_DEBUG, "(%t) shutting down on handle %d\n", this->get_handle ())); + return this->reinitiate_connection (); +} + +int +ACE_TS_Clerk_Handler::reinitiate_connection (void) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::reinitiate_connection"); + // Skip over deactivated descriptors. + + // Set state to connecting so that we don't try to send anything + // using this handler + this->state (ACE_TS_Clerk_Handler::CONNECTING); + if (this->get_handle () != ACE_INVALID_HANDLE) + { + ACE_DEBUG ((LM_DEBUG, "(%t) Scheduling reinitiation of connection\n")); + + // Reschedule ourselves to try and connect again. + if (ACE_Service_Config::reactor ()->schedule_timer (this, 0, + this->timeout ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "schedule_timer"), -1); + } + return 0; +} + +// Receive a time update from a server +int +ACE_TS_Clerk_Handler::handle_input (ACE_HANDLE handle) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::handle_input"); + // We're getting a time update message from a server + ACE_Time_Request reply; + if (this->recv_reply (reply) != 0) + return -1; + else + { + // Get current local time + ACE_UINT32 local_time = ACE_OS::time (0); + + // Compure delta time (difference between current local time and + // system time obtained from the server) + long t = reply.time () - local_time; + + // Compute round trip delay and adjust time accordingly + ACE_UINT32 one_way_time = (local_time - this->start_time_)/2; + t += one_way_time; + + // Now update time info (to be retrieved by Clerk_Processor) + this->time_info_.delta_time_ = t; + this->time_info_.sequence_num_ = this->cur_sequence_num_; + } + return 0; +} + +// Restart connection asynchronously when timeout occurs. +int +ACE_TS_Clerk_Handler::handle_timeout (const ACE_Time_Value &tv, + const void *arg) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::handle_timeout"); + ACE_DEBUG ((LM_DEBUG, + "(%t) attempting to reconnect to server with timeout = %d\n", + this->timeout_)); + + // Close down peer to reclaim descriptor if need be. Note this is + // necessary to reconnect. + this->peer ().close (); + + return this->processor_->initiate_connection (this, ACE_Synch_Options::asynch); +} + +void +ACE_TS_Clerk_Handler::remote_addr (ACE_INET_Addr &addr) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::remote_addr"); + this->remote_addr_ = addr; +} + +ACE_INET_Addr & +ACE_TS_Clerk_Handler::remote_addr (void) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::remote_addr"); + return this->remote_addr_; +} + +int +ACE_TS_Clerk_Handler::recv_reply (ACE_Time_Request &reply) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::recv_reply"); + const int bytes_expected = reply.size (); + + // Since Time_Request messages are fixed size, read the entire + // message in one go. + ssize_t n = this->peer ().recv ((void *) &reply, bytes_expected); + + if (n != bytes_expected) + { + switch (n) + { + case -1: + // FALLTHROUGH + ACE_DEBUG ((LM_DEBUG, "****************** recv_reply returned -1\n")); + default: + ACE_ERROR ((LM_ERROR, "%p got %d bytes, expected %d bytes\n", + "recv failed", n, bytes_expected)); + // FALLTHROUGH + case 0: + // We've shutdown unexpectedly + return -1; + // NOTREACHED + } + } + else if (reply.decode () == -1) // Decode the request into host byte order. + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "decode failed"), -1); + return 0; +} + + +int +ACE_TS_Clerk_Handler::send_request (ACE_UINT32 sequence_num, ACE_Time_Info &time_info) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::send_request"); + void *buffer; + ssize_t length; + + // Update current sequence number + this->cur_sequence_num_ = sequence_num; + + // First update the current time info. + time_info.delta_time_ = this->time_info_.delta_time_; + time_info.sequence_num_ = this->time_info_.sequence_num_; + + // Now prepare a new time update request + ACE_Time_Request request (ACE_Time_Request::TIME_UPDATE, 0, 0); + + if ((length = request.encode (buffer)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "encode failed"), -1); + + // Compute start time of sending request (needed to compute + // roundtrip delay) + this->start_time_ = ACE_OS::time (0); + + // Send the request + if (this->peer ().send_n (buffer, length) != length) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send_n failed"), -1); + + return 0; +} + +ACE_TS_Clerk_Processor::ACE_TS_Clerk_Processor () +: timeout_ (ACE_DEFAULT_TIMEOUT), + poolname_ (ACE_DEFAULT_BACKING_STORE), + blocking_semantics_ (0), + cur_sequence_num_ (0) +{ +} + +void +ACE_TS_Clerk_Processor::alloc (void) +{ + ACE_TRACE ("ACE_TS_Clerk_Processor::alloc"); + ACE_NEW (this->shmem_, ALLOCATOR (this->poolname_)); + + void *temp = 0; + // Only create the state if it doesn't already exist. + if (this->shmem_->find (ACE_DEFAULT_TIME_SERVER_STR, temp) == -1) + { + // Allocate the space out of shared memory for the system time entry + temp = this->shmem_->malloc (sizeof (this->system_time_)); + + // Give it a name binding + this->shmem_->bind (ACE_DEFAULT_TIME_SERVER_STR, temp); + + // Set up pointers. Note that we add one to get to the second + // field in the structure + this->system_time_.delta_time_ = (long *) temp; + this->system_time_.last_local_time_ = ((long *) temp) + 1; + + // Initialize + *(this->system_time_.delta_time_) = 0; + *(this->system_time_.last_local_time_) = ACE_OS::time (0); + } +} + +// Query the servers for the latest time +int +ACE_TS_Clerk_Processor::handle_timeout (const ACE_Time_Value &tv, + const void *arg) +{ + ACE_TRACE ("ACE_TS_Clerk_Processor::handle_timeout"); + return this->update_time (); +} + +int +ACE_TS_Clerk_Processor::update_time () +{ + ACE_TRACE ("ACE_TS_Clerk_Processor::update_time"); + ACE_UINT32 expected_sequence_num = this->cur_sequence_num_; + + // Increment sequence number + this->cur_sequence_num_++; + + int count = 0; + long total_delta = 0; + ACE_Time_Info time_info; + + // Call send_request() on all handlers + ACE_TS_Clerk_Handler **handler = 0; + + for (HANDLER_SET_ITERATOR set_iterator (this->handler_set_); + set_iterator.next (handler) != 0; + set_iterator.advance ()) + { + if ((*handler)->state () == ACE_TS_Clerk_Handler::ESTABLISHED) + { + if ((*handler)->send_request (this->cur_sequence_num_, time_info) == -1) + return -1; + // Check if sequence numbers match; otherwise discard + else if (expected_sequence_num != 0 && + time_info.sequence_num_ == expected_sequence_num) + { + count++; + ACE_DEBUG ((LM_DEBUG, "[%d] Delta time: %d\n", count, time_info.delta_time_)); + + // #### Can check here if delta value falls within a threshold #### + total_delta += time_info.delta_time_; + } + } + } + // Update system_time_ using average of times obtained from all the servers. + // Note that we are keeping two things in shared memory: the delta + // time (difference between our system clock and the local clock), + // and the last local time + if (count > 0) + { + // At least one server is out there + *(this->system_time_.delta_time_) = total_delta/count; + } + else + { + // No servers are out there (or this is the first time around + // computing the time) so set delta time to zero. This + // would mean that clients would use the actual local system time. + *(this->system_time_.delta_time_) = 0; + } + // Update the last local time + *(this->system_time_.last_local_time_) = ACE_OS::time (0); + + ACE_DEBUG ((LM_DEBUG, "Average delta time: %d\n", *(this->system_time_.delta_time_))); + return 0; +} + + +int +ACE_TS_Clerk_Processor::fini (void) +{ + ACE_TRACE ("ACE_TS_Clerk_Processor::fini"); + + // Cancel the timer + if (this->timer_id_ != -1) + ACE_Service_Config::reactor ()->cancel_timer (this->timer_id_); + + // Destroy all the handlers + ACE_TS_Clerk_Handler **handler = 0; + + for (HANDLER_SET_ITERATOR set_iterator (this->handler_set_); + set_iterator.next (handler) != 0; + set_iterator.advance ()) + { + if ((*handler)->state () != ACE_TS_Clerk_Handler::IDLE) + // Mark state as DISCONNECTING so we don't try to reconnect... + (*handler)->state (ACE_TS_Clerk_Handler::DISCONNECTING); + + // Deallocate resources. + (*handler)->destroy (); // Will trigger a delete + } + + // Remove the backing store + this->shmem_->remove (); + return 0; +} + +int +ACE_TS_Clerk_Processor::info (char **strp, size_t length) const +{ + ACE_TRACE ("ACE_TS_Clerk_Processor::info"); + return 0; +} + +int +ACE_TS_Clerk_Processor::init (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_TS_Clerk_Processor::init"); + // Use the options hook to parse the command line arguments and set + // options. + this->parse_args (argc, argv); + + this->alloc (); + +#if !defined (ACE_WIN32) + // Ignore SIPPIPE so each Output_Channel can handle it. + ACE_Sig_Action sig (ACE_SignalHandler (SIG_IGN), SIGPIPE); + +// ACE_Sig_Set sig_set; +// sig_set.sig_add (SIGINT); + + // Register ourselves to receive SIGINT and SIGPIPE + // so we can shut down gracefully via signals. + if (ACE_Service_Config::reactor ()->register_handler (SIGINT, + this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n", + "register_handler"), -1); +#endif + ACE_Synch_Options &synch_options = this->blocking_semantics_ == 0 + ? ACE_Synch_Options::asynch : ACE_Synch_Options::synch; + + // Now set up connections to all servers + ACE_TS_Clerk_Handler **handler = 0; + + for (HANDLER_SET_ITERATOR set_iterator (this->handler_set_); + set_iterator.next (handler) != 0; + set_iterator.advance ()) + { + this->initiate_connection (*handler, synch_options); + } + // Now set up timer to receive updates from server + // set the timer to go off after timeout value + this->timer_id_ = ACE_Service_Config::reactor ()->schedule_timer (this, + NULL, + ACE_Time_Value (this->timeout_), + ACE_Time_Value (this->timeout_)); + return 0; +} + +int +ACE_TS_Clerk_Processor::initiate_connection (ACE_TS_Clerk_Handler *handler, + ACE_Synch_Options &synch_options) +{ + ACE_TRACE ("ACE_TS_Clerk_Processor::initiate_connection"); + char buf[MAXHOSTNAMELEN]; + + // Mark ourselves as idle so that the various iterators + // will ignore us until we are connected/reconnected. + handler->state (ACE_TS_Clerk_Handler::IDLE); + + if (handler->remote_addr ().addr_to_string (buf, sizeof buf) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", + "can't obtain peer's address"), -1); + + // Establish connection with the server. + if (this->connect (handler, + handler->remote_addr (), + synch_options) == -1) + { + if (errno != EWOULDBLOCK) + { + handler->state (ACE_TS_Clerk_Handler::FAILED); + ACE_DEBUG ((LM_DEBUG, "(%t) %p on address %s\n", "connect", buf)); + + // Reschedule ourselves to try and connect again. + if (synch_options[ACE_Synch_Options::USE_REACTOR]) + { + if (ACE_Service_Config::reactor ()->schedule_timer (handler, + 0, + handler->timeout ()) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "schedule_timer"), -1); + } + else + // Failures on synchronous connects are reported as errors + // so that the caller can decide how to proceed. + return -1; + } + else + { + handler->state (ACE_TS_Clerk_Handler::CONNECTING); + ACE_DEBUG ((LM_DEBUG, + "(%t) in the process of connecting %s to %s\n", + synch_options[ACE_Synch_Options::USE_REACTOR] + ? "asynchronously" : "synchronously", buf)); + } + } + else + { + handler->state (ACE_TS_Clerk_Handler::ESTABLISHED); + ACE_DEBUG ((LM_DEBUG, "(%t) connected to %s on %d\n", + buf, handler->get_handle ())); + } + return 0; +} + +int +ACE_TS_Clerk_Processor::parse_args (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_TS_Clerk_Processor::parse_args"); + ACE_INET_Addr server_addr; + ACE_TS_Clerk_Handler *handler; + char server_host[BUFSIZ]; + + // Create a default entry + ACE_OS::sprintf (server_host, "%s:%d", + ACE_DEFAULT_SERVER_HOST, + ACE_DEFAULT_LOGGING_SERVER_PORT); + + ACE_Get_Opt get_opt (argc, argv, "h:t:p:b", 0); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'h': + // Get the hostname:port and create an ADDR + server_addr.set (get_opt.optarg); + + // Create a new handler + ACE_NEW_RETURN (handler, + ACE_TS_Clerk_Handler (this, server_addr), + -1); + + // Cache the handler + this->handler_set_.insert (handler); + break; + case 't': + // Get the timeout value + this->timeout_ = ACE_OS::atoi (get_opt.optarg); + break; + case 'p': + // Get the poolname + this->poolname_ = get_opt.optarg; + break; + case 'b': + // Blocking semantics + this->blocking_semantics_ = 1; + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n[-p hostname:port] [-t timeout] [-p poolname]\n%a", 1), + -1); + break; + } + } + return 0; +} + +int +ACE_TS_Clerk_Processor::suspend (void) +{ + ACE_TRACE ("ACE_TS_Clerk_Processor::suspend"); + return 0; +} + +int +ACE_TS_Clerk_Processor::resume (void) +{ + ACE_TRACE ("ACE_TS_Clerk_Processor::resume"); + return 0; +} + +// Signal the server to shutdown gracefully. + +int +ACE_TS_Clerk_Processor::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + ACE_TRACE ("ACE_TS_Clerk_Processor::handle_signal"); + ACE_Service_Config::end_reactor_event_loop (); + return 0; +} + +// The following is a "Factory" used by the ACE_Service_Config and +// svc.conf file to dynamically initialize the state of the TS_Clerk. + +ACE_SVC_FACTORY_DEFINE (ACE_TS_Clerk_Processor) + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Connector; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/netsvcs/lib/TS_Clerk_Handler.h b/netsvcs/lib/TS_Clerk_Handler.h new file mode 100644 index 00000000000..8a1c63a5a8d --- /dev/null +++ b/netsvcs/lib/TS_Clerk_Handler.h @@ -0,0 +1,23 @@ +/* -*- C++ -*- */ +// @(#)TS_Clerk_Handler.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// TS_Clerk_Handler.h +// +// = AUTHOR +// Prashant Jain +// +// ============================================================================ + +#if !defined (ACE_TS_CLERK_HANDLER_H) +#define ACE_TS_CLERK_HANDLER_H + +ACE_SVC_FACTORY_DECLARE (ACE_TS_Clerk_Processor) + +#endif /* ACE_TS_CLERK_HANDLER_H */ diff --git a/netsvcs/lib/TS_Server_Handler.cpp b/netsvcs/lib/TS_Server_Handler.cpp new file mode 100644 index 00000000000..8b60c1562bf --- /dev/null +++ b/netsvcs/lib/TS_Server_Handler.cpp @@ -0,0 +1,324 @@ +// TS_Server_Handler.cpp +// @(#)TS_Server_Handler.cpp 1.1 10/18/96 + +#define ACE_BUILD_SVC_DLL +#include "ace/SString.h" +#include "ace/Set.h" +#include "ace/Get_Opt.h" +#include "ace/Acceptor.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/SOCK_Stream.h" +#include "ace/Time_Request_Reply.h" +#include "TS_Server_Handler.h" + +class ACE_Svc_Export ACE_TS_Server_Handler : public ACE_Svc_Handler + // = TITLE + // Product object created by . + // + // = DESCRIPTION +{ + friend class ACE_Shutup_GPlusPlus; // Turn off g++ warning +public: + // = Initialization and termination. + + ACE_TS_Server_Handler (ACE_Thread_Manager * = 0); + // Default constructor. + + virtual int open (void * = 0); + // Activate this instance of the (called by the + // ). + +protected: + // = Helper routines for the operations exported to clients. + + virtual int abandon (void); + // Give up waiting (e.g., when a timeout occurs or a client shuts + // down unexpectedly). + + // = Low level routines for framing requests, dispatching + // operations, and returning replies. + + virtual int recv_request (void); + // Receive, frame, and decode the client's request. + + virtual int dispatch (void); + // Dispatch the appropriate operation to handle the client's + // request. + + virtual int send_request (ACE_Time_Request &); + // Special kind of reply + + // = Demultiplexing hooks. + virtual ACE_HANDLE get_handle (void) const; + // Return the underlying . + + virtual int handle_input (ACE_HANDLE); + // Callback method invoked by the when client events + // arrive. + + // = Timer hook. + virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg); + // Enable clients to limit the amount of time they wait. + +private: + ACE_Time_Request time_request_; + // Cache request from the client. + + ACE_INET_Addr addr_; + // Address of client we are connected with. + + ~ACE_TS_Server_Handler (void); + // Ensure dynamic allocation... +}; + +class ACE_TS_Server_Acceptor : public ACE_Strategy_Acceptor + // = TITLE + // This class contains the service-specific methods that can't + // easily be factored into the . +{ +public: + virtual int init (int argc, char *argv[]); + // Dynamic linking hook. + + int parse_args (int argc, char *argv[]); + // Parse svc.conf arguments. + +private: + ACE_Schedule_All_Reactive_Strategy scheduling_strategy_; + // The scheduling strategy is designed for Reactive services. +}; + +int +ACE_TS_Server_Acceptor::parse_args (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_TS_Server_Acceptor::parse_args"); + + this->service_port_ = ACE_DEFAULT_SERVER_PORT; + + ACE_LOG_MSG->open ("Time Service"); + + ACE_Get_Opt get_opt (argc, argv, "p:", 0); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'p': + this->service_port_ = ACE_OS::atoi (get_opt.optarg); + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n[-p server-port]\n%a", 1), + -1); + break; + } + } + this->service_addr_.set (this->service_port_); + return 0; +} + +int +ACE_TS_Server_Acceptor::init (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_TS_Server_Acceptor::init"); + + // Use the options hook to parse the command line arguments and set + // options. + this->parse_args (argc, argv); + + // Set the acceptor endpoint into listen mode (use the Singleton + // global Reactor...). + if (this->open (this->service_addr_, ACE_Service_Config::reactor (), + 0, 0, 0, + &this->scheduling_strategy_, + "Time Server", "ACE time service") == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p on port %d\n", + "acceptor::open failed", + this->service_addr_.get_port_number ()), -1); + + // Register ourselves to receive SIGINT so we can shutdown + // gracefully. + if (this->reactor ()->register_handler (SIGINT, this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n", + "register_handler (SIGINT)"), -1); + + // Ignore SIGPIPE so that each can handle this on its + // own. + ACE_Sig_Action sig (ACE_SignalHandler (SIG_IGN), SIGPIPE); + + ACE_INET_Addr server_addr; + + // Figure out what port we're really bound to. + if (this->acceptor ().get_local_addr (server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "get_local_addr"), -1); + + ACE_DEBUG ((LM_DEBUG, + "starting up Time Server at port %d on handle %d\n", + server_addr.get_port_number (), + this->acceptor ().get_handle ())); + return 0; +} + +// The following is a "Factory" used by the ACE_Service_Config and +// svc.conf file to dynamically initialize the state of the Time Server + +ACE_SVC_FACTORY_DEFINE (ACE_TS_Server_Acceptor) + +// Default constructor. +ACE_TS_Server_Handler::ACE_TS_Server_Handler (ACE_Thread_Manager *tm) + : ACE_Svc_Handler (tm) +{ + ACE_TRACE ("ACE_TS_Server_Handler::ACE_TS_Server_Handler"); +} + +// Activate this instance of the ACE_TS_Server_Handler (called by the +// ACE_TS_Server_Acceptor). + +/* VIRTUAL */ int +ACE_TS_Server_Handler::open (void *) +{ + ACE_TRACE ("ACE_TS_Server_Handler::open"); + + ACE_INET_Addr client_addr; + + // Determine the address of the client and display it. + if (this->peer ().get_remote_addr (client_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "get_remote_addr"), -1); + + ACE_DEBUG ((LM_DEBUG, "(%t) accepted connection from host %s on fd %d\n", + client_addr.get_host_name (), this->peer ().get_handle ())); + + // Call down to our parent to register ourselves with the Reactor. + if (ACE_Svc_Handler::open (0) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + return 0; +} + +/* VIRTUAL */ int +ACE_TS_Server_Handler::send_request (ACE_Time_Request &request) +{ + ACE_TRACE ("ACE_TS_Server_Handler::send_request"); + void *buffer; + ssize_t length = request.encode (buffer); + + if (length == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "encode failed"), -1); + + // Transmit request via a blocking send. + + if (this->peer ().send_n (buffer, length) != length) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send_n failed"), -1); + + return 0; +} + +// Give up waiting (e.g., when a timeout occurs or a client shuts down +// unexpectedly). + +/* VIRTUAL */ int +ACE_TS_Server_Handler::abandon (void) +{ + ACE_TRACE ("ACE_TS_Server_Handler::abandon"); + + // Note we are using the time field to report the errno in case of + // failure. + ACE_Time_Request rq (ACE_Time_Request::FAILURE, errno); + return this->send_request (rq); +} + +// Enable clients to limit the amount of time they'll wait +/* VIRTUAL */ int +ACE_TS_Server_Handler::handle_timeout (const ACE_Time_Value &, const void *) +{ + ACE_TRACE ("ACE_TS_Server_Handler::handle_timeout"); + return this->abandon (); +} + +// Return the underlying ACE_HANDLE. + +/* VIRTUAL */ ACE_HANDLE +ACE_TS_Server_Handler::get_handle (void) const +{ + ACE_TRACE ("ACE_TS_Server_Handler::get_handle"); + return this->peer ().get_handle (); +} + +// Dispatch the appropriate operation to handle the client request. + +/* VIRTUAL */ int +ACE_TS_Server_Handler::dispatch (void) +{ + ACE_TRACE ("ACE_TS_Server_Handler::dispatch"); + // Get the system time and then create an ACE_Time_Request + time_t t = ACE_OS::time (0); + ACE_Time_Request rq (ACE_Time_Request::TIME_UPDATE, t); + return this->send_request (rq); +} + +// Receive, frame, and decode the client's request. Note, this method +// should use non-blocking I/O. + +/* VIRTUAL */ int +ACE_TS_Server_Handler::recv_request (void) +{ + ACE_TRACE ("ACE_TS_Server_Handler::recv_request"); + ssize_t bytes_expected = this->time_request_.size (); + + // Since Time_Request messages are fixed size, read the entire + // message in one go. + ssize_t n = this->peer ().recv ((void *) &this->time_request_, bytes_expected); + if (n != bytes_expected) + { + switch (n) + { + case -1: + /* FALLTHROUGH */ + ACE_DEBUG ((LM_DEBUG, "****************** recv_request returned -1\n")); + default: + ACE_ERROR ((LM_ERROR, "%p got %d bytes, expected %d bytes\n", + "recv failed", n, bytes_expected)); + /* FALLTHROUGH */ + case 0: + // We've shutdown unexpectedly, let's abandon the connection. + this->abandon (); + return -1; + /* NOTREACHED */ + } + } + else + { + // Decode the request into host byte order. + if (this->time_request_.decode () == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "decode failed")); + return this->abandon (); + } + } + return 0; +} + +// Callback method invoked by the ACE_Reactor when events arrive from +// the client. + +/* VIRTUAL */ int +ACE_TS_Server_Handler::handle_input (ACE_HANDLE) +{ + ACE_TRACE ("ACE_TS_Server_Handler::handle_input"); + + if (this->recv_request () == -1) + return -1; + else + return this->dispatch (); +} + +ACE_TS_Server_Handler::~ACE_TS_Server_Handler (void) +{ + ACE_TRACE ("ACE_TS_Server_Handler::~ACE_TS_Server_Handler"); + ACE_DEBUG ((LM_DEBUG, "closing down Handle %d\n", + this->get_handle ())); +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Strategy_Acceptor; +template class ACE_Schedule_All_Reactive_Strategy; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/netsvcs/lib/TS_Server_Handler.h b/netsvcs/lib/TS_Server_Handler.h new file mode 100644 index 00000000000..5d571bd2aac --- /dev/null +++ b/netsvcs/lib/TS_Server_Handler.h @@ -0,0 +1,25 @@ +/* -*- C++ -*- */ +// @(#)TS_Server_Handler.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// TS_Server_Handler.h +// +// = AUTHOR +// Prashant Jain +// +// ============================================================================ + +#if !defined (ACE_TS_SERVER_HANDLER_H) +#define ACE_TS_SERVER_HANDLER_H + +#include "ace/OS.h" + +ACE_SVC_FACTORY_DECLARE (ACE_TS_Server_Acceptor) + +#endif /* ACE_TS_SERVER_HANDLER_H */ diff --git a/netsvcs/lib/Token_Handler.cpp b/netsvcs/lib/Token_Handler.cpp new file mode 100644 index 00000000000..bdb2a425a8e --- /dev/null +++ b/netsvcs/lib/Token_Handler.cpp @@ -0,0 +1,882 @@ +// Token_Handler.cpp +// @(#)Token_Handler.cpp 1.1 10/18/96 + +#define ACE_BUILD_SVC_DLL +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/Acceptor.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/Token_Request_Reply.h" +#include "ace/Token_Collection.h" +#include "ace/Local_Tokens.h" +#include "Token_Handler.h" + +class ACE_Svc_Export ACE_Token_Handler : public ACE_Svc_Handler + // = TITLE + // Product object created by an . A + // exchanges messages with a object + // on the client-side. + // + // = DESCRIPTION + // This class is the main workhorse of the ACE Token service. It + // receives token operation requests from remote clients and turns + // them into calls on local tokens (acquire, release, renew, and + // remove). In OMG CORBA terms, it is an object adapter. It also + // schedules and handles timeouts that are used to support "timed + // waits." Clients used timed waits to bound the amount of time + // they block trying to get a token. + +{ +public: + // = Initialization and termination. + + ACE_Token_Handler (ACE_Thread_Manager * = 0); + // Default constructor. + + // = Accessor and mutator methods. + + // = Remote operations "exported" to a client. + virtual int acquire (ACE_Token_Proxy *proxy); + // Try to acquire the token. + // Precondition: client *may* hold the token already (i.e., + // supports recursive acquisitions). + + virtual int try_acquire (ACE_Token_Proxy *proxy); + // Try to acquire the token. + + virtual int release (ACE_Token_Proxy *proxy); + // Release the token and allow the next client that is waiting to + // proceed. Preconditions: client must hold the token. + + virtual int renew (ACE_Token_Proxy *proxy); + // Yield the token if any clients are waiting, otherwise keep the + // token. Preconditions: client must hold the token. + + virtual int remove (ACE_Token_Proxy *proxy); + // Remove the specified token from the Token_Map. Preconditions: + // ACE_Token must exist. @@ Any other preconditions, e.g., must + // client hold token, must there be no waiters, etc.? + + void sleep_hook (void); + // Called by TS_[Mutex,RLock,WLock] when we hold the mutex and + // someone wants it. + + void token_acquired (ACE_TPQ_Entry *); + // Called by TS_[Mutex,RLock,WLock] when we are waiting and acquire + // the mutex. + +protected: + // = Low level routines for framing requests, dispatching + // operations, and returning replies. + + virtual int abandon (int send_error); + // Our connection has been closed. + + virtual int recv_request (void); + // Receive, frame, and decode the client's request. + + virtual int dispatch (void); + // Dispatch the appropriate operation to handle the client's + // request. + + virtual int send_reply (ACE_UINT32 errnum); + // Create and send a reply to the client. + + // = Demultiplexing hooks. + virtual int handle_input (ACE_HANDLE); + // Callback method invoked by the when client events + // arrive. + + // = Timer hook. + virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg); + // Enable clients to limit the amount of time they wait for a token. + + ACE_Token_Proxy *get_proxy (void); + // return a proxy for the calling client_id and token name. + +private: + + virtual ACE_Token_Proxy *create_proxy (void); + // Switches on the type of token_request_ and creates a new + // Token_Proxy. + + ACE_Synch_Options request_options_; + // Keeps track of the synchronization options (i.e., the timeout + // interval). + + int timeout_id_; + // ID returned by the Reactor that is used to kill registered timers + // when a token operation times out. + + ACE_Token_Collection collection_; + // collection of the client's token proxies. + + ACE_Token_Request token_request_; + // Cache request from the client. + + ACE_Token_Reply token_reply_; + // Cache reply to the client. +}; + +// = DESCRIPTION of ACE_TS_* classes: +// When Tokens are released, waiting token proxies are notified +// when the releasing thread calls token_acquired on the waiting +// proxy. The Token Server specializes ACE_Token_Proxy to +// redefine the implementation of token_acquired. When +// token_acquired is called, the Token_Handler can then send the +// response back over the socket connection to unblock the +// client side. +// Since only the Token_Handler uses ACE_TS_Mutex, we've moved +// the definition to the .cpp file. + +class ACE_TS_Mutex : public ACE_Local_Mutex + // = TITLE + // ACE_TS_Mutex -- ACE_*T*oken_*S*erver_Mutex +{ +public: + ACE_TS_Mutex (const char *name, + ACE_Token_Handler *th); + // Creation. + +protected: + virtual void sleep_hook (void); + // Somebody wants our token! + + virtual void token_acquired (ACE_TPQ_Entry *); + // We've been taken off the waiters list and given the token! Call + // the Token_Handler associated at construction, so it can tell the + // remote client. + + ACE_TS_Mutex (const ACE_TS_Mutex &); + // Duplication. + + virtual ACE_Token_Proxy *clone (void) const; + // Return a deep copy. + +private: + ACE_Token_Handler* th_; + // The Token Handler associated with this proxy. Set at + // construction and notified when blocking acquires succeed. +}; + +class ACE_TS_RLock : public ACE_Local_RLock + // = TITLE + // ACE_TS_RLock -- ACE_*T*oken_*S*erver_RLock +{ +public: + ACE_TS_RLock (const char *name, + ACE_Token_Handler *th); + // Creation. + +protected: + virtual void sleep_hook (void); + // Somebody wants our token! + + virtual void token_acquired (ACE_TPQ_Entry *); + // We've been taken off the waiters list and given the token! Call + // the Token_Handler associated at construction, so it can tell the + // remote client. + + ACE_TS_RLock (const ACE_TS_RLock&); + // Duplication. + + virtual ACE_Token_Proxy *clone (void) const; + // Return a deep copy. + +private: + ACE_Token_Handler* th_; + // the Token Handler associated with this proxy. Set at + // construction and notified when blocking acquires succeed. +}; + +class ACE_TS_WLock : public ACE_Local_WLock + // = TITLE + // ACE_TS_WLock -- ACE_*T*oken_*S*erver_WLock +{ +public: + ACE_TS_WLock (const char *name, + ACE_Token_Handler *th); + // Creation. + +protected: + virtual void sleep_hook (void); + // Somebody wants our token! + + virtual void token_acquired (ACE_TPQ_Entry *); + // We've been taken off the waiters list and given the token! Call + // the Token_Handler associated at construction, so it can tell the + // remote client. + + ACE_TS_WLock (const ACE_TS_WLock&); + // Duplication. + + virtual ACE_Token_Proxy *clone (void) const; + // Return a deep copy. + +private: + ACE_Token_Handler* th_; + // the Token Handler associated with this proxy. Set at + // construction and notified when blocking acquires succeed. +}; + +// ************************************************************ + +class ACE_Token_Acceptor : public ACE_Strategy_Acceptor + // = TITLE + // This class contains the service-specific methods that can't + // easily be factored into the . +{ +public: + virtual int init (int argc, char *argv[]); + // Dynamic linking hook. + + int parse_args (int argc, char *argv[]); + // Parse svc.conf arguments. + +private: + ACE_Schedule_All_Reactive_Strategy scheduling_strategy_; + // The scheduling strategy is designed for Reactive services. +}; + +int +ACE_Token_Acceptor::parse_args (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_Token_Acceptor::parse_args"); + + this->service_port_ = ACE_DEFAULT_SERVER_PORT; + + ACE_LOG_MSG->open ("Token Service"); + + ACE_Get_Opt get_opt (argc, argv, "p:", 0); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'p': + this->service_port_ = ACE_OS::atoi (get_opt.optarg); + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n[-p server-port]\n%a", 1), + -1); + break; + } + } + + this->service_addr_.set (this->service_port_); + return 0; +} + +int +ACE_Token_Acceptor::init (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_Token_Acceptor::init"); + + // Use the options hook to parse the command line arguments and set + // options. + this->parse_args (argc, argv); + + // Set the acceptor endpoint into listen mode (use the Singleton + // global Reactor...). + if (this->open (this->service_addr_, ACE_Service_Config::reactor (), + 0, 0, 0, + &this->scheduling_strategy_, + "Token Server", "ACE token service") == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p on port %d\n", + "acceptor::open failed", + this->service_addr_.get_port_number ()), -1); + + // Register ourselves to receive SIGINT so we can shutdown + // gracefully. + if (this->reactor ()->register_handler (SIGINT, this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n", + "register_handler (SIGINT)"), -1); + + // Ignore SIGPIPE so that each can handle this on its + // own. + ACE_Sig_Action sig (ACE_SignalHandler (SIG_IGN), SIGPIPE); + + ACE_INET_Addr server_addr; + + if (this->acceptor ().get_local_addr (server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "get_remote_addr"), -1); + + ACE_DEBUG ((LM_DEBUG, + "starting up Token Server at port %d on handle %d\n", + server_addr.get_port_number (), + this->acceptor ().get_handle ())); + return 0; +} + +// The following is a "Factory" used by the ACE_Service_Config and +// svc.conf file to dynamically initialize the state of the Naming +// Server. + +ACE_SVC_FACTORY_DEFINE (ACE_Token_Acceptor) + +// Default constructor. + +ACE_Token_Handler::ACE_Token_Handler (ACE_Thread_Manager *tm) + : ACE_Svc_Handler (tm), + collection_ (1), + timeout_id_ (0) +{ + ACE_TRACE ("ACE_Token_Handler::ACE_Token_Handler"); +} + +// Create and send a reply to the client. + +/* VIRTUAL */ int +ACE_Token_Handler::send_reply (ACE_UINT32 err) +{ + ACE_TRACE ("ACE_Token_Handler::send_reply"); + void *buf; + size_t len; + ssize_t n; + + this->token_reply_.errnum (err); + + len = this->token_reply_.encode (buf); + + n = this->peer ().send (buf, len); + + if (n != len) + ACE_ERROR_RETURN ((LM_ERROR, + "%p, expected len = %d, actual len = %d\n", + "send failed", len, n), -1); + else + return 0; +} + +// Acquire the token. + +/* VIRTUAL */ int +ACE_Token_Handler::acquire (ACE_Token_Proxy *proxy) +{ + ACE_TRACE ("ACE_Token_Handler::acquire"); + ACE_DEBUG ((LM_DEBUG, "in acquire for client id = %s\n", + proxy->client_id ())); + + // @@ add notify in token request reply + if (proxy->acquire (0, 0, ACE_Synch_Options::asynch) == -1) + { + if (errno != EWOULDBLOCK) + // bad bad bad + return this->send_reply (errno); + + // acquire would block + if (request_options_[ACE_Synch_Options::USE_TIMEOUT] == 1) + { + // check for polling + if ((request_options_.timeout ().sec () == 0) && + (request_options_.timeout ().usec () == 0)) + return this->send_reply (EWOULDBLOCK); + + // schedule a timer + this->timeout_id_ = this->reactor ()->schedule_timer + (this, (void *) proxy, request_options_.timeout ()); + if (timeout_id_ == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "schedule_timer")); + return this->send_reply (errno); + } + } + // send no reply. wait until we acquire it or until the timer + // goes off. + return 0; + } + else // success + return this->send_reply (ACE_Token_Reply::SUCCESS); +} + +// Try to acquire the token. Never block. + +/* VIRTUAL */ int +ACE_Token_Handler::try_acquire (ACE_Token_Proxy *proxy) +{ + ACE_TRACE ("ACE_Token_Handler::try_acquire"); + + ACE_DEBUG ((LM_DEBUG, "in try_acquire for client id = %s\n", + proxy->client_id ())); + + // @@ add notify in token request reply + if (proxy->tryacquire () == -1) + return this->send_reply (errno); + else + return this->send_reply (ACE_Token_Reply::SUCCESS); +} + +// Release the token and allow the next client that is waiting to +// proceed. + +/* VIRTUAL */ int +ACE_Token_Handler::release (ACE_Token_Proxy *proxy) +{ + ACE_TRACE ("ACE_Token_Handler::release"); + ACE_DEBUG ((LM_DEBUG, + "in release for client id = %s\n", + proxy->client_id ())); + + if (proxy->release (ACE_Synch_Options::asynch) == -1) + // oops, it failed + return this->send_reply (ACE_LOG_MSG->errnum ()); + + // success + if (this->timeout_id_ != 0) + { + this->reactor ()->cancel_timer (timeout_id_); + this->timeout_id_ = 0; + } + + return this->send_reply (ACE_Token_Reply::SUCCESS); +} + +// Yield the token if any clients are waiting, otherwise keep the +// token. + +/* VIRTUAL */ int +ACE_Token_Handler::renew (ACE_Token_Proxy *proxy) +{ + ACE_TRACE ("ACE_Token_Handler::renew"); + + ACE_DEBUG ((LM_DEBUG, "in renew for client id = %s\n", + proxy->client_id ())); + + if (proxy->renew (token_request_.requeue_position (), + ACE_Synch_Options::asynch) == -1) + { + int result = ACE_LOG_MSG->errnum (); + if (result != EWOULDBLOCK) + // bad bad bad + return this->send_reply (result); + + // acquire would block + if (request_options_[ACE_Synch_Options::USE_TIMEOUT] == 1) + { + this->timeout_id_ = this->reactor ()->schedule_timer + (this, 0, request_options_.timeout ()); + if (timeout_id_ == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "schedule_timer")); + return this->send_reply (ACE_LOG_MSG->errnum ()); + } + } + // Send no reply. wait until we acquire it or until the timer + // goes off. + return 0; + } + else + // Success, we still hold the token. + return this->send_reply (ACE_Token_Reply::SUCCESS); +} + +/* VIRTUAL */ int +ACE_Token_Handler::remove (ACE_Token_Proxy *proxy) +{ + ACE_TRACE ("ACE_Token_Handler::remove"); + ACE_DEBUG ((LM_DEBUG, "in remove for client id = %s\n", + proxy->client_id ())); + ACE_ERROR ((LM_ERROR, "sorry: ACE_Token_Handler::remove() is not implemented")); + + return this->send_reply (ENOTSUP); +} + +// Enable clients to limit the amount of time they'll wait for a +// token. + +/* VIRTUAL */ int +ACE_Token_Handler::handle_timeout (const ACE_Time_Value &, + const void *tp) +{ + ACE_TRACE ("ACE_Token_Handler::handle_timeout"); + + this->timeout_id_ = 0; + + // @@ add a try acquire here! + // Try to acquire the token, but if we can't get it immediately + // then abandon the wait. + // if (this->try_acquire (&token_entry) == -1) + // return this->abandon (token_entry); + + ACE_Token_Proxy *proxy = (ACE_Token_Proxy *) tp; + + ACE_DEBUG ((LM_DEBUG, "in handle_timeout for client id = %s\n", + proxy->client_id ())); + + // Remove ourselves from the waiter list. + proxy->release (); + + this->send_reply (ETIME); + return 0; +} + +// Dispatch the appropriate operation to handle the client request. + +ACE_Token_Proxy * +ACE_Token_Handler::get_proxy (void) +{ + ACE_TRACE ("ACE_Token_Handler::get_proxy"); + + // See if the proxy already exists in the collection. + ACE_Token_Proxy *proxy = collection_.is_member (token_request_.token_name ()); + + // If not, create one. + if (proxy == 0) + { + proxy = this->create_proxy (); + + // Put the new_proxy in this client_id's collection. + if (collection_.insert (*proxy) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "insert failed\n"), 0); + + // Delete our copy (one was created in the collection). + delete proxy; + proxy = collection_.is_member (token_request_.token_name ()); + + if (proxy == 0) + ACE_ERROR_RETURN ((LM_ERROR, "is_member failed\n"), 0); + + // Set the client_id (it was set to 1 since we're + // single-threaded. + proxy->client_id (token_request_.client_id ()); + } + + return proxy; +} + +ACE_Token_Proxy * +ACE_Token_Handler::create_proxy (void) +{ + ACE_TRACE ("ACE_Token_Handler::new_proxy"); + + ACE_Token_Proxy *proxy; + + switch (token_request_.token_type ()) + { + case ACE_Tokens::RWLOCK: + if (token_request_.proxy_type () == ACE_RW_Token::READER) + ACE_NEW_RETURN (proxy, + ACE_TS_RLock (token_request_.token_name (), this), + 0); + else + ACE_NEW_RETURN (proxy, + ACE_TS_WLock (token_request_.token_name (), this), + 0); + break; + case ACE_Tokens::MUTEX: + ACE_NEW_RETURN (proxy, + ACE_TS_Mutex (token_request_.token_name (), this), + 0); + break; + default: + // Nonexistent token type. + errno = EINVAL; + return 0; + } + + // Check for failed new. + if (proxy == 0) + errno = ENOMEM; + + return proxy; +} + +int +ACE_Token_Handler::dispatch (void) +{ + ACE_TRACE ("ACE_Token_Handler::dispatch"); + ACE_Token_Proxy *proxy = this->get_proxy (); + + if (proxy == 0) + return -1; + + // Dispatch the appropriate request. + switch (this->token_request_.operation_type ()) + { + case ACE_Token_Request::ACQUIRE: + return this->acquire (proxy); + case ACE_Token_Request::TRY_ACQUIRE: + return this->try_acquire (proxy); + case ACE_Token_Request::RELEASE: + return this->release (proxy); + case ACE_Token_Request::RENEW: + return this->renew (proxy); + case ACE_Token_Request::REMOVE: + return this->remove (proxy); + default: + ACE_ERROR_RETURN ((LM_ERROR, "invalid type = %d\n", + this->token_request_.operation_type ()), -1); + /* NOTREACHED */ + } +} + +// Receive, frame, and decode the client's request. +// Note, this method should use non-blocking I/O. + +/* VIRTUAL */ int +ACE_Token_Handler::recv_request (void) +{ + ACE_TRACE ("ACE_Token_Handler::recv_request"); + ssize_t n; + + // Read the first 4 bytes to get the length of the message + // This implementation assumes that the first 4 bytes are + // the length of the message. + n = this->peer ().recv ((void *) &this->token_request_, + sizeof (ACE_UINT32)); + + switch (n) + { + case -1: + /* FALLTHROUGH */ + default: + ACE_ERROR ((LM_ERROR, "%p got %d bytes, expected %d bytes\n", + "recv failed", n, sizeof (ACE_UINT32))); + /* FALLTHROUGH */ + case 0: + // We've shutdown unexpectedly, let's abandon the connection. + this->abandon (0); + return -1; + /* NOTREACHED */ + case sizeof (ACE_UINT32): + { + // Transform the length into host byte order. + ssize_t length = this->token_request_.length (); + + // Do a sanity check on the length of the message. + if (length > sizeof this->token_request_) + { + ACE_ERROR ((LM_ERROR, "length %d too long\n", length)); + return this->abandon (1); + } + + // Receive the rest of the request message. + // @@ beware of blocking read!!!. + n = this->peer ().recv ((void *) (((char *) &this->token_request_) + + sizeof (ACE_UINT32)), + length - sizeof (ACE_UINT32)); + + // Subtract off the size of the part we skipped over... + if (n != (length - sizeof (ACE_UINT32))) + { + ACE_ERROR ((LM_ERROR, "%p expected %d, got %d\n", + "invalid length", length, n)); + return this->abandon (1); + } + + // Decode the request into host byte order. + if (this->token_request_.decode () == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "decode failed")); + return this->abandon (1); + } + + // if (OS::debug) + this->token_request_.dump (); + } + } + return 0; +} + +// Callback method invoked by the ACE_Reactor when +// events arrive from the client. + +/* VIRTUAL */ int +ACE_Token_Handler::handle_input (ACE_HANDLE) +{ + ACE_TRACE ("ACE_Token_Handler::handle_input"); + + ACE_DEBUG ((LM_DEBUG, "****************** in handle_input\n")); + + if (this->recv_request () == -1) + return -1; + else + return this->dispatch (); +} + +void +ACE_Token_Handler::sleep_hook (void) +{ + ACE_TRACE ("ACE_Token_Handler::sleep_hook"); + // @@ what should we do? + return; +} + +void +ACE_Token_Handler::token_acquired (ACE_TPQ_Entry *) +{ + ACE_TRACE ("ACE_Token_Handler::token_acquired"); + + if (this->timeout_id_ != 0) + { + this->reactor ()->cancel_timer (this->timeout_id_); + this->timeout_id_ = 0; + } + + this->send_reply (ACE_Token_Reply::SUCCESS); +} + +int +ACE_Token_Handler::abandon (int send_error) +{ + ACE_TRACE ("ACE_Token_Handler::abandon"); + + // Release ownership or remove us from the waiter list. + if (this->timeout_id_ != 0) + { + this->reactor ()->cancel_timer (timeout_id_); + this->timeout_id_ = 0; + } + + // @@ release all tokens + collection_.release (); + + if (send_error) + return this->send_reply (EIO); + else + return -1; +} + +// ************************************************************ +// ************************************************************ +// ************************************************************ + +ACE_TS_Mutex::ACE_TS_Mutex (const char *name, + ACE_Token_Handler *th) +: th_ (th), + ACE_Local_Mutex (name, 0, 1) // The 1 is debug. +{ + ACE_TRACE ("ACE_TS_Mutex::ACE_TS_Mutex"); +} + +ACE_TS_Mutex::ACE_TS_Mutex (const ACE_TS_Mutex &m) +: th_ (m.th_), + ACE_Local_Mutex (m) +{ + ACE_TRACE ("ACE_TS_Mutex::ACE_TS_Mutex"); + this->open (m.name (), m.ignore_deadlock_, m.debug_); +} + +void +ACE_TS_Mutex::sleep_hook (void) +{ + ACE_TRACE ("ACE_TS_Mutex::sleep_hook"); + th_->sleep_hook (); + return; +} + +void +ACE_TS_Mutex::token_acquired (ACE_TPQ_Entry *e) +{ + ACE_TRACE ("ACE_TS_Mutex::token_acquired"); + // Notify the token handler. + th_->token_acquired (e); + return; +} + +ACE_Token_Proxy * +ACE_TS_Mutex::clone (void) const +{ + ACE_TRACE ("ACE_TS_Mutex::clone"); + ACE_Token_Proxy *temp; + ACE_NEW_RETURN (temp, ACE_TS_Mutex (*this), 0); + return temp; +} + +// ************************************************************ + +ACE_TS_RLock::ACE_TS_RLock (const char *name, + ACE_Token_Handler *th) +: th_ (th), + ACE_Local_RLock (name, 0, 1) // The 1 is debug. +{ + ACE_TRACE ("ACE_TS_RLock::ACE_TS_RLock"); +} + +ACE_TS_RLock::ACE_TS_RLock (const ACE_TS_RLock &r) +: th_ (r.th_), + ACE_Local_RLock (r) +{ + ACE_TRACE ("ACE_TS_RLock::ACE_TS_RLock"); + this->open (r.name (), r.ignore_deadlock_, r.debug_); +} + +void +ACE_TS_RLock::sleep_hook (void) +{ + ACE_TRACE ("ACE_TS_RLock::sleep_hook"); + th_->sleep_hook (); + return; +} + +void +ACE_TS_RLock::token_acquired (ACE_TPQ_Entry *e) +{ + ACE_TRACE ("ACE_TS_RLock::token_acquired"); + // Notify the token handler. + th_->token_acquired (e); + return; +} + +ACE_Token_Proxy * +ACE_TS_RLock::clone (void) const +{ + ACE_TRACE ("ACE_TS_RLock::clone"); + ACE_Token_Proxy *temp; + + ACE_NEW_RETURN (temp, ACE_TS_RLock (*this), 0); + return temp; +} + +// ************************************************************ + +ACE_TS_WLock::ACE_TS_WLock (const char *name, + ACE_Token_Handler *th) +: th_ (th), + ACE_Local_WLock (name, 0, 1) // The 1 is debug. +{ + ACE_TRACE ("ACE_TS_WLock::ACE_TS_WLock"); +} + +ACE_TS_WLock::ACE_TS_WLock (const ACE_TS_WLock &w) +: th_ (w.th_), + ACE_Local_WLock (w) +{ + ACE_TRACE ("ACE_TS_WLock::ACE_TS_WLock"); + this->open (w.name (), w.ignore_deadlock_, w.debug_); +} + +void +ACE_TS_WLock::sleep_hook (void) +{ + ACE_TRACE ("ACE_TS_WLock::sleep_hook"); + th_->sleep_hook (); + return; +} + +void +ACE_TS_WLock::token_acquired (ACE_TPQ_Entry *e) +{ + ACE_TRACE ("ACE_TS_WLock::token_acquired"); + // Notify the token handler. + th_->token_acquired (e); + return; +} + +ACE_Token_Proxy * +ACE_TS_WLock::clone (void) const +{ + ACE_TRACE ("ACE_TS_WLock::clone"); + ACE_Token_Proxy *temp; + + ACE_NEW_RETURN (temp, ACE_TS_WLock (*this), 0); + return temp; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Strategy_Acceptor; +template class ACE_Schedule_All_Reactive_Strategy; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ + + diff --git a/netsvcs/lib/Token_Handler.h b/netsvcs/lib/Token_Handler.h new file mode 100644 index 00000000000..6858347f2b8 --- /dev/null +++ b/netsvcs/lib/Token_Handler.h @@ -0,0 +1,26 @@ +/* -*- C++ -*- */ +// @(#)Token_Handler.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// Token_Handler.h +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) +// Tim Harrison (harrison@cs.wustl.edu) +// +// ============================================================================ + +#if !defined (ACE_TOKEN_HANDLER_H) +#define ACE_TOKEN_HANDLER_H + +#include "ace/OS.h" + +ACE_SVC_FACTORY_DECLARE (ACE_Token_Acceptor) + +#endif /* ACE_TOKEN_HANDLER_H */ diff --git a/netsvcs/lib/netsvcs.mak b/netsvcs/lib/netsvcs.mak new file mode 100644 index 00000000000..e5bc6ebd557 --- /dev/null +++ b/netsvcs/lib/netsvcs.mak @@ -0,0 +1,1082 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +!IF "$(CFG)" == "" +CFG=netsvcs - Win32 Debug +!MESSAGE No configuration specified. Defaulting to netsvcs - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "netsvcs - Win32 Release" && "$(CFG)" !=\ + "netsvcs - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "netsvcs.mak" CFG="netsvcs - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "netsvcs - Win32 Release" (based on\ + "Win32 (x86) Dynamic-Link Library") +!MESSAGE "netsvcs - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "netsvcs - Win32 Debug" +RSC=rc.exe +MTL=mktyplib.exe +CPP=cl.exe + +!IF "$(CFG)" == "netsvcs - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "netsvcs\Release" +# PROP BASE Intermediate_Dir "netsvcs\Release" +# PROP BASE Target_Dir "netsvcs" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "netsvcs\Release" +# PROP Intermediate_Dir "netsvcs\Release" +# PROP Target_Dir "netsvcs" +OUTDIR=.\netsvcs\Release +INTDIR=.\netsvcs\Release + +ALL : "$(OUTDIR)\netsvcs.dll" + +CLEAN : + -@erase ".\netsvcs\Release\netsvcs.dll" + -@erase ".\netsvcs\Release\Token_Handler.obj" + -@erase ".\netsvcs\Release\Server_Logging_Handler.obj" + -@erase ".\netsvcs\Release\TS_Server_Handler.obj" + -@erase ".\netsvcs\Release\Client_Logging_Handler.obj" + -@erase ".\netsvcs\Release\TS_Clerk_Handler.obj" + -@erase ".\netsvcs\Release\Name_Handler.obj" + -@erase ".\netsvcs\Release\Logging_Strategy.obj" + -@erase ".\netsvcs\Release\netsvcs.lib" + -@erase ".\netsvcs\Release\netsvcs.exp" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/netsvcs.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\netsvcs\Release/ +CPP_SBRS= +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/netsvcs.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib /nologo /subsystem:windows /dll /incremental:no\ + /pdb:"$(OUTDIR)/netsvcs.pdb" /machine:I386 /out:"$(OUTDIR)/netsvcs.dll"\ + /implib:"$(OUTDIR)/netsvcs.lib" +LINK32_OBJS= \ + "$(INTDIR)/Token_Handler.obj" \ + "$(INTDIR)/Server_Logging_Handler.obj" \ + "$(INTDIR)/TS_Server_Handler.obj" \ + "$(INTDIR)/Client_Logging_Handler.obj" \ + "$(INTDIR)/TS_Clerk_Handler.obj" \ + "$(INTDIR)/Name_Handler.obj" \ + "$(INTDIR)/Logging_Strategy.obj" \ + "..\..\ace\ace.lib" + +"$(OUTDIR)\netsvcs.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "netsvcs - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "netsvcs\Debug" +# PROP BASE Intermediate_Dir "netsvcs\Debug" +# PROP BASE Target_Dir "netsvcs" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\..\ace" +# PROP Intermediate_Dir "debug" +# PROP Target_Dir "netsvcs" +OUTDIR=.\..\..\ace +INTDIR=.\debug + +ALL : "$(OUTDIR)\netsvcs.dll" + +CLEAN : + -@erase ".\debug\vc40.pdb" + -@erase ".\debug\vc40.idb" + -@erase "..\..\ace\netsvcs.dll" + -@erase ".\debug\Client_Logging_Handler.obj" + -@erase ".\debug\Server_Logging_Handler.obj" + -@erase ".\debug\Token_Handler.obj" + -@erase ".\debug\TS_Server_Handler.obj" + -@erase ".\debug\Name_Handler.obj" + -@erase ".\debug\TS_Clerk_Handler.obj" + -@erase ".\debug\Logging_Strategy.obj" + -@erase "..\..\ace\netsvcs.ilk" + -@erase "..\..\ace\netsvcs.lib" + -@erase "..\..\ace\netsvcs.exp" + -@erase "..\..\ace\netsvcs.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\ + /Fp"$(INTDIR)/netsvcs.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\debug/ +CPP_SBRS= +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/netsvcs.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:windows /dll /debug /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib wsock32.lib /nologo /subsystem:windows /dll /incremental:yes\ + /pdb:"$(OUTDIR)/netsvcs.pdb" /debug /machine:I386 /out:"$(OUTDIR)/netsvcs.dll"\ + /implib:"$(OUTDIR)/netsvcs.lib" +LINK32_OBJS= \ + "$(INTDIR)/Client_Logging_Handler.obj" \ + "$(INTDIR)/Server_Logging_Handler.obj" \ + "$(INTDIR)/Token_Handler.obj" \ + "$(INTDIR)/TS_Server_Handler.obj" \ + "$(INTDIR)/Name_Handler.obj" \ + "$(INTDIR)/TS_Clerk_Handler.obj" \ + "$(INTDIR)/Logging_Strategy.obj" \ + "..\..\ace\ace.lib" + +"$(OUTDIR)\netsvcs.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "netsvcs - Win32 Release" +# Name "netsvcs - Win32 Debug" + +!IF "$(CFG)" == "netsvcs - Win32 Release" + +!ELSEIF "$(CFG)" == "netsvcs - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=\ACE_wrappers\ace\ace.lib + +!IF "$(CFG)" == "netsvcs - Win32 Release" + +!ELSEIF "$(CFG)" == "netsvcs - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Token_Handler.cpp +DEP_CPP_TOKEN=\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Get_Opt.h"\ + {$(INCLUDE)}"\ace\Acceptor.h"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.h"\ + {$(INCLUDE)}"\ace\Token_Request_Reply.h"\ + {$(INCLUDE)}"\ace\Token_Collection.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + ".\Token_Handler.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Get_Opt.i"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Svc_Handler.h"\ + {$(INCLUDE)}"\ace\Strategies.h"\ + {$(INCLUDE)}"\ace\Acceptor.i"\ + {$(INCLUDE)}"\ace\Acceptor.cpp"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Task.h"\ + {$(INCLUDE)}"\ace\Svc_Handler.i"\ + {$(INCLUDE)}"\ace\Svc_Handler.cpp"\ + {$(INCLUDE)}"\ace\Message_Queue.h"\ + {$(INCLUDE)}"\ace\Task.i"\ + {$(INCLUDE)}"\ace\Task.cpp"\ + {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\ + {$(INCLUDE)}"\ace\Message_Queue.i"\ + {$(INCLUDE)}"\ace\Message_Queue.cpp"\ + {$(INCLUDE)}"\ace\Module.h"\ + {$(INCLUDE)}"\ace\Module.i"\ + {$(INCLUDE)}"\ace\Module.cpp"\ + {$(INCLUDE)}"\ace\Stream_Modules.h"\ + {$(INCLUDE)}"\ace\Stream_Modules.i"\ + {$(INCLUDE)}"\ace\Stream_Modules.cpp"\ + {$(INCLUDE)}"\ace\Dynamic.h"\ + {$(INCLUDE)}"\ace\Dynamic.i"\ + {$(INCLUDE)}"\ace\Strategies.cpp"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.i"\ + {$(INCLUDE)}"\ace\Token_Request_Reply.i"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\SString.h"\ + {$(INCLUDE)}"\ace\Token_Collection.i"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\SString.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + +NODEP_CPP_TOKEN=\ + ".\..\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\Token_Handler.obj" : $(SOURCE) $(DEP_CPP_TOKEN) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\TS_Clerk_Handler.cpp +DEP_CPP_TS_CL=\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Connector.h"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Get_Opt.h"\ + {$(INCLUDE)}"\ace\SOCK_Connector.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Svc_Handler.h"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\ace\Time_Request_Reply.h"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + ".\TS_Clerk_Handler.h"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\Strategies.h"\ + {$(INCLUDE)}"\ace\Connector.i"\ + {$(INCLUDE)}"\ace\Connector.cpp"\ + {$(INCLUDE)}"\ace\Strategies.cpp"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\Get_Opt.i"\ + {$(INCLUDE)}"\ace\SOCK_Connector.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\Task.h"\ + {$(INCLUDE)}"\ace\Svc_Handler.i"\ + {$(INCLUDE)}"\ace\Svc_Handler.cpp"\ + {$(INCLUDE)}"\ace\Message_Queue.h"\ + {$(INCLUDE)}"\ace\Task.i"\ + {$(INCLUDE)}"\ace\Task.cpp"\ + {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\ + {$(INCLUDE)}"\ace\Message_Queue.i"\ + {$(INCLUDE)}"\ace\Message_Queue.cpp"\ + {$(INCLUDE)}"\ace\Module.h"\ + {$(INCLUDE)}"\ace\Module.i"\ + {$(INCLUDE)}"\ace\Module.cpp"\ + {$(INCLUDE)}"\ace\Stream_Modules.h"\ + {$(INCLUDE)}"\ace\Stream_Modules.i"\ + {$(INCLUDE)}"\ace\Stream_Modules.cpp"\ + {$(INCLUDE)}"\ace\Dynamic.h"\ + {$(INCLUDE)}"\ace\Dynamic.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\SString.h"\ + {$(INCLUDE)}"\ace\SString.i"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + +NODEP_CPP_TS_CL=\ + ".\..\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\TS_Clerk_Handler.obj" : $(SOURCE) $(DEP_CPP_TS_CL) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\TS_Server_Handler.cpp +DEP_CPP_TS_SE=\ + {$(INCLUDE)}"\ace\SString.h"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Get_Opt.h"\ + {$(INCLUDE)}"\ace\Acceptor.h"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Time_Request_Reply.h"\ + ".\TS_Server_Handler.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\SString.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Get_Opt.i"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Svc_Handler.h"\ + {$(INCLUDE)}"\ace\Strategies.h"\ + {$(INCLUDE)}"\ace\Acceptor.i"\ + {$(INCLUDE)}"\ace\Acceptor.cpp"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Task.h"\ + {$(INCLUDE)}"\ace\Svc_Handler.i"\ + {$(INCLUDE)}"\ace\Svc_Handler.cpp"\ + {$(INCLUDE)}"\ace\Message_Queue.h"\ + {$(INCLUDE)}"\ace\Task.i"\ + {$(INCLUDE)}"\ace\Task.cpp"\ + {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\ + {$(INCLUDE)}"\ace\Message_Queue.i"\ + {$(INCLUDE)}"\ace\Message_Queue.cpp"\ + {$(INCLUDE)}"\ace\Module.h"\ + {$(INCLUDE)}"\ace\Module.i"\ + {$(INCLUDE)}"\ace\Module.cpp"\ + {$(INCLUDE)}"\ace\Stream_Modules.h"\ + {$(INCLUDE)}"\ace\Stream_Modules.i"\ + {$(INCLUDE)}"\ace\Stream_Modules.cpp"\ + {$(INCLUDE)}"\ace\Dynamic.h"\ + {$(INCLUDE)}"\ace\Dynamic.i"\ + {$(INCLUDE)}"\ace\Strategies.cpp"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + +NODEP_CPP_TS_SE=\ + ".\..\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\TS_Server_Handler.obj" : $(SOURCE) $(DEP_CPP_TS_SE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Server_Logging_Handler.cpp +DEP_CPP_SERVE=\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\TLI_Acceptor.h"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.h"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Get_Opt.h"\ + {$(INCLUDE)}"\ace\Acceptor.h"\ + ".\Server_Logging_Handler.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\TLI.h"\ + {$(INCLUDE)}"\ace\TLI_Stream.h"\ + {$(INCLUDE)}"\ace\TLI_Acceptor.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\TLI.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\TLI_Stream.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\Get_Opt.i"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Svc_Handler.h"\ + {$(INCLUDE)}"\ace\Strategies.h"\ + {$(INCLUDE)}"\ace\Acceptor.i"\ + {$(INCLUDE)}"\ace\Acceptor.cpp"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Task.h"\ + {$(INCLUDE)}"\ace\Svc_Handler.i"\ + {$(INCLUDE)}"\ace\Svc_Handler.cpp"\ + {$(INCLUDE)}"\ace\Message_Queue.h"\ + {$(INCLUDE)}"\ace\Task.i"\ + {$(INCLUDE)}"\ace\Task.cpp"\ + {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\ + {$(INCLUDE)}"\ace\Message_Queue.i"\ + {$(INCLUDE)}"\ace\Message_Queue.cpp"\ + {$(INCLUDE)}"\ace\Module.h"\ + {$(INCLUDE)}"\ace\Module.i"\ + {$(INCLUDE)}"\ace\Module.cpp"\ + {$(INCLUDE)}"\ace\Stream_Modules.h"\ + {$(INCLUDE)}"\ace\Stream_Modules.i"\ + {$(INCLUDE)}"\ace\Stream_Modules.cpp"\ + {$(INCLUDE)}"\ace\Dynamic.h"\ + {$(INCLUDE)}"\ace\Dynamic.i"\ + {$(INCLUDE)}"\ace\Strategies.cpp"\ + +NODEP_CPP_SERVE=\ + ".\..\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\Server_Logging_Handler.obj" : $(SOURCE) $(DEP_CPP_SERVE) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Name_Handler.cpp +DEP_CPP_NAME_=\ + {$(INCLUDE)}"\ace\SString.h"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Get_Opt.h"\ + {$(INCLUDE)}"\ace\Naming_Context.h"\ + {$(INCLUDE)}"\ace\Acceptor.h"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Name_Request_Reply.h"\ + ".\Name_Handler.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\SString.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Get_Opt.i"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Name_Proxy.h"\ + {$(INCLUDE)}"\ace\Name_Space.h"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Connector.h"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\SOCK_Connector.i"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\Svc_Handler.h"\ + {$(INCLUDE)}"\ace\Strategies.h"\ + {$(INCLUDE)}"\ace\Acceptor.i"\ + {$(INCLUDE)}"\ace\Acceptor.cpp"\ + {$(INCLUDE)}"\ace\Task.h"\ + {$(INCLUDE)}"\ace\Svc_Handler.i"\ + {$(INCLUDE)}"\ace\Svc_Handler.cpp"\ + {$(INCLUDE)}"\ace\Message_Queue.h"\ + {$(INCLUDE)}"\ace\Task.i"\ + {$(INCLUDE)}"\ace\Task.cpp"\ + {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\ + {$(INCLUDE)}"\ace\Message_Queue.i"\ + {$(INCLUDE)}"\ace\Message_Queue.cpp"\ + {$(INCLUDE)}"\ace\Module.h"\ + {$(INCLUDE)}"\ace\Module.i"\ + {$(INCLUDE)}"\ace\Module.cpp"\ + {$(INCLUDE)}"\ace\Stream_Modules.h"\ + {$(INCLUDE)}"\ace\Stream_Modules.i"\ + {$(INCLUDE)}"\ace\Stream_Modules.cpp"\ + {$(INCLUDE)}"\ace\Dynamic.h"\ + {$(INCLUDE)}"\ace\Dynamic.i"\ + {$(INCLUDE)}"\ace\Strategies.cpp"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + +NODEP_CPP_NAME_=\ + ".\..\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\Name_Handler.obj" : $(SOURCE) $(DEP_CPP_NAME_) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Client_Logging_Handler.cpp +DEP_CPP_CLIEN=\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Connector.h"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Get_Opt.h"\ + {$(INCLUDE)}"\ace\SOCK_Connector.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\FIFO_Recv_Msg.h"\ + ".\Client_Logging_Handler.h"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\Svc_Handler.h"\ + {$(INCLUDE)}"\ace\Strategies.h"\ + {$(INCLUDE)}"\ace\Connector.i"\ + {$(INCLUDE)}"\ace\Connector.cpp"\ + {$(INCLUDE)}"\ace\Task.h"\ + {$(INCLUDE)}"\ace\Svc_Handler.i"\ + {$(INCLUDE)}"\ace\Svc_Handler.cpp"\ + {$(INCLUDE)}"\ace\Message_Queue.h"\ + {$(INCLUDE)}"\ace\Task.i"\ + {$(INCLUDE)}"\ace\Task.cpp"\ + {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\ + {$(INCLUDE)}"\ace\Message_Queue.i"\ + {$(INCLUDE)}"\ace\Message_Queue.cpp"\ + {$(INCLUDE)}"\ace\Module.h"\ + {$(INCLUDE)}"\ace\Module.i"\ + {$(INCLUDE)}"\ace\Module.cpp"\ + {$(INCLUDE)}"\ace\Stream_Modules.h"\ + {$(INCLUDE)}"\ace\Stream_Modules.i"\ + {$(INCLUDE)}"\ace\Stream_Modules.cpp"\ + {$(INCLUDE)}"\ace\Dynamic.h"\ + {$(INCLUDE)}"\ace\Dynamic.i"\ + {$(INCLUDE)}"\ace\Strategies.cpp"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\Get_Opt.i"\ + {$(INCLUDE)}"\ace\SOCK_Connector.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\FIFO_Recv.h"\ + {$(INCLUDE)}"\ace\FIFO_Recv_Msg.i"\ + {$(INCLUDE)}"\ace\FIFO.h"\ + {$(INCLUDE)}"\ace\FIFO_Recv.i"\ + {$(INCLUDE)}"\ace\FIFO.i"\ + +NODEP_CPP_CLIEN=\ + ".\..\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\Client_Logging_Handler.obj" : $(SOURCE) $(DEP_CPP_CLIEN) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\Logging_Strategy.cpp +DEP_CPP_LOGGI=\ + {$(INCLUDE)}"\ace\Get_Opt.h"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + ".\Logging_Strategy.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Get_Opt.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + + +"$(INTDIR)\Logging_Strategy.obj" : $(SOURCE) $(DEP_CPP_LOGGI) "$(INTDIR)" + + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/netsvcs/lib/netsvcs.mdp b/netsvcs/lib/netsvcs.mdp new file mode 100644 index 00000000000..84178cff993 Binary files /dev/null and b/netsvcs/lib/netsvcs.mdp differ diff --git a/netsvcs/servers/Makefile b/netsvcs/servers/Makefile new file mode 100644 index 00000000000..1c9e0d1dc9f --- /dev/null +++ b/netsvcs/servers/Makefile @@ -0,0 +1,51 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = main + +FILES = main + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +LDLIBS = -lnet_svcs + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +CPPFLAGS += -I$(WRAPPER_ROOT)/netsvcs/lib + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + + + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/servers/README b/netsvcs/servers/README new file mode 100644 index 00000000000..d5dee4ff601 --- /dev/null +++ b/netsvcs/servers/README @@ -0,0 +1,29 @@ +This directory contains the driver program that links the various +services together, either statically or dynamically, to form complete +server programs. + +You can configure the following ACE network services into the driver +program by changing how the svc.conf file is setup: + + . Logger -- Controls the output of all services that are + invoked along with the Logger service. Please see the README + file in /netsvcs/lib for details on how to control the output. + + . [Thr_]Server_Logging_Handler.* -- Implements server portion + of the ACE distributed logging service. Both multi-threaded + and single-threaded implementations are provided. + + . Client_Logging_Handler.* -- Implements the client portion + of the ACE distributed logging service. + + . Name_Handler.* -- Implements a distributed name service that + allows applications to bind, find, and unbind names in + a distributed system. + + . Token_Handler.* -- Implements a distributed token service + that allows distributed applications to acquire and release + locks in a distributed system. + + . Time_Handler.* -- Implements a distributed time service that + allows distributed applications to synchronize their + time. diff --git a/netsvcs/servers/cli.conf b/netsvcs/servers/cli.conf new file mode 100644 index 00000000000..875e445f813 --- /dev/null +++ b/netsvcs/servers/cli.conf @@ -0,0 +1,11 @@ +# UNIX version +# +# These are the services that can be linked into ACE. +# Note that you can replace the hardcoded "../lib/libnet_svcs.so" with +# a relative path if you set your LD search path correctly -- ACE will +# locate this for you automatically by reading your LD search path! +# In addition, you can replace the hardcoded "-p 20xxx" with "-p +# $PORTxxx" if you set your environment variables correctly. + +# Activate the Client Logging Daemon. +dynamic Client_Logging_Service Service_Object * ../lib/libnet_svcs.so:_make_ACE_Client_Logging_Connector() active "-p 20009 -h merengue" diff --git a/netsvcs/servers/main.cpp b/netsvcs/servers/main.cpp new file mode 100644 index 00000000000..acfb491c7df --- /dev/null +++ b/netsvcs/servers/main.cpp @@ -0,0 +1,77 @@ +#include "ace/Service_Config.h" +// @(#)main.cpp 1.1 10/18/96 + +#include "TS_Clerk_Handler.h" +#include "TS_Server_Handler.h" +#include "Client_Logging_Handler.h" +#include "Name_Handler.h" +#include "Token_Handler.h" +#include "Server_Logging_Handler.h" +#include "Logging_Strategy.h" + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config daemon; + + // Try to link in the svc.conf entries dynamically. + if (daemon.open (argc, argv) == -1) + { + if (errno != ENOENT) + ACE_ERROR ((LM_ERROR, "%p\n%a", "open", 1)); + else // Use static binding. + { + char *l_argv[3]; + ACE_Service_Object *so; + + l_argv[0] = "-p " ACE_DEFAULT_NAME_SERVER_PORT_STR; + l_argv[1] = 0; + so = ACE_SVC_INVOKE (ACE_Name_Acceptor); + + if (so->init (1, l_argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "Name_Service", 1)); + + l_argv[0] = "-p " ACE_DEFAULT_TIME_SERVER_PORT_STR; + l_argv[1] = 0; + so = ACE_SVC_INVOKE (ACE_TS_Server_Acceptor); + + if (so->init (2, l_argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "ACE_TS_Server_Acceptor", 1)); + + l_argv[0] = argv[0]; + l_argv[1] = "-p 10011"; + so = ACE_SVC_INVOKE (ACE_TS_Clerk_Processor); + + if (so->init (2, l_argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "ACE_TS_Clerk_Processor", 1)); + + l_argv[0] = "-p " ACE_DEFAULT_TOKEN_SERVER_PORT_STR; + l_argv[1] = 0; + so = ACE_SVC_INVOKE (ACE_Token_Acceptor); + + if (so->init (1, l_argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "Token_Service", 1)); + + l_argv[0] = "-p " ACE_DEFAULT_LOGGING_SERVER_PORT_STR; + l_argv[1] = 0; + so = ACE_SVC_INVOKE (ACE_Server_Logging_Acceptor); + + if (so->init (1, l_argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "Logging_Service", 1)); + + l_argv[0] = "-p " ACE_DEFAULT_THR_LOGGING_SERVER_PORT_STR; + l_argv[1] = 0; + so = ACE_SVC_INVOKE (ACE_Thr_Server_Logging_Acceptor); + + if (so->init (1, l_argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "Thr_Logging_Service", 1)); + } + } + + // Run forever, performing the configured services until we are shut + // down by a SIGINT/SIGQUIT signal. + + daemon.run_reactor_event_loop (); + + return 0; +} diff --git a/netsvcs/servers/ntsvc.conf b/netsvcs/servers/ntsvc.conf new file mode 100644 index 00000000000..94ed5d78c2a --- /dev/null +++ b/netsvcs/servers/ntsvc.conf @@ -0,0 +1,12 @@ +# Windows NT version. +# +# These are the services that can be linked into ACE. +# Note that your path needs to include the path for netsvcs.dll +# In addition, you can replace the hardcoded "-p 20xxx" with "-p +# $PORTxxx" if you set your environment variables correctly. + +dynamic Token_Service Service_Object * netsvcs.dll:_make_ACE_Token_Acceptor() "-p 20202" +dynamic Name_Server Service_Object * netsvcs.dll:_make_ACE_Name_Acceptor() "-p 20012" +#dynamic Client_Logging_Service Service_Object * netsvcs.dll:_make_ACE_Client_Logging_Connector() active "-p 20008" +#dynamic Server_Logging_Service Service_Object * netsvcs.dll:_make_ACE_Server_Logging_Acceptor() active "-p 20009" +#dynamic Thr_Server_Logging_Service Service_Object * netsvcs.dll:_make_ACE_Thr_Server_Logging_Acceptor() active "-p 20020" diff --git a/netsvcs/servers/servers.mak b/netsvcs/servers/servers.mak new file mode 100644 index 00000000000..b88c04c4b51 --- /dev/null +++ b/netsvcs/servers/servers.mak @@ -0,0 +1,402 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +!IF "$(CFG)" == "" +CFG=servers - Win32 Debug +!MESSAGE No configuration specified. Defaulting to servers - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "servers - Win32 Release" && "$(CFG)" !=\ + "servers - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "servers.mak" CFG="servers - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "servers - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "servers - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "servers - Win32 Debug" +RSC=rc.exe +CPP=cl.exe + +!IF "$(CFG)" == "servers - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +OUTDIR=.\Release +INTDIR=.\Release + +ALL : "$(OUTDIR)\servers.exe" + +CLEAN : + -@erase ".\Release\servers.exe" + -@erase ".\Release\main.obj" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\ + /Fp"$(INTDIR)/servers.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/servers.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo\ + /subsystem:console /incremental:no /pdb:"$(OUTDIR)/servers.pdb" /machine:I386\ + /out:"$(OUTDIR)/servers.exe" +LINK32_OBJS= \ + "$(INTDIR)/main.obj" + +"$(OUTDIR)\servers.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "servers - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "debug" +# PROP Target_Dir "" +OUTDIR=. +INTDIR=.\debug + +ALL : "$(OUTDIR)\main.exe" + +CLEAN : + -@erase ".\debug\vc40.pdb" + -@erase ".\debug\vc40.idb" + -@erase ".\main.exe" + -@erase ".\debug\main.obj" + -@erase ".\main.ilk" + -@erase ".\main.pdb" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\lib" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\lib" /D "WIN32" /D "_DEBUG" /D\ + "_CONSOLE" /Fp"$(INTDIR)/servers.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/servers.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ace.lib netsvcs.lib /nologo /subsystem:console /debug /machine:I386 /out:"main.exe" +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ace.lib netsvcs.lib\ + /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)/main.pdb" /debug\ + /machine:I386 /out:"$(OUTDIR)/main.exe" +LINK32_OBJS= \ + "$(INTDIR)/main.obj" + +"$(OUTDIR)\main.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "servers - Win32 Release" +# Name "servers - Win32 Debug" + +!IF "$(CFG)" == "servers - Win32 Release" + +!ELSEIF "$(CFG)" == "servers - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\main.cpp + +!IF "$(CFG)" == "servers - Win32 Release" + +DEP_CPP_MAIN_=\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\msg_hack.h"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + +NODEP_CPP_MAIN_=\ + ".\TS_Clerk_Handler.h"\ + ".\TS_Server_Handler.h"\ + ".\Client_Logging_Handler.h"\ + ".\Name_Handler.h"\ + ".\Token_Handler.h"\ + ".\Server_Logging_Handler.h"\ + ".\Logger.h"\ + ".\..\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\main.obj" : $(SOURCE) $(DEP_CPP_MAIN_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "servers - Win32 Debug" + +DEP_CPP_MAIN_=\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + ".\..\lib\TS_Clerk_Handler.h"\ + ".\..\lib\TS_Server_Handler.h"\ + ".\..\lib\Client_Logging_Handler.h"\ + ".\..\lib\Name_Handler.h"\ + ".\..\lib\Token_Handler.h"\ + ".\..\lib\Server_Logging_Handler.h"\ + ".\..\lib\Logger.h"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\msg_hack.h"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + +NODEP_CPP_MAIN_=\ + ".\..\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\main.obj" : $(SOURCE) $(DEP_CPP_MAIN_) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/netsvcs/servers/servers.mdp b/netsvcs/servers/servers.mdp new file mode 100644 index 00000000000..5304247a52d Binary files /dev/null and b/netsvcs/servers/servers.mdp differ diff --git a/netsvcs/servers/svc.conf b/netsvcs/servers/svc.conf new file mode 100644 index 00000000000..8fdb837b6aa --- /dev/null +++ b/netsvcs/servers/svc.conf @@ -0,0 +1,15 @@ +# These are the services that can be linked into ACE. +# Note that you can replace the hardcoded "../lib/libnet_svcs.so" with +# a relative path if you set your LD search path correctly -- ACE will +# locate this for you automatically by reading your LD search path! +# In addition, you can replace the hardcoded "-p 20xxx" with "-p +# $PORTxxx" if you set your environment variables correctly. + +dynamic Logger Service_Object * ../lib/libnet_svcs.so:_make_ACE_Logger() "-s foobar -f STDERR|OSTREAM" +dynamic Time_Service Service_Object * ../lib/libnet_svcs.so:_make_ACE_TS_Server_Acceptor() "-p 10222" +dynamic Name_Server Service_Object * ../lib/libnet_svcs.so:_make_ACE_Name_Acceptor() "-p 10012" +dynamic Token_Service Service_Object * ../lib/libnet_svcs.so:_make_ACE_Token_Acceptor() "-p 10202" +dynamic Server_Logging_Service Service_Object * ../lib/libnet_svcs.so:_make_ACE_Server_Logging_Acceptor() active "-p 10009" +dynamic Thr_Server_Logging_Service Service_Object * ../lib/libnet_svcs.so:_make_ACE_Thr_Server_Logging_Acceptor() active "-p 10020" +dynamic Client_Logging_Service Service_Object * ../lib/libnet_svcs.so:_make_ACE_Client_Logging_Connector() active "-p 10009" + diff --git a/performance-tests/Makefile b/performance-tests/Makefile new file mode 100644 index 00000000000..93e83f2ee1f --- /dev/null +++ b/performance-tests/Makefile @@ -0,0 +1,30 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the performance-tests directory +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +INFO = README + +DIRS = Synch-Benchmarks \ + Misc + +# The following directory isn't compiled by default since haven't +# finished integrating it into ACE... +# +# TTCP + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + diff --git a/performance-tests/Misc/Makefile b/performance-tests/Misc/Makefile new file mode 100644 index 00000000000..9600b1e4c37 --- /dev/null +++ b/performance-tests/Misc/Makefile @@ -0,0 +1,146 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for tests of the miscellaneous ACE performance tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = test_mutex \ + test_singleton \ + test_naming + +LSRC = $(addsuffix .cpp,$(BIN)) +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +LIBS += -lm +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/test_mutex.o .shobj/test_mutex.so: test_mutex.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h +.obj/test_singleton.o .shobj/test_singleton.so: test_singleton.cpp \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Singleton.h \ + $(WRAPPER_ROOT)/ace/Singleton.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Singleton.i +.obj/test_naming.o .shobj/test_naming.so: test_naming.cpp \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Naming_Context.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Name_Proxy.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Name_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Name_Space.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/performance-tests/Misc/test_mutex.cpp b/performance-tests/Misc/test_mutex.cpp new file mode 100644 index 00000000000..fe6854916e2 --- /dev/null +++ b/performance-tests/Misc/test_mutex.cpp @@ -0,0 +1,230 @@ +// This test program illustrates the performance difference between +// @(#)test_mutex.cpp 1.1 10/18/96 + +// three versions of wrappers for thread mutexes. These three +// versions exercise various combinations of the following classes: +// +// Thread_Mutex -- +// This version is just like ACE_Thread_Mutex, which doesn't use +// inheritance and dynamic binding. +// +// Mutex_Base -- +// This is an abstract base class that defines the +// acquire()/release() interface. +// +// Thread_Mutex_Derived -- +// This derived from Mutex_Base and uses inheritance and +// dynamic binding. +// +// The following are the results I got when running this on our +// SPARCstation 20 model 712: +// +// ./test_mutex 1000000 +// iterations = 1000000 +// Thread_Mutex +// real time = 1.727843 secs, user time = 1.729262 secs, system time = 0.000325 secs +// time per call = 1.747843 usecs +// Thread_Mutex_Derived +// real time = 1.730225 secs, user time = 1.724744 secs, system time = 0.000096 secs +// time per call = 1.730225 usecs +// Mutex_Base +// real time = 2.112831 secs, user time = 2.104245 secs, system time = 0.000095 secs +// time per call = 2.112831 usecs +// +// My conclusions are as follows: +// +// 1. If your C++ compiler optimizes calls to virtual functions that +// are made through instances of derived classes, then the +// performance of the Thread_Mutex and Thread_Mutex_Derived are +// essentially identical. +// +// 2. The overhead from using virtual functions is approximately +// 20%. Naturally, as the amount of contention goes up, the +// relative overhead of the virtual function calls will decrease. +// +// Keep in mind, however, that using virtual functions to implement +// the Thread_Mutex will make it infeasible to put instances of +// Thread_Mutex into shared memory since the vptrs won't point to the +// correct vtables... + +#include "ace/Log_Msg.h" +#include "ace/Profile_Timer.h" +#include "ace/OS.h" + +#if defined (ACE_HAS_THREADS) + +static const int DEFAULT_ITERATIONS = 100000000; + +// A thread mutex that doesn't use virtual functions. +class Thread_Mutex +{ +public: + Thread_Mutex (void); + ~Thread_Mutex (void); + int acquire (void); + int release (void); + +private: + ACE_mutex_t mutex_; +}; + +Thread_Mutex::Thread_Mutex (void) +{ + ACE_OS::mutex_init (&this->mutex_); +} + +Thread_Mutex::~Thread_Mutex (void) +{ + ACE_OS::mutex_destroy (&this->mutex_); +} + +inline int +Thread_Mutex::acquire (void) +{ + return ACE_OS::mutex_lock (&this->mutex_); +} + +inline int +Thread_Mutex::release (void) +{ + return ACE_OS::mutex_unlock (&this->mutex_); +} + +// Base class for mutex, declares pure virtual functions. +class Mutex_Base +{ +public: + virtual int acquire (void) = 0; + virtual int release (void) = 0; +}; + +// Subclass for threaded mutex, defines virtual functions. +class Thread_Mutex_Derived : public Mutex_Base +{ +public: + Thread_Mutex_Derived (void); + ~Thread_Mutex_Derived (void); + virtual int acquire (void); + virtual int release (void); + +private: + ACE_mutex_t mutex_; +}; + +Thread_Mutex_Derived::Thread_Mutex_Derived (void) +{ + ACE_OS::mutex_init (&this->mutex_); +} + +Thread_Mutex_Derived::~Thread_Mutex_Derived (void) +{ + ACE_OS::mutex_destroy (&this->mutex_); +} + +inline int +Thread_Mutex_Derived::acquire (void) +{ + return ACE_OS::mutex_lock (&this->mutex_); +} + +inline int +Thread_Mutex_Derived::release (void) +{ + return ACE_OS::mutex_unlock (&this->mutex_); +} + +static Thread_Mutex thread_mutex; +static Thread_Mutex_Derived thread_mutex_derived; +static Mutex_Base *mutex_base = &thread_mutex_derived; + +int +main (int argc, char *argv[]) +{ + ACE_Profile_Timer timer; + int iterations = argc > 1 ? ACE_OS::atoi (argv[1]) : DEFAULT_ITERATIONS; + int i; + + ACE_DEBUG ((LM_DEBUG, "iterations = %d\n", iterations)); + + timer.start (); + + // Test the thread mutex (which doesn't use inheritance or dynamic + // binding). + + for (i = 0; i < iterations; i++) + { + thread_mutex.acquire (); + thread_mutex.release (); + } + + timer.stop (); + + ACE_Profile_Timer::ACE_Elapsed_Time et; + + timer.elapsed_time (et); + + ACE_DEBUG ((LM_DEBUG, "Thread_Mutex\n")); + ACE_DEBUG ((LM_DEBUG, "real time = %f secs, user time = %f secs, system time = %f secs\n", + et.real_time, et.user_time, et.system_time)); + + ACE_DEBUG ((LM_DEBUG, "time per call = %f usecs\n", + (et.real_time / double (iterations)) * 1000000)); + + // Test the thread mutex derived (which does use inheritance or + // dynamic binding). Note that we call this via an instance of the + // derived class, so good C++ compilers should optimize the virtual + // function calls in this case. + + timer.start (); + + for (i = 0; i < iterations; i++) + { + thread_mutex_derived.acquire (); + thread_mutex_derived.release (); + } + + timer.stop (); + + timer.elapsed_time (et); + + ACE_DEBUG ((LM_DEBUG, "Thread_Mutex_Derived\n")); + ACE_DEBUG ((LM_DEBUG, "real time = %f secs, user time = %f secs, system time = %f secs\n", + et.real_time, et.user_time, et.system_time)); + + ACE_DEBUG ((LM_DEBUG, "time per call = %f usecs\n", + (et.real_time / double (iterations)) * 1000000)); + + // Test the thread mutex derived (which does use inheritance or + // dynamic binding). Note that we call this via a pointer to the + // base class, which points to an instance of the derived class. + // Thus, C++ compilers won't be able to optimize the virtual + // function calls in this case. + + timer.start (); + + for (i = 0; i < iterations; i++) + { + mutex_base->acquire (); + mutex_base->release (); + } + + timer.stop (); + + timer.elapsed_time (et); + + ACE_DEBUG ((LM_DEBUG, "Mutex_Base\n")); + ACE_DEBUG ((LM_DEBUG, "real time = %f secs, user time = %f secs, system time = %f secs\n", + et.real_time, et.user_time, et.system_time)); + + ACE_DEBUG ((LM_DEBUG, "time per call = %f usecs\n", + (et.real_time / double (iterations)) * 1000000)); + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/performance-tests/Misc/test_naming.cpp b/performance-tests/Misc/test_naming.cpp new file mode 100644 index 00000000000..851e9bfe9df --- /dev/null +++ b/performance-tests/Misc/test_naming.cpp @@ -0,0 +1,169 @@ +// ============================================================================ +// @(#)test_naming.cpp 1.1 10/18/96 + +// +// = LIBRARY +// performance_tests +// +// = FILENAME +// test_naming.cpp +// +// = DESCRIPTION +// This is an example to do performance testing of the Naming Service +// using both the normal Memory Pool as well as the light Memory Pool. +// +// = AUTHOR +// Prashant Jain +// +// ============================================================================ + +#include "ace/SString.h" +#include "ace/Naming_Context.h" +#include "ace/Profile_Timer.h" +#define ACE_NS_MAX_ENTRIES 4000 + +static char name[BUFSIZ]; +static char value[BUFSIZ]; +static char type[BUFSIZ]; + +void +bind (ACE_Naming_Context *ns_context, int result) +{ + // do the binds + for (int i = 1; i <= ACE_NS_MAX_ENTRIES; i++) + { + if (i % 50 == 0) + ACE_DEBUG ((LM_DEBUG, ".")); + sprintf (name, "%s%d", "name", i); + ACE_WString w_name (name); + + sprintf (value, "%s%d", "value", i); + ACE_WString w_value (value); + + sprintf (type, "%s%d", "type", i); + ACE_ASSERT (ns_context->bind (w_name, w_value, type) == result); + } + ACE_DEBUG ((LM_DEBUG, "\n")); +} + +void +rebind (ACE_Naming_Context *ns_context, int result) +{ + // do the rebinds + for (int i = 1; i <= ACE_NS_MAX_ENTRIES; i++) + { + sprintf (name, "%s%d", "name", i); + ACE_WString w_name (name); + sprintf (value, "%s%d", "value", -i); + ACE_WString w_value (value); + sprintf (type, "%s%d", "type", -i); + ACE_ASSERT (ns_context->rebind (w_name, w_value, type) == result); + } +} + +void +unbind (ACE_Naming_Context *ns_context, int result) +{ + // do the unbinds + for (int i = 1; i <= ACE_NS_MAX_ENTRIES; i++) + { + sprintf (name, "%s%d", "name", i); + ACE_WString w_name (name); + ACE_ASSERT (ns_context->unbind (w_name) == result); + } +} + +void +find (ACE_Naming_Context *ns_context, int sign, int result) +{ + char temp_val[BUFSIZ]; + char temp_type[BUFSIZ]; + + // do the finds + for (int i = 1; i <= ACE_NS_MAX_ENTRIES; i++) + { + sprintf (name, "%s%d", "name", i); + ACE_WString w_name (name); + + ACE_WString w_value; + char *type_out; + + if (sign == 1) + { + sprintf (temp_val, "%s%d", "value", i); + sprintf (temp_type, "%s%d", "type", i); + } + else + { + sprintf (temp_val, "%s%d", "value", -i); + sprintf (temp_type, "%s%d", "type", -i); + } + + ACE_WString val (temp_val); + + ACE_ASSERT (ns_context->resolve (w_name, w_value, type_out) == result); + if (w_value.char_rep ()) + { + ACE_ASSERT (w_value == val); + cerr << "Name: " << name << "\tValue: " << w_value.char_rep () << "\tType: " << type_out << endl; + if (type_out) + { + ACE_ASSERT (::strcmp (type_out, temp_type) == 0); + delete[] type_out; + } + } + } +} + +void do_testing (int argc, char *argv[], int light) +{ + ACE_Profile_Timer timer; + + ACE_Naming_Context ns_context; + ACE_Name_Options *name_options = ns_context.name_options (); + name_options->parse_args (argc, argv); + + if (light == 0) // Use SYNC + { + name_options->database (ACE::basename (name_options->process_name (), + ACE_DIRECTORY_SEPARATOR_CHAR)); + ns_context.open (ACE_Naming_Context::PROC_LOCAL); + } + else // Use NO-SYNC + { + name_options->database (ACE_OS::strcat ("light", ACE::basename (name_options->process_name (), + ACE_DIRECTORY_SEPARATOR_CHAR))); + ns_context.open (ACE_Naming_Context::PROC_LOCAL, 1); + } + + // Add bindings to the database + ACE_DEBUG ((LM_DEBUG, "Binding\n")); + + timer.start (); + bind (&ns_context, 0); + + ACE_DEBUG ((LM_DEBUG, "Unbinding\n")); + unbind (&ns_context, 0); + timer.stop (); + + ACE_Profile_Timer::ACE_Elapsed_Time et; + + timer.elapsed_time (et); + ACE_DEBUG ((LM_DEBUG, "real time = %f secs, user time = %f secs, system time = %f secs\n", + et.real_time, et.user_time, et.system_time)); +} + +int +main (int argc, char *argv[]) +{ + // Do testing with SYNC on + ACE_DEBUG ((LM_DEBUG, "SYNC is ON\n")); + do_testing (argc, argv, 0); + + // Do testing with SYNC off + ACE_DEBUG ((LM_DEBUG, "SYNC is OFF\n")); + do_testing (argc, argv, 1); + + return 0; +} + diff --git a/performance-tests/Misc/test_singleton.cpp b/performance-tests/Misc/test_singleton.cpp new file mode 100644 index 00000000000..ce71ef5da74 --- /dev/null +++ b/performance-tests/Misc/test_singleton.cpp @@ -0,0 +1,183 @@ +// This example illustrates the performance impact of using the +// @(#)test_singleton.cpp 1.1 10/18/96 + +// Double-Checked Locking pattern compared with using the "standard" +// practice of acquiring and releasing a lock on every instance() +// call. In addition, we compare the performance of using the +// ACE_Singleton (which encapsulates the Double-Check Locking pattern) +// vs. hand-coding the pattern. +// +// Here's the output from running this test on our SPARCstation 20, model 712s. +// +// ./test_singleton 1000000 +// iterations = 1000000 +// ACE_Singleton +// real time = 0.193731 secs, user time = 0.190416 secs, system time = 0.000549 secs +// time per call = 0.193731 usecs +// DC_Singleton +// real time = 0.176208 secs, user time = 0.176045 secs, system time = 0.000092 secs +// time per call = 0.176208 usecs +// Mutex_Singleton +// real time = 3.160998 secs, user time = 3.121434 secs, system time = 0.000109 secs +// time per call = 3.160998 usecs +// +// As you can see, both Double-Checked Locking implementations are about +// 15 times faster than the standard mutex version. Moreover, +// this test is run with only a single thread, so there's no contention +// for the lock. If there were multiple threads contending for the lock, +// the Mutex_Singleton performance would get increasing worse... + +#include "ace/Profile_Timer.h" +#include "ace/Singleton.h" +#include "ace/Synch.h" +#include "ace/Log_Msg.h" + +#if defined (ACE_HAS_THREADS) + +static const int DEFAULT_ITERATIONS = 100000000; + +class Mutex_Singleton +{ +public: + Mutex_Singleton (void) {} + void svc (void) {} + static Mutex_Singleton *instance (void); + +private: + static ACE_Thread_Mutex lock_; + static Mutex_Singleton *instance_; +}; + +ACE_Thread_Mutex Mutex_Singleton::lock_; + +Mutex_Singleton *Mutex_Singleton::instance_; + +Mutex_Singleton * +Mutex_Singleton::instance (void) +{ + // Acquire the lock every time in. + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, Mutex_Singleton::lock_, 0); + + if (Mutex_Singleton::instance_ == 0) + ACE_NEW_RETURN (Mutex_Singleton::instance_, Mutex_Singleton, 0); + + return Mutex_Singleton::instance_; +} + +class DC_Singleton +{ +public: + DC_Singleton (void) {} + void svc (void) {} + static DC_Singleton *instance (void); + +private: + static ACE_Thread_Mutex lock_; + static DC_Singleton *instance_; +}; + +ACE_Thread_Mutex DC_Singleton::lock_; + +DC_Singleton *DC_Singleton::instance_; + +DC_Singleton * +DC_Singleton::instance (void) +{ + if (DC_Singleton::instance_ == 0) + { + // Only lock if instance_ isn't 0. + ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, DC_Singleton::lock_, 0); + + // Perform the Double-Check. + if (DC_Singleton::instance_ == 0) + ACE_NEW_RETURN (DC_Singleton::instance_, DC_Singleton, 0); + } + + return DC_Singleton::instance_; +} + +typedef ACE_Singleton My_Singleton; + +int +main (int argc, char *argv[]) +{ + ACE_Profile_Timer timer; + int iterations = argc > 1 ? ACE_OS::atoi (argv[1]) : DEFAULT_ITERATIONS; + int i; + + ACE_DEBUG ((LM_DEBUG, "iterations = %d\n", iterations)); + + // Test the ACE_Singleton performance (which uses Double-Checked + // Locking). + + timer.start (); + + for (i = 0; i < iterations; i++) + My_Singleton::instance ()->svc (); + + timer.stop (); + + ACE_Profile_Timer::ACE_Elapsed_Time et; + + timer.elapsed_time (et); + + ACE_DEBUG ((LM_DEBUG, "ACE_Singleton\n")); + ACE_DEBUG ((LM_DEBUG, "real time = %f secs, user time = %f secs, system time = %f secs\n", + et.real_time, et.user_time, et.system_time)); + + ACE_DEBUG ((LM_DEBUG, "time per call = %f usecs\n", + (et.real_time / double (iterations)) * 1000000)); + + // Test the hand-coded Singleton performance (which uses + // Double-Checked Locking). + + timer.start (); + + for (i = 0; i < iterations; i++) + DC_Singleton::instance ()->svc (); + + timer.stop (); + + timer.elapsed_time (et); + + ACE_DEBUG ((LM_DEBUG, "DC_Singleton\n")); + ACE_DEBUG ((LM_DEBUG, "real time = %f secs, user time = %f secs, system time = %f secs\n", + et.real_time, et.user_time, et.system_time)); + + ACE_DEBUG ((LM_DEBUG, "time per call = %f usecs\n", + (et.real_time / double (iterations)) * 1000000)); + + // Test the Mutex_Singleton implementation (which does not use + // Double-Checked Locking). + + timer.start (); + + for (i = 0; i < iterations; i++) + Mutex_Singleton::instance ()->svc (); + + timer.stop (); + + timer.elapsed_time (et); + + ACE_DEBUG ((LM_DEBUG, "Mutex_Singleton\n")); + ACE_DEBUG ((LM_DEBUG, "real time = %f secs, user time = %f secs, system time = %f secs\n", + et.real_time, et.user_time, et.system_time)); + + ACE_DEBUG ((LM_DEBUG, "time per call = %f usecs\n", + (et.real_time / double (iterations)) * 1000000)); + + return 0; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Singleton; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ + +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/performance-tests/Synch-Benchmarks/Benchmark.cpp b/performance-tests/Synch-Benchmarks/Benchmark.cpp new file mode 100644 index 00000000000..44be1b18f0c --- /dev/null +++ b/performance-tests/Synch-Benchmarks/Benchmark.cpp @@ -0,0 +1,95 @@ +#include "Benchmark.h" +// @(#)Benchmark.cpp 1.1 10/18/96 + + +#if defined (ACE_HAS_THREADS) + +// Global variables (used by the dynamically linked services). +int synch_count; +int buffer; + +// Initialize the static variables. +/* static */ +sig_atomic_t Benchmark::done_ = 0; + +sig_atomic_t +Benchmark::done (void) +{ + return Benchmark::done_; +} + +int +Benchmark::thr_id (void) +{ +#if defined (ACE_HAS_PTHREADS) || defined (ACE_HAS_DCETHREADS) + // This invokes the thread-specific storage smart pointer. + return this->id_->thr_id (); +#else + return ACE_Thread::self (); +#endif /* ACE_HAS_PTHREADS */ +} + +void +Benchmark::done (sig_atomic_t d) +{ + Benchmark::done_ = d; +} + +int +Benchmark::svc (void) +{ + return -1; +} + +int +Benchmark::init (int, char **) +{ + return 1; +} + +int +Benchmark::info (char **, size_t) const +{ + return -1; +} + +int +Benchmark::fini (void) +{ + return -1; +} + +void * +Benchmark::svc_run (Benchmark *bp) +{ + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + return (void *) (bp->svc () == -1 ? -1 : 0); +} + +#if defined (ACE_HAS_PTHREADS) +/* static */ +MT_INT Thr_ID::thread_id_ (0); + +Thr_ID::Thr_ID (void) + : thr_id_ (++Thr_ID::thread_id_) +{ +} + +int +Thr_ID::thr_id (void) +{ + return this->thr_id_; +} + +void +Thr_ID::thr_id (int i) +{ + this->thr_id_ = i; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_TSS; +template class ACE_Atomic_Op; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ +#endif /* ACE_HAS_PTHREADS */ +#endif /* ACE_HAS_THREADS */ diff --git a/performance-tests/Synch-Benchmarks/Benchmark.h b/performance-tests/Synch-Benchmarks/Benchmark.h new file mode 100644 index 00000000000..aad12e2bac6 --- /dev/null +++ b/performance-tests/Synch-Benchmarks/Benchmark.h @@ -0,0 +1,73 @@ +/* -*- C++ -*- */ +// @(#)Benchmark.h 1.1 10/18/96 + +/* Defines the class used to dynamically link in the benchmark tests */ + +#if !defined (ACE_BENCHMARK_H) +#define ACE_BENCHMARK_H + +#include "ace/Service_Config.h" +#include "ace/Synch.h" +#include "ace/Service_Record.h" + +#if defined (ACE_HAS_THREADS) + +extern int buffer; +extern int synch_count; + +#if defined (ACE_HAS_PTHREADS) + +typedef ACE_Atomic_Op MT_INT; + +class Thr_ID + // TITLE + // A simple class that provides a thread-specific value in order + // to compensate for POSIX Pthreads. + // + // DESCRIPTION + // Pthreads are too lame to have a sensible scalar values for the + // thread id (unlike Solaris threads). Therefore, we have to + // emulate this ourselves with this class (gag). +{ +public: + Thr_ID (void); + int thr_id (void); + void thr_id (int); + +private: + int thr_id_; + static MT_INT thread_id_; +}; +#endif /* ACE_HAS_PTHREADS */ + +class Benchmark : public ACE_Service_Object + // TITLE + // Base class for all the timing tests. +{ +public: + // = Hooks inherited from ACE_Service_Object. + virtual int svc (void); + virtual int init (int, char *[]); + virtual int info (char **, size_t) const; + virtual int fini (void); + static void *svc_run (Benchmark *bp); + + int thr_id (void); + // Returns our thread id; + + // = Set/get flag that controls how the tests are shut down + // gracefully. + static void done (sig_atomic_t); + static sig_atomic_t done (void); + +protected: + static sig_atomic_t done_; + // Keeps track if we are finished or not. + +#if defined (ACE_HAS_PTHREADS) || defined (ACE_HAS_DCETHREADS) + ACE_TSS id_; + // Keeps track of our "virtual" thread id... +#endif /* ACE_HAS_PTHREADS */ +}; +#endif /* ACE_HAS_THREADS */ +#endif /* ACE_BENCHMARK_H */ diff --git a/performance-tests/Synch-Benchmarks/Makefile b/performance-tests/Synch-Benchmarks/Makefile new file mode 100644 index 00000000000..a258fdaec6f --- /dev/null +++ b/performance-tests/Synch-Benchmarks/Makefile @@ -0,0 +1,1192 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Solaris 2.x synchronization benchmarks +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = synch_driver +LIB = libSynch_Tests.a +SHLIB = libSynch_Tests.so + +FILES = mutex_test \ + recursive_lock_test \ + sema_test \ + sysvsema_test \ + rwrd_test \ + rwwr_test \ + context_test \ + condb_test \ + conds_test \ + memory_test \ + pipe_thr_test \ + pipe_proc_test \ + Options \ + Benchmark + +SRC = $(addsuffix .cpp,$(BIN)) +OBJ = $(SRC:%.cpp=$(VDIR)%.o) + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +LDLIBS = -lSynch_Tests +LIBS += -lACE + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VLIB) $(VSHLIB) $(SHLIBA) $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/mutex_test.o .shobj/mutex_test.so: mutex_test.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i +.obj/recursive_lock_test.o .shobj/recursive_lock_test.so: recursive_lock_test.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i +.obj/sema_test.o .shobj/sema_test.so: sema_test.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i +.obj/sysvsema_test.o .shobj/sysvsema_test.so: sysvsema_test.cpp \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i +.obj/rwrd_test.o .shobj/rwrd_test.so: rwrd_test.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i +.obj/rwwr_test.o .shobj/rwwr_test.so: rwwr_test.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i +.obj/context_test.o .shobj/context_test.so: context_test.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i +.obj/condb_test.o .shobj/condb_test.so: condb_test.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i +.obj/conds_test.o .shobj/conds_test.so: conds_test.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i +.obj/memory_test.o .shobj/memory_test.so: memory_test.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i +.obj/pipe_thr_test.o .shobj/pipe_thr_test.so: pipe_thr_test.cpp \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i +.obj/pipe_proc_test.o .shobj/pipe_proc_test.so: pipe_proc_test.cpp Options.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i +.obj/Options.o .shobj/Options.so: Options.cpp Options.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/Benchmark.o .shobj/Benchmark.so: Benchmark.cpp Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i +.obj/synch_driver.o .shobj/synch_driver.so: synch_driver.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Synch_T.cpp \ + $(WRAPPER_ROOT)/ace/Synch_T.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Set.cpp \ + $(WRAPPER_ROOT)/ace/Set.i \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.cpp \ + $(WRAPPER_ROOT)/ace/Malloc_T.i \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Service_Repository.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.cpp \ + $(WRAPPER_ROOT)/ace/Message_Queue.i \ + $(WRAPPER_ROOT)/ace/Task.cpp \ + $(WRAPPER_ROOT)/ace/Task.i \ + $(WRAPPER_ROOT)/ace/Module.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.h \ + $(WRAPPER_ROOT)/ace/Stream_Modules.cpp \ + $(WRAPPER_ROOT)/ace/Stream_Modules.i \ + $(WRAPPER_ROOT)/ace/Module.i \ + $(WRAPPER_ROOT)/ace/Stream.cpp \ + $(WRAPPER_ROOT)/ace/Stream.i \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/performance-tests/Synch-Benchmarks/Makefile.driver b/performance-tests/Synch-Benchmarks/Makefile.driver new file mode 100644 index 00000000000..5fdb615a944 --- /dev/null +++ b/performance-tests/Synch-Benchmarks/Makefile.driver @@ -0,0 +1,41 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile.driver 1.1 10/18/96 +# +# Makefile for the Solaris 2.x synchronization benchmark driver +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = synch_driver + +FILES = synch_driver + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +LIBS += -lsynch_tests + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- diff --git a/performance-tests/Synch-Benchmarks/Makefile.synch_tests b/performance-tests/Synch-Benchmarks/Makefile.synch_tests new file mode 100644 index 00000000000..011d2206b84 --- /dev/null +++ b/performance-tests/Synch-Benchmarks/Makefile.synch_tests @@ -0,0 +1,948 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile.synch_tests 1.1 10/18/96 +# +# Makefile for the Solaris 2.x synchronization benchmarks +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +LIB = libsynch_tests.a +SHLIB = libsynch_tests.so + +FILES = mutex_test \ + recursive_lock_test \ + sema_test \ + sysvsema_test \ + rwrd_test \ + rwwr_test \ + context_test \ + condb_test \ + conds_test \ + memory_test \ + pipe_thr_test \ + pipe_proc_test \ + Options \ + Benchmark + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +LIBS += -lACE + +BUILD = $(VSHLIB) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/mutex_test.o .shobj/mutex_test.so: mutex_test.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens_T.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h +.obj/recursive_lock_test.o .shobj/recursive_lock_test.so: recursive_lock_test.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens_T.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h +.obj/sema_test.o .shobj/sema_test.so: sema_test.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens_T.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h +.obj/sysvsema_test.o .shobj/sysvsema_test.so: sysvsema_test.cpp \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens_T.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h +.obj/rwrd_test.o .shobj/rwrd_test.so: rwrd_test.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens_T.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h +.obj/rwwr_test.o .shobj/rwwr_test.so: rwwr_test.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens_T.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h +.obj/context_test.o .shobj/context_test.so: context_test.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens_T.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h +.obj/condb_test.o .shobj/condb_test.so: condb_test.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens_T.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h +.obj/conds_test.o .shobj/conds_test.so: conds_test.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens_T.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h +.obj/synch_driver.o .shobj/synch_driver.so: synch_driver.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens_T.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Service_Repository.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + Options.i $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h +.obj/memory_test.o .shobj/memory_test.so: memory_test.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens_T.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h +.obj/pipe_thr_test.o .shobj/pipe_thr_test.so: pipe_thr_test.cpp \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Thread.h Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + Options.i $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens_T.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h +.obj/pipe_proc_test.o .shobj/pipe_proc_test.so: pipe_proc_test.cpp Options.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens_T.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h +.obj/Options.o .shobj/Options.so: Options.cpp Options.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h Options.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h +.obj/Benchmark.o .shobj/Benchmark.so: Benchmark.cpp Benchmark.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens_T.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h +.obj/synch_driver.o .shobj/synch_driver.so: synch_driver.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens_T.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Service_Repository.h \ + $(WRAPPER_ROOT)/ace/Service_Record.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + Options.h \ + $(WRAPPER_ROOT)/ace/Profile_Timer.h \ + Options.i $(WRAPPER_ROOT)/ace/Get_Opt.h \ + Benchmark.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/performance-tests/Synch-Benchmarks/Options.cpp b/performance-tests/Synch-Benchmarks/Options.cpp new file mode 100644 index 00000000000..f43ec27ce95 --- /dev/null +++ b/performance-tests/Synch-Benchmarks/Options.cpp @@ -0,0 +1,391 @@ +#include "Options.h" +// @(#)Options.cpp 1.1 10/18/96 + + +#if defined (ACE_HAS_THREADS) +/* Manages the options */ +Options options; + +size_t +Options::count (void) +{ + size_t total = 0; + + for (size_t i = 0; i < options.thr_wc_size; i++) + { + if (options.thr_work_count[i] != 0) + { + if (options.verbose ()) + ACE_DEBUG ((LM_DEBUG, "count[%d] = %d\n", i, options.thr_work_count[i])); + total += options.thr_work_count[i]; + } + } + + return total; +} + +void +Options::init (void) +{ + for (int i = 0; i < this->thr_wc_size; i++) + this->thr_work_count[i] = 0; +} + +Options::Options (void) + : _debugging (0), + _verbosity (0), + _low_water_mark (1024), + _high_water_mark (8 * 1024), + _msg_size (128), + _thr_count (4), + _generate (0), + _initial_queue_length (0), + _iterations (100000), + _t_flags (0), + _logical_connections (1), + _physical_connections (1), + _ack (1), + thr_wc_size (10000), + _service_entry (0), + _mapped_file (0), + _pipe_addr ("/tmp/pipe"), + _checksum (1), + _xdr (1), + _sleep_time (100), + _n_lwps (0), + _free_memory (1), + _zero_copy (0), + _print_summary (0), + _consecutive_ports (1), + _eager_exit (0), + _udp (0) +{ + this->thr_work_count = new int[this->thr_wc_size]; + this->init (); +} + +void +Options::parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, "a:A:bBc:C:dDe:F:g:H:i:L:l:M:m:n:Np:P:s:S:t:T:uvX:Z:"); + int c; + + while ((c = get_opt ()) != -1) + switch (c) + { + case 'a': + this->_ack = ACE_OS::strcasecmp (get_opt.optarg, "ON") == 0; + break; + case 'A': + this->pipe_addr (get_opt.optarg); + break; + case 'B': + this->t_flags (THR_BOUND); + break; + case 'c': + { + long connections = ACE_OS::atoi (get_opt.optarg); + + if (connections < 0) + this->physical_connections (size_t (-connections)); + else if (connections > 0) + this->logical_connections (size_t (connections)); + else + ACE_DEBUG ((LM_WARNING, "warning, 0 connections!\n")); + + break; + } + case 'C': + this->_checksum = ACE_OS::strcasecmp (get_opt.optarg, "ON") == 0; + break; + case 'd': + this->_debugging = 1; + break; + case 'D': + this->t_flags (THR_DETACHED); + break; + case 'e': + this->_eager_exit = ACE_OS::strcasecmp (get_opt.optarg, "ON") == 0; + break; + case 'F': + this->_free_memory = ACE_OS::strcasecmp (get_opt.optarg, "ON") == 0; + break; + case 'g': + this->_generate = ACE_OS::strcasecmp (get_opt.optarg, "ON") == 0; + break; + case 'H': + this->high_water_mark (ACE_OS::atoi (get_opt.optarg)); + break; + case 'i': + this->iterations (ACE_OS::atoi (get_opt.optarg)); + break; + case 'L': + this->low_water_mark (ACE_OS::atoi (get_opt.optarg)); + break; + case 'l': + this->initial_queue_length (ACE_OS::atoi (get_opt.optarg)); + break; + case 'M': + this->msg_size (ACE_OS::atoi (get_opt.optarg)); + break; + case 'm': + this->mapped_file (get_opt.optarg); + break; + case 'N': + this->t_flags (THR_NEW_LWP); + break; + case 'n': + this->n_lwps (ACE_OS::atoi (get_opt.optarg)); + break; + case 'p': + this->_print_summary = ACE_OS::strcasecmp (get_opt.optarg, "ON") == 0; + break; + case 'P': + this->consecutive_ports (ACE_OS::atoi (get_opt.optarg)); + break; + case 'S': + this->service_entry (get_opt.optarg); + break; + case 's': + this->sleep_time (ACE_OS::atoi (get_opt.optarg)); + break; + case 'T': + if (ACE_OS::strcasecmp (get_opt.optarg, "ON") == 0) + ACE_Trace::start_tracing (); + else if (ACE_OS::strcasecmp (get_opt.optarg, "OFF") == 0) + ACE_Trace::stop_tracing (); + break; + case 't': + this->thr_count (ACE_OS::atoi (get_opt.optarg)); + break; + case 'u': + this->_udp = 1; + break; + case 'v': + this->_verbosity = 1; + break; + case 'X': + this->_xdr = ACE_OS::strcasecmp (get_opt.optarg, "ON") == 0; + break; + case 'Z': + this->_zero_copy = ACE_OS::strcasecmp (get_opt.optarg, "ON") == 0; + break; + default: + ACE_DEBUG ((LM_INFO, + "%s\n" + "\t[-a] (send acknowledgement)\n" + "\t[-A] address of pipe [%s]\n" + "\t[-B] (THR_BOUND)\n" + "\t[-c] + number of logical connections\n" + "\t[-c] - number of physical connections\n" + "\t[-C] (enable checksumming)\n" + "\t[-d] (enable debugging)\n" + "\t[-D] (THR_DETACHED)\n" + "\t[-e] (eager exit)\n" + "\t[-F] (free memory)\n" + "\t[-g] (generate data)\n" + "\t[-H] high water mark\n" + "\t[-i] number of test iterations [%d]\n" + "\t[-L] low water mark\n" + "\t[-m] mapped file\n" + "\t[-M] message size\n" + "\t[-n] number of LWPs\n" + "\t[-N] (THR_NEW_LWP)\n" + "\t[-p] (print benchmark summary)\n" + "\t[-P] number of consecutive ports\n" + "\t[-s] sleep time\n" + "\t[-S] service entry\n" + "\t[-t] number of threads [%d]\n" + "\t[-T] (enable tracing)\n" + "\t[-u] (UDP) \n" + "\t[-v] (verbose) \n" + "\t[-X] (enable xdr conversion)\n" + "\t[-Z] (enable zero-copy driver)\n%a", + argv[0], + this->pipe_addr (), + this->iterations (), + this->thr_count (), + 1)); + /* NOTREACHED */ + break; + } + + if (this->do_print_summary ()) + ACE_DEBUG ((LM_INFO, + "%8d = total iterations\n" + "%8d = logical connections\n" + "%8d = physical connections\n" + "%8d = message_size\n" + "%8d = calculated checksum\n" + "%8d = perform xdr conversion\n" + "%8d = number of LWPs requested\n" + "%8d = number of LWPs used\n", + this->iterations (), + this->logical_connections (), + this->physical_connections (), + this->msg_size (), + this->do_checksum () != 0, + this->do_xdr() != 0, + this->n_lwps (), + ACE_Thread::getconcurrency ())); + else if (this->verbose ()) + ACE_DEBUG ((LM_INFO, + "%8d = total iterations\n" + "%8d = logical connections\n" + "%8d = physical connections\n" + "%8d = thread count\n" + "%8d = low water mark\n" + "%8d = high water mark\n" + "%8d = message_size\n" + "%8d = initial queue length\n" + "%8d = consecutive ports\n" + "%8d = calculated checksum\n" + "%8d = perform xdr conversion\n" + "%8d = zero-copy driver\n" + "%8d = free dynamic memory\n" + "%8d = print summary only\n" + "%8d = eager exit\n" + "%8d = UDP\n" + "%8d = send ack\n" + "%8d = THR_DETACHED\n" + "%8d = THR_BOUND\n" + "%8d = THR_NEW_LWP\n" + "%8d = sleep time\n", + this->iterations (), + this->logical_connections (), + this->physical_connections (), + this->thr_count (), + this->low_water_mark (), + this->high_water_mark (), + this->msg_size (), + this->initial_queue_length (), + this->consecutive_ports (), + this->do_checksum () != 0, + this->do_xdr() != 0, + this->do_zero_copy () != 0, + this->do_delete () != 0, + this->do_print_summary () != 0, + this->do_eager_exit () != 0, + this->do_udp () != 0, + this->do_ack () != 0, + (this->t_flags () & THR_DETACHED) != 0, + (this->t_flags () & THR_BOUND) != 0, + (this->t_flags () & THR_NEW_LWP) != 0, + this->sleep_time ())); +} + +void +Options::print_results (void) +{ + ACE_Profile_Timer::ACE_Elapsed_Time et; + ACE_Profile_Timer::Rusage rusage; + + this->_itimer.elapsed_time (et); + this->_itimer.elapsed_rusage (rusage); + + size_t total = this->count (); + double nbytes = total * this->msg_size (); + double cpu_time = et.user_time + et.system_time; + +#if 0 + mutex_timer.print_total ("ACE_Thread_Mutex overhead:", mutex_counter, 2); + condition_timer.print_total ("ACE_Condition overhead:", condition_counter, 2); + ACE_DEBUG ((LM_INFO, + "%8d (number of ACE_Thread_Mutex operations)\n" + "%8d (number of ACE_Condition operations)", + mutex_counter, condition_counter)); +#endif /* NDEBUG */ + + if (this->do_print_summary ()) + { +#if defined (ACE_HAS_PRUSAGE_T) + ACE_DEBUG ((LM_INFO, + "\n%8d PEs\n" + "%8.2f Mbit/sec\n" + "%8d (voluntary context switches)\n" + "%8d (involuntary context switches)\n" + "%8d (total context switches)\n" + "%8d.%d sec (wait-cpu time)\n" + "%8d.%d sec (user lock wait sleep time)\n" + "%8d.%d sec (all other sleep time)\n" + "%8d (major page faults)\n" + "%8d (minor page faults)\n" + "%8d (number of LWPs)\n", + this->thr_count (), + (nbytes / et.real_time) * 8.0 / 1024.0 / 1024.0, + rusage.pr_vctx, + rusage.pr_ictx, + rusage.pr_vctx + rusage.pr_ictx, + rusage.pr_wtime.tv_sec, rusage.pr_wtime.tv_nsec / 1000000, + rusage.pr_ltime.tv_sec, rusage.pr_ltime.tv_nsec / 1000000, + rusage.pr_slptime.tv_sec, rusage.pr_slptime.tv_nsec / 1000000, + rusage.pr_majf, + rusage.pr_minf, + ACE_Thread::getconcurrency ())); +#else + // need to write dump ops for rusage... +#endif /* ACE_HAS_PRUSAGE_T */ + } + else + { + ACE_DEBUG ((LM_INFO, + "\ntotal work = %d\n" + "(Only interpret the next two statistics for throughput tests)\n" + "%f bytes in %.2f real seconds = %.2f Mbit/sec\n" + "%f bytes in %.2f CPU seconds = %.2f Mbit/sec\n", + total, + nbytes, et.real_time, (nbytes / et.real_time) * 8.0 / 1024.0 / 1024.0, + nbytes, cpu_time, (nbytes / cpu_time) * 8.0 / 1024.0 / 1024.0)); + +#if defined (ACE_HAS_PRUSAGE_T) + ACE_DEBUG ((LM_INFO, + "%8d = lwpid\n" + "%8d = lwp count\n" + "%8d = minor page faults\n" + "%8d = major page faults\n" + "%8d = input blocks\n" + "%8d = output blocks\n" + "%8d = messages sent\n" + "%8d = messages received\n" + "%8d = signals received\n" + "%8ds, %dms = wait-cpu (latency) time\n" + "%8ds, %dms = user lock wait sleep time\n" + "%8ds, %dms = all other sleep time\n" + "%8d = voluntary context switches\n" + "%8d = involuntary context switches\n" + "%8d = total context switches\n" + "%8d = system calls\n" + "%8d = chars read/written\n" + "%8d = number of LWPs\n" + "---------------------\n" + "real time = %.3f\n" + "user time = %.3f\n" + "system time = %.3f\n" + "---------------------\n", + rusage.pr_lwpid, + rusage.pr_count, + rusage.pr_minf, + rusage.pr_majf, + rusage.pr_inblk, + rusage.pr_oublk, + rusage.pr_msnd, + rusage.pr_mrcv, + rusage.pr_sigs, + rusage.pr_wtime.tv_sec, rusage.pr_wtime.tv_nsec / 1000000, + rusage.pr_ltime.tv_sec, rusage.pr_ltime.tv_nsec / 1000000, + rusage.pr_slptime.tv_sec, rusage.pr_slptime.tv_nsec / 1000000, + rusage.pr_vctx, + rusage.pr_ictx, + rusage.pr_vctx + rusage.pr_ictx, + rusage.pr_sysc, + rusage.pr_ioch, + ACE_Thread::getconcurrency (), + et.real_time, et.user_time, et.system_time)); +#else + // need to write dump ops for rusage... +#endif /* ACE_HAS_PRUSAGE_T */ + } + if (options.do_eager_exit ()) + ACE_OS::_exit (0); +} +#endif /* ACE_HAS_THREADS */ diff --git a/performance-tests/Synch-Benchmarks/Options.h b/performance-tests/Synch-Benchmarks/Options.h new file mode 100644 index 00000000000..7fa53e5fbae --- /dev/null +++ b/performance-tests/Synch-Benchmarks/Options.h @@ -0,0 +1,126 @@ +/* -*- C++ -*- */ +// @(#)Options.h 1.1 10/18/96 + +/* Option manager for ustreams */ + +#if !defined (_OPTIONS_H) +#define _OPTIONS_H + +#include "ace/OS.h" +#include "ace/Profile_Timer.h" +#include "ace/Log_Msg.h" +#include "ace/Thread_Manager.h" + +#if defined (ACE_HAS_THREADS) + +class Options +{ +public: + Options (void); + void parse_args (int argc, char *argv[]); + + void init (void); + + void start_timer (void); + void stop_timer (void); + + void thr_count (size_t count); + size_t thr_count (void); + + void pipe_addr (char pipe[]); + char *pipe_addr (void); + + void mapped_file (char filename[]); + char *mapped_file (void); + + void service_entry (char *service_entry); + char *service_entry (void); + + void sleep_time (size_t count); + size_t sleep_time (void); + + void logical_connections (size_t count); + size_t logical_connections (void); + + void physical_connections (size_t count); + size_t physical_connections (void); + + void consecutive_ports (size_t count); + size_t consecutive_ports (void); + + void initial_queue_length (size_t length); + size_t initial_queue_length (void); + + void high_water_mark (size_t size); + size_t high_water_mark (void); + + void low_water_mark (size_t size); + size_t low_water_mark (void); + + void msg_size (size_t size); + size_t msg_size (void); + + void iterations (size_t n); + size_t iterations (void); + + void n_lwps (size_t n); + size_t n_lwps (void); + + void t_flags (long flag); + long t_flags (void); + + size_t count (void); + + int debug (void); + int verbose (void); + int do_checksum (void); + int do_generate (void); + int do_ack (void); + int do_delete (void); + int do_eager_exit (void); + int do_print_summary (void); + int do_udp (void); + int do_xdr (void); + int do_zero_copy (void); + void print_results (void); + + ACE_Atomic_Op msg_count; /* Keep track of number of messages atomically */ + int *thr_work_count; /* Count activity per-thread */ + int thr_wc_size; /* Max number of threads */ + +private: + ACE_Profile_Timer _itimer; /* Keep track of time */ + char *_service_entry; /* Name of the shared object file and shared object */ + char *_mapped_file; /* Name of the mapped file */ + char *_pipe_addr; /* Name of the STREAM pipe */ + size_t _sleep_time; /* Time to sleep */ + size_t _n_lwps; /* Number of LWPs */ + size_t _thr_count; /* Number of threads to spawn */ + long _t_flags; /* Flags to thr_create() */ + size_t _high_water_mark; /* ACE_Queue high water mark */ + size_t _low_water_mark; /* ACE_Queue low water mark */ + size_t _msg_size; /* Size of a message */ + size_t _initial_queue_length; /* Initial number of items in the queue */ + size_t _logical_connections; /* Number of logical connections */ + size_t _physical_connections; /* Number of physical connections */ + size_t _iterations; /* Number of iterations to run the test program */ + int _generate; /* Generate the data */ + int _udp; /* Use UDP format */ + int _debugging; /* Extra debugging info */ + int _verbosity; /* Extra verbose messages */ + int _ack; /* Do an acknowledgement */ + int _checksum; /* Is checksumming enabled? */ + int _xdr; /* Is xdr conversion enabled? */ + int _free_memory; /* Are we freeing up memory? */ + int _zero_copy; /* Implement a zero-copy driver? */ + int _print_summary; /* Print a summary of the results only */ + int _consecutive_ports; /* Number of consecutive messages from same port */ + int _eager_exit; /* Exit eagerly, without cleaning up */ +}; + +/* Make this available to any code that wants to see it! */ +extern Options options; + +#include "Options.i" +#endif /* ACE_HAS_THREADS */ +#endif /* _OPTIONS_H */ diff --git a/performance-tests/Synch-Benchmarks/Options.i b/performance-tests/Synch-Benchmarks/Options.i new file mode 100644 index 00000000000..0c6030118bb --- /dev/null +++ b/performance-tests/Synch-Benchmarks/Options.i @@ -0,0 +1,264 @@ +/* -*- C++ -*- */ +// @(#)Options.i 1.1 10/18/96 + +/* Option manager for ustreams */ + +#include "ace/Get_Opt.h" + +inline int +Options::do_print_summary (void) +{ + return this->_print_summary; +} + +inline int +Options::do_udp (void) +{ + return this->_udp; +} + +inline void +Options::start_timer (void) +{ + this->_itimer.start (); +} + +inline void +Options::stop_timer (void) +{ + this->_itimer.stop (); +} + +inline int +Options::do_generate (void) +{ + return this->_generate; +} + +inline int +Options::do_ack (void) +{ + return this->_ack; +} + +inline int +Options::do_eager_exit (void) +{ + return this->_eager_exit; +} + +inline int +Options::do_zero_copy (void) +{ + return this->_zero_copy; +} + +inline int +Options::do_checksum (void) +{ + return this->_checksum; +} + +inline int +Options::do_delete (void) +{ + return this->_free_memory; +} + +inline int +Options::do_xdr (void) +{ + return this->_xdr; +} + +inline void +Options::n_lwps (size_t count) +{ + this->_n_lwps = count; +} + +inline size_t +Options::n_lwps (void) +{ + return this->_n_lwps; +} + +inline void +Options::pipe_addr (char *pipe) +{ + this->_pipe_addr = pipe; +} + +inline char * +Options::pipe_addr (void) +{ + return this->_pipe_addr; +} + +inline void +Options::service_entry (char *pipe) +{ + this->_service_entry = pipe; +} + +inline char * +Options::service_entry (void) +{ + return this->_service_entry; +} + +inline void +Options::mapped_file (char *filename) +{ + this->_mapped_file = filename; +} + +inline char * +Options::mapped_file (void) +{ + return this->_mapped_file; +} + +inline void +Options::sleep_time (size_t count) +{ + this->_sleep_time = count; +} + +inline size_t +Options::sleep_time (void) +{ + return this->_sleep_time; +} + +inline void +Options::thr_count (size_t count) +{ + this->_thr_count = count; +} + +inline size_t +Options::thr_count (void) +{ + return this->_thr_count; +} + +inline void +Options::consecutive_ports (size_t count) +{ + this->_consecutive_ports = count; +} + +inline size_t +Options::consecutive_ports (void) +{ + return this->_consecutive_ports; +} + +inline void +Options::logical_connections (size_t count) +{ + this->_logical_connections = count; +} + +inline size_t +Options::logical_connections (void) +{ + return this->_logical_connections; +} + +inline void +Options::physical_connections (size_t count) +{ + this->_physical_connections = count; +} + +inline size_t +Options::physical_connections (void) +{ + return this->_physical_connections; +} + +inline void +Options::initial_queue_length (size_t length) +{ + this->_initial_queue_length = length; +} + +inline size_t +Options::initial_queue_length (void) +{ + return this->_initial_queue_length; +} + +inline void +Options::high_water_mark (size_t size) +{ + this->_high_water_mark = size; +} + +inline size_t +Options::high_water_mark (void) +{ + return this->_high_water_mark; +} + +inline void +Options::low_water_mark (size_t size) +{ + this->_low_water_mark = size; +} + +inline size_t +Options::low_water_mark (void) +{ + return this->_low_water_mark; +} + +inline void +Options::msg_size (size_t size) +{ + this->_msg_size = size; +} + +inline size_t +Options::msg_size (void) +{ + return this->_msg_size; +} + +inline void +Options::iterations (size_t n) +{ + this->_iterations = n; +} + +inline size_t +Options::iterations (void) +{ + return this->_iterations; +} + +inline void +Options::t_flags (long flag) +{ + this->_t_flags |= flag; +} + +inline long +Options::t_flags (void) +{ + return this->_t_flags; +} + +inline int +Options::debug (void) +{ + return this->_debugging; +} + +inline int +Options::verbose (void) +{ + return this->_verbosity; +} diff --git a/performance-tests/Synch-Benchmarks/README b/performance-tests/Synch-Benchmarks/README new file mode 100644 index 00000000000..417757de524 --- /dev/null +++ b/performance-tests/Synch-Benchmarks/README @@ -0,0 +1,29 @@ +The files in this directory support controlled benchmarking of the ACE +C++ wrappers for Solaris 2.x synchronization mechanisms. These +mechanisms include: + + . Mutexes + . Reader/writer locks + . Condition variables + . Semaphores (both Solaris and traditional System V) + +There are additional tests that measure the memory bandwidth under the +following conditions: + + . User memory-to-memory copying of data within a single thread + . User memory-to-kernel-to-user memory copying via pipes + between separate processes, as well as between separate + threads in the same process + +There are many options available for this program. See the +Options.[Chi] file for more details. Some reasonable options to use +to run the tests are: + +% ./synch_driver -v -B -s 15 +% ./synch_driver -v -n 4 -t 4 -s 15 + +You should experiment with other options as you see fit. Note that in +general you should always make sure that you have more than 1 LWP (by +using either the -B or the -n options) since otherwise the program may +to into an infinite loop due to the semantics of SunOS unbound +threads... diff --git a/performance-tests/Synch-Benchmarks/benchmarks b/performance-tests/Synch-Benchmarks/benchmarks new file mode 100644 index 00000000000..5b3a6644bc5 --- /dev/null +++ b/performance-tests/Synch-Benchmarks/benchmarks @@ -0,0 +1,19 @@ +#!/bin/csh -f + +echo "Memory test = 512, 40M" +./memory_test -i 80000 -M 512 +echo "Memory test = 1024, 40M" +./memory_test -i 40000 -M 1024 +echo "Memory test = 2048, 40M" +./memory_test -i 20000 -M 2048 +echo "Memory test = 4096, 40M" +./memory_test -i 10000 -M 4096 + +echo "Pipe test = 512, 40M" +./pipe_test -i 80000 -M 512 +echo "Pipe test = 1024, 40M" +./pipe_test -i 40000 -M 1024 +echo "Pipe test = 2048, 40M" +./pipe_test -i 20000 -M 2048 +echo "Pipe test = 4096, 40M" +./pipe_test -i 10000 -M 4096 diff --git a/performance-tests/Synch-Benchmarks/condb_test.cpp b/performance-tests/Synch-Benchmarks/condb_test.cpp new file mode 100644 index 00000000000..64cc90ffd5d --- /dev/null +++ b/performance-tests/Synch-Benchmarks/condb_test.cpp @@ -0,0 +1,71 @@ +#include "ace/Synch.h" +// @(#)condb_test.cpp 1.1 10/18/96 + +#include "Options.h" +#include "Benchmark.h" + +#if defined (ACE_HAS_THREADS) + +class Cond_Brdcast_Test : public Benchmark +{ +public: + virtual int svc (void); + +private: + static ACE_Thread_Mutex mutex; + static int resources; + + static ACE_Condition_Thread_Mutex notfull; + static ACE_Condition_Thread_Mutex notempty; +}; + +ACE_Thread_Mutex Cond_Brdcast_Test::mutex; +int Cond_Brdcast_Test::resources; +ACE_Condition_Thread_Mutex Cond_Brdcast_Test::notfull (Cond_Brdcast_Test::mutex); +ACE_Condition_Thread_Mutex Cond_Brdcast_Test::notempty (Cond_Brdcast_Test::mutex); + +int +Cond_Brdcast_Test::svc (void) +{ + int ni = this->thr_id (); + synch_count = 2; + + // Special case for first thread... + if (ni == 4) + while (!this->done ()) + { + mutex.acquire (); + while (resources > 0) + notfull.wait (); + options.thr_work_count[ni]++; + resources = options.thr_count () - 1; + buffer++; + notempty.broadcast (); + mutex.release (); + } + else + while (!this->done ()) + { + mutex.acquire (); + while (resources == 0) + notempty.wait (); + options.thr_work_count[ni]++; + buffer++; + if (--resources == 0) + notfull.signal (); + mutex.release (); + } + + /* NOTREACHED */ + return 0; +} + +extern "C" ACE_Service_Object *cond_brdcast_test (void); + +ACE_Service_Object *cond_brdcast_test (void) +{ + return new Cond_Brdcast_Test; +} + +// ACE_Service_Object_Type cbt (&cond_brdcast_test, "Condition_Broadcast_Test"); +#endif /* ACE_HAS_THREADS */ diff --git a/performance-tests/Synch-Benchmarks/conds_test.cpp b/performance-tests/Synch-Benchmarks/conds_test.cpp new file mode 100644 index 00000000000..b32be50a5e1 --- /dev/null +++ b/performance-tests/Synch-Benchmarks/conds_test.cpp @@ -0,0 +1,74 @@ +#include "ace/Synch.h" +// @(#)conds_test.cpp 1.1 10/18/96 + +#include "Options.h" +#include "Benchmark.h" + +#if defined (ACE_HAS_THREADS) + +class Cond_Signal_Test : public Benchmark +{ +public: + virtual int svc (void); + +private: + static ACE_Thread_Mutex mutex; + static int resources; + + static ACE_Condition_Thread_Mutex notfull; + static ACE_Condition_Thread_Mutex notempty; +}; + +ACE_Thread_Mutex Cond_Signal_Test::mutex; +int Cond_Signal_Test::resources; +ACE_Condition_Thread_Mutex Cond_Signal_Test::notfull (Cond_Signal_Test::mutex); +ACE_Condition_Thread_Mutex Cond_Signal_Test::notempty (Cond_Signal_Test::mutex); + +int +Cond_Signal_Test::svc (void) +{ + int ni = this->thr_id (); + synch_count = 2; + + // This is a horrible hack and only works for Solaris threads. This + // clearly needs to change... + if (ni == 4) + while (!this->done ()) + { + mutex.acquire (); + + while (resources > 0) + notfull.wait (); + + options.thr_work_count[ni]++; + resources = options.thr_count () - 1; + buffer++; + notempty.signal (); + mutex.release (); + } + else + while (!this->done ()) + { + mutex.acquire (); + while (resources == 0) + notempty.wait (); + options.thr_work_count[ni]++; + buffer++; + if (--resources == 0) + notfull.signal (); + mutex.release (); + } + + /* NOTREACHED */ + return 0; +} + +extern "C" ACE_Service_Object *cond_signal_test (void); + +ACE_Service_Object *cond_signal_test (void) +{ + return new Cond_Signal_Test; +} + +// ACE_Service_Object_Type cst (&cond_signal_test, "Condition_Signal_Test"); +#endif /* ACE_HAS_THREADS */ diff --git a/performance-tests/Synch-Benchmarks/context.c b/performance-tests/Synch-Benchmarks/context.c new file mode 100644 index 00000000000..0ac4264bd00 --- /dev/null +++ b/performance-tests/Synch-Benchmarks/context.c @@ -0,0 +1,72 @@ +#include +// @(#)context.c 1.1 10/18/96 + +#include +#include + +#define NSLEEP 100 +#define TMAX 2 +int count[TMAX]; + +void * +work (void *n) +{ + int ni = (int) n; + + while (1) + { + thr_yield (); + count[ni]++; + } + return 0; +} + +main (int argc, char *argv[]) +{ + int ncorr, t1arg, t0arg, orig_ncorr; + thread_t tid1, tid0; + float rate; + + if (argc != 6) + { + printf ("usage: %s t0_bound t0_new_lwp t1_bound t1_new_lwp ncorr\n", argv[0]); + exit (1); + } + t0arg = THR_DETACHED; + if (atoi (argv[1])) + t0arg |= THR_BOUND; + if (atoi (argv[2])) + t0arg |= THR_NEW_LWP; + + t1arg = THR_DETACHED; + if (atoi (argv[3])) + t1arg |= THR_BOUND; + if (atoi (argv[4])) + t1arg |= THR_NEW_LWP; + + ncorr = atoi (argv[5]); + + if (thr_create (NULL, 0, work, 0, t0arg, &tid0) != 0) + perror ("couldn't create thread 0"); + if (thr_create (NULL, 0, work, (void *) 1, t1arg, &tid1) != 0) + perror ("couldn't create thread 1"); + + orig_ncorr = thr_getconcurrency (); + if (ncorr) + thr_setconcurrency (ncorr); + sleep (NSLEEP); + rate = (count[0] + count[1]) / ((float) NSLEEP); + printf ("\n------------------------------------------------------------------------\n"); + printf ("t0arg 0x%x (%s, %s, %s)\nt1arg 0x%x (%s, %s, %s)\ncount[0] %d count[1] %d\n\ +ncorr_orig %d ncorr_set %d ncorr_end %d rate %.3f per_cxt %.2f usec\n", + t0arg, + (t0arg & THR_DETACHED) ? "THR_DETACHED" : "Not Detached", + (t0arg & THR_BOUND) ? "THR_BOUND" : "Not Bound", + (t0arg & THR_NEW_LWP) ? "THR_NEW_LWP" : "No New_LWP", + t1arg, + (t1arg & THR_DETACHED) ? "THR_DETACHED" : "Not Detached", + (t1arg & THR_BOUND) ? "THR_BOUND" : "Not Bound", + (t1arg & THR_NEW_LWP) ? "THR_NEW_LWP" : "No New_LWP", + count[0], count[1], + orig_ncorr, ncorr, thr_getconcurrency (), rate, 1.0e6 / rate); +} diff --git a/performance-tests/Synch-Benchmarks/context.csh b/performance-tests/Synch-Benchmarks/context.csh new file mode 100644 index 00000000000..867611f07e1 --- /dev/null +++ b/performance-tests/Synch-Benchmarks/context.csh @@ -0,0 +1,16 @@ +#/bin/csh -f +time ./context 0 0 0 0 0 +time ./context 0 0 0 0 2 +time ./context 0 0 0 0 3 + +time ./context 1 0 1 0 0 +time ./context 1 0 1 0 2 +time ./context 1 0 1 0 3 + +time ./context 0 1 0 1 0 +time ./context 0 1 0 1 2 +time ./context 0 1 0 1 3 + +time ./context 1 1 1 1 0 +time ./context 1 1 1 1 2 +time ./context 1 1 1 1 3 diff --git a/performance-tests/Synch-Benchmarks/context_test.cpp b/performance-tests/Synch-Benchmarks/context_test.cpp new file mode 100644 index 00000000000..d8ec2bbd872 --- /dev/null +++ b/performance-tests/Synch-Benchmarks/context_test.cpp @@ -0,0 +1,40 @@ +#include "ace/Synch.h" +// @(#)context_test.cpp 1.1 10/18/96 + +#include "Options.h" +#include "Benchmark.h" + +#if defined (ACE_HAS_THREADS) + +class Context_Test : public Benchmark +{ +public: + virtual int svc (void); +}; + +int +Context_Test::svc (void) +{ + int ni = this->thr_id (); + + synch_count = 1; + + while (!this->done ()) + { + ACE_Thread::yield (); + options.thr_work_count[ni]++; + } + + /* NOTREACHED */ + return 0; +} + +extern "C" ACE_Service_Object *context_test (void); + +ACE_Service_Object *context_test (void) +{ + return new Context_Test; +} + +// ACE_Service_Object_Type ct (&context_test, "Context_Test"); +#endif /* ACE_HAS_THREADS */ diff --git a/performance-tests/Synch-Benchmarks/memory_test.cpp b/performance-tests/Synch-Benchmarks/memory_test.cpp new file mode 100644 index 00000000000..612e86999d0 --- /dev/null +++ b/performance-tests/Synch-Benchmarks/memory_test.cpp @@ -0,0 +1,42 @@ +#include "ace/Synch.h" +// @(#)memory_test.cpp 1.1 10/18/96 + +#include "Options.h" +#include "Benchmark.h" + +#if defined (ACE_HAS_THREADS) + +class Memory_Test : public Benchmark +{ +public: + virtual int svc (void); +}; + +int +Memory_Test::svc (void) +{ + int ni = this->thr_id (); + size_t length = options.msg_size (); + char *from = new char[length]; + char *to = new char[length]; + + synch_count = 1; + + while (!this->done ()) + { + ACE_OS::memcpy (to, from, length); + options.thr_work_count[ni]++; + } + /* NOTREACHED */ + return 0; +} + +extern "C" ACE_Service_Object *memory_test (void); + +ACE_Service_Object *memory_test (void) +{ + return new Memory_Test; +} + +// ACE_Service_Object_Type mt (&memory_test, "Memory_Test"); +#endif /* ACE_HAS_THREADS */ diff --git a/performance-tests/Synch-Benchmarks/mutex_test.cpp b/performance-tests/Synch-Benchmarks/mutex_test.cpp new file mode 100644 index 00000000000..ea4933945f7 --- /dev/null +++ b/performance-tests/Synch-Benchmarks/mutex_test.cpp @@ -0,0 +1,46 @@ +#include "ace/Synch.h" +// @(#)mutex_test.cpp 1.1 10/18/96 + +#include "Options.h" +#include "Benchmark.h" + +#if defined (ACE_HAS_THREADS) + +class Mutex_Test : public Benchmark +{ +public: + virtual int svc (void); + +private: + static ACE_Thread_Mutex mutex; +}; + +ACE_Thread_Mutex Mutex_Test::mutex; + +int +Mutex_Test::svc (void) +{ + // Extract out the unique thread-specific value to be used as an + // index... + int ni = this->thr_id (); + synch_count = 2; + + while (!this->done ()) + { + mutex.acquire (); + options.thr_work_count[ni]++; + buffer++; + mutex.release (); + } + /* NOTREACHED */ + return 0; +} + +extern "C" ACE_Service_Object *mutex_test (void); + +ACE_Service_Object *mutex_test (void) +{ + return new Mutex_Test; +} +// ACE_Service_Object_Type mut (&mutex_test, "Mutex_Test"); +#endif /* ACE_HAS_THREADS */ diff --git a/performance-tests/Synch-Benchmarks/orig-results b/performance-tests/Synch-Benchmarks/orig-results new file mode 100644 index 00000000000..9d4389005f1 --- /dev/null +++ b/performance-tests/Synch-Benchmarks/orig-results @@ -0,0 +1,73 @@ +/* + --------------------- results ------------------------------------- + t0arg 0x40 (THR_DETACHED, Not Bound, No New_LWP) + t1arg 0x40 (THR_DETACHED, Not Bound, No New_LWP) + count[0] 2222061 count[1] 2222061 + ncorr_orig 1 ncorr_set 0 ncorr_end 2 rate 22070.520 per_cxt 45.31 usec + + ------------------------------------------------------------------------ + t0arg 0x40 (THR_DETACHED, Not Bound, No New_LWP) + t1arg 0x40 (THR_DETACHED, Not Bound, No New_LWP) + count[0] 3979311 count[1] 3824273 + ncorr_orig 1 ncorr_set 2 ncorr_end 2 rate 38975.535 per_cxt 25.66 usec + + ------------------------------------------------------------------------ + t0arg 0x40 (THR_DETACHED, Not Bound, No New_LWP) + t1arg 0x40 (THR_DETACHED, Not Bound, No New_LWP) + count[0] 4173290 count[1] 3690153 + ncorr_orig 1 ncorr_set 3 ncorr_end 3 rate 39134.219 per_cxt 25.55 usec + + ------------------------------------------------------------------------ + t0arg 0x41 (THR_DETACHED, THR_BOUND, No New_LWP) + t1arg 0x41 (THR_DETACHED, THR_BOUND, No New_LWP) + count[0] 1376594 count[1] 1404050 + ncorr_orig 1 ncorr_set 0 ncorr_end 1 rate 13902.920 per_cxt 71.93 usec + + ------------------------------------------------------------------------ + t0arg 0x41 (THR_DETACHED, THR_BOUND, No New_LWP) + t1arg 0x41 (THR_DETACHED, THR_BOUND, No New_LWP) + count[0] 1522495 count[1] 1550889 + ncorr_orig 1 ncorr_set 2 ncorr_end 2 rate 15366.580 per_cxt 65.08 usec + + ------------------------------------------------------------------------ + t0arg 0x41 (THR_DETACHED, THR_BOUND, No New_LWP) + t1arg 0x41 (THR_DETACHED, THR_BOUND, No New_LWP) + count[0] 1282030 count[1] 1265453 + ncorr_orig 1 ncorr_set 3 ncorr_end 3 rate 12737.125 per_cxt 78.51 usec + + ------------------------------------------------------------------------ + t0arg 0x42 (THR_DETACHED, Not Bound, THR_NEW_LWP) + t1arg 0x42 (THR_DETACHED, Not Bound, THR_NEW_LWP) + count[0] 3892994 count[1] 3981143 + ncorr_orig 3 ncorr_set 0 ncorr_end 3 rate 39273.352 per_cxt 25.46 usec + + ------------------------------------------------------------------------ + t0arg 0x42 (THR_DETACHED, Not Bound, THR_NEW_LWP) + t1arg 0x42 (THR_DETACHED, Not Bound, THR_NEW_LWP) + count[0] 4008638 count[1] 3882986 + ncorr_orig 3 ncorr_set 2 ncorr_end 2 rate 39415.660 per_cxt 25.37 usec + + ------------------------------------------------------------------------ + t0arg 0x42 (THR_DETACHED, Not Bound, THR_NEW_LWP) + t1arg 0x42 (THR_DETACHED, Not Bound, THR_NEW_LWP) + count[0] 3859767 count[1] 3998157 + ncorr_orig 3 ncorr_set 3 ncorr_end 3 rate 39145.160 per_cxt 25.55 usec + + ------------------------------------------------------------------------ + t0arg 0x43 (THR_DETACHED, THR_BOUND, THR_NEW_LWP) + t1arg 0x43 (THR_DETACHED, THR_BOUND, THR_NEW_LWP) + count[0] 1557142 count[1] 1588775 + ncorr_orig 3 ncorr_set 0 ncorr_end 3 rate 15729.235 per_cxt 63.58 usec + + ------------------------------------------------------------------------ + t0arg 0x43 (THR_DETACHED, THR_BOUND, THR_NEW_LWP) + t1arg 0x43 (THR_DETACHED, THR_BOUND, THR_NEW_LWP) + count[0] 1570636 count[1] 1579111 + ncorr_orig 3 ncorr_set 2 ncorr_end 3 rate 15748.395 per_cxt 63.50 usec + + ------------------------------------------------------------------------ + t0arg 0x43 (THR_DETACHED, THR_BOUND, THR_NEW_LWP) + t1arg 0x43 (THR_DETACHED, THR_BOUND, THR_NEW_LWP) + count[0] 1414198 count[1] 1371431 + ncorr_orig 3 ncorr_set 3 ncorr_end 3 rate 13927.800 per_cxt 71.80 usec + */ diff --git a/performance-tests/Synch-Benchmarks/pipe_proc_test.cpp b/performance-tests/Synch-Benchmarks/pipe_proc_test.cpp new file mode 100644 index 00000000000..c06cf64653b --- /dev/null +++ b/performance-tests/Synch-Benchmarks/pipe_proc_test.cpp @@ -0,0 +1,85 @@ +#include "Options.h" +// @(#)pipe_proc_test.cpp 1.1 10/18/96 + +#include "Benchmark.h" + +#if defined (ACE_HAS_THREADS) + +extern int buffer; +extern int synch_count; + +class Pipe_Proc_Test : public Benchmark +{ +public: + int init (int, char **); + virtual int svc (void); + +private: + int pipe_fds[2]; + + void reader (int fd); +}; + +int +Pipe_Proc_Test::init (int, char **) +{ + synch_count = 1; + + if (ACE_OS::pipe (this->pipe_fds) == -1) + ACE_OS::perror ("pipe"), ACE_OS::exit (1); + + switch (ACE_OS::fork ()) + { + case -1: + ACE_OS::perror ("fork"), ACE_OS::exit (1); + case 0: + this->reader (pipe_fds[0]); + /* NOTREACHED */ + break; + default: + break; + } + return 1; +} + +void +Pipe_Proc_Test::reader (int fd) +{ + int ni = this->thr_id (); + int length = options.msg_size (); + char *to = new char[length]; + int n; + + while ((n = ACE_OS::read (fd, to, length)) > 0) + options.thr_work_count[ni]++; +} + + +int +Pipe_Proc_Test::svc (void) +{ + size_t length = options.msg_size (); + char *from = new char[length]; + int ni = this->thr_id (); + int fd = this->pipe_fds[1]; + + while (!this->done ()) + if (ACE_OS::write (fd, from, length) == length) + options.thr_work_count[ni]++; + else + ACE_OS::perror ("write"); + + ACE_OS::close (this->pipe_fds[0]); + ACE_OS::close (this->pipe_fds[1]); + return 0; +} + +extern "C" ACE_Service_Object *pipe_proc_test (void); + +ACE_Service_Object *pipe_proc_test (void) +{ + return new Pipe_Proc_Test; +} + +// ACE_Service_Object_Type ppt (&pipe_proc_test, "Pipe_Proc_Test"); +#endif /* ACE_HAS_THREADS */ diff --git a/performance-tests/Synch-Benchmarks/pipe_thr_test.cpp b/performance-tests/Synch-Benchmarks/pipe_thr_test.cpp new file mode 100644 index 00000000000..848608081d9 --- /dev/null +++ b/performance-tests/Synch-Benchmarks/pipe_thr_test.cpp @@ -0,0 +1,81 @@ +#include "ace/Thread_Manager.h" +// @(#)pipe_thr_test.cpp 1.1 10/18/96 + +#include "Options.h" +#include "Benchmark.h" + +#if defined (ACE_HAS_THREADS) + +extern int synch_count; + +class Pipe_Thr_Test : public Benchmark +{ +public: + virtual int init (int, char **); + virtual int svc (void); + +private: + int pipe_fds[2]; + + static void *reader (Pipe_Thr_Test *); +}; + +void * +Pipe_Thr_Test::reader (Pipe_Thr_Test *t) +{ + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + + int fd = t->pipe_fds[0]; + int ni = t->thr_id (); + int length = options.msg_size (); + char *to = new char[length]; + int n; + + while ((n = ACE_OS::read (fd, to, length)) > 0) + options.thr_work_count[ni]++; + + return 0; +} + +int +Pipe_Thr_Test::init (int, char **) +{ + synch_count = 1; + + if (ACE_OS::pipe (this->pipe_fds) == -1) + ACE_OS::perror ("pipe"), ACE_OS::exit (1); + + if (ACE_Service_Config::thr_mgr ()->spawn + (ACE_THR_FUNC (Pipe_Thr_Test::reader), + (void *) this, options.t_flags ()) == -1) + ACE_OS::perror ("thr_create"), ACE_OS::exit (1); + + return 1; +} + +int +Pipe_Thr_Test::svc (void) +{ + size_t length = options.msg_size (); + char *from = new char[length]; + int fd = this->pipe_fds[1]; + + while (!this->done ()) + if (ACE_OS::write (fd, from, length) != length) + ACE_OS::perror ("write"); + + ACE_OS::close (this->pipe_fds[0]); + ACE_OS::close (this->pipe_fds[1]); + + return 0; +} + +extern "C" ACE_Service_Object *pipe_thr_test (void); + +ACE_Service_Object *pipe_thr_test (void) +{ + return new Pipe_Thr_Test; +} + +// ACE_Service_Object_Type ptt (&pipe_thr_test, "Pipe_Thr_Test"); +#endif /* ACE_HAS_THREADS */ diff --git a/performance-tests/Synch-Benchmarks/recursive_lock_test.cpp b/performance-tests/Synch-Benchmarks/recursive_lock_test.cpp new file mode 100644 index 00000000000..1712d608503 --- /dev/null +++ b/performance-tests/Synch-Benchmarks/recursive_lock_test.cpp @@ -0,0 +1,45 @@ +#include "ace/Synch.h" +// @(#)recursive_lock_test.cpp 1.1 10/18/96 + +#include "Options.h" +#include "Benchmark.h" + +#if defined (ACE_HAS_THREADS) + +class Recursive_Lock_Test : public Benchmark +{ +public: + virtual int svc (void); + +private: + static ACE_Recursive_Thread_Mutex mutex; +}; + +ACE_Recursive_Thread_Mutex Recursive_Lock_Test::mutex; + +int +Recursive_Lock_Test::svc (void) +{ + int ni = this->thr_id (); + synch_count = 2; + + while (!this->done ()) + { + this->mutex.acquire (); + options.thr_work_count[ni]++; + buffer++; + this->mutex.release (); + } + /* NOTREACHED */ + return 0; +} + +extern "C" ACE_Service_Object *recursive_lock_test (void); + +ACE_Service_Object *recursive_lock_test (void) +{ + return new Recursive_Lock_Test; +} + +// ACE_Service_Object_Type rlt (&recursive_lock_test, "Recursive_Lock_Test"); +#endif /* ACE_HAS_THREADS */ diff --git a/performance-tests/Synch-Benchmarks/rwrd_test.cpp b/performance-tests/Synch-Benchmarks/rwrd_test.cpp new file mode 100644 index 00000000000..89f4e35d303 --- /dev/null +++ b/performance-tests/Synch-Benchmarks/rwrd_test.cpp @@ -0,0 +1,46 @@ +#include "ace/Synch.h" +// @(#)rwrd_test.cpp 1.1 10/18/96 + +#include "Options.h" +#include "Benchmark.h" + +#if defined (ACE_HAS_THREADS) + +class RWRD_Test : public Benchmark +{ +public: + virtual int svc (void); + +private: + static ACE_RW_Mutex rw_lock; +}; + +ACE_RW_Mutex RWRD_Test::rw_lock; + +int +RWRD_Test::svc (void) +{ + int ni = this->thr_id (); + synch_count = 2; + + while (!this->done ()) + { + rw_lock.acquire_read (); + options.thr_work_count[ni]++; + buffer++; + rw_lock.release (); + } + + /* NOTREACHED */ + return 0; +} + +extern "C" ACE_Service_Object *rwrd_test (void); + +ACE_Service_Object *rwrd_test (void) +{ + return new RWRD_Test; +} + +// ACE_Service_Object_Type rwrdt (&rwrd_test, "RWRD_Mutex_Test"); +#endif /* ACE_HAS_THREADS */ diff --git a/performance-tests/Synch-Benchmarks/rwwr_test.cpp b/performance-tests/Synch-Benchmarks/rwwr_test.cpp new file mode 100644 index 00000000000..daf7cd32818 --- /dev/null +++ b/performance-tests/Synch-Benchmarks/rwwr_test.cpp @@ -0,0 +1,46 @@ +#include "ace/Synch.h" +// @(#)rwwr_test.cpp 1.1 10/18/96 + +#include "Options.h" +#include "Benchmark.h" + +#if defined (ACE_HAS_THREADS) + +class RWWR_Test : public Benchmark +{ +public: + virtual int svc (void); + +private: + static ACE_RW_Mutex rw_lock; +}; + +ACE_RW_Mutex RWWR_Test::rw_lock; + +int +RWWR_Test::svc (void) +{ + int ni = this->thr_id (); + synch_count = 2; + + while (!this->done ()) + { + rw_lock.acquire_write (); + options.thr_work_count[ni]++; + buffer++; + rw_lock.release (); + } + + /* NOTREACHED */ + return 0; +} + +extern "C" ACE_Service_Object *rwwr_test (void); + +ACE_Service_Object *rwwr_test (void) +{ + return new RWWR_Test; +} + +// ACE_Service_Object_Type rwwrt (&rwwr_test, "RWWR_Mutext_Test"); +#endif /* ACE_HAS_THREADS */ diff --git a/performance-tests/Synch-Benchmarks/sema_test.cpp b/performance-tests/Synch-Benchmarks/sema_test.cpp new file mode 100644 index 00000000000..0a20d1bc07f --- /dev/null +++ b/performance-tests/Synch-Benchmarks/sema_test.cpp @@ -0,0 +1,46 @@ +#include "ace/Synch.h" +// @(#)sema_test.cpp 1.1 10/18/96 + +#include "Options.h" +#include "Benchmark.h" + +#if defined (ACE_HAS_THREADS) + +class Sema_Test : public Benchmark +{ +public: + virtual int svc (void); + +private: + static ACE_Semaphore sema; +}; + +ACE_Semaphore Sema_Test::sema (1); + +int +Sema_Test::svc (void) +{ + int ni = this->thr_id (); + synch_count = 2; + + while (!this->done ()) + { + sema.acquire (); + options.thr_work_count[ni]++; + buffer++; + sema.release (); + } + + /* NOTREACHED */ + return 0; +} + +extern "C" ACE_Service_Object *sema_test (void); + +ACE_Service_Object *sema_test (void) +{ + return new Sema_Test; +} + +// ACE_Service_Object_Type semt (&sema_test, "Semaphore_Test"); +#endif /* ACE_HAS_THREADS */ diff --git a/performance-tests/Synch-Benchmarks/svc.conf b/performance-tests/Synch-Benchmarks/svc.conf new file mode 100644 index 00000000000..4504968908e --- /dev/null +++ b/performance-tests/Synch-Benchmarks/svc.conf @@ -0,0 +1,14 @@ +# Dynamically configure all the tests +dynamic Mutex_Test Service_Object * .shobj/mutex_test.so:mutex_test() +dynamic Semaphore_Test Service_Object * .shobj/sema_test.so:sema_test() +dynamic Recursive_Lock_Test Service_Object * .shobj/recursive_lock_test.so:recursive_lock_test() +dynamic RWRD_Mutex_Test Service_Object * .shobj/rwrd_test.so:rwrd_test() +dynamic RWWR_Mutex_Test Service_Object * .shobj/rwwr_test.so:rwwr_test() +dynamic SYSVSema_Test Service_Object * .shobj/sysvsema_test.so:sysvsema_test() +dynamic Context_Test Service_Object * .shobj/context_test.so:context_test() +# dynamic Memory_Test Service_Object * .shobj/memory_test.so:memory_test() +# dynamic Pipe_Thr_Test Service_Object * .shobj/pipe_thr_test.so:pipe_thr_test() +# dynamic Pipe_Proc_Test Service_Object * .shobj/pipe_proc_test.so:pipe_proc_test() +# The following two tests don't work correctly yet... +# dynamic Condition_Broadcast_Test Service_Object * .shobj/condb_test.so:cond_brdcast_test() +# dynamic Condition_Signal_Test Service_Object * .shobj/conds_test.so:cond_signal_test() diff --git a/performance-tests/Synch-Benchmarks/synch_driver.cpp b/performance-tests/Synch-Benchmarks/synch_driver.cpp new file mode 100644 index 00000000000..3e2566c9f30 --- /dev/null +++ b/performance-tests/Synch-Benchmarks/synch_driver.cpp @@ -0,0 +1,166 @@ +// Driver program that measures the performance of synchronization +// @(#)synch_driver.cpp 1.1 10/18/96 + +// mechanisms provided by ACE and the underlying OS. + +#include "ace/Service_Config.h" +#include "ace/Service_Repository.h" +#include "ace/Synch.h" +#include "Options.h" +#include "Benchmark.h" + +#if defined (ACE_HAS_THREADS) + +class Benchmark_Test : public ACE_Service_Config +{ +public: + Benchmark_Test (void); + int init (int argc, char **argv); + +private: + void run_test (void); + + virtual int handle_signal (int signum +#if defined (ACE_HAS_SIGINFO_T) +, siginfo_t * = 0, ucontext_t * = 0 +#endif /* ACE_HAS_SIGINFO_T */ +); + + int n_lwps_; + int orig_n_lwps_; +}; + +int +Benchmark_Test::handle_signal (int signum +#if defined (ACE_HAS_SIGINFO_T) +, siginfo_t *, ucontext_t * +#endif /* ACE_HAS_SIGINFO_T */ +) +{ + ACE_DEBUG ((LM_DEBUG, "caught %S, shutting down the test%a\n", signum, 1)); + return 0; +} + +Benchmark_Test::Benchmark_Test (void) + : ACE_Service_Config (1), // Do not load default services + n_lwps_ (0), + orig_n_lwps_ (0) +{ + ACE_Service_Config::reactor ()->register_handler (SIGINT, this); +} + +void +Benchmark_Test::run_test (void) +{ + // Tell the threads that we are not finished. + Benchmark::done (0); + + // Allow thread(s) to make progress. + ACE_Service_Config::thr_mgr ()->resume_all (); + + ACE_Time_Value timeout (options.sleep_time ()); + + ACE_DEBUG ((LM_DEBUG, "starting timer\n")); + options.start_timer (); + + ACE_OS::select (0, 0, 0, 0, &timeout); + options.stop_timer (); + ACE_DEBUG ((LM_DEBUG, "stopping timer\n")); + + // Stop thread(s) from making any further progress. + ACE_Service_Config::thr_mgr ()->suspend_all (); + + // Tell the threads that we are finished. + Benchmark::done (1); + + ACE_DEBUG ((LM_DEBUG, "------------------------------------------------------------------------\n")); + ACE_DEBUG ((LM_DEBUG, "targ 0x%x (%s, %s, %s)\n" + "n_lwps_orig = %d, n_lwps_set = %d, n_lwps_end = %d\n", + options.t_flags (), + (options.t_flags () & THR_DETACHED) ? "THR_DETACHED" : "Not Detached", + (options.t_flags () & THR_BOUND) ? "THR_BOUND" : "Not Bound", + (options.t_flags () & THR_NEW_LWP) ? "THR_NEW_LWP" : "No New_LWP", + this->orig_n_lwps_, this->n_lwps_, ACE_Thread::getconcurrency ())); + + int count = options.count (); + float rate = count / (float (options.sleep_time ())); + + ACE_DEBUG ((LM_DEBUG, "to count = %d\nrate = %.3f ops/sec, per operation = %.2f usec\n", + count, rate, (1.0e6 / rate) / synch_count)); + options.print_results (); + + // Allow thread(s) to finish up. + ACE_Service_Config::thr_mgr ()->resume_all (); + + // Wait for all the threads to exit. + ACE_Service_Config::thr_mgr ()->wait (); + options.init (); +} + +// Initialize and run the benchmarks tests. + +Benchmark_Test::init (int argc, char **argv) +{ + options.parse_args (argc, argv); + + // Open the service configurator and process the directives in the + // svc.conf file. + + if (this->open (argv[0]) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "ACE_Service_Config::open failed\n%a", 1), -1); + + ACE_Service_Repository_Iterator sri (*this->ACE_Service_Config::svc_rep ()); + + // Iteratively execute each service loaded in from the svc.conf + // file. + + for (const ACE_Service_Record *sr; + sri.next (sr) != 0; + sri.advance ()) + { + // This would greatly benefit from RTTI typesafe downcasting... + const ACE_Service_Type *type = sr->type (); + const void *obj = type->object (); + ACE_Service_Object *so = (ACE_Service_Object *) obj; + Benchmark *bp = (Benchmark *) so; + + ACE_DEBUG ((LM_DEBUG, "\nstarting up %s\n", sr->name ())); + + this->orig_n_lwps_ = ACE_Thread::getconcurrency (); + this->n_lwps_ = options.n_lwps (); + + if (this->n_lwps_ > 0) + ACE_Thread::setconcurrency (this->n_lwps_); + + // We should probably use a "barrier" here rather than + // THR_SUSPENDED since many OS platforms lack the ability to + // create suspended threads... + if (ACE_Service_Config::thr_mgr ()->spawn_n + (options.thr_count (), ACE_THR_FUNC (bp->svc_run), + (void *) bp, options.t_flags () | THR_SUSPENDED) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "couldn't spawn threads", 1)); + + this->run_test (); + } + + return 0; +} + +int +main (int argc, char *argv[]) +{ + Benchmark_Test benchmark_tester; + + if (benchmark_tester.init (argc, argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "open", 1)); + + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "This test requires the platform to have threads\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/performance-tests/Synch-Benchmarks/sysvsema_test.cpp b/performance-tests/Synch-Benchmarks/sysvsema_test.cpp new file mode 100644 index 00000000000..fb9be5c7eef --- /dev/null +++ b/performance-tests/Synch-Benchmarks/sysvsema_test.cpp @@ -0,0 +1,47 @@ +#include "ace/SV_Semaphore_Simple.h" +// @(#)sysvsema_test.cpp 1.1 10/18/96 + +#include "Options.h" +#include "Benchmark.h" + +#if defined (ACE_HAS_THREADS) + +class SYSVSema_Test : public Benchmark +{ +public: + virtual int svc (void); + +private: + static ACE_SV_Semaphore_Simple sema; +}; + +ACE_SV_Semaphore_Simple SYSVSema_Test::sema (1234, ACE_SV_Semaphore_Simple::ACE_CREATE, 1); + +int +SYSVSema_Test::svc (void) +{ + int ni = this->thr_id (); + synch_count = 2; + + while (!this->done ()) + { + sema.acquire (); + options.thr_work_count[ni]++; + buffer++; + sema.release (); + } + + sema.remove (); + /* NOTREACHED */ + return 0; +} + +extern "C" ACE_Service_Object *sysvsema_test (void); + +ACE_Service_Object *sysvsema_test (void) +{ + return new SYSVSema_Test; +} + +// ACE_Service_Object_Type st (&sysvsema_test, "SYSVSema_Test"); +#endif /* ACE_HAS_THREADS */ diff --git a/performance-tests/TTCP/ACE-C++/How_to_run_tests b/performance-tests/TTCP/ACE-C++/How_to_run_tests new file mode 100644 index 00000000000..1346a745504 --- /dev/null +++ b/performance-tests/TTCP/ACE-C++/How_to_run_tests @@ -0,0 +1,29 @@ +// ACE version +// +// + +// HOSTNAMES: +// for our tests, encip1-tango.cs.wustl.edu was the receiver hostname used for atm transfers +// tango.cs.wustl.edu was the receiver hostname used for ethernet transfers +// substitute the proper receiver hostname for your system. + +// Results: +// These examples show the result files being stored in a /results directory off +// the current path. This can be set to whatever you like. + +// ATM with 64k receiver buffers +Receiver_Host: repeat 100 server -r -s -fm -p 10002 -b 65536 +Sender_Host: run_test 64 encip1-tango.cs.wustl.edu ./results/ace.atm.64 10002 + or: client -fm -s -t -l 1048576 -n 100 -h encip1-tango.cs.wustl.edu -L ./results/ace.atm.64 -p 10002 + +// ATM with 8k receiver buffers +Receiver_Host: repeat 100 wrapper-new-ttcp -r -s -fm -p 10002 +Sender_Host: run_test 64 encip1-tango.cs.wustl.edu ./results/ace.atm.8 10002 + +// ETHERNET with 64k receiver buffers +Receiver_Host: repeat 100 wrapper-new-ttcp -r -s -fm -p 10002 -b 65536 +Sender_Host: run_test 64 tango.cs.wustl.edu ./results/ace.ethernet.64 10002 + +// ETHERNET with 8k receiver buffers +Receiver_Host: repeat 100 wrapper-new-ttcp -r -s -fm -p 10002 +Sender_Host: run_test 64 tango.cs.wustl.edu ./results/ace.ethernet.8 10002 diff --git a/performance-tests/TTCP/ACE-C++/Makefile b/performance-tests/TTCP/ACE-C++/Makefile new file mode 100644 index 00000000000..f54d72fe4f2 --- /dev/null +++ b/performance-tests/TTCP/ACE-C++/Makefile @@ -0,0 +1,52 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the wrapper-new-ttcp +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = wrapper-new-ttcp + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(addsuffix .o,$(FILES)) + +LDLIBS = $(addprefix .obj/,$(LOBJ)) -Bstatic -Bdynamic + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VOBJS) $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +LINK_COMMAND = quantify -cache-dir=/$(IR)/quantify + +CCFLAGS = -O2 -DLM_RESULTS +#CCFLAGS = -g -DLM_RESULTS +#DCCFLAGS = -g + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + + + diff --git a/performance-tests/TTCP/ACE-C++/run_test b/performance-tests/TTCP/ACE-C++/run_test new file mode 100644 index 00000000000..e07e6ed0c80 --- /dev/null +++ b/performance-tests/TTCP/ACE-C++/run_test @@ -0,0 +1,35 @@ +# test_run 64 enatm0-kavita.cs.wustl.edu title 10002 +# repeat 100 wrapper-new-ttcp -r -s -fm -p 10002 -b 65536 +#!/bin/csh -f +if ($#argv != 4) then + echo "Usage: sclt " $4 + exit 1 +endif +# +@ msize=1024 +@ limit= ($argv[1] * 1024) +#echo $limit +#echo $msize +echo "Iteration#" 1 ": wrapper-new-ttcp -fm -s -t -l" $msize "-h" $2 "-L" $3 "-p" $4 +wrapper-new-ttcp -fm -s -t -l $msize -h $2 -x -L $3 -p $4 +sleep 1 +set flag=0 +while ($msize <= $limit) + if ($flag == 0) goto label + echo "Iteration#" 1 ": wrapper-new-ttcp -fm -s -t -l" $msize "-h" $2 "-x -L" $3 "-p" $4 + wrapper-new-ttcp -fm -s -t -l $msize -h $2 -x -L $3 -p $4 + sleep 1 + label: + set flag=1 + foreach i (2 3 4 5) + echo "Iteration#" $i ": wrapper-new-ttcp -fm -s -t -l" $msize "-h" $2 "-L " $3 "-p" $4 + wrapper-new-ttcp -fm -s -t -l $msize -h $2 -L $3 -p $4 + sleep 1 + end + echo "---------------------------" + @ msize = ($msize * 2) +end + +echo " " +echo "Done at:" +date diff --git a/performance-tests/TTCP/ACE-C++/wrapper-new-ttcp.cpp b/performance-tests/TTCP/ACE-C++/wrapper-new-ttcp.cpp new file mode 100644 index 00000000000..55fbdf1d077 --- /dev/null +++ b/performance-tests/TTCP/ACE-C++/wrapper-new-ttcp.cpp @@ -0,0 +1,947 @@ +/* -*- C++ -*- */ +// @(#)wrapper-new-ttcp.cpp 1.1 10/18/96 + +/* + * T T C P . C + * + * Test TCP connection. Makes a connection on port 5001 + * and transfers fabricated buffers or data copied from stdin. + * + * Usable on 4.2, 4.3, and 4.1a systems by defining one of + * BSD42 BSD43 (BSD41a) + * Machines using System V with BSD sockets should define SYSV. + * + * Modified for operation under 4.2BSD, 18 Dec 84 + * T.C. Slattery, USNA + * Minor improvements, Mike Muuss and Terry Slattery, 16-Oct-85. + * Modified in 1989 at Silicon Graphics, Inc. + * catch SIGPIPE to be able to print stats when receiver has died + * for tcp, don't look for sentinel during reads to allow small transfers + * increased default buffer size to 8K, nbuf to 2K to transfer 16MB + * moved default port to 5001, beyond IPPORT_USERRESERVED + * make sinkmode default because it is more popular, + * -s now means don't sink/source + * count number of read/write system calls to see effects of + * blocking from full socket buffers + * for tcp, -D option turns off buffered writes (sets TCP_NODELAY sockopt) + * buffer alignment options, -A and -O + * print stats in a format that's a bit easier to use with grep & awk + * for SYSV, mimic BSD routines to use most of the existing timing code + * Modified by Steve Miller of the University of Maryland, College Park + * -b sets the socket buffer size (SO_SNDBUF/SO_RCVBUF) + * Modified Sept. 1989 at Silicon Graphics, Inc. + * restored -s sense at request of tcs@brl + * Modified Oct. 1991 at Silicon Graphics, Inc. + * use getopt(3) for option processing, add -f and -T options. + * SGI IRIX 3.3 and 4.0 releases don't need #define SYSV. + * Modified Aug.1993 at University Paderborn, Germany + * some SVR4 changes and time functions changed to itimer() calls + * Modified by Douglas C. Schmidt September 28, 1994 + * added support for testing UNIX domain socket performance + * Modified by Tim Harrison May, 1995 + * added support for ACE wrappers + * Distribution Status - + * Public Domain. Distribution Unlimited. + */ +#ifndef lint +static char RCSid[] = "ttcp.c $Revision$"; +#endif + +/* #define BSD43 */ +/* #define BSD42 */ +/* #define BSD41a */ +#define SYSV /* required on SGI IRIX releases before 3.3 */ + +#include +ACE_SOCK_Connector connector_factory; + +#include +ACE_SOCK_Acceptor acceptor_factory; + +#include +ACE_INET_Addr address; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* struct itimerval */ +#include +#include +#include + +#if defined(SYSV) +#define bcopy(b1,b2,n) memcpy(b2,b1,n) +#define bzero(b1,n) memset(b1,0,n) +#include +#include +struct rusage + { + struct timeval ru_utime, ru_stime; + }; +#define RUSAGE_SELF 0 + +#else +#include +#endif + +struct sockaddr_in sinme; +struct sockaddr_un sunme; +struct sockaddr_in sinhim; +struct sockaddr_un sunhim; +struct sockaddr_in frominet; +struct sockaddr_un fromunix; + +struct Session_Control_Message +{ + long nbuf_; + // number of buffers that will be sent this round. + long size_; + // size of the buffers that will be sent +} session_control_buf; + +struct Data_Control_Message +{ + long size_; + char data_; +} *message_buf; + +int fromlen; +int domain = PF_INET; /* Default is to use Internet domain sockets. */ +char *domainname; /* Rendezvous address for UNIX domain sockets. */ +int fd; /* fd of network socket */ + +int data_buf_len = 1024 * 1024 * 2; // length of data portion +long total_msg_len; // length of entire message +char *data_buf; // pointer to data portion +int nbuf = 2 * 1024; /* number of buffers to send in sinkmode */ + +int bufoffset = 0; /* align buffer to this */ +int bufalign = 16 * 1024; /* modulo this */ + +int udp = 0; /* 0 = tcp, !0 = udp */ +int options = 0; /* socket options */ +int one = 1; /* for 4.3 BSD style setsockopt() */ +short port = 5001; /* TCP port number */ +char *host; /* ptr to name of host */ +int trans; /* 0=receive, !0=transmit mode */ +int sinkmode = 0; /* 0=normal I/O, !0=sink/source mode */ +int verbose = 0; /* 0=print basic info, 1=print cpu rate, proc + * resource usage. */ +int nodelay = 0; /* set TCP_NODELAY socket option */ +int b_flag = 0; /* use mread() */ +int sockbufsize = 0; /* socket buffer size to use */ +char fmt = 'K'; /* output format: k = kilobits, K = kilobytes, + * m = megabits, M = megabytes, + * g = gigabits, G = gigabytes */ +int touchdata = 0; /* access data after reading */ + +struct hostent *addr; +extern int errno; +extern int optind; +extern char *optarg; + +char Usage[] = "\ +Usage: ttcp -t [-options] host [ < in ]\n\ + ttcp -r [-options > out]\n\ +Common options:\n\ + -l ## length of bufs read from or written to network (default 8192)\n\ + -u use UDP instead of TCP\n\ + -U use UNIX domain sockets instead of Internet domain sockets\n\ + -p ## port number to send to or listen at (default 5001)\n\ + -s -t: source a pattern to network\n\ + -r: sink (discard) all data from network\n\ + -A align the start of buffers to this modulus (default 16384)\n\ + -O start buffers at this offset from the modulus (default 0)\n\ + -v verbose: print more statistics\n\ + -d set SO_DEBUG socket option\n\ + -b ## set socket buffer size (if supported)\n\ + -f X format for rate: k,K = kilo{bit,byte}; m,M = mega; g,G = giga\n\ +Options specific to -t:\n\ + -n## number of source bufs written to network (default 2048)\n\ + -D don't buffer TCP writes (sets TCP_NODELAY socket option)\n\ +Options specific to -r:\n\ + -B for -s, only output full blocks as specified by -l (for TAR)\n\ + -T \"touch\": access each byte as it's read\n\ +"; + +char stats[128]; +unsigned long nbytes; /* bytes on net */ +unsigned long numCalls = 0; /* # of I/O system calls */ +double cput, realt; /* user, real time (seconds) */ + +void err (char *s); +void mes (char *s); +void pattern (register char *cp, register int cnt); +char *outfmt (double b); +static void getrusage (int ignored, register struct rusage *ru); +static void gettimeofday (struct timeval *tp, struct timezone *zp); +void prep_timer (void); +double read_timer (char *str, int len); +static void prusage (register struct rusage *r0, struct rusage *r1, struct timeval *e, struct timeval *b, char *outp); +static void tvadd (struct timeval *tsum, struct timeval *t0, struct timeval *t1); +static void tvsub (struct timeval *tdiff, struct timeval *t1, struct timeval *t0); +static void psecs (long l, register char *cp); +void delay (int us); +int mread (int fd, register char *bufp, unsigned n); +int Nread (ACE_SOCK_Stream &s, void *buf, int count); +int Nwrite (ACE_SOCK_Stream &s, void *buf, int count); + +#if !defined (__cplusplus) +typedef void (*SIG_TYP)(); +#endif + +#ifdef SVR4 +void +sigpipe (int foo) +#else +void +sigpipe () +#endif +{ +} + +char *title = 0; +int new_line = 0; + +int +main (int argc, char *argv[]) +{ + ACE_SOCK_Stream connection_stream; + unsigned long addr_tmp; + int c; + + if (argc < 2) + goto usage; + + while ((c = getopt (argc, argv, "drstU:uvBDTb:f:l:n:p:A:O:L:xh:")) != -1) + { + switch (c) + { + + case 'h': + host = optarg; + break; + case 'x': + new_line = 1; + break; + case 'L': + title = optarg; + break; + case 'B': + b_flag = 1; + break; + case 't': + trans = 1; + break; + case 'r': + trans = 0; + break; + case 'd': + options |= SO_DEBUG; + break; + case 'D': +#ifdef TCP_NODELAY + nodelay = 1; +#else + fprintf (stderr, + "ttcp: -D option ignored: TCP_NODELAY socket option not supported\n"); +#endif + break; + case 'n': + nbuf = atoi (optarg); + break; + case 'l': + data_buf_len = atoi (optarg); + break; + case 's': + sinkmode = !sinkmode; + break; + case 'p': + port = atoi (optarg); + break; + case 'U': + domain = PF_UNIX; + domainname = optarg; + break; + case 'u': + udp = 1; + break; + case 'v': + verbose = 1; + break; + case 'A': + bufalign = atoi (optarg); + break; + case 'O': + bufoffset = atoi (optarg); + break; + case 'b': +#if defined(SO_SNDBUF) || defined(SO_RCVBUF) + sockbufsize = atoi (optarg); +#else + fprintf (stderr, "ttcp: -b option ignored: SO_SNDBUF/SO_RCVBUF socket options not supported\n"); +#endif + break; + case 'f': + fmt = *optarg; + break; + case 'T': + touchdata = 1; + break; + + default: + goto usage; + } + } + + /* if transmitter, create remote address to transmit to. */ + + if (trans) + { + if (address.set (port, host) == -1) + perror ("address.set"), exit (1); + } + + /* else, receiver create address to listen on */ + else + { + address.set (port); + } + + total_msg_len = sizeof (long) + data_buf_len; + + // allocate the buffer + message_buf = (Data_Control_Message *) malloc (total_msg_len); + if (message_buf == 0) + err ("malloc"); + +// if (bufalign != 0) +// message_buf += (bufalign - ((int) message_buf % bufalign) + bufoffset) % bufalign; + + // let's go ahead and set the control message for every send right now + message_buf->size_ = data_buf_len; + + session_control_buf.nbuf_ = nbuf; + session_control_buf.size_ = data_buf_len; + + // + // print out option values for trans and receiver + // + + if (trans) + { + fprintf (stdout, + "ttcp-t: data_buf_len=%d, nbuf=%d, align=%d/%d, port=%d", + data_buf_len, nbuf, bufalign, bufoffset, port); + if (sockbufsize) + fprintf (stdout, ", sockbufsize=%d", sockbufsize); + fprintf (stdout, " %s -> %s\n", + domain == PF_INET ? (udp ? "udp" : "tcp") : "unix", + host == 0 ? domainname : host); + } + else // receiver + { + fprintf (stdout, + "ttcp-r: data_buf_len=%d, nbuf=%d, align=%d/%d, port=%d", + data_buf_len, nbuf, bufalign, bufoffset, port); + if (sockbufsize) + fprintf (stdout, ", sockbufsize=%d", sockbufsize); + fprintf (stdout, " %s\n", domain == PF_INET ? (udp ? "udp" : "tcp") : "unix"); + } + + mes ("socket"); + + // + // connect and accept + // + + if (!udp) + { + signal (SIGPIPE, (SIG_TYP) sigpipe); + + /* the transmitter will set options and connect to receiver */ + if (trans) + { + if (connector_factory.connect (connection_stream, address) == -1) + perror ("connection failed"), exit (1); + fprintf (stdout, + "ttcp-t: data_buf_len=%d, nbuf=%d, align=%d/%d, port=%d", + data_buf_len, nbuf, bufalign, bufoffset, port); + + // turn off weird ack things + if (nodelay) + { + struct protoent *p = getprotobyname ("tcp"); + + if (p && connection_stream.set_option (p->p_proto, + TCP_NODELAY, + (char *)& one, + sizeof (one))) + err ("setsockopt: nodelay"); + mes ("nodelay"); + } + if (sockbufsize) + { + if (connection_stream.set_option (SOL_SOCKET, + SO_SNDBUF, + (char *) &sockbufsize, + sizeof sockbufsize) == -1) + err ("acceptor_factory.set_option"); + mes ("sndbuf"); + } + } + + /* receiver will listen for connections from the transmitter */ + else + { + if (acceptor_factory.open (address, 1) == -1) + perror ("acceptor open"), exit (1); + + ACE_INET_Addr remote_address; + + if (acceptor_factory.accept (connection_stream, + (ACE_Addr *) &remote_address) == -1) + perror ("acceptor accept"), exit (1); + + // set the window size + if (sockbufsize) + { + if (connection_stream.set_option (SOL_SOCKET, + SO_RCVBUF, + (char *) &sockbufsize, + sizeof sockbufsize) == -1) + err ("acceptor_factory.set_option"); + mes ("rcvbuf"); + } + + fprintf (stderr, "ttcp-r: accept from %s\n", remote_address.get_host_name()); + } + } + + // + // start timer + // + + errno = 0; + if (trans) + { + pattern (& (message_buf->data_), data_buf_len); + prep_timer (); + + ACE_DEBUG ((LM_DEBUG, "Sending session control message" + " nbuf %d, size %d\n", session_control_buf.nbuf_, + session_control_buf.size_)); + if (connection_stream.send_n ((char *) &session_control_buf, + sizeof (Session_Control_Message)) + != sizeof (Session_Control_Message)) + ACE_ERROR_RETURN ((LM_ERROR, "%p send session control failed\n", + "ttcp"), -1); + + long ack; + int send_result; + while (nbuf--) + { + send_result = connection_stream.send_n ((char *) message_buf, total_msg_len); + if (send_result != total_msg_len) + ACE_ERROR_RETURN ((LM_ERROR, "%p only sent %d of %d bytes on call %d\n", + "ttcp", send_result, total_msg_len, numCalls + 1), -1); + numCalls++; + nbytes += data_buf_len; + + if (connection_stream.recv_n ((char *) &ack, sizeof ack) + != sizeof ack) + ACE_ERROR_RETURN ((LM_ERROR, "%p recv of ack failed\n", + "ttcp"), -1); + + if (ack != data_buf_len) + ACE_DEBUG ((LM_DEBUG, "%received ack for only %d bytes\n", ack)); + } + } + else + { + prep_timer (); + + if (connection_stream.recv_n ((char *) &session_control_buf, + sizeof (Session_Control_Message)) + != sizeof (Session_Control_Message)) + ACE_ERROR_RETURN ((LM_ERROR, "%p recv session control failed\n", + "ttcp"), -1); + + ACE_DEBUG ((LM_DEBUG, "received session control message" + " nbuf %d, size %d\n", session_control_buf.nbuf_, + session_control_buf.size_)); + + nbuf = session_control_buf.nbuf_; + // ignore session_control_buf.size_ for now + + long cnt; + + while (nbuf--) + { + if (connection_stream.recv_n ((char *) message_buf, sizeof (long)) + != sizeof (long)) + ACE_ERROR_RETURN ((LM_ERROR, "%p recv data control failed\n", + "ttcp"), -1); + + cnt = connection_stream.recv_n (& (message_buf->data_), message_buf->size_); + if (cnt != message_buf->size_) + ACE_ERROR_RETURN ((LM_ERROR, "recv data failed\n"), -1); + + numCalls++; + nbytes += cnt; + + if (connection_stream.send_n ((char *) &cnt, sizeof cnt) + != sizeof cnt) + ACE_ERROR_RETURN ((LM_ERROR, "%p send ack failed\n", + "ttcp"), -1); + } + } + + if (errno) + err ("IO"); + + // + // stop the timer + // + + (void) read_timer (stats, sizeof (stats)); + if (udp && trans) + { + (void) Nwrite (connection_stream, message_buf, 4); /* rcvr end */ + (void) Nwrite (connection_stream, message_buf, 4); /* rcvr end */ + (void) Nwrite (connection_stream, message_buf, 4); /* rcvr end */ + (void) Nwrite (connection_stream, message_buf, 4); /* rcvr end */ + } + if (cput <= 0.0) + cput = 0.001; + if (realt <= 0.0) + realt = 0.001; + +#if defined (LM_RESULTS) + if (trans && (title != 0)) + { + double tmp; + FILE *fd; + char filename[BUFSIZ]; + ACE_OS::sprintf (filename, "%s.results", title); + fd = fopen(filename,"a+"); + if (new_line) + fprintf(fd,"\n -l %ldk \t", data_buf_len/1024); + tmp = ((double) nbytes) / realt; + fprintf(fd,"%.2f ", tmp * 8.0 / 1024.0 / 1024.0); + fclose(fd); + } +#endif + + fprintf (stdout, + "ttcp%s: %ld bytes in %.2f real seconds = %s/sec +++\n", + trans ? "-t" : "-r", + nbytes, realt, outfmt (((double) nbytes) / realt)); + if (verbose) + { + fprintf (stdout, + "ttcp%s: %ld bytes in %.2f CPU seconds = %s/cpu sec\n", + trans ? "-t" : "-r", + nbytes, cput, outfmt (((double) nbytes) / cput)); + } + fprintf (stdout, + "ttcp%s: %d I/O calls, msec/call = %.2f, calls/sec = %.2f\n", + trans ? "-t" : "-r", + numCalls, + 1024.0 * realt / ((double) numCalls), + ((double) numCalls) / realt); + fprintf (stdout, "ttcp%s: %s\n", trans ? "-t" : "-r", stats); + if (verbose) + { + fprintf (stdout, + "ttcp%s: buffer address %#x\n", + trans ? "-t" : "-r", + message_buf); + } + exit (0); + +usage: + fprintf (stderr, Usage); + return 1; +} + +void +err (char *s) +{ + fprintf (stderr, "ttcp%s: ", trans ? "-t" : "-r"); + perror (s); + fprintf (stderr, "errno=%d\n", errno); + exit (1); +} + +void +mes (char *s) +{ + fprintf (stderr, "ttcp%s: %s\n", trans ? "-t" : "-r", s); +} + +void +pattern (register char *cp, register int cnt) +{ + register char c; + c = 0; + while (cnt-- > 0) + { + while (!isprint ((c & 0x7F))) + c++; + *cp++ = (c++ & 0x7F); + } +} + +char * +outfmt (double b) +{ + static char obuf[50]; + switch (fmt) + { + case 'G': + sprintf (obuf, "%.2f GB", b / 1024.0 / 1024.0 / 1024.0); + break; + default: + case 'K': + sprintf (obuf, "%.2f KB", b / 1024.0); + break; + case 'M': + sprintf (obuf, "%.2f MB", b / 1024.0 / 1024.0); + break; + case 'g': + sprintf (obuf, "%.2f Gbit", b * 8.0 / 1024.0 / 1024.0 / 1024.0); + break; + case 'k': + sprintf (obuf, "%.2f Kbit", b * 8.0 / 1024.0); + break; + case 'm': + sprintf (obuf, "%.2f Mbit", b * 8.0 / 1024.0 / 1024.0); + break; + } + return obuf; +} + +static struct itimerval itime0; /* Time at which timing started */ +static struct rusage ru0; /* Resource utilization at the start */ + +#if defined(SYSV) +/*ARGSUSED */ +static void +getrusage (int ignored, register struct rusage *ru) +{ + struct tms buf; + + times (&buf); + + /* Assumption: HZ <= 2147 (LONG_MAX/1000000) */ + ru->ru_stime.tv_sec = buf.tms_stime / HZ; + ru->ru_stime.tv_usec = ((buf.tms_stime % HZ) * 1000000) / HZ; + ru->ru_utime.tv_sec = buf.tms_utime / HZ; + ru->ru_utime.tv_usec = ((buf.tms_utime % HZ) * 1000000) / HZ; +} + +/*ARGSUSED */ +static void +gettimeofday (struct timeval *tp, struct timezone *zp) +{ + tp->tv_sec = time (0); + tp->tv_usec = 0; +} +#endif /* SYSV */ +/* + * P R E P _ T I M E R + */ +void +prep_timer () +{ + itime0.it_interval.tv_sec = 0; + itime0.it_interval.tv_usec = 0; + itime0.it_value.tv_sec = LONG_MAX / 22; /* greatest possible value , itimer() count backwards */ + itime0.it_value.tv_usec = 0; + + + getrusage (RUSAGE_SELF, &ru0); + + /* Init REAL Timer */ + if (setitimer (ITIMER_REAL, &itime0, NULL)) + { + perror ("Setting 'itimer' REAL failed"); + return; + } + +} + +/* + * R E A D _ T I M E R + * + */ +double +read_timer (char *str, int len) +{ + struct itimerval itimedol; + struct rusage ru1; + struct timeval td; + struct timeval tend, tstart; + char line[132]; + + getrusage (RUSAGE_SELF, &ru1); + + if (getitimer (ITIMER_REAL, &itimedol)) + { + perror ("Getting 'itimer' REAL failed"); + return (0.0); + } + + prusage (&ru0, &ru1, &itime0.it_value, &itimedol.it_value, line); + (void) strncpy (str, line, len); + + /* Get real time */ + tvsub (&td, &itime0.it_value, &itimedol.it_value); + realt = td.tv_sec + ((double) td.tv_usec) / 1000000; + + /* Get CPU time (user+sys) */ + tvadd (&tend, &ru1.ru_utime, &ru1.ru_stime); + tvadd (&tstart, &ru0.ru_utime, &ru0.ru_stime); + tvsub (&td, &tend, &tstart); + cput = td.tv_sec + ((double) td.tv_usec) / 1000000; + if (cput < 0.00001) + cput = 0.00001; + return (cput); +} + +static void +prusage (register struct rusage *r0, struct rusage *r1, + struct timeval *e, struct timeval *b, char *outp) +{ + struct timeval tdiff; + register time_t t; + register char *cp; + register int i; + int ms; + + t = (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 + + (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 + + (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 + + (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000; + ms = (e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000; + +#define END(x) {while(*x) x++;} +#if defined(SYSV) + cp = "%Uuser %Ssys %Ereal %P"; +#else +#if defined(sgi) /* IRIX 3.3 will show 0 for %M,%F,%R,%C */ + cp = "%Uuser %Ssys %Ereal %P %Mmaxrss %F+%Rpf %Ccsw"; +#else + cp = "%Uuser %Ssys %Ereal %P %Xi+%Dd %Mmaxrss %F+%Rpf %Ccsw"; +#endif +#endif + for (; *cp; cp++) + { + if (*cp != '%') + *outp++ = *cp; + else if (cp[1]) + switch (*++cp) + { + + case 'U': + tvsub (&tdiff, &r1->ru_utime, &r0->ru_utime); + sprintf (outp, "%d.%01d", tdiff.tv_sec, tdiff.tv_usec / 100000); + END (outp); + break; + + case 'S': + tvsub (&tdiff, &r1->ru_stime, &r0->ru_stime); + sprintf (outp, "%d.%01d", tdiff.tv_sec, tdiff.tv_usec / 100000); + END (outp); + break; + + case 'E': + psecs (ms / 100, outp); + END (outp); + break; + + case 'P': + sprintf (outp, "%d%%", (int) (t * 100 / ((ms ? ms : 1)))); + END (outp); + break; + +#if !defined(SYSV) + case 'W': + i = r1->ru_nswap - r0->ru_nswap; + sprintf (outp, "%d", i); + END (outp); + break; + + case 'X': + sprintf (outp, "%d", t == 0 ? 0 : (r1->ru_ixrss - r0->ru_ixrss) / t); + END (outp); + break; + + case 'D': + sprintf (outp, "%d", t == 0 ? 0 : + (r1->ru_idrss + r1->ru_isrss - (r0->ru_idrss + r0->ru_isrss)) / t); + END (outp); + break; + + case 'K': + sprintf (outp, "%d", t == 0 ? 0 : + ((r1->ru_ixrss + r1->ru_isrss + r1->ru_idrss) - + (r0->ru_ixrss + r0->ru_idrss + r0->ru_isrss)) / t); + END (outp); + break; + + case 'M': + sprintf (outp, "%d", r1->ru_maxrss / 2); + END (outp); + break; + + case 'F': + sprintf (outp, "%d", r1->ru_majflt - r0->ru_majflt); + END (outp); + break; + + case 'R': + sprintf (outp, "%d", r1->ru_minflt - r0->ru_minflt); + END (outp); + break; + + case 'I': + sprintf (outp, "%d", r1->ru_inblock - r0->ru_inblock); + END (outp); + break; + + case 'O': + sprintf (outp, "%d", r1->ru_oublock - r0->ru_oublock); + END (outp); + break; + case 'C': + sprintf (outp, "%d+%d", r1->ru_nvcsw - r0->ru_nvcsw, + r1->ru_nivcsw - r0->ru_nivcsw); + END (outp); + break; +#endif /* !SYSV */ + } + } + *outp = '\0'; +} + +static void +tvadd (struct timeval *tsum, struct timeval *t0, struct timeval *t1) +{ + + tsum->tv_sec = t0->tv_sec + t1->tv_sec; + tsum->tv_usec = t0->tv_usec + t1->tv_usec; + if (tsum->tv_usec > 1000000) + tsum->tv_sec++, tsum->tv_usec -= 1000000; +} + +static void +tvsub (struct timeval *tdiff, struct timeval *t1, struct timeval *t0) +{ + + tdiff->tv_sec = t1->tv_sec - t0->tv_sec; + tdiff->tv_usec = t1->tv_usec - t0->tv_usec; + if (tdiff->tv_usec < 0) + tdiff->tv_sec--, tdiff->tv_usec += 1000000; +} + +static void +psecs (long l, register char *cp) +{ + register int i; + + i = l / 3600; + if (i) + { + sprintf (cp, "%d:", i); + END (cp); + i = l % 3600; + sprintf (cp, "%d%d", (i / 60) / 10, (i / 60) % 10); + END (cp); + } + else + { + i = l; + sprintf (cp, "%d", i / 60); + END (cp); + } + i %= 60; + *cp++ = ':'; + sprintf (cp, "%d%d", i / 10, i % 10); +} + +/* + * N R E A D + */ +int +Nread (ACE_SOCK_Stream &s, void *buf, int count) +{ + numCalls++; + return (s.recv (buf, count)); +} + +/* + * N W R I T E + */ +int +Nwrite (ACE_SOCK_Stream &s, void *buf, int count) +{ + numCalls++; + return s.send (buf, count); +} + +void +delay (int us) +{ + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = us; + (void) select (1, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &tv); +} + +/* + * M R E A D + * + * This function performs the function of a read(II) but will + * call read(II) multiple times in order to get the requested + * number of characters. This can be necessary because + * network connections don't deliver data with the same + * grouping as it is written with. Written by Robert S. Miles, BRL. + */ +int +mread (int fd, register char *bufp, unsigned n) +{ + register unsigned count = 0; + register int nread; + + do + { + nread = read (fd, bufp, n - count); + numCalls++; + if (nread < 0) + { + perror ("ttcp_mread"); + return (-1); + } + if (nread == 0) + return ((int) count); + count += (unsigned) nread; + bufp += nread; + } + while (count < n); + + return ((int) count); +} diff --git a/performance-tests/TTCP/C/How_to_run_tests b/performance-tests/TTCP/C/How_to_run_tests new file mode 100644 index 00000000000..c08a515a5af --- /dev/null +++ b/performance-tests/TTCP/C/How_to_run_tests @@ -0,0 +1,30 @@ +// C version +// +// + +// HOSTNAMES: +// for our tests, enatm0-tango.cs.wustl.edu was the receiver hostname used for atm transfers +// tango.cs.wustl.edu was the receiver hostname used for ethernet transfers +// substitute the proper receiver hostname for your system. + +// Results: +// These examples show the result files being stored in a /results directory off +// the current path. This can be set to whatever you like. + +// ATM with 32k receiver buffers +Receiver_Host: repeat 100 server -r -s -fm -p 10002 -b 65536 +Sender_Host: run_test 64 encip1-tango.cs.wustl.edu ./results/ace.atm.64 10002 + or: client -fm -s -t -l 1048576 -n 100 -h encip1-tango.cs.wustl.edu -L ./results/ace.atm.64 -p 10002 + +// ATM with 8k receiver buffers +Receiver_Host: repeat 100 new-ttcp -r -s -fm -p 10002 +Sender_Host: run_test 64 enatm0-tango.cs.wustl.edu ./results/c.atm.8 10002 + +// ETHERNET with 64k receiver buffers +Receiver_Host: repeat 100 new-ttcp -r -s -fm -p 10002 -b 65536 +Sender_Host: run_test 64 tango.cs.wustl.edu ./results/c.ethernet.64 10002 + +// ETHERNET with 8k receiver buffers +Receiver_Host: repeat 100 new-ttcp -r -s -fm -p 10002 +Sender_Host: run_test 64 tango.cs.wustl.edu ./results/c.ethernet.8 10002 + diff --git a/performance-tests/TTCP/C/Makefile b/performance-tests/TTCP/C/Makefile new file mode 100644 index 00000000000..d9df79f3bb0 --- /dev/null +++ b/performance-tests/TTCP/C/Makefile @@ -0,0 +1,52 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the wrapper-new-ttcp +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = new-ttcp + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(addsuffix .o,$(FILES)) + +LDLIBS = $(addprefix .obj/,$(LOBJ)) -Bstatic -Bdynamic + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VOBJS) $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +LINK_COMMAND = quantify -cache-dir=/$(IR)/quantify + +CCFLAGS = -O2 -DLM_RESULTS +#CCFLAGS = -g -DLM_RESULTS +#DCCFLAGS = -g + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + + + diff --git a/performance-tests/TTCP/C/README b/performance-tests/TTCP/C/README new file mode 100644 index 00000000000..88788c386eb --- /dev/null +++ b/performance-tests/TTCP/C/README @@ -0,0 +1,38 @@ + + TTCP for c_version, ACE-wrappers, ORBeline and Orbix + ---------------------------------------------------- + +This is the super-readme file for the "ttcp" code. This directory contains the C, ACE-wrappers, +ORBeline and Orbix versions of ttcp code. To compile the code, you have to do the following: + +1. You should have ACE, ORBeline and Orbix installed in your system and configured correctly. + (see the reference manual for installation and configuration procedure) + +2. Copy this directory (ttcp) in the same directory structure to your disk space. + +3. setup the following environment parameters (before compilation stage): + WRAPPER_ROOT, ORBELINE_ROOT, ORBIX_ROOT, LD_LIBRARY_PATH. + +For example: +WRAPPER_ROOT=/project/adaptive/ACE_wrappers +ORBELINE_ROOT=/project/adaptive/ORBelineV1.2 +ORBIX_ROOT=/project/adaptive/Orbix +LD_LIBRARY_PATH=/project/adaptive/ORBelineV1.2/lib + :/project/adaptive/ACE_wrappers/build/SunOS5.4/src + :/project/adaptive/Orbix/lib + +4. Do make (using GNU make) in this directory level. This will create the executable ttcp + target code for each ttcp version. + +5. Read the README or How_to_run_tests file existing in each directory to know how to use the + executable. + +6. Have fun. + + + +Ehab S. Al-Shaer +6/30/1995 + + + diff --git a/performance-tests/TTCP/C/new-ttcp.cpp b/performance-tests/TTCP/C/new-ttcp.cpp new file mode 100644 index 00000000000..92f24f6cf97 --- /dev/null +++ b/performance-tests/TTCP/C/new-ttcp.cpp @@ -0,0 +1,981 @@ +/* -*- C++ -*- */ +// @(#)new-ttcp.cpp 1.1 10/18/96 + +/* + * T T C P . C + * + * Test TCP connection. Makes a connection on port 5001 + * and transfers fabricated buffers or data copied from stdin. + * + * Usable on 4.2, 4.3, and 4.1a systems by defining one of + * BSD42 BSD43 (BSD41a) + * Machines using System V with BSD sockets should define SYSV. + * + * Modified for operation under 4.2BSD, 18 Dec 84 + * T.C. Slattery, USNA + * Minor improvements, Mike Muuss and Terry Slattery, 16-Oct-85. + * Modified in 1989 at Silicon Graphics, Inc. + * catch SIGPIPE to be able to print stats when receiver has died + * for tcp, don't look for sentinel during reads to allow small transfers + * increased default buffer size to 8K, nbuf to 2K to transfer 16MB + * moved default port to 5001, beyond IPPORT_USERRESERVED + * make sinkmode default because it is more popular, + * -s now means don't sink/source + * count number of read/write system calls to see effects of + * blocking from full socket buffers + * for tcp, -D option turns off buffered writes (sets TCP_NODELAY sockopt) + * buffer alignment options, -A and -O + * print stats in a format that's a bit easier to use with grep & awk + * for SYSV, mimic BSD routines to use most of the existing timing code + * Modified by Steve Miller of the University of Maryland, College Park + * -b sets the socket buffer size (SO_SNDBUF/SO_RCVBUF) + * Modified Sept. 1989 at Silicon Graphics, Inc. + * restored -s sense at request of tcs@brl + * Modified Oct. 1991 at Silicon Graphics, Inc. + * use getopt(3) for option processing, add -f and -T options. + * SGI IRIX 3.3 and 4.0 releases don't need #define SYSV. + * Modified Aug.1993 at University Paderborn, Germany + * some SVR4 changes and time functions changed to itimer() calls + * Modified by Douglas C. Schmidt September 28, 1994 + * added support for testing UNIX domain socket performance + * Modified by Tim Harrison May, 1995 + * added support for ACE wrappers + * Distribution Status - + * Public Domain. Distribution Unlimited. + */ +#ifndef lint +static char RCSid[] = "ttcp.c $Revision$"; +#endif + +/* #define BSD43 */ +/* #define BSD42 */ +/* #define BSD41a */ +#define SYSV /* required on SGI IRIX releases before 3.3 */ + +#include +ACE_SOCK_Connector connector_factory; + +#include +ACE_SOCK_Acceptor acceptor_factory; + +#include +ACE_INET_Addr address; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* struct itimerval */ +#include +#include +#include + +#if defined(SYSV) +#define bcopy(b1,b2,n) memcpy(b2,b1,n) +#define bzero(b1,n) memset(b1,0,n) +#include +#include +struct rusage + { + struct timeval ru_utime, ru_stime; + }; +#define RUSAGE_SELF 0 + +#else +#include +#endif + +struct sockaddr_in sinme; +struct sockaddr_un sunme; +struct sockaddr_in sinhim; +struct sockaddr_un sunhim; +struct sockaddr_in frominet; +struct sockaddr_un fromunix; + +int send_n (const void *buf, int len); +int recv_n (void *buf, int len); +int connection_descriptor; + +struct Session_Control_Message +{ + long nbuf_; + // number of buffers that will be sent this round. + long size_; + // size of the buffers that will be sent +} session_control_buf; + +struct Data_Control_Message +{ + long size_; + char data_; +} *message_buf; + +int fromlen; +int domain = PF_INET; /* Default is to use Internet domain sockets. */ +char *domainname; /* Rendezvous address for UNIX domain sockets. */ +int fd; /* fd of network socket */ + +int data_buf_len = 1024 * 1024 * 2; // length of data portion +long total_msg_len; // length of entire message +char *data_buf; // pointer to data portion +int nbuf = 2 * 1024; /* number of buffers to send in sinkmode */ + +int bufoffset = 0; /* align buffer to this */ +int bufalign = 16 * 1024; /* modulo this */ + +int udp = 0; /* 0 = tcp, !0 = udp */ +int options = 0; /* socket options */ +int one = 1; /* for 4.3 BSD style setsockopt() */ +short port = 5001; /* TCP port number */ +char *host; /* ptr to name of host */ +int trans; /* 0=receive, !0=transmit mode */ +int sinkmode = 0; /* 0=normal I/O, !0=sink/source mode */ +int verbose = 0; /* 0=print basic info, 1=print cpu rate, proc + * resource usage. */ +int nodelay = 0; /* set TCP_NODELAY socket option */ +int b_flag = 0; /* use mread() */ +int sockbufsize = 0; /* socket buffer size to use */ +char fmt = 'K'; /* output format: k = kilobits, K = kilobytes, + * m = megabits, M = megabytes, + * g = gigabits, G = gigabytes */ +int touchdata = 0; /* access data after reading */ + +struct hostent *addr; +extern int errno; +extern int optind; +extern char *optarg; + +char Usage[] = "\ +Usage: ttcp -t [-options] host [ < in ]\n\ + ttcp -r [-options > out]\n\ +Common options:\n\ + -l ## length of bufs read from or written to network (default 8192)\n\ + -u use UDP instead of TCP\n\ + -U use UNIX domain sockets instead of Internet domain sockets\n\ + -p ## port number to send to or listen at (default 5001)\n\ + -s -t: source a pattern to network\n\ + -r: sink (discard) all data from network\n\ + -A align the start of buffers to this modulus (default 16384)\n\ + -O start buffers at this offset from the modulus (default 0)\n\ + -v verbose: print more statistics\n\ + -d set SO_DEBUG socket option\n\ + -b ## set socket buffer size (if supported)\n\ + -f X format for rate: k,K = kilo{bit,byte}; m,M = mega; g,G = giga\n\ +Options specific to -t:\n\ + -n## number of source bufs written to network (default 2048)\n\ + -D don't buffer TCP writes (sets TCP_NODELAY socket option)\n\ +Options specific to -r:\n\ + -B for -s, only output full blocks as specified by -l (for TAR)\n\ + -T \"touch\": access each byte as it's read\n\ +"; + +char stats[128]; +unsigned long nbytes; /* bytes on net */ +unsigned long numCalls = 0; /* # of I/O system calls */ +double cput, realt; /* user, real time (seconds) */ + +void err (char *s); +void mes (char *s); +void pattern (register char *cp, register int cnt); +char *outfmt (double b); +static void getrusage (int ignored, register struct rusage *ru); +static void gettimeofday (struct timeval *tp, struct timezone *zp); +void prep_timer (void); +double read_timer (char *str, int len); +static void prusage (register struct rusage *r0, struct rusage *r1, struct timeval *e, struct timeval *b, char *outp); +static void tvadd (struct timeval *tsum, struct timeval *t0, struct timeval *t1); +static void tvsub (struct timeval *tdiff, struct timeval *t1, struct timeval *t0); +static void psecs (long l, register char *cp); +void delay (int us); +int mread (int fd, register char *bufp, unsigned n); +int Nread (ACE_SOCK_Stream &s, void *buf, int count); +int Nwrite (ACE_SOCK_Stream &s, void *buf, int count); + +#if !defined (__cplusplus) +typedef void (*SIG_TYP)(); +#endif + +#ifdef SVR4 +void +sigpipe (int foo) +#else +void +sigpipe () +#endif +{ +} + +char *title = 0; +int new_line = 0; + +int +main (int argc, char *argv[]) +{ + ACE_SOCK_Stream connection_stream; + unsigned long addr_tmp; + int c; + + if (argc < 2) + goto usage; + + while ((c = getopt (argc, argv, "drstU:uvBDTb:f:l:n:p:A:O:L:xh:")) != -1) + { + switch (c) + { + + case 'h': + host = optarg; + break; + case 'x': + new_line = 1; + break; + case 'L': + title = optarg; + break; + case 'B': + b_flag = 1; + break; + case 't': + trans = 1; + break; + case 'r': + trans = 0; + break; + case 'd': + options |= SO_DEBUG; + break; + case 'D': +#ifdef TCP_NODELAY + nodelay = 1; +#else + fprintf (stderr, + "ttcp: -D option ignored: TCP_NODELAY socket option not supported\n"); +#endif + break; + case 'n': + nbuf = atoi (optarg); + break; + case 'l': + data_buf_len = atoi (optarg); + break; + case 's': + sinkmode = !sinkmode; + break; + case 'p': + port = atoi (optarg); + break; + case 'U': + domain = PF_UNIX; + domainname = optarg; + break; + case 'u': + udp = 1; + break; + case 'v': + verbose = 1; + break; + case 'A': + bufalign = atoi (optarg); + break; + case 'O': + bufoffset = atoi (optarg); + break; + case 'b': +#if defined(SO_SNDBUF) || defined(SO_RCVBUF) + sockbufsize = atoi (optarg); +#else + fprintf (stderr, "ttcp: -b option ignored: SO_SNDBUF/SO_RCVBUF socket options not supported\n"); +#endif + break; + case 'f': + fmt = *optarg; + break; + case 'T': + touchdata = 1; + break; + + default: + goto usage; + } + } + + /* if transmitter, create remote address to transmit to. */ + + if (trans) + { + if (address.set (port, host) == -1) + perror ("address.set"), exit (1); + } + + /* else, receiver create address to listen on */ + else + { + address.set (port); + } + + total_msg_len = sizeof (long) + data_buf_len; + + // allocate the buffer + message_buf = (Data_Control_Message *) malloc (total_msg_len); + if (message_buf == 0) + err ("malloc"); + +// if (bufalign != 0) +// message_buf += (bufalign - ((int) message_buf % bufalign) + bufoffset) % bufalign; + + // let's go ahead and set the control message for every send right now + message_buf->size_ = data_buf_len; + + session_control_buf.nbuf_ = nbuf; + session_control_buf.size_ = data_buf_len; + + // + // print out option values for trans and receiver + // + + if (trans) + { + fprintf (stdout, + "ttcp-t: data_buf_len=%d, nbuf=%d, align=%d/%d, port=%d", + data_buf_len, nbuf, bufalign, bufoffset, port); + if (sockbufsize) + fprintf (stdout, ", sockbufsize=%d", sockbufsize); + fprintf (stdout, " %s -> %s\n", + domain == PF_INET ? (udp ? "udp" : "tcp") : "unix", + host == 0 ? domainname : host); + } + else // receiver + { + fprintf (stdout, + "ttcp-r: data_buf_len=%d, nbuf=%d, align=%d/%d, port=%d", + data_buf_len, nbuf, bufalign, bufoffset, port); + if (sockbufsize) + fprintf (stdout, ", sockbufsize=%d", sockbufsize); + fprintf (stdout, " %s\n", domain == PF_INET ? (udp ? "udp" : "tcp") : "unix"); + } + + mes ("socket"); + + // + // connect and accept + // + + if (!udp) + { + signal (SIGPIPE, (SIG_TYP) sigpipe); + + /* the transmitter will set options and connect to receiver */ + if (trans) + { + if (connector_factory.connect (connection_stream, address) == -1) + perror ("connection failed"), exit (1); + fprintf (stdout, + "ttcp-t: data_buf_len=%d, nbuf=%d, align=%d/%d, port=%d", + data_buf_len, nbuf, bufalign, bufoffset, port); + + // turn off weird ack things + if (nodelay) + { + struct protoent *p = getprotobyname ("tcp"); + + if (p && connection_stream.set_option (p->p_proto, + TCP_NODELAY, + (char *)& one, + sizeof (one))) + err ("setsockopt: nodelay"); + mes ("nodelay"); + } + if (sockbufsize) + { + if (connection_stream.set_option (SOL_SOCKET, + SO_SNDBUF, + (char *) &sockbufsize, + sizeof sockbufsize) == -1) + err ("acceptor_factory.set_option"); + mes ("sndbuf"); + } + } + + /* receiver will listen for connections from the transmitter */ + else + { + if (acceptor_factory.open (address, 1) == -1) + perror ("acceptor open"), exit (1); + + ACE_INET_Addr remote_address; + + if (acceptor_factory.accept (connection_stream, + (ACE_Addr *) &remote_address) == -1) + perror ("acceptor accept"), exit (1); + + // set the window size + if (sockbufsize) + { + if (connection_stream.set_option (SOL_SOCKET, + SO_RCVBUF, + (char *) &sockbufsize, + sizeof sockbufsize) == -1) + err ("acceptor_factory.set_option"); + mes ("rcvbuf"); + } + + fprintf (stderr, "ttcp-r: accept from %s\n", remote_address.get_host_name()); + } + } + + // + // start timer + // + + errno = 0; + + // used in send_n and recv_n + connection_descriptor = connection_stream.get_handle (); + + if (trans) + { + pattern (& (message_buf->data_), data_buf_len); + prep_timer (); + + ACE_DEBUG ((LM_DEBUG, "Sending session control message" + " nbuf %d, size %d\n", session_control_buf.nbuf_, + session_control_buf.size_)); + if (send_n ((char *) &session_control_buf, + sizeof (Session_Control_Message)) + != sizeof (Session_Control_Message)) + ACE_ERROR_RETURN ((LM_ERROR, "%p send session control failed\n", + "ttcp"), -1); + + long ack; + int send_result; + while (nbuf--) + { + send_result = send_n ((char *) message_buf, total_msg_len); + if (send_result != total_msg_len) + ACE_ERROR_RETURN ((LM_ERROR, "%p only sent %d of %d bytes on call %d\n", + "ttcp", send_result, total_msg_len, numCalls + 1), -1); + numCalls++; + nbytes += data_buf_len; + + if (recv_n ((char *) &ack, sizeof ack) != sizeof ack) + ACE_ERROR_RETURN ((LM_ERROR, "%p recv of ack failed\n", + "ttcp"), -1); + + if (ack != data_buf_len) + ACE_DEBUG ((LM_DEBUG, "%received ack for only %d bytes\n", ack)); + } + } + else + { + prep_timer (); + + if (recv_n ((char *) &session_control_buf, + sizeof (Session_Control_Message)) != sizeof (Session_Control_Message)) + ACE_ERROR_RETURN ((LM_ERROR, "%p recv session control failed\n", + "ttcp"), -1); + + ACE_DEBUG ((LM_DEBUG, "received session control message" + " nbuf %d, size %d\n", session_control_buf.nbuf_, + session_control_buf.size_)); + + nbuf = session_control_buf.nbuf_; + // ignore session_control_buf.size_ for now + + long cnt; + + while (nbuf--) + { + if (recv_n ((char *) message_buf, sizeof (long)) != sizeof (long)) + ACE_ERROR_RETURN ((LM_ERROR, "%p recv data control failed\n", + "ttcp"), -1); + + cnt = recv_n (& (message_buf->data_), message_buf->size_); + if (cnt != message_buf->size_) + ACE_ERROR_RETURN ((LM_ERROR, "recv data failed\n"), -1); + + numCalls++; + nbytes += cnt; + + if (send_n ((char *) &cnt, sizeof cnt) != sizeof cnt) + ACE_ERROR_RETURN ((LM_ERROR, "%p send ack failed\n", + "ttcp"), -1); + } + } + + if (errno) + err ("IO"); + + // + // stop the timer + // + + (void) read_timer (stats, sizeof (stats)); + if (udp && trans) + { + (void) Nwrite (connection_stream, message_buf, 4); /* rcvr end */ + (void) Nwrite (connection_stream, message_buf, 4); /* rcvr end */ + (void) Nwrite (connection_stream, message_buf, 4); /* rcvr end */ + (void) Nwrite (connection_stream, message_buf, 4); /* rcvr end */ + } + if (cput <= 0.0) + cput = 0.001; + if (realt <= 0.0) + realt = 0.001; + +#if defined (LM_RESULTS) + if (trans && (title != 0)) + { + double tmp; + FILE *fd; + char filename[BUFSIZ]; + ACE_OS::sprintf (filename, "%s.results", title); + fd = fopen(filename,"a+"); + if (new_line) + fprintf(fd,"\n -l %ldk \t", data_buf_len/1024); + tmp = ((double) nbytes) / realt; + fprintf(fd,"%.2f ", tmp * 8.0 / 1024.0 / 1024.0); + fclose(fd); + } +#endif + + fprintf (stdout, + "ttcp%s: %ld bytes in %.2f real seconds = %s/sec +++\n", + trans ? "-t" : "-r", + nbytes, realt, outfmt (((double) nbytes) / realt)); + if (verbose) + { + fprintf (stdout, + "ttcp%s: %ld bytes in %.2f CPU seconds = %s/cpu sec\n", + trans ? "-t" : "-r", + nbytes, cput, outfmt (((double) nbytes) / cput)); + } + fprintf (stdout, + "ttcp%s: %d I/O calls, msec/call = %.2f, calls/sec = %.2f\n", + trans ? "-t" : "-r", + numCalls, + 1024.0 * realt / ((double) numCalls), + ((double) numCalls) / realt); + fprintf (stdout, "ttcp%s: %s\n", trans ? "-t" : "-r", stats); + if (verbose) + { + fprintf (stdout, + "ttcp%s: buffer address %#x\n", + trans ? "-t" : "-r", + message_buf); + } + exit (0); + +usage: + fprintf (stderr, Usage); + return 1; +} + +int +send_n (const void *buf, int len) +{ + size_t bytes_written; + int n; + + for (bytes_written = 0; bytes_written < len; bytes_written += n) + if ((n = write (connection_descriptor, (const char *) buf + bytes_written, + len - bytes_written)) == -1) + return -1; + + return bytes_written; +} + +int +recv_n (void *buf, int len) +{ + size_t bytes_read; + int n; + + for (bytes_read = 0; bytes_read < len; bytes_read += n) + if ((n = read (connection_descriptor, (char *) buf + bytes_read, + len - bytes_read)) == -1) + return -1; + else if (n == 0) + break; + + return bytes_read; +} + +void +err (char *s) +{ + fprintf (stderr, "ttcp%s: ", trans ? "-t" : "-r"); + perror (s); + fprintf (stderr, "errno=%d\n", errno); + exit (1); +} + +void +mes (char *s) +{ + fprintf (stderr, "ttcp%s: %s\n", trans ? "-t" : "-r", s); +} + +void +pattern (register char *cp, register int cnt) +{ + register char c; + c = 0; + while (cnt-- > 0) + { + while (!isprint ((c & 0x7F))) + c++; + *cp++ = (c++ & 0x7F); + } +} + +char * +outfmt (double b) +{ + static char obuf[50]; + switch (fmt) + { + case 'G': + sprintf (obuf, "%.2f GB", b / 1024.0 / 1024.0 / 1024.0); + break; + default: + case 'K': + sprintf (obuf, "%.2f KB", b / 1024.0); + break; + case 'M': + sprintf (obuf, "%.2f MB", b / 1024.0 / 1024.0); + break; + case 'g': + sprintf (obuf, "%.2f Gbit", b * 8.0 / 1024.0 / 1024.0 / 1024.0); + break; + case 'k': + sprintf (obuf, "%.2f Kbit", b * 8.0 / 1024.0); + break; + case 'm': + sprintf (obuf, "%.2f Mbit", b * 8.0 / 1024.0 / 1024.0); + break; + } + return obuf; +} + +static struct itimerval itime0; /* Time at which timing started */ +static struct rusage ru0; /* Resource utilization at the start */ + +#if defined(SYSV) +/*ARGSUSED */ +static void +getrusage (int ignored, register struct rusage *ru) +{ + struct tms buf; + + times (&buf); + + /* Assumption: HZ <= 2147 (LONG_MAX/1000000) */ + ru->ru_stime.tv_sec = buf.tms_stime / HZ; + ru->ru_stime.tv_usec = ((buf.tms_stime % HZ) * 1000000) / HZ; + ru->ru_utime.tv_sec = buf.tms_utime / HZ; + ru->ru_utime.tv_usec = ((buf.tms_utime % HZ) * 1000000) / HZ; +} + +/*ARGSUSED */ +static void +gettimeofday (struct timeval *tp, struct timezone *zp) +{ + tp->tv_sec = time (0); + tp->tv_usec = 0; +} +#endif /* SYSV */ +/* + * P R E P _ T I M E R + */ +void +prep_timer () +{ + itime0.it_interval.tv_sec = 0; + itime0.it_interval.tv_usec = 0; + itime0.it_value.tv_sec = LONG_MAX / 22; /* greatest possible value , itimer() count backwards */ + itime0.it_value.tv_usec = 0; + + + getrusage (RUSAGE_SELF, &ru0); + + /* Init REAL Timer */ + if (setitimer (ITIMER_REAL, &itime0, NULL)) + { + perror ("Setting 'itimer' REAL failed"); + return; + } + +} + +/* + * R E A D _ T I M E R + * + */ +double +read_timer (char *str, int len) +{ + struct itimerval itimedol; + struct rusage ru1; + struct timeval td; + struct timeval tend, tstart; + char line[132]; + + getrusage (RUSAGE_SELF, &ru1); + + if (getitimer (ITIMER_REAL, &itimedol)) + { + perror ("Getting 'itimer' REAL failed"); + return (0.0); + } + + prusage (&ru0, &ru1, &itime0.it_value, &itimedol.it_value, line); + (void) strncpy (str, line, len); + + /* Get real time */ + tvsub (&td, &itime0.it_value, &itimedol.it_value); + realt = td.tv_sec + ((double) td.tv_usec) / 1000000; + + /* Get CPU time (user+sys) */ + tvadd (&tend, &ru1.ru_utime, &ru1.ru_stime); + tvadd (&tstart, &ru0.ru_utime, &ru0.ru_stime); + tvsub (&td, &tend, &tstart); + cput = td.tv_sec + ((double) td.tv_usec) / 1000000; + if (cput < 0.00001) + cput = 0.00001; + return (cput); +} + +static void +prusage (register struct rusage *r0, struct rusage *r1, + struct timeval *e, struct timeval *b, char *outp) +{ + struct timeval tdiff; + register time_t t; + register char *cp; + register int i; + int ms; + + t = (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 + + (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 + + (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 + + (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000; + ms = (e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000; + +#define END(x) {while(*x) x++;} +#if defined(SYSV) + cp = "%Uuser %Ssys %Ereal %P"; +#else +#if defined(sgi) /* IRIX 3.3 will show 0 for %M,%F,%R,%C */ + cp = "%Uuser %Ssys %Ereal %P %Mmaxrss %F+%Rpf %Ccsw"; +#else + cp = "%Uuser %Ssys %Ereal %P %Xi+%Dd %Mmaxrss %F+%Rpf %Ccsw"; +#endif +#endif + for (; *cp; cp++) + { + if (*cp != '%') + *outp++ = *cp; + else if (cp[1]) + switch (*++cp) + { + + case 'U': + tvsub (&tdiff, &r1->ru_utime, &r0->ru_utime); + sprintf (outp, "%d.%01d", tdiff.tv_sec, tdiff.tv_usec / 100000); + END (outp); + break; + + case 'S': + tvsub (&tdiff, &r1->ru_stime, &r0->ru_stime); + sprintf (outp, "%d.%01d", tdiff.tv_sec, tdiff.tv_usec / 100000); + END (outp); + break; + + case 'E': + psecs (ms / 100, outp); + END (outp); + break; + + case 'P': + sprintf (outp, "%d%%", (int) (t * 100 / ((ms ? ms : 1)))); + END (outp); + break; + +#if !defined(SYSV) + case 'W': + i = r1->ru_nswap - r0->ru_nswap; + sprintf (outp, "%d", i); + END (outp); + break; + + case 'X': + sprintf (outp, "%d", t == 0 ? 0 : (r1->ru_ixrss - r0->ru_ixrss) / t); + END (outp); + break; + + case 'D': + sprintf (outp, "%d", t == 0 ? 0 : + (r1->ru_idrss + r1->ru_isrss - (r0->ru_idrss + r0->ru_isrss)) / t); + END (outp); + break; + + case 'K': + sprintf (outp, "%d", t == 0 ? 0 : + ((r1->ru_ixrss + r1->ru_isrss + r1->ru_idrss) - + (r0->ru_ixrss + r0->ru_idrss + r0->ru_isrss)) / t); + END (outp); + break; + + case 'M': + sprintf (outp, "%d", r1->ru_maxrss / 2); + END (outp); + break; + + case 'F': + sprintf (outp, "%d", r1->ru_majflt - r0->ru_majflt); + END (outp); + break; + + case 'R': + sprintf (outp, "%d", r1->ru_minflt - r0->ru_minflt); + END (outp); + break; + + case 'I': + sprintf (outp, "%d", r1->ru_inblock - r0->ru_inblock); + END (outp); + break; + + case 'O': + sprintf (outp, "%d", r1->ru_oublock - r0->ru_oublock); + END (outp); + break; + case 'C': + sprintf (outp, "%d+%d", r1->ru_nvcsw - r0->ru_nvcsw, + r1->ru_nivcsw - r0->ru_nivcsw); + END (outp); + break; +#endif /* !SYSV */ + } + } + *outp = '\0'; +} + +static void +tvadd (struct timeval *tsum, struct timeval *t0, struct timeval *t1) +{ + + tsum->tv_sec = t0->tv_sec + t1->tv_sec; + tsum->tv_usec = t0->tv_usec + t1->tv_usec; + if (tsum->tv_usec > 1000000) + tsum->tv_sec++, tsum->tv_usec -= 1000000; +} + +static void +tvsub (struct timeval *tdiff, struct timeval *t1, struct timeval *t0) +{ + + tdiff->tv_sec = t1->tv_sec - t0->tv_sec; + tdiff->tv_usec = t1->tv_usec - t0->tv_usec; + if (tdiff->tv_usec < 0) + tdiff->tv_sec--, tdiff->tv_usec += 1000000; +} + +static void +psecs (long l, register char *cp) +{ + register int i; + + i = l / 3600; + if (i) + { + sprintf (cp, "%d:", i); + END (cp); + i = l % 3600; + sprintf (cp, "%d%d", (i / 60) / 10, (i / 60) % 10); + END (cp); + } + else + { + i = l; + sprintf (cp, "%d", i / 60); + END (cp); + } + i %= 60; + *cp++ = ':'; + sprintf (cp, "%d%d", i / 10, i % 10); +} + +/* + * N R E A D + */ +int +Nread (ACE_SOCK_Stream &s, void *buf, int count) +{ + numCalls++; + return (s.recv (buf, count)); +} + +/* + * N W R I T E + */ +int +Nwrite (ACE_SOCK_Stream &s, void *buf, int count) +{ + numCalls++; + return s.send (buf, count); +} + +void +delay (int us) +{ + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = us; + (void) select (1, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &tv); +} + +/* + * M R E A D + * + * This function performs the function of a read(II) but will + * call read(II) multiple times in order to get the requested + * number of characters. This can be necessary because + * network connections don't deliver data with the same + * grouping as it is written with. Written by Robert S. Miles, BRL. + */ +int +mread (int fd, register char *bufp, unsigned n) +{ + register unsigned count = 0; + register int nread; + + do + { + nread = read (fd, bufp, n - count); + numCalls++; + if (nread < 0) + { + perror ("ttcp_mread"); + return (-1); + } + if (nread == 0) + return ((int) count); + count += (unsigned) nread; + bufp += nread; + } + while (count < n); + + return ((int) count); +} diff --git a/performance-tests/TTCP/C/run_test b/performance-tests/TTCP/C/run_test new file mode 100644 index 00000000000..9a4fa346ad3 --- /dev/null +++ b/performance-tests/TTCP/C/run_test @@ -0,0 +1,35 @@ +# test_run 64 enatm0-kavita.cs.wustl.edu title 10002 +# repeat 100 new-ttcp -r -s -fm -p 10002 -b 65536 +#!/bin/csh -f +if ($#argv != 4) then + echo "Usage: sclt " $4 + exit 1 +endif +# +@ msize=1024 +@ limit= ($argv[1] * 1024) +#echo $limit +#echo $msize +echo "Iteration#" 1 ": new-ttcp -fm -s -t -l" $msize "-h" $2 "-x -L" $3 "-p" $4 +new-ttcp -fm -s -t -l $msize -h $2 -x -L $3 -p $4 +sleep 1 +set flag=0 +while ($msize <= $limit) + if ($flag == 0) goto label + echo "Iteration#" 1 ": new-ttcp -fm -s -t -l" $msize "-h" $2 "-x -L" $3 "-p" $4 + new-ttcp -fm -s -t -l $msize -h $2 -x -L $3 -p $4 + sleep 1 + label: + set flag=1 + foreach i (2 3 4 5) + echo "Iteration#" $i ": new-ttcp -fm -s -t -l" $msize "-h" $2 "-L" $3 "-p" $4 + new-ttcp -fm -s -t -l $msize -h $2 -L $3 -p $4 + sleep 1 + end + echo "---------------------------" + @ msize = ($msize * 2) +end + +echo " " +echo "Done at:" +date diff --git a/performance-tests/TTCP/Makefile b/performance-tests/TTCP/Makefile new file mode 100644 index 00000000000..c62d08f8641 --- /dev/null +++ b/performance-tests/TTCP/Makefile @@ -0,0 +1,27 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Orbix applications +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +INFO = README + +DIRS = ACE-C++ \ + C \ + Orbix \ + ORBeline + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + diff --git a/performance-tests/TTCP/ORBeline/How_to_run_tests b/performance-tests/TTCP/ORBeline/How_to_run_tests new file mode 100644 index 00000000000..1ec726d26bd --- /dev/null +++ b/performance-tests/TTCP/ORBeline/How_to_run_tests @@ -0,0 +1,57 @@ +// ORBeline +// +// sequence AND string + +// HOSTNAMES: +// For our tests, tango.cs.wustl.edu was the receiver hostname. For atm transfers, you +// should setup the environment variable ORBELINE_IPADDR=ATM-IP-ADDR. Otherwise, +// the ethernet IP address of tango.cs.wustl.edu wis used. +// For your case, substitute the proper receiver hostname for your system. + +// ORBeline DAEMONS: +// there must be an ORBeline daemon running on the receiver host in your system. +// in our case, we had an ORBeline daemon running on tango.cs.wustl.edu + +// WRAPPER_ROOT: +// WRAPPER_ROOT can be set to the root directory of ACE so that these lines +// can be cut and pasted to run tests. + +// Results: +// These examples show the result files being stored in a /results directory off +// the current path. This can be set to whatever you like. + +// ****** sequence ****** (-q option flag) + +// ATM with 64k receiver buffers (setenv ORBELINE_IPADDR=128.252.114.18) +Receiver_Host: server "$WRAPPER_ROOT/apps/ttcp/orbeline/server -s -r -fm -b 65536 -q" +Sender_Host: run_test 64 tango.cs.wustl.edu ./results/sequence.atm.64 -q + +// ATM with 8k reciever buffers (setenv ORBELINE_IPADDR=128.252.114.18) +Receiver_Host: server "$WRAPPER_ROOT/apps/ttcp/orbeline/server -s -r -fm -q" +Sender_Host: run_test 64 tango.cs.wustl.edu ./results/sequence.atm.8 -q + +// ETHERNET with 64k receiver buffers +Receiver_Host: server "$WRAPPER_ROOT/apps/ttcp/orbeline/server -s -r -fm -b 65536 -q" +Sender_Host: run_test 64 tango.cs.wustl.edu ./results/sequence.atm.64 -q + +// ETHERNET with 8k reciever buffers +Receiver_Host: server "$WRAPPER_ROOT/apps/ttcp/orbeline/server -s -r -fm -q" +Sender_Host: run_test 64 tango.cs.wustl.edu ./results/sequence.atm.8 -q + +// ****** string ****** (-q is omitted) + +// ATM with 64k receiver buffers (setenv ORBELINE_IPADDR=128.252.114.18) +Receiver_Host: server "$WRAPPER_ROOT/apps/ttcp/orbeline/server -s -r -fm -b 65536" +Sender_Host: run_test 64 tango.cs.wustl.edu ./results/sequence.atm.64 + +// ATM with 8k reciever buffers (setenv ORBELINE_IPADDR=128.252.114.18) +Receiver_Host: server "$WRAPPER_ROOT/apps/ttcp/orbeline/server -s -r -fm" +Sender_Host: run_test 64 tango.cs.wustl.edu ./results/sequence.atm.64 + +// ETHERNET with 64k receiver buffers +Receiver_Host: server "$WRAPPER_ROOT/apps/ttcp/orbeline/server -s -r -fm" +Sender_Host: run_test 64 tango.cs.wustl.edu ./results/sequence.atm.8 + +// ETHERNET with 8k reciever buffers +Receiver_Host: server "$WRAPPER_ROOT/apps/ttcp/orbeline/server -s -r -fm" +Sender_Host: run_test 64 tango.cs.wustl.edu ./results/sequence.atm.8 diff --git a/performance-tests/TTCP/ORBeline/Makefile b/performance-tests/TTCP/ORBeline/Makefile new file mode 100644 index 00000000000..b5e39348090 --- /dev/null +++ b/performance-tests/TTCP/ORBeline/Makefile @@ -0,0 +1,33 @@ +include ./stdmk +EXE = server client + +all: $(EXE) + +# Remeber -p for generating mon.out for profiler +#C++FLAGS = -O4 -p -DTEST_SEQUENCE +#C++FLAGS = -O4 -DTEST_SEQUENCE +#C++FLAGS = -O4 -p +#C++FLAGS = -g +C++FLAGS = -O4 $(CCFLAGS) + +realclean: + -rm -f core *.o client server $(EXE) *~ + +clean: + -rm -f core *.o client server $(EXE) *~ + +ttcp_c.cc: ttcp.idl + $(ORBCC) ttcp.idl + +ttcp_s.cc: ttcp.idl + $(ORBCC) ttcp.idl + +ttcp_i.o: ttcp_i.cpp + $(CC) $(C++FLAGS) -I./ -I../../include -c ttcp_i.cpp + +client : ttcp_s.o ttcp_c.o ttcp_i.o + $(CC) $(C++FLAGS) -o client ttcp_i.o ttcp_s.o ttcp_c.o $(LIBPATH) $(LIBORB) $(STDCC_LIBS) + +server : ttcp_s.o ttcp_c.o ttcp_i.o + $(CC) $(C++FLAGS) -o server ttcp_i.o ttcp_s.o ttcp_c.o $(LIBPATH) $(LIBORB) $(STDCC_LIBS) + diff --git a/performance-tests/TTCP/ORBeline/run_test b/performance-tests/TTCP/ORBeline/run_test new file mode 100644 index 00000000000..842be36c4ac --- /dev/null +++ b/performance-tests/TTCP/ORBeline/run_test @@ -0,0 +1,30 @@ +#!/bin/csh -f +if ($#argv < 3) then + echo "Usage: sclt -q" + exit 1 +endif +# +@ msize=1024 +@ limit= ($argv[1] * 1024) +#echo $limit +#echo $msize +echo "Iteration#" 1 ": client -D -fm -s -t -l" $msize "-h" $2 "-L" $3 $4 +client -D -fm -s -t -l $msize -h $2 -x -L $3 $4 +set flag=0 +while ($msize <= $limit) + if ($flag == 0) goto label + echo "Iteration#" 1 ": client -D -fm -s -t -l" $msize "-h" $2 "-x -L" $3 $4 + client -D -fm -s -t -l $msize -h $2 -x -L $3 $4 + label: + set flag=1 + foreach i (2 3 4 5) + echo "Iteration#" $i ": client -D -fm -s -t -l" $msize "-h" $2 "-x -L " $3 $4 + client -D -fm -s -t -l $msize -h $2 -L $3 $4 + end + echo "---------------------------" + @ msize = ($msize * 2) +end + +echo " " +echo "Done at:" +date diff --git a/performance-tests/TTCP/ORBeline/ser b/performance-tests/TTCP/ORBeline/ser new file mode 100644 index 00000000000..da25e305013 --- /dev/null +++ b/performance-tests/TTCP/ORBeline/ser @@ -0,0 +1,4 @@ +server -s -r -fm -b 65536 $1 +#8192 +#16384 +#32768 diff --git a/performance-tests/TTCP/ORBeline/stdmk b/performance-tests/TTCP/ORBeline/stdmk new file mode 100644 index 00000000000..0acbf5c922c --- /dev/null +++ b/performance-tests/TTCP/ORBeline/stdmk @@ -0,0 +1,34 @@ +CC = CC +DEBUG = + +ORBELINEDIR = $(ORBELINE_ROOT) + +ORBCC = $(ORBELINEDIR)/bin/orbeline -v _c -m _s + +CCINCLUDES = -I. -I$(ORBELINEDIR)/include + +CCFLAGS = $(CCINCLUDES) $(DEBUG) + +LIBPATH = -L$(ORBELINEDIR)/lib + +STDCC_LIBS = -lsocket -lnsl -ldl + +LIBIR = -lir +LIBORB = -lorb -lorbinit +LIBDII = -ldii -lir + +.SUFFIXES: .C .o .h .hh .cc + +.C.o: + $(CC) $(CCFLAGS) -c -o $@ $< + +.cc.o: + $(CC) $(CCFLAGS) -c -o $@ $< + +.C.cpp: + $(CC) -E $(CCFLAGS) $< > $@ + +.cc.cpp: + $(CC) -E $(CCFLAGS) $< > $@ + + diff --git a/performance-tests/TTCP/ORBeline/tango_clt b/performance-tests/TTCP/ORBeline/tango_clt new file mode 100644 index 00000000000..fb5ec083ec1 --- /dev/null +++ b/performance-tests/TTCP/ORBeline/tango_clt @@ -0,0 +1,6 @@ +client -fm -s -t -D -l 1024 -h tango.cs.wustl.edu $1 +#4096 +#32768 +#16384 +#131072 +#262144 diff --git a/performance-tests/TTCP/ORBeline/ttcp.idl b/performance-tests/TTCP/ORBeline/ttcp.idl new file mode 100644 index 00000000000..cf83cc83a20 --- /dev/null +++ b/performance-tests/TTCP/ORBeline/ttcp.idl @@ -0,0 +1,23 @@ +/* -*- C++ -*- */ +// @(#)ttcp.idl 1.1 10/18/96 + + +interface ttcp_sequence { + +typedef sequence my_sequence; + + oneway void send (in my_sequence ttcp_rec); + oneway void send_hack (in string ttcp_string); + oneway void start_timer (); + oneway void stop_timer (); +}; + +interface ttcp_string { + + oneway void send (in string ttcp_string); + oneway void send_hack (in string ttcp_string); + oneway void start_timer (); + oneway void stop_timer (); +}; + + diff --git a/performance-tests/TTCP/ORBeline/ttcp_c.cc b/performance-tests/TTCP/ORBeline/ttcp_c.cc new file mode 100644 index 00000000000..da268e96821 --- /dev/null +++ b/performance-tests/TTCP/ORBeline/ttcp_c.cc @@ -0,0 +1,302 @@ +/* This file is automatically generated by Orbeline. */ +/* Do not modify this file. */ +/* Orbeline (c) is copyrighted by PostModern Computing, Inc. */ + +#include + +const CORBA::TypeInfo ttcp_sequence::_class_info("ttcp_sequence", + &ttcp_sequence::_reader, + CORBA::Object::_desc(), + 0); +const CORBA::TypeInfo *ttcp_sequence::_desc() +{ + return &_class_info; +} +const CORBA::TypeInfo *ttcp_sequence::_type_info() const +{ + return &_class_info; +} +void *ttcp_sequence::_safe_narrow(const CORBA::TypeInfo *info) const +{ + if (&_class_info == info) + return (void *) this; + void *ret = NULL; + return ret; +} +ttcp_sequence *ttcp_sequence::_narrow(const CORBA::Object *obj) +{ + void *ptr = obj->_safe_narrow(&_class_info); + return (ttcp_sequence *) ptr; +} +ttcp_sequence *ttcp_sequence::_bind(CORBA::Environment &_env, const char *_object_name, + const char *_host_name, const CORBA::BindOptions *opt) +{ + _env.clear_exception(); + ttcp_sequence *_impl; + CORBA::Object *_obj = _implementation("ttcp_sequence", _object_name); + if (!_obj) { + _impl = new ttcp_sequence(_object_name); +#if defined(_MSC_BUG) + _impl->Object::_bind("ttcp_sequence", _env, _object_name, _host_name, opt); +#else + _impl->CORBA::Object::_bind("ttcp_sequence", _env, _object_name, _host_name, opt); +#endif + if (_env.check_exception()) { + delete _impl; + return NULL; + } + } + else + _impl = ttcp_sequence::_narrow(_obj); + return _impl; +} + +#if !defined(_IMPLEMENT_SEQUENCE_CORBA__Char_ttcp_sequence__) && defined(_DECLARE_SEQUENCE_CORBA__Char_ttcp_sequence___ttcp_idl) +#define _IMPLEMENT_SEQUENCE_CORBA__Char_ttcp_sequence__ +IMPLEMENT_PRIMITIVE_SEQUENCE(CORBA__Char,CORBA::Char,ttcp_sequence::) +#endif + + + + + +void ttcp_sequence::send(const ttcp_sequence::my_sequence& ttcp_rec, CORBA::Environment& _env) +{ + _env.clear_exception(); + if (_is_local()) { + send(ttcp_rec); + return; + } + CORBA::MarshalStream *_strm = _create_oneway_request( + "ttcp_sequence", _ttcp_sequence_M_send,_env); + if (_env.check_exception()) + return; + _strm->putSequence(ttcp_rec, CORBA::MarshalStream::ARG_IN); + _send_oneway(_env); + if (_env.check_exception()) { + if (CORBA::StExcep::TRANSIENT::_cast(_env.exception_value()) != NULL) + send(ttcp_rec, _env); + return; + } + _strm->flush(_env); + return; +} + + + + +void ttcp_sequence::send_hack(const CORBA::String& ttcp_string, CORBA::Environment& _env) +{ + _env.clear_exception(); + if (_is_local()) { + send_hack(ttcp_string); + return; + } + CORBA::MarshalStream *_strm = _create_oneway_request( + "ttcp_sequence", _ttcp_sequence_M_send_hack,_env); + if (_env.check_exception()) + return; + _strm->putString(ttcp_string, CORBA::MarshalStream::ARG_IN); + _send_oneway(_env); + if (_env.check_exception()) { + if (CORBA::StExcep::TRANSIENT::_cast(_env.exception_value()) != NULL) + send_hack(ttcp_string, _env); + return; + } + _strm->flush(_env); + return; +} + + + + +void ttcp_sequence::start_timer(CORBA::Environment& _env) +{ + _env.clear_exception(); + if (_is_local()) { + start_timer(); + return; + } + CORBA::MarshalStream *_strm = _create_oneway_request( + "ttcp_sequence", _ttcp_sequence_M_start_timer,_env); + if (_env.check_exception()) + return; + _send_oneway(_env); + if (_env.check_exception()) { + if (CORBA::StExcep::TRANSIENT::_cast(_env.exception_value()) != NULL) + start_timer(_env); + return; + } + _strm->flush(_env); + return; +} + + + + +void ttcp_sequence::stop_timer(CORBA::Environment& _env) +{ + _env.clear_exception(); + if (_is_local()) { + stop_timer(); + return; + } + CORBA::MarshalStream *_strm = _create_oneway_request( + "ttcp_sequence", _ttcp_sequence_M_stop_timer,_env); + if (_env.check_exception()) + return; + _send_oneway(_env); + if (_env.check_exception()) { + if (CORBA::StExcep::TRANSIENT::_cast(_env.exception_value()) != NULL) + stop_timer(_env); + return; + } + _strm->flush(_env); + return; +} + +const CORBA::TypeInfo ttcp_string::_class_info("ttcp_string", + &ttcp_string::_reader, + CORBA::Object::_desc(), + 0); +const CORBA::TypeInfo *ttcp_string::_desc() +{ + return &_class_info; +} +const CORBA::TypeInfo *ttcp_string::_type_info() const +{ + return &_class_info; +} +void *ttcp_string::_safe_narrow(const CORBA::TypeInfo *info) const +{ + if (&_class_info == info) + return (void *) this; + void *ret = NULL; + return ret; +} +ttcp_string *ttcp_string::_narrow(const CORBA::Object *obj) +{ + void *ptr = obj->_safe_narrow(&_class_info); + return (ttcp_string *) ptr; +} +ttcp_string *ttcp_string::_bind(CORBA::Environment &_env, const char *_object_name, + const char *_host_name, const CORBA::BindOptions *opt) +{ + _env.clear_exception(); + ttcp_string *_impl; + CORBA::Object *_obj = _implementation("ttcp_string", _object_name); + if (!_obj) { + _impl = new ttcp_string(_object_name); +#if defined(_MSC_BUG) + _impl->Object::_bind("ttcp_string", _env, _object_name, _host_name, opt); +#else + _impl->CORBA::Object::_bind("ttcp_string", _env, _object_name, _host_name, opt); +#endif + if (_env.check_exception()) { + delete _impl; + return NULL; + } + } + else + _impl = ttcp_string::_narrow(_obj); + return _impl; +} + + + +void ttcp_string::send(const CORBA::String& ttcp_string, CORBA::Environment& _env) +{ + _env.clear_exception(); + if (_is_local()) { + send(ttcp_string); + return; + } + CORBA::MarshalStream *_strm = _create_oneway_request( + "ttcp_string", _ttcp_string_M_send,_env); + if (_env.check_exception()) + return; + _strm->putString(ttcp_string, CORBA::MarshalStream::ARG_IN); + _send_oneway(_env); + if (_env.check_exception()) { + if (CORBA::StExcep::TRANSIENT::_cast(_env.exception_value()) != NULL) + send(ttcp_string, _env); + return; + } + _strm->flush(_env); + return; +} + + + + +void ttcp_string::send_hack(const CORBA::String& ttcp_string, CORBA::Environment& _env) +{ + _env.clear_exception(); + if (_is_local()) { + send_hack(ttcp_string); + return; + } + CORBA::MarshalStream *_strm = _create_oneway_request( + "ttcp_string", _ttcp_string_M_send_hack,_env); + if (_env.check_exception()) + return; + _strm->putString(ttcp_string, CORBA::MarshalStream::ARG_IN); + _send_oneway(_env); + if (_env.check_exception()) { + if (CORBA::StExcep::TRANSIENT::_cast(_env.exception_value()) != NULL) + send_hack(ttcp_string, _env); + return; + } + _strm->flush(_env); + return; +} + + + + +void ttcp_string::start_timer(CORBA::Environment& _env) +{ + _env.clear_exception(); + if (_is_local()) { + start_timer(); + return; + } + CORBA::MarshalStream *_strm = _create_oneway_request( + "ttcp_string", _ttcp_string_M_start_timer,_env); + if (_env.check_exception()) + return; + _send_oneway(_env); + if (_env.check_exception()) { + if (CORBA::StExcep::TRANSIENT::_cast(_env.exception_value()) != NULL) + start_timer(_env); + return; + } + _strm->flush(_env); + return; +} + + + + +void ttcp_string::stop_timer(CORBA::Environment& _env) +{ + _env.clear_exception(); + if (_is_local()) { + stop_timer(); + return; + } + CORBA::MarshalStream *_strm = _create_oneway_request( + "ttcp_string", _ttcp_string_M_stop_timer,_env); + if (_env.check_exception()) + return; + _send_oneway(_env); + if (_env.check_exception()) { + if (CORBA::StExcep::TRANSIENT::_cast(_env.exception_value()) != NULL) + stop_timer(_env); + return; + } + _strm->flush(_env); + return; +} + + diff --git a/performance-tests/TTCP/ORBeline/ttcp_c.hh b/performance-tests/TTCP/ORBeline/ttcp_c.hh new file mode 100644 index 00000000000..b8eaca3f9a8 --- /dev/null +++ b/performance-tests/TTCP/ORBeline/ttcp_c.hh @@ -0,0 +1,181 @@ +#ifndef _ttcp_c_hh +#define _ttcp_c_hh + +/* This file is automatically generated by Orbeline. */ +/* Do not modify this file. */ +/* Orbeline (c) is copyrighted by PostModern Computing, Inc. */ + +#include +#include +#include + + + +class ttcp_sequence: public virtual CORBA::Object +{ + private: + static const CORBA::TypeInfo _class_info; + public: + static const CORBA::TypeInfo *_desc(); + virtual const CORBA::TypeInfo *_type_info() const; + virtual void *_safe_narrow(const CORBA::TypeInfo *) const; + static CORBA::Object *_reader(NCistream& strm) { + return new ttcp_sequence(strm); + } + protected: +#if defined(_MSC_BUG) + ttcp_sequence(const char *obj_name = NULL) :Object(obj_name) {} + ttcp_sequence(NCistream& strm) :Object(strm) {} +#else + ttcp_sequence(const char *obj_name = NULL) :CORBA::Object(obj_name) {} + ttcp_sequence(NCistream& strm) :CORBA::Object(strm) {} +#endif + virtual ~ttcp_sequence() {} + public: + enum _ttcp_sequence_Methods { + _ttcp_sequence_M_send = 0, + _ttcp_sequence_M_send_hack, + _ttcp_sequence_M_start_timer, + _ttcp_sequence_M_stop_timer + }; + static ttcp_sequence *_narrow(const CORBA::Object *obj); + static ttcp_sequence *_bind(CORBA::Environment &_env, const char *object_name = NULL, + const char *host_name = NULL, const CORBA::BindOptions* opt = NULL); + static ttcp_sequence *_bind(const char *object_name = NULL, + const char *host_name = NULL, const CORBA::BindOptions* opt = NULL) { + CORBA::Environment env; + return _bind(env, object_name, host_name, opt); + } + virtual const char *_interface_name() const { return "ttcp_sequence"; } + +#ifndef _DECLARE_SEQUENCE_CORBA__Char_ttcp_sequence__ +#define _DECLARE_SEQUENCE_CORBA__Char_ttcp_sequence__ +#define _DECLARE_SEQUENCE_CORBA__Char_ttcp_sequence___ttcp_idl +DECLARE_PRIMITIVE_SEQUENCE(CORBA__Char,CORBA::Char); +#endif + + typedef ttcp_sequence::IDLSequence(CORBA__Char) my_sequence; + + + + + void send(const ttcp_sequence::my_sequence& ttcp_rec, CORBA::Environment& _env); + + virtual void send(const ttcp_sequence::my_sequence& ttcp_rec) { + send(ttcp_rec, _environment()); + } + + + + + void send_hack(const CORBA::String& ttcp_string, CORBA::Environment& _env); + + virtual void send_hack(const CORBA::String& ttcp_string) { + send_hack(ttcp_string, _environment()); + } + + + + + void start_timer(CORBA::Environment& _env); + + virtual void start_timer() { + start_timer(_environment()); + } + + + + + void stop_timer(CORBA::Environment& _env); + + virtual void stop_timer() { + stop_timer(_environment()); + } + + +}; +typedef ttcp_sequence* ttcp_sequenceRef; + + + + +class ttcp_string: public virtual CORBA::Object +{ + private: + static const CORBA::TypeInfo _class_info; + public: + static const CORBA::TypeInfo *_desc(); + virtual const CORBA::TypeInfo *_type_info() const; + virtual void *_safe_narrow(const CORBA::TypeInfo *) const; + static CORBA::Object *_reader(NCistream& strm) { + return new ttcp_string(strm); + } + protected: +#if defined(_MSC_BUG) + ttcp_string(const char *obj_name = NULL) :Object(obj_name) {} + ttcp_string(NCistream& strm) :Object(strm) {} +#else + ttcp_string(const char *obj_name = NULL) :CORBA::Object(obj_name) {} + ttcp_string(NCistream& strm) :CORBA::Object(strm) {} +#endif + virtual ~ttcp_string() {} + public: + enum _ttcp_string_Methods { + _ttcp_string_M_send = 0, + _ttcp_string_M_send_hack, + _ttcp_string_M_start_timer, + _ttcp_string_M_stop_timer + }; + static ttcp_string *_narrow(const CORBA::Object *obj); + static ttcp_string *_bind(CORBA::Environment &_env, const char *object_name = NULL, + const char *host_name = NULL, const CORBA::BindOptions* opt = NULL); + static ttcp_string *_bind(const char *object_name = NULL, + const char *host_name = NULL, const CORBA::BindOptions* opt = NULL) { + CORBA::Environment env; + return _bind(env, object_name, host_name, opt); + } + virtual const char *_interface_name() const { return "ttcp_string"; } + + + + void send(const CORBA::String& ttcp_string, CORBA::Environment& _env); + + virtual void send(const CORBA::String& ttcp_string) { + send(ttcp_string, _environment()); + } + + + + + void send_hack(const CORBA::String& ttcp_string, CORBA::Environment& _env); + + virtual void send_hack(const CORBA::String& ttcp_string) { + send_hack(ttcp_string, _environment()); + } + + + + + void start_timer(CORBA::Environment& _env); + + virtual void start_timer() { + start_timer(_environment()); + } + + + + + void stop_timer(CORBA::Environment& _env); + + virtual void stop_timer() { + stop_timer(_environment()); + } + + +}; +typedef ttcp_string* ttcp_stringRef; + + + +#endif + diff --git a/performance-tests/TTCP/ORBeline/ttcp_i.cpp b/performance-tests/TTCP/ORBeline/ttcp_i.cpp new file mode 100644 index 00000000000..1f79276ecab --- /dev/null +++ b/performance-tests/TTCP/ORBeline/ttcp_i.cpp @@ -0,0 +1,1028 @@ +/* +// @(#)ttcp_i.cpp 1.1 10/18/96 + + * T T C P . C + * + */ +#ifndef lint +static char RCSid[] = "ttcp.c $Revision$"; +#endif + +/* #define BSD43 */ +/* #define BSD42 */ +/* #define BSD41a */ +#define SYSV /* required on SGI IRIX releases before 3.3 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* struct itimerval */ +#include +#include +#include + +#if defined(SYSV) +#define bcopy(b1,b2,n) memcpy(b2,b1,n) +#define bzero(b1,n) memset(b1,0,n) +#include +#include +struct rusage + { + struct timeval ru_utime, ru_stime; + }; +#define RUSAGE_SELF 0 + +#else +#include +#endif + +void err (char *s); +void mes (char *s); +void pattern (register char *cp, register int cnt); +char *outfmt (double b); +static void getrusage (int ignored, register struct rusage *ru); +static void gettimeofday (struct timeval *tp, struct timezone *zp); +void prep_timer (void); +double read_timer (char *str, int len); +static void prusage (register struct rusage *r0, struct rusage *r1, struct timeval *e, struct timeval *b, char *outp); +static void tvadd (struct timeval *tsum, struct timeval *t0, struct timeval *t1); +static void tvsub (struct timeval *tdiff, struct timeval *t1, struct timeval *t0); +static void psecs (long l, register char *cp); +void delay (int us); +int mread (int fd, register char *bufp, unsigned n); +int Nread (int fd, void *buf, int count); +int Nwrite (int fd, void *buf, int count); +static void SD_Ready (int io_descriptor); +void set_sock_desc(int starter); +void stop_timer (unsigned long numbytes); + +int fromlen; +int domain = PF_INET; /* Default is to use Internet domain sockets. */ +char *domainname; /* Rendezvous address for UNIX domain sockets. */ +int fd; /* fd of network socket */ + +int buflen = 8 * 1024; /* length of buffer */ +char *buf; /* ptr to dynamic buffer */ +int nbuf = 2 * 1024; /* number of buffers to send in sinkmode */ + +int bufoffset = 0; /* align buffer to this */ +int bufalign = 16 * 1024; /* modulo this */ + +int udp = 0; /* 0 = tcp, !0 = udp */ +int options = 0; /* socket options */ +int one = 1; /* for 4.3 BSD style setsockopt() */ +short port = 5001; /* TCP port number */ +char *host; /* ptr to name of host */ +int trans; /* 0=receive, !0=transmit mode */ +int sinkmode = 0; /* 0=normal I/O, !0=sink/source mode */ +int verbose = 0; /* 0=print basic info, 1=print cpu rate, proc + * resource usage. */ +int nodelay = 0; /* set TCP_NODELAY socket option */ +int b_flag = 0; /* use mread() */ +int sockbufsize = 0; /* socket buffer size to use */ +int new_line=0; /* This is a special flag */ +int write_to_file=1; /* indecates writing to file (default)*/ +int SEQUENCE=0; /* String parameter is the default */ +char fmt = 'K'; /* output format:k=kilobits,K=kilobytes, + * m = megabits, M = megabytes, + * g = gigabits, G = gigabytes */ +int touchdata = 0; /* access data after reading */ + +struct hostent *addr; +extern int errno; +extern int optind; +extern char *optarg; +char *title = 0; + +char stats[128]; +unsigned long nbytes; /* bytes on net */ +unsigned long numCalls; /* # of I/O system calls */ +double cput, realt; /* user, real time (seconds) */ + +// AAAAHHHHHHH what's this!!! C++ in the middle of C code???????!!!!!! + + +#include +#include "ttcp_i.h" + +char *orb_host; + +// ttcp_i is the server side + + +// ----------------------------------------- start hack +// hack to get the sock desc ehab + +void +set_sock_desc(int starter) +{ + // 14 is just a guess... + for (int i = starter; i < 14; i++) + { + sockaddr_in addr; + int addrlen = sizeof addr; + if (getpeername (i, (sockaddr *) &addr, &addrlen) < 0) + continue; + + printf ("socket descriptor %d connected to %s on port %d\n", + i, inet_ntoa (addr.sin_addr), ntohs (addr.sin_port)); + SD_Ready (i); + } +} + +// hack to get the socket descriptor in the server side + +// I dublicated the functions. However, the ideal way is to creat a base +// class that will be inhereted from both ttcp_sequence and ttcp_string. +// BTW, I could not get '#ifdef' to work over here ! +void +ttcp_sequence_i::send_hack (const CORBA::String& ttcp_string) +{ + set_sock_desc(1); +} + +void +ttcp_string_i::send_hack (const CORBA::String& ttcp_string) +{ + set_sock_desc(1); +} + +static void +SD_Ready (int io_descriptor) +{ + if (sockbufsize) + { + if (setsockopt (io_descriptor, SOL_SOCKET, SO_RCVBUF, (char *) &sockbufsize, + sizeof sockbufsize) < 0) + perror ("setsockopt: rcvbuf"), exit (1); + + if (setsockopt (io_descriptor, SOL_SOCKET, SO_SNDBUF, (char *) &sockbufsize, + sizeof sockbufsize) < 0) + perror ("setsockopt: sndbuf"), exit (1); + } + + int sndbufsize = 0, rcvbufsize = 0; + int buflen = sizeof (int); + if (getsockopt (io_descriptor, SOL_SOCKET, SO_SNDBUF, (char *) &sndbufsize, &buflen) < 0) + err ("getsockopt: sndbuf"); + if (getsockopt (io_descriptor, SOL_SOCKET, SO_RCVBUF, (char *) &rcvbufsize, &buflen) < 0) + err ("getsockopt: rcvbuf"); + char buf[BUFSIZ]; + sprintf (buf, "descriptor %d, sndbuf = %d, rcvbuf = %d\n", + io_descriptor, sndbufsize, rcvbufsize); + mes (buf); + + if (nodelay) + { + struct protoent *p; + p = getprotobyname ("tcp"); + if (setsockopt (io_descriptor, + p->p_proto, + TCP_NODELAY, + (char *)& one, + sizeof (one))) + mes ("setsockopt: nodelay"); + mes ("nodelay"); + } +} + +// ----------------------------------------- end hack + + +// ttcp_i is the server side + +ttcp_sequence_i::ttcp_sequence_i() +{ + this->nbytes_ = 0; + // register a callback so we can futs with the descriptor + // being used by orbix. +} + +void +ttcp_sequence_i::start_timer () +{ + this->nbytes_ = 0; + prep_timer (); +} + +void +ttcp_sequence_i::stop_timer () +{ + stop_timer (this->nbytes_); +} + +void +ttcp_sequence_i::send(const ttcp_sequence::my_sequence& ttcp_seq) +{ + this->nbytes_ += ttcp_seq.length(); +} + +ttcp_string_i::ttcp_string_i() +{ + this->nbytes_ = 0; + // register a callback so we can futs with the descriptor + // being used by orbix. +} + +void +ttcp_string_i::start_timer () +{ + prep_timer (); +} + + +void +ttcp_string_i::stop_timer () +{ + stop_timer (this->nbytes_); +} + +void +ttcp_string_i::send(const CORBA::String& ttcp_string) +{ + this->nbytes_ += strlen (ttcp_string); +} + +// common to sequence and string +void +stop_timer (unsigned long numbytes) +{ + (void) read_timer (stats, sizeof (stats)); + + if (cput <= 0.0) + cput = 0.001; + if (realt <= 0.0) + realt = 0.001; + fprintf (stdout, + "ttcp%s%s: %ld bytes in %.2f real seconds = %s/sec +++\n", + trans ? "-t" : "-r", SEQUENCE ? "(Seq)" : "(Str)", + numbytes, realt, outfmt (((double) numbytes) / realt)); + + + if (verbose) + { + fprintf (stdout, + "ttcp%s%s: %ld bytes in %.2f CPU seconds = %s/cpu sec\n", + trans ? "-t" : "-r",SEQUENCE ? "(Seq)" : "(Str)", + numbytes, cput, outfmt (((double) numbytes) / cput)); + } + fprintf (stdout, + "ttcp%s%s: %d I/O calls, msec/call = %.2f, calls/sec = %.2f\n", + trans ? "-t" : "-r",SEQUENCE ? "(Seq)" : "(Str)", + numCalls, + 1024.0 * realt / ((double) numCalls), + ((double) numCalls) / realt); + fprintf (stdout, "ttcp%s%s: %s\n", trans ? "-t" : "-r",SEQUENCE ? "(Seq)" : "(Str)", stats); + if (verbose) + { + fprintf (stdout, + "ttcp%s: buffer address %#x\n", + trans ? "-t" : "-r", + buf); + } +numbytes = 0; + + // you shoudl exit here when you use -p (profiler) so the server will + // produce mon.out +#ifdef PROFILE + exit(1); +#endif +} // end of stop_timer + + +char Usage[] = "\ +Usage: ttcp -t [-options] host [ < in ]\n\ + ttcp -r [-options > out]\n\ +Common options:\n\ + -l ## length of bufs read from or written to network (default 8192)\n\ + -u use UDP instead of TCP\n\ + -U use UNIX domain sockets instead of Internet domain sockets\n\ + -p ## port number to send to or listen at (default 5001)\n\ + -s -t: source a pattern to network\n\ + -r: sink (discard) all data from network\n\ + -A align the start of buffers to this modulus (default 16384)\n\ + -O start buffers at this offset from the modulus (default 0)\n\ + -v verbose: print more statistics\n\ + -d set SO_DEBUG socket option\n\ + -b ## set socket buffer size (if supported)\n\ + -f X format for rate: k,K = kilo{bit,byte}; m,M = mega; g,G = giga\n\ +Options specific to -t:\n\ + -n## number of source bufs written to network (default 2048)\n\ + -D don't buffer TCP writes (sets TCP_NODELAY socket option)\n\ +Options specific to -r:\n\ + -B for -s, only output full blocks as specified by -l (for TAR)\n\ + -T \"touch\": access each byte as it's read\n\ + -L the title of the current test\n\ + -F don't write to a file (writting in a file dat.out is default)\n\ + -q run the test using sequence parameter (string is defualt) \n\ +"; + +#if !defined (__cplusplus) +typedef void (*SIG_TYP)(); +#endif + +#ifdef SVR4 +void +sigpipe (int foo) +#else +void +sigpipe () +#endif +{ +} + +int +main (int argc, char *argv[]) +{ + + unsigned long addr_tmp; + int c; + + if (argc < 2) + goto usage; + + while ((c = ACE_OS::getopt (argc, argv, "qFdrstU:uvBDTb:L:f:l:n:p:A:O:h:x")) != -1) + { + switch (c) + { + case 'L': + title = optarg; + fprintf(stdout,"---->title=%s\n",title); + break; + case 'x': + new_line = 1; + break; + case 'q': + SEQUENCE = 1; + break; + case 'F': + write_to_file = 0; + break; + case 'h': + orb_host = optarg; + break; + case 'B': + b_flag = 1; + break; + case 't': + trans = 1; + break; + case 'r': + trans = 0; + break; + case 'd': + options |= SO_DEBUG; + break; + case 'D': +#ifdef TCP_NODELAY + nodelay = 1; +#else + fprintf (stderr, + "ttcp: -D option ignored: TCP_NODELAY socket option not supported\n"); +#endif + break; + case 'n': + nbuf = atoi (optarg); + break; + case 'l': + buflen = atoi (optarg); + break; + case 's': + sinkmode = !sinkmode; + break; + case 'p': + port = atoi (optarg); + break; + case 'U': + domain = PF_UNIX; + domainname = optarg; + break; + case 'u': + udp = 1; + break; + case 'v': + verbose = 1; + break; + case 'A': + bufalign = atoi (optarg); + break; + case 'O': + bufoffset = atoi (optarg); + break; + case 'b': +#if defined(SO_SNDBUF) || defined(SO_RCVBUF) + sockbufsize = atoi (optarg); +#else + fprintf (stderr, "ttcp: -b option ignored: SO_SNDBUF/SO_RCVBUF socket options not supported\n"); +#endif + break; + case 'f': + fmt = *optarg; + break; + case 'T': + touchdata = 1; + break; + + default: + goto usage; + } + } + + // + // Receiver + // + + if (!trans) + { + + // Sequence and String Interfaces + // instantiate ONLY one object at a time, so no dispatching overhead is counted + char *interface_name = new char[15]; + if (SEQUENCE) + { + printf("I am here\n"); + ttcp_sequence *my_ttcp = new ttcp_sequence_i; + strcpy(interface_name,"ttcp_sequence"); + } + else + { + ttcp_string *my_ttcp_s = new ttcp_string_i; + strcpy(interface_name,"ttcp_string"); + } + + // tell ORBeline that we have completed the server's initialization: + CORBA::BOA::impl_is_ready(); + + cout << "server exiting" << endl; + return 42; + } + + // + // Transmitter + // + + CORBA::Environment env; + ttcp_sequence *ttcp_seq; + ttcp_string *ttcp_str; + + if (SEQUENCE) + { + if ( (ttcp_seq = ttcp_sequence::_bind(0,::orb_host,0)) == 0) + { + cerr << "\n ttcp_i: Failed to _bind to " << orb_host << endl; + exit(-1); + } + } + else // string parameter used + if ( (ttcp_str = ttcp_string::_bind (0,::orb_host,0))== 0) + { + cerr << "\n ttcp_i: Failed to _bind to " << orb_host << endl; + exit(-1); + } + + // hack to get the socket descriptor in the server side after sending this msg + if (SEQUENCE) + ttcp_seq->send_hack("hack"); + else + ttcp_str->send_hack("hack"); + + // hack to get the socket descriptor in the client side: + + set_sock_desc(1); // replace "ttcp_->_fd" in the following with sockdesc + + // + // Prepare the Message to be sent + // + + errno = 0; + if (sinkmode) + { + if ((buf = (char *) malloc (buflen + bufalign)) == (char *) NULL) + err ("malloc"); + if (bufalign != 0) + buf += (bufalign - ((int) buf % bufalign) + bufoffset) % bufalign; + + // ttcp_sequence::my_sequence sequence_message; ORBIX + ttcp_sequence::my_sequence message (buflen + 1); + ::buf[::buflen-1] = '\0'; + if (SEQUENCE) + { + message._num_allocated = buflen; + message._count = buflen; + message._contents = buf; + } + + + pattern (buf, buflen); + // + // Start the timers on the client and server sides + // + + prep_timer (); + + if (SEQUENCE) + ttcp_seq->start_timer (); + else + ttcp_str->start_timer (); + while (nbuf--) + { + if (SEQUENCE) + ttcp_seq->send (message); + else + ttcp_str->send (buf); + + numCalls++; + nbytes += buflen; + } + + } + else + { + register int cnt; + while ((cnt = read (0, buf, buflen)) > 0 && + Nwrite (fd, buf, cnt) == cnt) + nbytes += cnt; + } + + if (errno) + err ("IO"); + + + // + // Stop the timers on both sides + // + + + if (SEQUENCE) + ttcp_seq->stop_timer(); + else + ttcp_str->stop_timer(); + + + (void) read_timer (stats, sizeof (stats)); + + + // + // Print the results. + // + + if (cput <= 0.0) + cput = 0.001; + if (realt <= 0.0) + realt = 0.001; + + if (write_to_file) + { + if (title != 0) + { + double tmp; + FILE *fd; + char filename[BUFSIZ]; + ACE_OS::sprintf (filename, "%s.results", title); + fd = fopen(filename,"a+"); + if (new_line) + fprintf(fd,"\n -l %ldk \t", buflen/1024); + tmp = ((double) nbytes) / realt; + fprintf(fd,"%.2f ", tmp * 8.0 / 1024.0 / 1024.0); + fclose(fd); + } + } + + fprintf (stdout, + "\nttcp%s%s: %ld bytes in %.2f real seconds = %s/sec +++\n", + trans ? "-t" : "-r", SEQUENCE ? "(Seq)" : "(Str)", + nbytes, realt, outfmt (((double) nbytes) / realt)); + + if (verbose) + { + fprintf (stdout, + "ttcp%s%s: %ld bytes in %.2f CPU seconds = %s/cpu sec\n", + trans ? "-t" : "-r", SEQUENCE ? "(Seq)" : "(Str)", + nbytes, cput, outfmt (((double) nbytes) / cput)); + } + fprintf (stdout, + "ttcp%s%s: %d I/O calls, msec/call = %.2f, calls/sec = %.2f\n", + trans ? "-t" : "-r", SEQUENCE ? "(Seq)" : "(Str)", + numCalls, + 1024.0 * realt / ((double) numCalls), + ((double) numCalls) / realt); + fprintf (stdout, "ttcp%s%s: %s\n",trans ? "-t" : "-r", SEQUENCE ? "(Seq)" : "(Str)", stats); + if (verbose) + { + fprintf (stdout, + "ttcp%s: buffer address %#x\n", + trans ? "-t" : "-r", + buf); + } + exit (0); + + usage: + fprintf (stderr, Usage); + return 1; +} + +void +err (char *s) +{ + fprintf (stderr, "ttcp%s: ", trans ? "-t" : "-r"); + perror (s); + fprintf (stderr, "errno=%d\n", errno); + exit (1); +} + +void +mes (char *s) +{ + fprintf (stderr, "ttcp%s%s: %s\n", trans ? "-t" : "-r",SEQUENCE ? "(Seq)" : "(Str)", s); +// fprintf (stderr, "ttcp%s: %s\n", trans ? "-t" : "-r", s); +} + +void +pattern (register char *cp, register int cnt) +{ + register char c; + c = 0; + while (cnt-- > 0) + { + while (!isprint ((c & 0x7F))) + c++; + *cp++ = (c++ & 0x7F); + } +} + +char * +outfmt (double b) +{ + static char obuf[50]; + switch (fmt) + { + case 'G': + sprintf (obuf, "%.2f GB", b / 1024.0 / 1024.0 / 1024.0); + break; + default: + case 'K': + sprintf (obuf, "%.2f KB", b / 1024.0); + break; + case 'M': + sprintf (obuf, "%.2f MB", b / 1024.0 / 1024.0); + break; + case 'g': + sprintf (obuf, "%.2f Gbit", b * 8.0 / 1024.0 / 1024.0 / 1024.0); + break; + case 'k': + sprintf (obuf, "%.2f Kbit", b * 8.0 / 1024.0); + break; + case 'm': + sprintf (obuf, "%.2f Mbit", b * 8.0 / 1024.0 / 1024.0); + break; + } + return obuf; +} + +static struct itimerval itime0; /* Time at which timing started */ +static struct rusage ru0; /* Resource utilization at the start */ + +#if defined(SYSV) +/*ARGSUSED */ +static void +getrusage (int ignored, register struct rusage *ru) +{ + struct tms buf; + + times (&buf); + + /* Assumption: HZ <= 2147 (LONG_MAX/1000000) */ + ru->ru_stime.tv_sec = buf.tms_stime / HZ; + ru->ru_stime.tv_usec = ((buf.tms_stime % HZ) * 1000000) / HZ; + ru->ru_utime.tv_sec = buf.tms_utime / HZ; + ru->ru_utime.tv_usec = ((buf.tms_utime % HZ) * 1000000) / HZ; +} + +/*ARGSUSED */ +static void +gettimeofday (struct timeval *tp, struct timezone *zp) +{ + tp->tv_sec = time (0); + tp->tv_usec = 0; +} +#endif /* SYSV */ +/* + * P R E P _ T I M E R + */ +void +prep_timer () +{ + itime0.it_interval.tv_sec = 0; + itime0.it_interval.tv_usec = 0; + itime0.it_value.tv_sec = LONG_MAX / 22; /* greatest possible value , itimer() count backwards */ + itime0.it_value.tv_usec = 0; + + + getrusage (RUSAGE_SELF, &ru0); + + /* Init REAL Timer */ + if (setitimer (ITIMER_REAL, &itime0, NULL)) + { + perror ("Setting 'itimer' REAL failed"); + return; + } + +} + +/* + * R E A D _ T I M E R + * + */ +double +read_timer (char *str, int len) +{ + struct itimerval itimedol; + struct rusage ru1; + struct timeval td; + struct timeval tend, tstart; + char line[132]; + + getrusage (RUSAGE_SELF, &ru1); + + if (getitimer (ITIMER_REAL, &itimedol)) + { + perror ("Getting 'itimer' REAL failed"); + return (0.0); + } + + prusage (&ru0, &ru1, &itime0.it_value, &itimedol.it_value, line); + (void) strncpy (str, line, len); + + /* Get real time */ + tvsub (&td, &itime0.it_value, &itimedol.it_value); + realt = td.tv_sec + ((double) td.tv_usec) / 1000000; + + /* Get CPU time (user+sys) */ + tvadd (&tend, &ru1.ru_utime, &ru1.ru_stime); + tvadd (&tstart, &ru0.ru_utime, &ru0.ru_stime); + tvsub (&td, &tend, &tstart); + cput = td.tv_sec + ((double) td.tv_usec) / 1000000; + if (cput < 0.00001) + cput = 0.00001; + return (cput); +} + +static void +prusage (register struct rusage *r0, struct rusage *r1, + struct timeval *e, struct timeval *b, char *outp) +{ + struct timeval tdiff; + register time_t t; + register char *cp; + register int i; + int ms; + + t = (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 + + (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 + + (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 + + (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000; + ms = (e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000; + +#define END(x) {while(*x) x++;} +#if defined(SYSV) + cp = "%Uuser %Ssys %Ereal %P"; +#else +#if defined(sgi) /* IRIX 3.3 will show 0 for %M,%F,%R,%C */ + cp = "%Uuser %Ssys %Ereal %P %Mmaxrss %F+%Rpf %Ccsw"; +#else + cp = "%Uuser %Ssys %Ereal %P %Xi+%Dd %Mmaxrss %F+%Rpf %Ccsw"; +#endif +#endif + for (; *cp; cp++) + { + if (*cp != '%') + *outp++ = *cp; + else if (cp[1]) + switch (*++cp) + { + + case 'U': + tvsub (&tdiff, &r1->ru_utime, &r0->ru_utime); + sprintf (outp, "%d.%01d", tdiff.tv_sec, tdiff.tv_usec / 100000); + END (outp); + break; + + case 'S': + tvsub (&tdiff, &r1->ru_stime, &r0->ru_stime); + sprintf (outp, "%d.%01d", tdiff.tv_sec, tdiff.tv_usec / 100000); + END (outp); + break; + + case 'E': + psecs (ms / 100, outp); + END (outp); + break; + + case 'P': + sprintf (outp, "%d%%", (int) (t * 100 / ((ms ? ms : 1)))); + END (outp); + break; + +#if !defined(SYSV) + case 'W': + i = r1->ru_nswap - r0->ru_nswap; + sprintf (outp, "%d", i); + END (outp); + break; + + case 'X': + sprintf (outp, "%d", t == 0 ? 0 : (r1->ru_ixrss - r0->ru_ixrss) / t); + END (outp); + break; + + case 'D': + sprintf (outp, "%d", t == 0 ? 0 : + (r1->ru_idrss + r1->ru_isrss - (r0->ru_idrss + r0->ru_isrss)) / t); + END (outp); + break; + + case 'K': + sprintf (outp, "%d", t == 0 ? 0 : + ((r1->ru_ixrss + r1->ru_isrss + r1->ru_idrss) - + (r0->ru_ixrss + r0->ru_idrss + r0->ru_isrss)) / t); + END (outp); + break; + + case 'M': + sprintf (outp, "%d", r1->ru_maxrss / 2); + END (outp); + break; + + case 'F': + sprintf (outp, "%d", r1->ru_majflt - r0->ru_majflt); + END (outp); + break; + + case 'R': + sprintf (outp, "%d", r1->ru_minflt - r0->ru_minflt); + END (outp); + break; + + case 'I': + sprintf (outp, "%d", r1->ru_inblock - r0->ru_inblock); + END (outp); + break; + + case 'O': + sprintf (outp, "%d", r1->ru_oublock - r0->ru_oublock); + END (outp); + break; + case 'C': + sprintf (outp, "%d+%d", r1->ru_nvcsw - r0->ru_nvcsw, + r1->ru_nivcsw - r0->ru_nivcsw); + END (outp); + break; +#endif /* !SYSV */ + } + } + *outp = '\0'; +} + +static void +tvadd (struct timeval *tsum, struct timeval *t0, struct timeval *t1) +{ + + tsum->tv_sec = t0->tv_sec + t1->tv_sec; + tsum->tv_usec = t0->tv_usec + t1->tv_usec; + if (tsum->tv_usec > 1000000) + tsum->tv_sec++, tsum->tv_usec -= 1000000; +} + +static void +tvsub (struct timeval *tdiff, struct timeval *t1, struct timeval *t0) +{ + + tdiff->tv_sec = t1->tv_sec - t0->tv_sec; + tdiff->tv_usec = t1->tv_usec - t0->tv_usec; + if (tdiff->tv_usec < 0) + tdiff->tv_sec--, tdiff->tv_usec += 1000000; +} + +static void +psecs (long l, register char *cp) +{ + register int i; + + i = l / 3600; + if (i) + { + sprintf (cp, "%d:", i); + END (cp); + i = l % 3600; + sprintf (cp, "%d%d", (i / 60) / 10, (i / 60) % 10); + END (cp); + } + else + { + i = l; + sprintf (cp, "%d", i / 60); + END (cp); + } + i %= 60; + *cp++ = ':'; + sprintf (cp, "%d%d", i / 10, i % 10); +} + +/* + * N R E A D + */ +int +Nread (int fd, void *buf, int count) +{ + struct sockaddr_in from; + int len = sizeof (from); + register int cnt; + if (udp) + { + cnt = recvfrom (fd, (char *) buf, count, 0, (struct sockaddr *) &from, &len); + numCalls++; + } + else + { + if (b_flag) + cnt = mread (fd, (char *) buf, count); /* fill buf */ + else + { + cnt = read (fd, buf, count); + numCalls++; + } + if (touchdata && cnt > 0) + { + register int c = cnt, sum; + register char *b = (char *) buf; + while (c--) + sum += *b++; + } + } + return (cnt); +} + + +/* + * N W R I T E + */ +int +Nwrite (int fd, void *buf, int count) +{ + return 0; +} + +void +delay (int us) +{ + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = us; + (void) select (1, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &tv); +} + +/* + * M R E A D + * + * This function performs the function of a read(II) but will + * call read(II) multiple times in order to get the requested + * number of characters. This can be necessary because + * network connections don't deliver data with the same + * grouping as it is written with. Written by Robert S. Miles, BRL. + */ +int +mread (int fd, register char *bufp, unsigned n) +{ + register unsigned count = 0; + register int nread; + + do + { + nread = read (fd, bufp, n - count); + numCalls++; + if (nread < 0) + { + perror ("ttcp_mread"); + return (-1); + } + if (nread == 0) + return ((int) count); + count += (unsigned) nread; + bufp += nread; + } + while (count < n); + + return ((int) count); +} diff --git a/performance-tests/TTCP/ORBeline/ttcp_i.h b/performance-tests/TTCP/ORBeline/ttcp_i.h new file mode 100644 index 00000000000..70cb752031f --- /dev/null +++ b/performance-tests/TTCP/ORBeline/ttcp_i.h @@ -0,0 +1,45 @@ +/* -*- C++ -*- */ +// @(#)ttcp_i.h 1.1 10/18/96 + + +// ttcp_i.C +// implementation of the ttcp and Profile_Logger objects. + +#if !defined (TTCP_I_H) +#define TTCP_I_H + +// This is a total hack... +#define private public +#include "ttcp_s.hh" +#include "ttcp_c.hh" + +class ttcp_string_i : public ttcp_string_impl { +public: + + ttcp_string_i(); + + virtual void send(const CORBA::String& ttcp_string); + virtual void send_hack(const CORBA::String& ttcp_string); + virtual void start_timer(); + virtual void stop_timer(); + +private: + unsigned long nbytes_; +}; + +class ttcp_sequence_i : public ttcp_sequence_impl { +public: + + ttcp_sequence_i(); + + virtual void send(const ttcp_sequence::my_sequence& ttcp_seq); + virtual void send_hack(const CORBA::String& ttcp_string); + virtual void start_timer(); + virtual void stop_timer(); + +private: + unsigned long nbytes_; +}; + + +#endif diff --git a/performance-tests/TTCP/ORBeline/ttcp_s.cc b/performance-tests/TTCP/ORBeline/ttcp_s.cc new file mode 100644 index 00000000000..514ff8a5d26 --- /dev/null +++ b/performance-tests/TTCP/ORBeline/ttcp_s.cc @@ -0,0 +1,168 @@ +/* This file is automatically generated by Orbeline. */ +/* Do not modify this file. */ +/* Orbeline (c) is copyrighted by PostModern Computing, Inc. */ + +#include + + + +static CORBA::_PMCSkelFunc _ttcp_sequence_func_array[] = { + &ttcp_sequence_impl::_send, + &ttcp_sequence_impl::_send_hack, + &ttcp_sequence_impl::_start_timer, + &ttcp_sequence_impl::_stop_timer, + 0 + }; +ttcp_sequence_impl::ttcp_sequence_impl(const char *object_name) : + ttcp_sequence(object_name) +{ + _object_name(object_name); + CORBA::Environment _env; + _register_implementation("ttcp_sequence", 4, _ttcp_sequence_func_array, (void *) this, _env); +} +ttcp_sequence_impl::~ttcp_sequence_impl() +{ + CORBA::Environment _env; + _unregister_implementation("ttcp_sequence", (void *) this, _env); +} + + +void ttcp_sequence_impl::_send(void *obj, CORBA::MarshalStream &strm, + CORBA::Environment& _env, CORBA::Principal *principal) { + ttcp_sequence_impl *_impl = (ttcp_sequence_impl *) obj; + _env.clear_exception(); + ttcp_sequence::my_sequence ttcp_rec; + strm.getSequence(ttcp_rec, CORBA::MarshalStream::ARG_IN); + strm.flush(_env); + if (_env.check_exception()) + return; + _impl->_principal(principal); + _impl->send(ttcp_rec); + strm.putEnvironment(_env); + _impl->_principal((CORBA::Principal *) NULL); +} + + +void ttcp_sequence_impl::_send_hack(void *obj, CORBA::MarshalStream &strm, + CORBA::Environment& _env, CORBA::Principal *principal) { + ttcp_sequence_impl *_impl = (ttcp_sequence_impl *) obj; + _env.clear_exception(); + CORBA::String ttcp_string; + strm.getString(ttcp_string, CORBA::MarshalStream::ARG_IN); + strm.flush(_env); + if (_env.check_exception()) + return; + _impl->_principal(principal); + _impl->send_hack(ttcp_string); + strm.putEnvironment(_env); + _impl->_principal((CORBA::Principal *) NULL); +} + + +void ttcp_sequence_impl::_start_timer(void *obj, CORBA::MarshalStream &strm, + CORBA::Environment& _env, CORBA::Principal *principal) { + ttcp_sequence_impl *_impl = (ttcp_sequence_impl *) obj; + _env.clear_exception(); + strm.flush(_env); + if (_env.check_exception()) + return; + _impl->_principal(principal); + _impl->start_timer(); + strm.putEnvironment(_env); + _impl->_principal((CORBA::Principal *) NULL); +} + + +void ttcp_sequence_impl::_stop_timer(void *obj, CORBA::MarshalStream &strm, + CORBA::Environment& _env, CORBA::Principal *principal) { + ttcp_sequence_impl *_impl = (ttcp_sequence_impl *) obj; + _env.clear_exception(); + strm.flush(_env); + if (_env.check_exception()) + return; + _impl->_principal(principal); + _impl->stop_timer(); + strm.putEnvironment(_env); + _impl->_principal((CORBA::Principal *) NULL); +} + +static CORBA::_PMCSkelFunc _ttcp_string_func_array[] = { + &ttcp_string_impl::_send, + &ttcp_string_impl::_send_hack, + &ttcp_string_impl::_start_timer, + &ttcp_string_impl::_stop_timer, + 0 + }; +ttcp_string_impl::ttcp_string_impl(const char *object_name) : + ttcp_string(object_name) +{ + _object_name(object_name); + CORBA::Environment _env; + _register_implementation("ttcp_string", 4, _ttcp_string_func_array, (void *) this, _env); +} +ttcp_string_impl::~ttcp_string_impl() +{ + CORBA::Environment _env; + _unregister_implementation("ttcp_string", (void *) this, _env); +} + +void ttcp_string_impl::_send(void *obj, CORBA::MarshalStream &strm, + CORBA::Environment& _env, CORBA::Principal *principal) { + ttcp_string_impl *_impl = (ttcp_string_impl *) obj; + _env.clear_exception(); + CORBA::String ttcp_string; + strm.getString(ttcp_string, CORBA::MarshalStream::ARG_IN); + strm.flush(_env); + if (_env.check_exception()) + return; + _impl->_principal(principal); + _impl->send(ttcp_string); + strm.putEnvironment(_env); + _impl->_principal((CORBA::Principal *) NULL); +} + + +void ttcp_string_impl::_send_hack(void *obj, CORBA::MarshalStream &strm, + CORBA::Environment& _env, CORBA::Principal *principal) { + ttcp_string_impl *_impl = (ttcp_string_impl *) obj; + _env.clear_exception(); + CORBA::String ttcp_string; + strm.getString(ttcp_string, CORBA::MarshalStream::ARG_IN); + strm.flush(_env); + if (_env.check_exception()) + return; + _impl->_principal(principal); + _impl->send_hack(ttcp_string); + strm.putEnvironment(_env); + _impl->_principal((CORBA::Principal *) NULL); +} + + +void ttcp_string_impl::_start_timer(void *obj, CORBA::MarshalStream &strm, + CORBA::Environment& _env, CORBA::Principal *principal) { + ttcp_string_impl *_impl = (ttcp_string_impl *) obj; + _env.clear_exception(); + strm.flush(_env); + if (_env.check_exception()) + return; + _impl->_principal(principal); + _impl->start_timer(); + strm.putEnvironment(_env); + _impl->_principal((CORBA::Principal *) NULL); +} + + +void ttcp_string_impl::_stop_timer(void *obj, CORBA::MarshalStream &strm, + CORBA::Environment& _env, CORBA::Principal *principal) { + ttcp_string_impl *_impl = (ttcp_string_impl *) obj; + _env.clear_exception(); + strm.flush(_env); + if (_env.check_exception()) + return; + _impl->_principal(principal); + _impl->stop_timer(); + strm.putEnvironment(_env); + _impl->_principal((CORBA::Principal *) NULL); +} + + diff --git a/performance-tests/TTCP/ORBeline/ttcp_s.hh b/performance-tests/TTCP/ORBeline/ttcp_s.hh new file mode 100644 index 00000000000..645981eec22 --- /dev/null +++ b/performance-tests/TTCP/ORBeline/ttcp_s.hh @@ -0,0 +1,89 @@ +#ifndef _ttcp_s_hh +#define _ttcp_s_hh + +#include +#include + +/* This file is automatically generated by Orbeline. */ +/* Do not modify this file. */ +/* Orbeline (c) is copyrighted by PostModern Computing, Inc. */ + +class ttcp_sequence_impl: public virtual ttcp_sequence +{ + protected: + ttcp_sequence_impl(const char *object_name = NULL); + virtual ~ttcp_sequence_impl(); + public: + virtual const CORBA::TypeInfo *_type_info() const { + return ttcp_sequence::_type_info(); + } + virtual void *_safe_narrow(const CORBA::TypeInfo *inf) const { + return ttcp_sequence::_safe_narrow(inf); + } + virtual const char *_interface_name() const { + return ttcp_sequence::_interface_name(); + } + virtual CORBA::Boolean _is_local() const { return 1; } + + /* The following operations need to be implemented by the server. */ + virtual void send(const ttcp_sequence::my_sequence& ttcp_rec) = 0; + virtual void send_hack(const CORBA::String& ttcp_string) = 0; + virtual void start_timer() = 0; + virtual void stop_timer() = 0; + + /* The following operations are implemented automatically. */ + + static void _send(void *obj, CORBA::MarshalStream &strm, + CORBA::Environment& _env, CORBA::Principal *principal); + + static void _send_hack(void *obj, CORBA::MarshalStream &strm, + CORBA::Environment& _env, CORBA::Principal *principal); + + static void _start_timer(void *obj, CORBA::MarshalStream &strm, + CORBA::Environment& _env, CORBA::Principal *principal); + + static void _stop_timer(void *obj, CORBA::MarshalStream &strm, + CORBA::Environment& _env, CORBA::Principal *principal); + +}; +class ttcp_string_impl: public virtual ttcp_string +{ + protected: + ttcp_string_impl(const char *object_name = NULL); + virtual ~ttcp_string_impl(); + public: + virtual const CORBA::TypeInfo *_type_info() const { + return ttcp_string::_type_info(); + } + virtual void *_safe_narrow(const CORBA::TypeInfo *inf) const { + return ttcp_string::_safe_narrow(inf); + } + virtual const char *_interface_name() const { + return ttcp_string::_interface_name(); + } + virtual CORBA::Boolean _is_local() const { return 1; } + + /* The following operations need to be implemented by the server. */ + virtual void send(const CORBA::String& ttcp_string) = 0; + virtual void send_hack(const CORBA::String& ttcp_string) = 0; + virtual void start_timer() = 0; + virtual void stop_timer() = 0; + + /* The following operations are implemented automatically. */ + + static void _send(void *obj, CORBA::MarshalStream &strm, + CORBA::Environment& _env, CORBA::Principal *principal); + + static void _send_hack(void *obj, CORBA::MarshalStream &strm, + CORBA::Environment& _env, CORBA::Principal *principal); + + static void _start_timer(void *obj, CORBA::MarshalStream &strm, + CORBA::Environment& _env, CORBA::Principal *principal); + + static void _stop_timer(void *obj, CORBA::MarshalStream &strm, + CORBA::Environment& _env, CORBA::Principal *principal); + +}; + +#endif + diff --git a/performance-tests/TTCP/Orbix/How_to_run_tests b/performance-tests/TTCP/Orbix/How_to_run_tests new file mode 100644 index 00000000000..435959f4511 --- /dev/null +++ b/performance-tests/TTCP/Orbix/How_to_run_tests @@ -0,0 +1,59 @@ +// Orbix +// +// sequence AND string + +// HOSTNAMES: +// for our tests, enatm0-tango.cs.wustl.edu was the receiver hostname used for atm transfers +// tango.cs.wustl.edu was the receiver hostname used for ethernet transfers +// substitute the proper receiver hostname for your system. + +// ORBIX DAEMONS: +// there must be an orbix daemon running on the receiver host in your system. +// in our case, we had an orbix daemon running on tango.cs.wustl.edu + +// WRAPPER_ROOT: +// WRAPPER_ROOT can be set to the root directory of ACE so that these lines +// can be cut and pasted to run tests. + +// Results: +// These examples show the result files being stored in a /results directory off +// the current path. This can be set to whatever you like. + +// ****** sequence ****** + +// ATM with 64k receiver buffers +Receiver_Host: putit ttcp_sequence "$WRAPPER_ROOT/apps/TTCP/Orbix/server -q -s -r -fm -b 65536" +Sender_Host: run_test 64 encip1-tango.cs.wustl.edu ./results/sequence.atm.64 -q + or: client -D -fm -s -t -l 1048576 -n 100 -h encip1-tango.cs.wustl.edu -L ./results/sequence.atm.64 -q + +// ATM with 8k reciever buffers +Receiver_Host: putit ttcp_sequence "$WRAPPER_ROOT/apps/TTCP/Orbix/server -q -s -r -fm" +Sender_Host: run_test 64 encip1-tango.cs.wustl.edu ./results/sequence.atm.8 -q + +// ETHERNET with 64k receiver buffers +Receiver_Host: putit ttcp_sequence "$WRAPPER_ROOT/apps/TTCP/Orbix/server -q -s -r -fm -b 65536" +Sender_Host: run_test 64 tango.cs.wustl.edu ./results/sequence.ethernet.64 -q + +// ETHERNET with 8k reciever buffers +Receiver_Host: putit ttcp_sequence "$WRAPPER_ROOT/apps/TTCP/Orbix/server -q -s -r -fm" +Sender_Host: run_test 64 tango.cs.wustl.edu ./results/sequence.ethernet.8 -q + +// ****** string ****** + +// ATM with 64k receiver buffers +Receiver_Host: putit ttcp_string "$WRAPPER_ROOT/apps/TTCP/Orbix/server -s -r -fm -b 65536" +Sender_Host: run_test 64 encip1-tango.cs.wustl.edu ./results/string.atm.64 + or: client -D -fm -s -t -l 1048576 -n 100 -h encip1-tango.cs.wustl.edu -L ./results/string.atm.64 + +// ATM with 8k reciever buffers +Receiver_Host: putit ttcp_string "$WRAPPER_ROOT/apps/TTCP/Orbix/server -s -r -fm" +Sender_Host: run_test 64 encip1-tango.cs.wustl.edu ./results/string.atm.8 + +// ETHERNET with 64k receiver buffers +Receiver_Host: putit ttcp_string "$WRAPPER_ROOT/apps/TTCP/Orbix/server -s -r -fm -b 65536" +Sender_Host: run_test 64 tango.cs.wustl.edu ./results/string.ethernet.64 + +// ETHERNET with 8k reciever buffers +Receiver_Host: putit ttcp_string "$WRAPPER_ROOT/apps/TTCP/Orbix/server -s -r -fm" +Sender_Host: run_test 64 tango.cs.wustl.edu ./results/string.ethernet.8 + diff --git a/performance-tests/TTCP/Orbix/Makefile b/performance-tests/TTCP/Orbix/Makefile new file mode 100644 index 00000000000..3a8c4a9ffd4 --- /dev/null +++ b/performance-tests/TTCP/Orbix/Makefile @@ -0,0 +1,30 @@ +include ./orbix_defaults.mk + +all: client server + @echo + + @echo "\"client\" and \"server\" have been compiled." + @echo + @echo "To run tests, check the how_to_run_tests file." + @echo + +C++FLAGS += -DWANT_ORBIX_FDS -DLM_RESULTS +IDLFLAGS += -c C.cpp -s S.cpp -B +SERVER_OBJS = ttcpS.o ttcp_i.o +CLIENT_OBJS = ttcpC.o ttcp_i.o + +#QUANTIFY = +QUANTIFY = quantify -cache-dir=$(IR)/quantify + +client: $(CLIENT_OBJS) + $(QUANTIFY) $(C++) $(C++FLAGS) -o client $(CLIENT_OBJS) -lITclt $(LDFLAGS) + +server: $(SERVER_OBJS) + $(QUANTIFY) $(C++) $(C++FLAGS) -o server $(SERVER_OBJS) -lITsrv $(LDFLAGS) + +clean: + rm -f core *.o *~ client server + +realclean: + rm -f core *.o *~ client server + diff --git a/performance-tests/TTCP/Orbix/README b/performance-tests/TTCP/Orbix/README new file mode 100644 index 00000000000..6fd64c6fdec --- /dev/null +++ b/performance-tests/TTCP/Orbix/README @@ -0,0 +1,13 @@ +How to compile. + +1. Orbix must be installed. +2. You must set the following paths in ./orbix_defaults.mk +ORBIX_BINDIR = /the/path/to/Orbix/bin +ORBIX_LIBDIR = /the/path/to/Orbix/lib +ORBIX_INCDIR = /the/path/to/Orbix/include + + +How to run tests. +1. Orbix must be installed and proper Orbix environment variables + must be set. (ie. IT_CONFIG_PATH) +2. Read ./how_to_run_tests diff --git a/performance-tests/TTCP/Orbix/orbix_defaults.mk b/performance-tests/TTCP/Orbix/orbix_defaults.mk new file mode 100644 index 00000000000..9a3e83f5fe3 --- /dev/null +++ b/performance-tests/TTCP/Orbix/orbix_defaults.mk @@ -0,0 +1,85 @@ + +# These rules define default C++, C++FLAGS and C++SUFFIX. +# C++ is the C++ compiler to use; C++FLAGS are command-line +# flags to the C++ compiler for use in compiling C++ source +# files into objects; C++SUFFIX is the filename suffix +# indicating C++ source. By default, it's set to "C" for AT&T C++, +# and "cc" for GNU g++. + +# Feel free to override these in your Makefiles *after* +# including this file. + +# IMPORTANT: If the -M switch is specified in IDLFLAGS, the IDL +# compiler appends to the user-specified file. The dependency for +# specified_file.o in the linking target should appear _after_ any use +# of the IDL compiler which takes the -M flag. Putting it _last_ +# is normally the best approach. + +# Note that these rule definitions use pattern matching, +# and therefore only work with SunOS make and GNU make. + +# They may not work with other vendor's versions of make. +# If they do not, you may wish to try using GNU make, which +# is free software produced by the Free Software Foundation. + +# If the version of make you wish to use does not support +# pattern matching, use the sample explicit rule set in +# the comments at the end of this file. + +# ------------------------------------------------------------ +# Essential: set these to the locations into which you +# have installed Orbix' components: + +ORBIX_BINDIR = $(ORBIX_ROOT)/bin +ORBIX_LIBDIR = $(ORBIX_ROOT)/lib +ORBIX_INCDIR = $(ORBIX_ROOT)/include + +C++ = CC +C++FLAGS = -I$(ORBIX_INCDIR) +C++SUFFIX = cpp + +LDFLAGS = -L$(ORBIX_LIBDIR) -R $(ORBIX_LIBDIR) -lnsl -lsocket + +IDL = $(ORBIX_BINDIR)/idl + +IDLFLAGS = + + +# ------------------------------------------------------------ +# The following section defines implicit rules for creating +# *.{client,server}.C files, rules for compiling those +# into objects, and even a rule for compiling C++ source into +# objects (in case one isn't already defined). + +# ------------------------------------------------------------ +# first, put the new suffixes at the *head* of the suffix list, +# overriding any existing .C compilation method. +.SUFFIXES: +.SUFFIXES: .$(C++SUFFIX) .idl $(SUFFIXES) + +# .SUFFIXES: .$(C++SUFFIX) .idl .hh $(SUFFIXES) +# ------------------------------------------------------------ +# *[CS].o must be compiled here, and depends +# mostly on the C++ files produced from the IDL file. + +%C.o: %C.$(C++SUFFIX) + $(C++) -c $(C++FLAGS) $< + +%S.o: %S.$(C++SUFFIX) + $(C++) -c $(C++FLAGS) $< + +%.o: %.$(C++SUFFIX) + $(C++) -c $(C++FLAGS) $< + +# and here's how to compile C++ files from the IDL file. +# only ONE of these rules will be run at make-time, + +%S.$(C++SUFFIX): %.idl + $(IDL) $(IDLFLAGS) $< + +%C.$(C++SUFFIX): %.idl + $(IDL) $(IDLFLAGS) $< + +%.hh: %.idl + $(IDL) $(IDLFLAGS) $< + diff --git a/performance-tests/TTCP/Orbix/run_test b/performance-tests/TTCP/Orbix/run_test new file mode 100644 index 00000000000..842be36c4ac --- /dev/null +++ b/performance-tests/TTCP/Orbix/run_test @@ -0,0 +1,30 @@ +#!/bin/csh -f +if ($#argv < 3) then + echo "Usage: sclt -q" + exit 1 +endif +# +@ msize=1024 +@ limit= ($argv[1] * 1024) +#echo $limit +#echo $msize +echo "Iteration#" 1 ": client -D -fm -s -t -l" $msize "-h" $2 "-L" $3 $4 +client -D -fm -s -t -l $msize -h $2 -x -L $3 $4 +set flag=0 +while ($msize <= $limit) + if ($flag == 0) goto label + echo "Iteration#" 1 ": client -D -fm -s -t -l" $msize "-h" $2 "-x -L" $3 $4 + client -D -fm -s -t -l $msize -h $2 -x -L $3 $4 + label: + set flag=1 + foreach i (2 3 4 5) + echo "Iteration#" $i ": client -D -fm -s -t -l" $msize "-h" $2 "-x -L " $3 $4 + client -D -fm -s -t -l $msize -h $2 -L $3 $4 + end + echo "---------------------------" + @ msize = ($msize * 2) +end + +echo " " +echo "Done at:" +date diff --git a/performance-tests/TTCP/Orbix/ttcp.hh b/performance-tests/TTCP/Orbix/ttcp.hh new file mode 100644 index 00000000000..ff24bfe58ec --- /dev/null +++ b/performance-tests/TTCP/Orbix/ttcp.hh @@ -0,0 +1,376 @@ + +#ifndef ttcp_hh +#define ttcp_hh + +#include + +#include + + +#ifndef _IDL_SEQUENCE_char_defined +#define _IDL_SEQUENCE_char_defined + +struct IONANC__IDL_SEQUENCE_char; +struct _IDL_SEQUENCE_char { + unsigned long _maximum; + unsigned long _length; + char *_buffer; + + operator IONANC__IDL_SEQUENCE_char(); + operator const IONANC__IDL_SEQUENCE_char() const; + _IDL_SEQUENCE_char& operator= (const IONANC__IDL_SEQUENCE_char&); + + _IDL_SEQUENCE_char& operator= (const _IDL_SEQUENCE_char&); + _IDL_SEQUENCE_char (const _IDL_SEQUENCE_char&); + + _IDL_SEQUENCE_char (unsigned long IT_size = 0); + + ~_IDL_SEQUENCE_char () { if (_buffer) delete [] _buffer; } + + char& operator [] (unsigned long IT_i) const {return _buffer[IT_i]; } + + void encodeOp (CORBA::Request &IT_r) const; + void decodeOp (CORBA::Request &IT_r); + void decodeInOutOp (CORBA::Request &IT_r); +}; + +struct IONANC__IDL_SEQUENCE_char { + unsigned long _maximum; + unsigned long _length; + char *_buffer; + + char& operator [] (unsigned long IT_i) const; + + operator _IDL_SEQUENCE_char (); + + operator const _IDL_SEQUENCE_char () const; + +}; + + + +#endif + + +#ifndef _ttcp_sequence_defined +#define _ttcp_sequence_defined +class ttcp_sequence_dispatch : public virtual CORBA::PPTR { +public: + + ttcp_sequence_dispatch (void *IT_p, CORBA::Object* IT_o, const char *IT_m, + CORBA::LoaderClass *IT_l, char *IT_i, void* IT_im) + : CORBA::PPTR (IT_p,IT_o,IT_m,IT_l,IT_i,IT_im) {} + + + ttcp_sequence_dispatch (char *IT_OR, void *IT_p, CORBA::Object *IT_o) + : CORBA::PPTR (IT_OR,IT_p,IT_o) {} + + + ttcp_sequence_dispatch () {} + + ttcp_sequence_dispatch (void *IT_p, CORBA::Object *IT_o, const char *IT_m, + char *IT_i, CORBA::Object* IT_ob, void* IT_im) + : CORBA::PPTR (IT_p,IT_o,IT_m,IT_i,IT_ob,IT_im) {} + + + virtual unsigned char dispatch (CORBA::Request &IT_r, + unsigned char IT_isTarget, void* IT_pp=NULL); + + +}; + +class ttcp_sequence; + + +#ifndef ttcp_sequenceForwH +#define ttcp_sequenceForwH +CORBA::ObjectRef ttcp_sequence_getBase (void *); +void ttcp_sequence_release (void *, CORBA::Environment &IT_env=CORBA::default_environment); +ttcp_sequence* ttcp_sequence_duplicate (void *, CORBA::Environment &IT_env=CORBA::default_environment); +#endif +#define ttcp_sequence_IMPL "ttcp_sequence" + + +class ttcp_sequence; +#define ttcp_sequence_IR "ttcp_sequence" +#define ttcp_sequence_IMPL "ttcp_sequence" + +typedef ttcp_sequence* ttcp_sequenceRef; +typedef ttcp_sequence* ttcp_sequence_ptr; +class ttcp_sequence: public virtual CORBA::Object { +public: + ttcp_sequence (char *IT_OR); + ttcp_sequence () : CORBA::Object (1) {} + ttcp_sequence* _duplicate( + CORBA::Environment &IT_env=CORBA::default_environment) { + CORBA::Object::_duplicate (IT_env); return this; } + static ttcp_sequence* _bind (const char* IT_markerServer, const char* host, + const CORBA::Context &IT_c, + CORBA::Environment &IT_env=CORBA::default_environment); + static ttcp_sequence* _bind (CORBA::Environment &IT_env); + static ttcp_sequence* _bind (const char* IT_markerServer=NULL, const char* host=NULL, + CORBA::Environment &IT_env=CORBA::default_environment); + static ttcp_sequence* _narrow (CORBA::Object* , CORBA::Environment &IT_env=CORBA::default_environment); +typedef _IDL_SEQUENCE_char my_sequence; + virtual long send (const ttcp_sequence::my_sequence& ttcp_seq, CORBA::Environment &IT_env=CORBA::default_environment); + virtual void start_timer (CORBA::Environment &IT_env=CORBA::default_environment); + virtual void stop_timer (CORBA::Environment &IT_env=CORBA::default_environment); +}; + + +#define TIE_ttcp_sequence(X) ttcp_sequence##X + +#define DEF_TIE_ttcp_sequence(X) \ + class ttcp_sequence##X : public virtual ttcp_sequence { \ + X* m_obj; \ + public: \ + \ + ttcp_sequence##X (X *objp, const char* m="", CORBA::LoaderClass *l=nil)\ + : ttcp_sequence(), CORBA::Object (), m_obj(objp) { \ + m_pptr = new ttcp_sequence_dispatch \ + (( ttcp_sequence*)this,(CORBA::Object*)this,m,l,ttcp_sequence_IR,m_obj); \ + } \ + ttcp_sequence##X (CORBA::Object *IT_p, const char* IT_m="", void *IT_q=nil)\ + : ttcp_sequence(), CORBA::Object () { \ + m_pptr = new ttcp_sequence_dispatch \ + (( ttcp_sequence*)this,(CORBA::Object*)this,IT_m,ttcp_sequence_IR,IT_p,IT_q); \ + m_obj = (X*)(m_pptr->getImplObj ()); \ + } \ + \ + virtual ~ttcp_sequence##X () { \ + if (_okToDeleteImpl ()) delete m_obj; } \ + \ + virtual void* _deref () { \ + return m_obj; } \ + \ + virtual long send (const ttcp_sequence::my_sequence& ttcp_seq, CORBA::Environment &IT_env) {\ +return m_obj->send ( ttcp_seq,IT_env);\ +}\ + \ + virtual void start_timer (CORBA::Environment &IT_env) {\ +m_obj->start_timer (IT_env);\ +}\ + \ + virtual void stop_timer (CORBA::Environment &IT_env) {\ +m_obj->stop_timer (IT_env);\ +}\ + \ + }; + + +#define QUALS_ttcp_sequence \ + virtual long send (const ttcp_sequence::my_sequence& ttcp_seq, CORBA::Environment &IT_env) {\ +return m_obj->send ( ttcp_seq,IT_env);\ +}\ + \ + virtual void start_timer (CORBA::Environment &IT_env) {\ +m_obj->start_timer (IT_env);\ +}\ + \ + virtual void stop_timer (CORBA::Environment &IT_env) {\ +m_obj->stop_timer (IT_env);\ +}\ + + + + +class ttcp_sequenceProxyFactoryClass : public virtual CORBA::ObjectFactoryClass { +public: + ttcp_sequenceProxyFactoryClass (unsigned char IT_p=0) + : CORBA::ProxyFactory (ttcp_sequence_IR, IT_p) {} + + virtual void* New (char *IT_OR, CORBA::Environment&); + + virtual void* New2 (); + + virtual void* IT_castUp (void *IT_p, char* IT_s); + + virtual CORBA::PPTR* pptr (void *IT_p); + + virtual void baseInterfaces (_IDL_SEQUENCE_string&); + + +}; + +extern ttcp_sequenceProxyFactoryClass ttcp_sequenceProxyFactory; + + + +class ttcp_sequenceBOAImpl : public virtual ttcp_sequence { +public: + ttcp_sequenceBOAImpl (const char *m="", CORBA::LoaderClass *l=NULL) { + if (CORBA::PPTR::isOK (m_pptr, ttcp_sequence_IR)) + m_pptr = new ttcp_sequence_dispatch ( (ttcp_sequence*)this, + (CORBA::Object*)this, m, l, ttcp_sequence_IR, this); +} + + virtual long send (const ttcp_sequence::my_sequence& ttcp_seq, CORBA::Environment &IT_env=CORBA::default_environment) =0; + virtual void start_timer (CORBA::Environment &IT_env=CORBA::default_environment) =0; + virtual void stop_timer (CORBA::Environment &IT_env=CORBA::default_environment) =0; +}; + + +#endif + + +#ifndef _ttcp_string_defined +#define _ttcp_string_defined +class ttcp_string_dispatch : public virtual CORBA::PPTR { +public: + + ttcp_string_dispatch (void *IT_p, CORBA::Object* IT_o, const char *IT_m, + CORBA::LoaderClass *IT_l, char *IT_i, void* IT_im) + : CORBA::PPTR (IT_p,IT_o,IT_m,IT_l,IT_i,IT_im) {} + + + ttcp_string_dispatch (char *IT_OR, void *IT_p, CORBA::Object *IT_o) + : CORBA::PPTR (IT_OR,IT_p,IT_o) {} + + + ttcp_string_dispatch () {} + + ttcp_string_dispatch (void *IT_p, CORBA::Object *IT_o, const char *IT_m, + char *IT_i, CORBA::Object* IT_ob, void* IT_im) + : CORBA::PPTR (IT_p,IT_o,IT_m,IT_i,IT_ob,IT_im) {} + + + virtual unsigned char dispatch (CORBA::Request &IT_r, + unsigned char IT_isTarget, void* IT_pp=NULL); + + +}; + +class ttcp_string; + + +#ifndef ttcp_stringForwH +#define ttcp_stringForwH +CORBA::ObjectRef ttcp_string_getBase (void *); +void ttcp_string_release (void *, CORBA::Environment &IT_env=CORBA::default_environment); +ttcp_string* ttcp_string_duplicate (void *, CORBA::Environment &IT_env=CORBA::default_environment); +#endif +#define ttcp_string_IMPL "ttcp_string" + + +class ttcp_string; +#define ttcp_string_IR "ttcp_string" +#define ttcp_string_IMPL "ttcp_string" + +typedef ttcp_string* ttcp_stringRef; +typedef ttcp_string* ttcp_string_ptr; +class ttcp_string: public virtual CORBA::Object { +public: + ttcp_string (char *IT_OR); + ttcp_string () : CORBA::Object (1) {} + ttcp_string* _duplicate( + CORBA::Environment &IT_env=CORBA::default_environment) { + CORBA::Object::_duplicate (IT_env); return this; } + static ttcp_string* _bind (const char* IT_markerServer, const char* host, + const CORBA::Context &IT_c, + CORBA::Environment &IT_env=CORBA::default_environment); + static ttcp_string* _bind (CORBA::Environment &IT_env); + static ttcp_string* _bind (const char* IT_markerServer=NULL, const char* host=NULL, + CORBA::Environment &IT_env=CORBA::default_environment); + static ttcp_string* _narrow (CORBA::Object* , CORBA::Environment &IT_env=CORBA::default_environment); + virtual long send (const char * ttcp_str, CORBA::Environment &IT_env=CORBA::default_environment); + virtual void start_timer (CORBA::Environment &IT_env=CORBA::default_environment); + virtual void stop_timer (CORBA::Environment &IT_env=CORBA::default_environment); +}; + + +#define TIE_ttcp_string(X) ttcp_string##X + +#define DEF_TIE_ttcp_string(X) \ + class ttcp_string##X : public virtual ttcp_string { \ + X* m_obj; \ + public: \ + \ + ttcp_string##X (X *objp, const char* m="", CORBA::LoaderClass *l=nil)\ + : ttcp_string(), CORBA::Object (), m_obj(objp) { \ + m_pptr = new ttcp_string_dispatch \ + (( ttcp_string*)this,(CORBA::Object*)this,m,l,ttcp_string_IR,m_obj); \ + } \ + ttcp_string##X (CORBA::Object *IT_p, const char* IT_m="", void *IT_q=nil)\ + : ttcp_string(), CORBA::Object () { \ + m_pptr = new ttcp_string_dispatch \ + (( ttcp_string*)this,(CORBA::Object*)this,IT_m,ttcp_string_IR,IT_p,IT_q); \ + m_obj = (X*)(m_pptr->getImplObj ()); \ + } \ + \ + virtual ~ttcp_string##X () { \ + if (_okToDeleteImpl ()) delete m_obj; } \ + \ + virtual void* _deref () { \ + return m_obj; } \ + \ + virtual long send (const char * ttcp_str, CORBA::Environment &IT_env) {\ +return m_obj->send ( ttcp_str,IT_env);\ +}\ + \ + virtual void start_timer (CORBA::Environment &IT_env) {\ +m_obj->start_timer (IT_env);\ +}\ + \ + virtual void stop_timer (CORBA::Environment &IT_env) {\ +m_obj->stop_timer (IT_env);\ +}\ + \ + }; + + +#define QUALS_ttcp_string \ + virtual long send (const char * ttcp_str, CORBA::Environment &IT_env) {\ +return m_obj->send ( ttcp_str,IT_env);\ +}\ + \ + virtual void start_timer (CORBA::Environment &IT_env) {\ +m_obj->start_timer (IT_env);\ +}\ + \ + virtual void stop_timer (CORBA::Environment &IT_env) {\ +m_obj->stop_timer (IT_env);\ +}\ + + + + +class ttcp_stringProxyFactoryClass : public virtual CORBA::ObjectFactoryClass { +public: + ttcp_stringProxyFactoryClass (unsigned char IT_p=0) + : CORBA::ProxyFactory (ttcp_string_IR, IT_p) {} + + virtual void* New (char *IT_OR, CORBA::Environment&); + + virtual void* New2 (); + + virtual void* IT_castUp (void *IT_p, char* IT_s); + + virtual CORBA::PPTR* pptr (void *IT_p); + + virtual void baseInterfaces (_IDL_SEQUENCE_string&); + + +}; + +extern ttcp_stringProxyFactoryClass ttcp_stringProxyFactory; + + + +class ttcp_stringBOAImpl : public virtual ttcp_string { +public: + ttcp_stringBOAImpl (const char *m="", CORBA::LoaderClass *l=NULL) { + if (CORBA::PPTR::isOK (m_pptr, ttcp_string_IR)) + m_pptr = new ttcp_string_dispatch ( (ttcp_string*)this, + (CORBA::Object*)this, m, l, ttcp_string_IR, this); +} + + virtual long send (const char * ttcp_str, CORBA::Environment &IT_env=CORBA::default_environment) =0; + virtual void start_timer (CORBA::Environment &IT_env=CORBA::default_environment) =0; + virtual void stop_timer (CORBA::Environment &IT_env=CORBA::default_environment) =0; +}; + + +#endif + + +#endif diff --git a/performance-tests/TTCP/Orbix/ttcp.idl b/performance-tests/TTCP/Orbix/ttcp.idl new file mode 100644 index 00000000000..9ceef61e0a3 --- /dev/null +++ b/performance-tests/TTCP/Orbix/ttcp.idl @@ -0,0 +1,22 @@ +/* -*- C++ -*- */ +// @(#)ttcp.idl 1.1 10/18/96 + + +interface ttcp_sequence +{ + typedef sequence my_sequence; + + long send (in my_sequence ttcp_seq); + oneway void start_timer (); + oneway void stop_timer (); +}; + +interface ttcp_string +{ + long send (in string ttcp_str); + oneway void start_timer (); + oneway void stop_timer (); +}; + + + diff --git a/performance-tests/TTCP/Orbix/ttcpC.cpp b/performance-tests/TTCP/Orbix/ttcpC.cpp new file mode 100644 index 00000000000..dd8c44d9d21 --- /dev/null +++ b/performance-tests/TTCP/Orbix/ttcpC.cpp @@ -0,0 +1,343 @@ + +// @(#)ttcpC.cpp 1.1 10/18/96 + +#include "ttcp.hh" + + +#ifndef _IDL_SEQUENCE_char_Ops +#define _IDL_SEQUENCE_char_Ops + +_IDL_SEQUENCE_char &_IDL_SEQUENCE_char:: operator= (const IONANC__IDL_SEQUENCE_char& IT_p) { + this->operator= (*(_IDL_SEQUENCE_char*) &IT_p); + return (*this); +} + +_IDL_SEQUENCE_char:: operator IONANC__IDL_SEQUENCE_char () { + IONANC__IDL_SEQUENCE_char tmp; + memset (&tmp, 0, sizeof(tmp)); + ((_IDL_SEQUENCE_char *) &tmp)->operator= (*this); + return tmp; +} + +_IDL_SEQUENCE_char:: operator const IONANC__IDL_SEQUENCE_char () const { + IONANC__IDL_SEQUENCE_char tmp; + memset (&tmp, 0, sizeof(tmp)); + ((_IDL_SEQUENCE_char *) &tmp)->operator= (*this); + return tmp; +} + +_IDL_SEQUENCE_char& _IDL_SEQUENCE_char:: operator= (const _IDL_SEQUENCE_char &IT_s){ + if (this == &IT_s) return *this; + if (_buffer) delete [] _buffer; + _length = IT_s._length; + _maximum = IT_s._maximum; + if (_maximum) { + _buffer = new char [ _maximum ]; + for (unsigned long IT_j=0; IT_j < _length; IT_j++) + _buffer [IT_j] = IT_s._buffer[IT_j]; + } + else + _buffer = NULL; + return *this; +} + +_IDL_SEQUENCE_char:: _IDL_SEQUENCE_char (unsigned long IT_size) { + if (IT_size) + _buffer = new char [ IT_size ]; + else + _buffer = NULL; + _length = 0; + _maximum = IT_size; + } + +_IDL_SEQUENCE_char:: _IDL_SEQUENCE_char (const _IDL_SEQUENCE_char &IT_s) { + _length = IT_s._length; + _maximum = IT_s._maximum; + if (_maximum) { + _buffer = new char [ _maximum ]; + for (unsigned long IT_j=0; IT_j < _length; IT_j++) + _buffer [IT_j] = IT_s._buffer[IT_j]; + } + else + _buffer = NULL; +} + +void _IDL_SEQUENCE_char:: decodeInOutOp (CORBA::Request &IT_r) { + unsigned long IT_max; + IT_r >> IT_max; + if (IT_max > _maximum) + IT_r.makeRuntimeException3 (); + else { + IT_r >> _length; + if (_length > _maximum) + IT_r.makeRuntimeException4 (); + else + if (_maximum) { + char* IT_arr = (char*) _buffer; + IT_r.decodeCharArray (IT_arr, _length); + } + } +} + +void _IDL_SEQUENCE_char:: encodeOp (CORBA::Request &IT_r) const { + IT_r << _maximum; + IT_r << _length; +if (_maximum) { + char* IT_arr = (char*) _buffer; + IT_r.encodeCharArray (IT_arr, _length); +} +} + +void _IDL_SEQUENCE_char:: decodeOp (CORBA::Request &IT_r) { + IT_r >> _maximum; + IT_r >> _length; + if (_maximum) { + _buffer = new char [ _maximum ]; + { + char* IT_arr = (char*) _buffer; + IT_r.decodeCharArray (IT_arr, _length); + } + } + else + _buffer = NULL; +} + +char &IONANC__IDL_SEQUENCE_char:: operator [](unsigned long IT_i) const { + return _buffer[IT_i]; +} + +IONANC__IDL_SEQUENCE_char:: operator _IDL_SEQUENCE_char () { + return (*((_IDL_SEQUENCE_char *) this)); +} + +IONANC__IDL_SEQUENCE_char:: operator const _IDL_SEQUENCE_char () const { + return (*((const _IDL_SEQUENCE_char *) this)); +} + + +#endif + +ttcp_sequence::ttcp_sequence (char *IT_OR) { + m_pptr = new ttcp_sequence_dispatch (IT_OR, this,(CORBA::Object*)this); +} + +#ifndef ttcp_sequenceForwC +#define ttcp_sequenceForwC +CORBA::ObjectRef ttcp_sequence_getBase(void *IT_p){ + return (ttcp_sequence*)IT_p;} + +void ttcp_sequence_release (void *IT_p, CORBA::Environment &IT_env) { + ((ttcp_sequence*)IT_p)->_release(IT_env);} + +ttcp_sequence* ttcp_sequence_duplicate (void *IT_p, CORBA::Environment &IT_env) { + return ((ttcp_sequence*)IT_p)->_duplicate(IT_env); } +#endif + + + +ttcp_sequence* ttcp_sequence:: _bind (const char* IT_markerServer, const char* host, + const CORBA::Context &IT_c, + CORBA::Environment &IT_env) { + ttcp_sequence*IT_p = + (ttcp_sequence*)CORBA::Factory.New (IT_markerServer, IT_env, IT_c, host, + ttcp_sequence_IMPL, ttcp_sequence_IR); + return IT_p ? IT_p->_duplicate () : NULL; } + + + +ttcp_sequence* ttcp_sequence:: _bind (CORBA::Environment &IT_env) { + return _bind (NULL,NULL,CORBA::Context(), IT_env); } + + +ttcp_sequence* ttcp_sequence:: _bind (const char* IT_markerServer, const char* host, + CORBA::Environment &IT_env) { + return _bind (IT_markerServer, host, CORBA::Context (), IT_env); } +ttcp_sequence* ttcp_sequence::_narrow (CORBA::Object* IT_obj, CORBA::Environment &IT_env) { + ttcp_sequence* IT_p = (ttcp_sequence*)CORBA::Object::_castDown (IT_obj, ttcp_sequence_IR, IT_env); + return IT_p ? IT_p->_duplicate(IT_env) : NULL; + } + +void* ttcp_sequenceProxyFactoryClass::New (char *IT_OR, CORBA::Environment&) { + return new ttcp_sequence(IT_OR);} + +void* ttcp_sequenceProxyFactoryClass::New2 () { + return new ttcp_sequence();} + +void* ttcp_sequenceProxyFactoryClass::IT_castUp (void *IT_p, char* IT_s) { + void *IT_l; + if (!CORBA::_interfaceCmp (IT_s,ttcp_sequence_IR)) + return IT_p; + else if (IT_l=CORBA::ObjectFactoryClass::IT_castUp((CORBA::Object*)((ttcp_sequence*)IT_p),IT_s)) + return IT_l; + else return NULL; + } + + +CORBA::PPTR* ttcp_sequenceProxyFactoryClass::pptr (void *IT_p) { + return ((ttcp_sequence*)IT_p)->_pptr ();} + +void ttcp_sequenceProxyFactoryClass::baseInterfaces (_IDL_SEQUENCE_string& seq) { + add (seq, ttcp_sequence_IR); + CORBA::ObjectFactoryClass::baseInterfaces (seq); +} + +long ttcp_sequence:: send(const ttcp_sequence::my_sequence& ttcp_seq, CORBA::Environment &IT_env) { + + if (IT_env || m_isNull) return 0; + CORBA::Request IT_r (this, "send",IT_env,1,0); + if (!IT_r.isException (IT_env)) { + ttcp_seq.encodeOp (IT_r); + } + + IT_r.invoke (CORBA::Flags(0),IT_env); + if (!IT_r.isException (IT_env)) { + long IT_result; + IT_r >> IT_result; + IT_r.checkEnv (IT_env); + return IT_result; + } + return 0; +} + +void ttcp_sequence:: start_timer(CORBA::Environment &IT_env) { + + if (IT_env || m_isNull) return ; + CORBA::Request IT_r (this, "start_timer",IT_env,1,1); + + IT_r.invoke (CORBA::Flags(CORBA::INV_NO_RESPONSE), IT_env); +} + +void ttcp_sequence:: stop_timer(CORBA::Environment &IT_env) { + + if (IT_env || m_isNull) return ; + CORBA::Request IT_r (this, "stop_timer",IT_env,1,1); + + IT_r.invoke (CORBA::Flags(CORBA::INV_NO_RESPONSE), IT_env); +} + + +ttcp_sequenceProxyFactoryClass ttcp_sequenceProxyFactory(1); + + +#ifndef ttcp_sequence_dispatch_impl + +unsigned char ttcp_sequence_dispatch::dispatch (CORBA::Request &IT_r, + unsigned char, void *) { + IT_r.makeRuntimeException1 ("ttcp_sequence"); + return 0; +} + +#endif + +ttcp_string::ttcp_string (char *IT_OR) { + m_pptr = new ttcp_string_dispatch (IT_OR, this,(CORBA::Object*)this); +} + +#ifndef ttcp_stringForwC +#define ttcp_stringForwC +CORBA::ObjectRef ttcp_string_getBase(void *IT_p){ + return (ttcp_string*)IT_p;} + +void ttcp_string_release (void *IT_p, CORBA::Environment &IT_env) { + ((ttcp_string*)IT_p)->_release(IT_env);} + +ttcp_string* ttcp_string_duplicate (void *IT_p, CORBA::Environment &IT_env) { + return ((ttcp_string*)IT_p)->_duplicate(IT_env); } +#endif + + + +ttcp_string* ttcp_string:: _bind (const char* IT_markerServer, const char* host, + const CORBA::Context &IT_c, + CORBA::Environment &IT_env) { + ttcp_string*IT_p = + (ttcp_string*)CORBA::Factory.New (IT_markerServer, IT_env, IT_c, host, + ttcp_string_IMPL, ttcp_string_IR); + return IT_p ? IT_p->_duplicate () : NULL; } + + + +ttcp_string* ttcp_string:: _bind (CORBA::Environment &IT_env) { + return _bind (NULL,NULL,CORBA::Context(), IT_env); } + + +ttcp_string* ttcp_string:: _bind (const char* IT_markerServer, const char* host, + CORBA::Environment &IT_env) { + return _bind (IT_markerServer, host, CORBA::Context (), IT_env); } +ttcp_string* ttcp_string::_narrow (CORBA::Object* IT_obj, CORBA::Environment &IT_env) { + ttcp_string* IT_p = (ttcp_string*)CORBA::Object::_castDown (IT_obj, ttcp_string_IR, IT_env); + return IT_p ? IT_p->_duplicate(IT_env) : NULL; + } + +void* ttcp_stringProxyFactoryClass::New (char *IT_OR, CORBA::Environment&) { + return new ttcp_string(IT_OR);} + +void* ttcp_stringProxyFactoryClass::New2 () { + return new ttcp_string();} + +void* ttcp_stringProxyFactoryClass::IT_castUp (void *IT_p, char* IT_s) { + void *IT_l; + if (!CORBA::_interfaceCmp (IT_s,ttcp_string_IR)) + return IT_p; + else if (IT_l=CORBA::ObjectFactoryClass::IT_castUp((CORBA::Object*)((ttcp_string*)IT_p),IT_s)) + return IT_l; + else return NULL; + } + + +CORBA::PPTR* ttcp_stringProxyFactoryClass::pptr (void *IT_p) { + return ((ttcp_string*)IT_p)->_pptr ();} + +void ttcp_stringProxyFactoryClass::baseInterfaces (_IDL_SEQUENCE_string& seq) { + add (seq, ttcp_string_IR); + CORBA::ObjectFactoryClass::baseInterfaces (seq); +} + +long ttcp_string:: send(const char * ttcp_str, CORBA::Environment &IT_env) { + + if (IT_env || m_isNull) return 0; + CORBA::Request IT_r (this, "send",IT_env,1,0); + if (!IT_r.isException (IT_env)) { + IT_r.encodeStringOp (ttcp_str); + } + + IT_r.invoke (CORBA::Flags(0),IT_env); + if (!IT_r.isException (IT_env)) { + long IT_result; + IT_r >> IT_result; + IT_r.checkEnv (IT_env); + return IT_result; + } + return 0; +} + +void ttcp_string:: start_timer(CORBA::Environment &IT_env) { + + if (IT_env || m_isNull) return ; + CORBA::Request IT_r (this, "start_timer",IT_env,1,1); + + IT_r.invoke (CORBA::Flags(CORBA::INV_NO_RESPONSE), IT_env); +} + +void ttcp_string:: stop_timer(CORBA::Environment &IT_env) { + + if (IT_env || m_isNull) return ; + CORBA::Request IT_r (this, "stop_timer",IT_env,1,1); + + IT_r.invoke (CORBA::Flags(CORBA::INV_NO_RESPONSE), IT_env); +} + + +ttcp_stringProxyFactoryClass ttcp_stringProxyFactory(1); + + +#ifndef ttcp_string_dispatch_impl + +unsigned char ttcp_string_dispatch::dispatch (CORBA::Request &IT_r, + unsigned char, void *) { + IT_r.makeRuntimeException1 ("ttcp_string"); + return 0; +} + +#endif + diff --git a/performance-tests/TTCP/Orbix/ttcpS.cpp b/performance-tests/TTCP/Orbix/ttcpS.cpp new file mode 100644 index 00000000000..e23dffd2d00 --- /dev/null +++ b/performance-tests/TTCP/Orbix/ttcpS.cpp @@ -0,0 +1,159 @@ + +// @(#)ttcpS.cpp 1.1 10/18/96 + +#include "ttcp.hh" + + +#define ttcp_sequence_dispatch_impl + +unsigned char ttcp_sequence_dispatch::dispatch (CORBA::Request &IT_r, + unsigned char IT_isTarget, void *IT_pp) { + if (!IT_pp) + IT_pp = m_obj; + const char *IT_s = IT_r.getOperation (); + if (!strcmp(IT_s,"send")) { + long IT_result; + CORBA::Environment IT_env (IT_r); + CORBA::Filter* IT_f = CORBA::Orbix.getFilter (); + if (!IT_r.tcAssert ("\ +Ro~send~+ttcp_seq{S{c},0},>{l},N{}\ +")) + return 1; + ttcp_sequence::my_sequence ttcp_seq; + ttcp_seq.decodeOp (IT_r); + + if (IT_f && !IT_r.isException (IT_env)) + IT_f->inRequestPostM (IT_r, IT_env); + if (!IT_r.isException (IT_env)) + IT_result = ((ttcp_sequence*)IT_pp)->send ( ttcp_seq, IT_env); + + + if (!IT_r.isException (IT_env)) { + if (!IT_r.convertToReply ("\ +l\ +", IT_env)) return 1; + IT_r << IT_result; + } + + else IT_r.makeSystemException (IT_env); + return 1; + } + + else if (!strcmp(IT_s,"start_timer")) { + CORBA::Environment IT_env (IT_r); + CORBA::Filter* IT_f = CORBA::Orbix.getFilter (); + if (!IT_r.tcAssert ("\ +Ro~start_timer~>{v},O{}\ +")) + return 1; + + if (IT_f && !IT_r.isException (IT_env)) + IT_f->inRequestPostM (IT_r, IT_env); + if (!IT_r.isException (IT_env)) + ((ttcp_sequence*)IT_pp)->start_timer (IT_env); + + IT_r.replyNoResults (CORBA::Flags(CORBA::INV_NO_RESPONSE),IT_env); + return 1; + } + + else if (!strcmp(IT_s,"stop_timer")) { + CORBA::Environment IT_env (IT_r); + CORBA::Filter* IT_f = CORBA::Orbix.getFilter (); + if (!IT_r.tcAssert ("\ +Ro~stop_timer~>{v},O{}\ +")) + return 1; + + if (IT_f && !IT_r.isException (IT_env)) + IT_f->inRequestPostM (IT_r, IT_env); + if (!IT_r.isException (IT_env)) + ((ttcp_sequence*)IT_pp)->stop_timer (IT_env); + + IT_r.replyNoResults (CORBA::Flags(CORBA::INV_NO_RESPONSE),IT_env); + return 1; + } + + else if (IT_isTarget) + IT_r.makeRuntimeException2 (); + + return 0; +} + +#define ttcp_string_dispatch_impl + +unsigned char ttcp_string_dispatch::dispatch (CORBA::Request &IT_r, + unsigned char IT_isTarget, void *IT_pp) { + if (!IT_pp) + IT_pp = m_obj; + const char *IT_s = IT_r.getOperation (); + if (!strcmp(IT_s,"send")) { + long IT_result; + CORBA::Environment IT_env (IT_r); + CORBA::Filter* IT_f = CORBA::Orbix.getFilter (); + if (!IT_r.tcAssert ("\ +Ro~send~+ttcp_str{0},>{l},N{}\ +")) + return 1; + char * ttcp_str; + IT_r.decodeStringOp(ttcp_str); + + if (IT_f && !IT_r.isException (IT_env)) + IT_f->inRequestPostM (IT_r, IT_env); + if (!IT_r.isException (IT_env)) + IT_result = ((ttcp_string*)IT_pp)->send ( ttcp_str, IT_env); + + delete [] ttcp_str; + + if (!IT_r.isException (IT_env)) { + if (!IT_r.convertToReply ("\ +l\ +", IT_env)) return 1; + IT_r << IT_result; + } + + else IT_r.makeSystemException (IT_env); + return 1; + } + + else if (!strcmp(IT_s,"start_timer")) { + CORBA::Environment IT_env (IT_r); + CORBA::Filter* IT_f = CORBA::Orbix.getFilter (); + if (!IT_r.tcAssert ("\ +Ro~start_timer~>{v},O{}\ +")) + return 1; + + if (IT_f && !IT_r.isException (IT_env)) + IT_f->inRequestPostM (IT_r, IT_env); + if (!IT_r.isException (IT_env)) + ((ttcp_string*)IT_pp)->start_timer (IT_env); + + IT_r.replyNoResults (CORBA::Flags(CORBA::INV_NO_RESPONSE),IT_env); + return 1; + } + + else if (!strcmp(IT_s,"stop_timer")) { + CORBA::Environment IT_env (IT_r); + CORBA::Filter* IT_f = CORBA::Orbix.getFilter (); + if (!IT_r.tcAssert ("\ +Ro~stop_timer~>{v},O{}\ +")) + return 1; + + if (IT_f && !IT_r.isException (IT_env)) + IT_f->inRequestPostM (IT_r, IT_env); + if (!IT_r.isException (IT_env)) + ((ttcp_string*)IT_pp)->stop_timer (IT_env); + + IT_r.replyNoResults (CORBA::Flags(CORBA::INV_NO_RESPONSE),IT_env); + return 1; + } + + else if (IT_isTarget) + IT_r.makeRuntimeException2 (); + + return 0; +} + +#include "ttcpC.cpp" + diff --git a/performance-tests/TTCP/Orbix/ttcp_i.cpp b/performance-tests/TTCP/Orbix/ttcp_i.cpp new file mode 100644 index 00000000000..f8221fd36d4 --- /dev/null +++ b/performance-tests/TTCP/Orbix/ttcp_i.cpp @@ -0,0 +1,1013 @@ + +// @(#)ttcp_i.cpp 1.1 10/18/96 + +/* + * T T C P . C + * + */ +#ifndef lint +static char RCSid[] = "ttcp.c $Revision$"; +#endif + +/* #define BSD43 */ +/* #define BSD42 */ +/* #define BSD41a */ +#define SYSV /* required on SGI IRIX releases before 3.3 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* struct itimerval */ +#include +#include +#include + +#if defined(SYSV) +#define bcopy(b1,b2,n) memcpy(b2,b1,n) +#define bzero(b1,n) memset(b1,0,n) +#include +#include +struct rusage + { + struct timeval ru_utime, ru_stime; + }; +#define RUSAGE_SELF 0 + +#else +#include +#endif + +void err (char *s); +void mes (char *s); +void pattern (register char *cp, register int cnt); +char *outfmt (double b); +static void getrusage (int ignored, register struct rusage *ru); +static void gettimeofday (struct timeval *tp, struct timezone *zp); +void prep_timer (void); +double read_timer (char *str, int len); +static void prusage (register struct rusage *r0, struct rusage *r1, struct timeval *e, struct timeval *b, char *outp); +static void tvadd (struct timeval *tsum, struct timeval *t0, struct timeval *t1); +static void tvsub (struct timeval *tdiff, struct timeval *t1, struct timeval *t0); +static void psecs (long l, register char *cp); +void delay (int us); +int mread (int fd, register char *bufp, unsigned n); +int Nread (int fd, void *buf, int count); +int Nwrite (int fd, void *buf, int count); +static void SD_Ready (int io_descriptor); +void set_sock_desc(int starter); +void c_stop_timer (unsigned long numbytes); + +int global_done = 0; + +int fromlen; +int domain = PF_INET; /* Default is to use Internet domain sockets. */ +char *domainname; /* Rendezvous address for UNIX domain sockets. */ +int fd; /* fd of network socket */ + +int buflen = 1024 * 1024 * 2; /* length of buffer */ +char *buf; /* ptr to dynamic buffer */ +int nbuf = 2 * 1024; /* number of buffers to send in sinkmode */ + +int bufoffset = 0; /* align buffer to this */ +int bufalign = 16 * 1024; /* modulo this */ + +int udp = 0; /* 0 = tcp, !0 = udp */ +int options = 0; /* socket options */ +int one = 1; /* for 4.3 BSD style setsockopt() */ +short port = 5001; /* TCP port number */ +char *host; /* ptr to name of host */ +int trans; /* 0=receive, !0=transmit mode */ +int sinkmode = 0; /* 0=normal I/O, !0=sink/source mode */ +int verbose = 0; /* 0=print basic info, 1=print cpu rate, proc + * resource usage. */ +int nodelay = 0; /* set TCP_NODELAY socket option */ +int b_flag = 0; /* use mread() */ +int sockbufsize = 0; /* socket buffer size to use */ +int new_line=0; /* This is a special flag */ +int write_to_file=1; /* indecates writing to file (default)*/ +int SEQUENCE=0; /* String parameter is the default */ +char fmt = 'K'; /* output format:k=kilobits,K=kilobytes, + * m = megabits, M = megabytes, + * g = gigabits, G = gigabytes */ +int touchdata = 0; /* access data after reading */ + +struct hostent *addr; +extern int errno; +extern int optind; +extern char *optarg; +char *title = 0; + +char stats[128]; +unsigned long nbytes; /* bytes on net */ +unsigned long numCalls; /* # of I/O system calls */ +double cput, realt; /* user, real time (seconds) */ + +// AAAAHHHHHHH what's this!!! C++ in the middle of C code???????!!!!!! + + +#include +#include "ttcp_i.h" + +char *orb_host; + +// ttcp_i is the server side + + + +// ttcp_i is the server side + +static void +SD_Ready (int io_descriptor) +{ + cout << "Orbix is using " << io_descriptor << endl; + if (sockbufsize) + { + if (setsockopt (io_descriptor, SOL_SOCKET, SO_RCVBUF, (char *) &sockbufsize, + sizeof sockbufsize) < 0) + perror ("setsockopt: rcvbuf"), exit (1); + } +} + + +ttcp_sequence_i::ttcp_sequence_i() +{ + this->nbytes_ = 0; + // register a callback so we can futs with the descriptor + // being used by orbix. + + if (CORBA::Orbix.registerIOCallback (OrbixIOCallback(SD_Ready), FD_OPEN_CALLBACK) != 0) + perror ("can't register callback"), exit (1); +} + +void +ttcp_sequence_i::start_timer (CORBA::Environment &IT_env) +{ + this->nbytes_ = 0; + prep_timer (); +} + +void +ttcp_sequence_i::stop_timer (CORBA::Environment &IT_env) +{ + c_stop_timer (this->nbytes_); + global_done = 1; +} + +long +ttcp_sequence_i::send(const ttcp_sequence::my_sequence& ttcp_seq,CORBA::Environment &IT_env) +{ + this->nbytes_ += ttcp_seq._length; + return this->nbytes_; +} + +ttcp_string_i::ttcp_string_i() +{ + this->nbytes_ = 0; + // register a callback so we can futs with the descriptor + // being used by orbix. + if (CORBA::Orbix.registerIOCallback (OrbixIOCallback(SD_Ready), FD_OPEN_CALLBACK) != 0) + perror ("can't register callback"), exit (1); +} + +void +ttcp_string_i::start_timer (CORBA::Environment &IT_env) +{ + prep_timer (); +} + + +void +ttcp_string_i::stop_timer (CORBA::Environment &IT_env) +{ + c_stop_timer (this->nbytes_); + global_done = 1; +} + +long +ttcp_string_i::send(const char * ttcp_string,CORBA::Environment &IT_env) +{ + this->nbytes_ += strlen (ttcp_string); + return this->nbytes_; +} + +// common to sequence and string +void +c_stop_timer (unsigned long numbytes) +{ + (void) read_timer (stats, sizeof (stats)); + + if (cput <= 0.0) + cput = 0.001; + if (realt <= 0.0) + realt = 0.001; + fprintf (stdout, + "ttcp%s%s: %ld bytes in %.2f real seconds = %s/sec +++\n", + trans ? "-t" : "-r", SEQUENCE ? "(Seq)" : "(Str)", + numbytes, realt, outfmt (((double) numbytes) / realt)); + + + if (verbose) + { + fprintf (stdout, + "ttcp%s%s: %ld bytes in %.2f CPU seconds = %s/cpu sec\n", + trans ? "-t" : "-r",SEQUENCE ? "(Seq)" : "(Str)", + numbytes, cput, outfmt (((double) numbytes) / cput)); + } + fprintf (stdout, + "ttcp%s%s: %d I/O calls, msec/call = %.2f, calls/sec = %.2f\n", + trans ? "-t" : "-r",SEQUENCE ? "(Seq)" : "(Str)", + numCalls, + 1024.0 * realt / ((double) numCalls), + ((double) numCalls) / realt); + fprintf (stdout, "ttcp%s%s: %s\n", trans ? "-t" : "-r",SEQUENCE ? "(Seq)" : "(Str)", stats); + if (verbose) + { + fprintf (stdout, + "ttcp%s: buffer address %#x\n", + trans ? "-t" : "-r", + buf); + } +numbytes = 0; + + // you shoudl exit here when you use -p (profiler) so the server will + // produce mon.out +#ifdef PROFILE + exit(1); +#endif +} // end of stop_timer + + +char Usage[] = "\ +Usage: ttcp -t [-options] host [ < in ]\n\ + ttcp -r [-options > out]\n\ +Common options:\n\ + -l ## length of bufs read from or written to network (default 8192)\n\ + -u use UDP instead of TCP\n\ + -U use UNIX domain sockets instead of Internet domain sockets\n\ + -p ## port number to send to or listen at (default 5001)\n\ + -s -t: source a pattern to network\n\ + -r: sink (discard) all data from network\n\ + -A align the start of buffers to this modulus (default 16384)\n\ + -O start buffers at this offset from the modulus (default 0)\n\ + -v verbose: print more statistics\n\ + -d set SO_DEBUG socket option\n\ + -b ## set socket buffer size (if supported)\n\ + -f X format for rate: k,K = kilo{bit,byte}; m,M = mega; g,G = giga\n\ +Options specific to -t:\n\ + -n## number of source bufs written to network (default 2048)\n\ + -D don't buffer TCP writes (sets TCP_NODELAY socket option)\n\ +Options specific to -r:\n\ + -B for -s, only output full blocks as specified by -l (for TAR)\n\ + -T \"touch\": access each byte as it's read\n\ + -L the title of the current test\n\ + -F don't write to a file (writting in a file dat.out is default)\n\ + -q run the test using sequence parameter (string is defualt) \n\ +"; + +#if !defined (__cplusplus) +typedef void (*SIG_TYP)(); +#endif + +#ifdef SVR4 +void +sigpipe (int foo) +#else +void +sigpipe () +#endif +{ +} + +int +main (int argc, char *argv[]) +{ + + unsigned long addr_tmp; + int c; + + if (argc < 2) + goto usage; + + while ((c = getopt (argc, argv, "qFdrstU:uvBDTb:L:f:l:n:p:A:O:h:x")) != -1) + { + switch (c) + { + case 'L': + title = optarg; + fprintf(stdout,"---->title=%s\n",title); + break; + case 'x': + new_line = 1; + break; + case 'q': + SEQUENCE = 1; + break; + case 'F': + write_to_file = 0; + break; + case 'h': + orb_host = optarg; + break; + case 'B': + b_flag = 1; + break; + case 't': + trans = 1; + break; + case 'r': + trans = 0; + break; + case 'd': + options |= SO_DEBUG; + break; + case 'D': +#ifdef TCP_NODELAY + nodelay = 1; +#else + fprintf (stderr, + "ttcp: -D option ignored: TCP_NODELAY socket option not supported\n"); +#endif + break; + case 'n': + nbuf = atoi (optarg); + break; + case 'l': + buflen = atoi (optarg); + break; + case 's': + sinkmode = !sinkmode; + break; + case 'p': + port = atoi (optarg); + break; + case 'U': + domain = PF_UNIX; + domainname = optarg; + break; + case 'u': + udp = 1; + break; + case 'v': + verbose = 1; + break; + case 'A': + bufalign = atoi (optarg); + break; + case 'O': + bufoffset = atoi (optarg); + break; + case 'b': +#if defined(SO_SNDBUF) || defined(SO_RCVBUF) + sockbufsize = atoi (optarg); +#else + fprintf (stderr, "ttcp: -b option ignored: SO_SNDBUF/SO_RCVBUF socket options not supported\n"); +#endif + break; + case 'f': + fmt = *optarg; + break; + case 'T': + touchdata = 1; + break; + + default: + goto usage; + } + } + + // + // Receiver + // + + if (!trans) + { + + // Sequence and String Interfaces + // instantiate ONLY one object at a time, so no dispatching overhead is counted + char *interface_name = new char[15]; + if (SEQUENCE) + { + ttcp_sequence *my_ttcp = new ttcp_sequence_i; + strcpy(interface_name,"ttcp_sequence"); + } + else + { + ttcp_string *my_ttcp_s = new ttcp_string_i; + strcpy(interface_name,"ttcp_string"); + } + + // tell Orbix/ORBeline that we have completed the server's initialization: + TRY { + CORBA::Orbix.impl_is_ready(interface_name, 0, IT_X); + + while ((!global_done) && (!IT_X)) + CORBA::Orbix.processNextEvent (CORBA::ORB::INFINITE_TIMEOUT, IT_X); + } + CATCHANY { + // an error occured calling impl_is_ready() - output the error. + cout << IT_X; + } + ENDTRY; + + cout << "server exiting" << endl; + return 42; + } + + // + // Transmitter + // + +// CORBA::Environment env; + ttcp_sequence *ttcp_seq; + ttcp_string *ttcp_str; + + + CORBA::Object *ttcp_; + + if (SEQUENCE) + { + TRY + { + ttcp_ = ttcp_seq = ttcp_sequence::_bind ("", orb_host, IT_X); + } + CATCHANY + { + // an error occurred while trying to bind to the logger object. + cerr << "Bind to object failed" << endl; + cerr << "Unexpected exception " << IT_X << endl; + return -1; + } ENDTRY; + + } + else // string parameter used + { + TRY + { + ttcp_ = ttcp_str = ttcp_string::_bind ("", orb_host, IT_X); + } + CATCHANY + { + // an error occurred while trying to bind to the logger object. + cerr << "Bind to object failed" << endl; + cerr << "Unexpected exception " << IT_X << endl; + return -1; + } ENDTRY; + } + + if (sockbufsize) + { + if (setsockopt (ttcp_->_fd (), SOL_SOCKET, SO_SNDBUF, (char *) &sockbufsize, + sizeof sockbufsize) < 0) + err ("setsockopt: sndbuf"); + mes ("sndbuf"); + } + + if (nodelay) + { + struct protoent *p; + p = getprotobyname ("tcp"); + if (setsockopt (ttcp_->_fd (), + p->p_proto, + TCP_NODELAY, + (char *)& one, + sizeof (one))) + err ("setsockopt: nodelay"); + mes ("nodelay"); + } + + // + // Prepare the Message to be sent + // + + errno = 0; + if (sinkmode) + { + if ((buf = (char *) malloc (buflen + bufalign)) == (char *) NULL) + err ("malloc"); + if (bufalign != 0) + buf += (bufalign - ((int) buf % bufalign) + bufoffset) % bufalign; + + // ttcp_sequence::my_sequence sequence_message; ORBIX + ttcp_sequence::my_sequence message (buflen + 1); + ::buf[::buflen-1] = '\0'; + if (SEQUENCE) + { + message._maximum = buflen; + message._length = buflen; + message._buffer = buf; + } + + + pattern (buf, buflen); + // + // Start the timers on the client and server sides + // + + prep_timer (); + + if (SEQUENCE) + ttcp_seq->start_timer (); + else + ttcp_str->start_timer (); + while (nbuf--) + { + if (SEQUENCE) + ttcp_seq->send (message); + else + ttcp_str->send (buf); + + numCalls++; + nbytes += buflen; + } + + } + else + { + register int cnt; + while ((cnt = read (0, buf, buflen)) > 0 && + Nwrite (fd, buf, cnt) == cnt) + nbytes += cnt; + } + + if (errno) + err ("IO"); + + + // + // Stop the timers on both sides + // + + + if (SEQUENCE) + ttcp_seq->stop_timer(); + else + ttcp_str->stop_timer(); + + + (void) read_timer (stats, sizeof (stats)); + + + // + // Print the results. + // + + if (cput <= 0.0) + cput = 0.001; + if (realt <= 0.0) + realt = 0.001; + + if (write_to_file) + { + if (title != 0) + { + double tmp; + FILE *fd; + char filename[BUFSIZ]; + sprintf (filename, "%s.results", title); + fd = fopen(filename,"a+"); + if (new_line) + fprintf(fd,"\n -l %ldk \t", buflen/1024); + tmp = ((double) nbytes) / realt; + fprintf(fd,"%.2f ", tmp * 8.0 / 1024.0 / 1024.0); + fclose(fd); + } + } + + fprintf (stdout, + "\nttcp%s%s: %ld bytes in %.2f real seconds = %s/sec +++\n", + trans ? "-t" : "-r", SEQUENCE ? "(Seq)" : "(Str)", + nbytes, realt, outfmt (((double) nbytes) / realt)); + + if (verbose) + { + fprintf (stdout, + "ttcp%s%s: %ld bytes in %.2f CPU seconds = %s/cpu sec\n", + trans ? "-t" : "-r", SEQUENCE ? "(Seq)" : "(Str)", + nbytes, cput, outfmt (((double) nbytes) / cput)); + } + fprintf (stdout, + "ttcp%s%s: %d I/O calls, msec/call = %.2f, calls/sec = %.2f\n", + trans ? "-t" : "-r", SEQUENCE ? "(Seq)" : "(Str)", + numCalls, + 1024.0 * realt / ((double) numCalls), + ((double) numCalls) / realt); + fprintf (stdout, "ttcp%s%s: %s\n",trans ? "-t" : "-r", SEQUENCE ? "(Seq)" : "(Str)", stats); + if (verbose) + { + fprintf (stdout, + "ttcp%s: buffer address %#x\n", + trans ? "-t" : "-r", + buf); + } + exit (0); + + usage: + fprintf (stderr, Usage); + return 1; +} + +void +err (char *s) +{ + fprintf (stderr, "ttcp%s: ", trans ? "-t" : "-r"); + perror (s); + fprintf (stderr, "errno=%d\n", errno); + exit (1); +} + +void +mes (char *s) +{ + fprintf (stderr, "ttcp%s%s: %s\n", trans ? "-t" : "-r",SEQUENCE ? "(Seq)" : "(Str)", s); +// fprintf (stderr, "ttcp%s: %s\n", trans ? "-t" : "-r", s); +} + +void +pattern (register char *cp, register int cnt) +{ + register char c; + c = 0; + while (cnt-- > 0) + { + while (!isprint ((c & 0x7F))) + c++; + *cp++ = (c++ & 0x7F); + } +} + +char * +outfmt (double b) +{ + static char obuf[50]; + switch (fmt) + { + case 'G': + sprintf (obuf, "%.2f GB", b / 1024.0 / 1024.0 / 1024.0); + break; + default: + case 'K': + sprintf (obuf, "%.2f KB", b / 1024.0); + break; + case 'M': + sprintf (obuf, "%.2f MB", b / 1024.0 / 1024.0); + break; + case 'g': + sprintf (obuf, "%.2f Gbit", b * 8.0 / 1024.0 / 1024.0 / 1024.0); + break; + case 'k': + sprintf (obuf, "%.2f Kbit", b * 8.0 / 1024.0); + break; + case 'm': + sprintf (obuf, "%.2f Mbit", b * 8.0 / 1024.0 / 1024.0); + break; + } + return obuf; +} + +static struct itimerval itime0; /* Time at which timing started */ +static struct rusage ru0; /* Resource utilization at the start */ + +#if defined(SYSV) +/*ARGSUSED */ +static void +getrusage (int ignored, register struct rusage *ru) +{ + struct tms buf; + + times (&buf); + + /* Assumption: HZ <= 2147 (LONG_MAX/1000000) */ + ru->ru_stime.tv_sec = buf.tms_stime / HZ; + ru->ru_stime.tv_usec = ((buf.tms_stime % HZ) * 1000000) / HZ; + ru->ru_utime.tv_sec = buf.tms_utime / HZ; + ru->ru_utime.tv_usec = ((buf.tms_utime % HZ) * 1000000) / HZ; +} + +/*ARGSUSED */ +static void +gettimeofday (struct timeval *tp, struct timezone *zp) +{ + tp->tv_sec = time (0); + tp->tv_usec = 0; +} +#endif /* SYSV */ +/* + * P R E P _ T I M E R + */ +void +prep_timer () +{ + itime0.it_interval.tv_sec = 0; + itime0.it_interval.tv_usec = 0; + itime0.it_value.tv_sec = LONG_MAX / 22; /* greatest possible value , itimer() count backwards */ + itime0.it_value.tv_usec = 0; + + + getrusage (RUSAGE_SELF, &ru0); + + /* Init REAL Timer */ + if (setitimer (ITIMER_REAL, &itime0, NULL)) + { + perror ("Setting 'itimer' REAL failed"); + return; + } + +} + +/* + * R E A D _ T I M E R + * + */ +double +read_timer (char *str, int len) +{ + struct itimerval itimedol; + struct rusage ru1; + struct timeval td; + struct timeval tend, tstart; + char line[132]; + + getrusage (RUSAGE_SELF, &ru1); + + if (getitimer (ITIMER_REAL, &itimedol)) + { + perror ("Getting 'itimer' REAL failed"); + return (0.0); + } + + prusage (&ru0, &ru1, &itime0.it_value, &itimedol.it_value, line); + (void) strncpy (str, line, len); + + /* Get real time */ + tvsub (&td, &itime0.it_value, &itimedol.it_value); + realt = td.tv_sec + ((double) td.tv_usec) / 1000000; + + /* Get CPU time (user+sys) */ + tvadd (&tend, &ru1.ru_utime, &ru1.ru_stime); + tvadd (&tstart, &ru0.ru_utime, &ru0.ru_stime); + tvsub (&td, &tend, &tstart); + cput = td.tv_sec + ((double) td.tv_usec) / 1000000; + if (cput < 0.00001) + cput = 0.00001; + return (cput); +} + +static void +prusage (register struct rusage *r0, struct rusage *r1, + struct timeval *e, struct timeval *b, char *outp) +{ + struct timeval tdiff; + register time_t t; + register char *cp; + register int i; + int ms; + + t = (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 + + (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 + + (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 + + (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000; + ms = (e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000; + +#define END(x) {while(*x) x++;} +#if defined(SYSV) + cp = "%Uuser %Ssys %Ereal %P"; +#else +#if defined(sgi) /* IRIX 3.3 will show 0 for %M,%F,%R,%C */ + cp = "%Uuser %Ssys %Ereal %P %Mmaxrss %F+%Rpf %Ccsw"; +#else + cp = "%Uuser %Ssys %Ereal %P %Xi+%Dd %Mmaxrss %F+%Rpf %Ccsw"; +#endif +#endif + for (; *cp; cp++) + { + if (*cp != '%') + *outp++ = *cp; + else if (cp[1]) + switch (*++cp) + { + + case 'U': + tvsub (&tdiff, &r1->ru_utime, &r0->ru_utime); + sprintf (outp, "%d.%01d", tdiff.tv_sec, tdiff.tv_usec / 100000); + END (outp); + break; + + case 'S': + tvsub (&tdiff, &r1->ru_stime, &r0->ru_stime); + sprintf (outp, "%d.%01d", tdiff.tv_sec, tdiff.tv_usec / 100000); + END (outp); + break; + + case 'E': + psecs (ms / 100, outp); + END (outp); + break; + + case 'P': + sprintf (outp, "%d%%", (int) (t * 100 / ((ms ? ms : 1)))); + END (outp); + break; + +#if !defined(SYSV) + case 'W': + i = r1->ru_nswap - r0->ru_nswap; + sprintf (outp, "%d", i); + END (outp); + break; + + case 'X': + sprintf (outp, "%d", t == 0 ? 0 : (r1->ru_ixrss - r0->ru_ixrss) / t); + END (outp); + break; + + case 'D': + sprintf (outp, "%d", t == 0 ? 0 : + (r1->ru_idrss + r1->ru_isrss - (r0->ru_idrss + r0->ru_isrss)) / t); + END (outp); + break; + + case 'K': + sprintf (outp, "%d", t == 0 ? 0 : + ((r1->ru_ixrss + r1->ru_isrss + r1->ru_idrss) - + (r0->ru_ixrss + r0->ru_idrss + r0->ru_isrss)) / t); + END (outp); + break; + + case 'M': + sprintf (outp, "%d", r1->ru_maxrss / 2); + END (outp); + break; + + case 'F': + sprintf (outp, "%d", r1->ru_majflt - r0->ru_majflt); + END (outp); + break; + + case 'R': + sprintf (outp, "%d", r1->ru_minflt - r0->ru_minflt); + END (outp); + break; + + case 'I': + sprintf (outp, "%d", r1->ru_inblock - r0->ru_inblock); + END (outp); + break; + + case 'O': + sprintf (outp, "%d", r1->ru_oublock - r0->ru_oublock); + END (outp); + break; + case 'C': + sprintf (outp, "%d+%d", r1->ru_nvcsw - r0->ru_nvcsw, + r1->ru_nivcsw - r0->ru_nivcsw); + END (outp); + break; +#endif /* !SYSV */ + } + } + *outp = '\0'; +} + +static void +tvadd (struct timeval *tsum, struct timeval *t0, struct timeval *t1) +{ + + tsum->tv_sec = t0->tv_sec + t1->tv_sec; + tsum->tv_usec = t0->tv_usec + t1->tv_usec; + if (tsum->tv_usec > 1000000) + tsum->tv_sec++, tsum->tv_usec -= 1000000; +} + +static void +tvsub (struct timeval *tdiff, struct timeval *t1, struct timeval *t0) +{ + + tdiff->tv_sec = t1->tv_sec - t0->tv_sec; + tdiff->tv_usec = t1->tv_usec - t0->tv_usec; + if (tdiff->tv_usec < 0) + tdiff->tv_sec--, tdiff->tv_usec += 1000000; +} + +static void +psecs (long l, register char *cp) +{ + register int i; + + i = l / 3600; + if (i) + { + sprintf (cp, "%d:", i); + END (cp); + i = l % 3600; + sprintf (cp, "%d%d", (i / 60) / 10, (i / 60) % 10); + END (cp); + } + else + { + i = l; + sprintf (cp, "%d", i / 60); + END (cp); + } + i %= 60; + *cp++ = ':'; + sprintf (cp, "%d%d", i / 10, i % 10); +} + +/* + * N R E A D + */ +int +Nread (int fd, void *buf, int count) +{ + struct sockaddr_in from; + int len = sizeof (from); + register int cnt; + if (udp) + { + cnt = recvfrom (fd, (char *) buf, count, 0, (struct sockaddr *) &from, &len); + numCalls++; + } + else + { + if (b_flag) + cnt = mread (fd, (char *) buf, count); /* fill buf */ + else + { + cnt = read (fd, buf, count); + numCalls++; + } + if (touchdata && cnt > 0) + { + register int c = cnt, sum; + register char *b = (char *) buf; + while (c--) + sum += *b++; + } + } + return (cnt); +} + + +/* + * N W R I T E + */ +int +Nwrite (int fd, void *buf, int count) +{ + return 0; +} + +void +delay (int us) +{ + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = us; + (void) select (1, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, &tv); +} + +/* + * M R E A D + * + * This function performs the function of a read(II) but will + * call read(II) multiple times in order to get the requested + * number of characters. This can be necessary because + * network connections don't deliver data with the same + * grouping as it is written with. Written by Robert S. Miles, BRL. + */ +int +mread (int fd, register char *bufp, unsigned n) +{ + register unsigned count = 0; + register int nread; + + do + { + nread = read (fd, bufp, n - count); + numCalls++; + if (nread < 0) + { + perror ("ttcp_mread"); + return (-1); + } + if (nread == 0) + return ((int) count); + count += (unsigned) nread; + bufp += nread; + } + while (count < n); + + return ((int) count); +} diff --git a/performance-tests/TTCP/Orbix/ttcp_i.h b/performance-tests/TTCP/Orbix/ttcp_i.h new file mode 100644 index 00000000000..cb3f60ad532 --- /dev/null +++ b/performance-tests/TTCP/Orbix/ttcp_i.h @@ -0,0 +1,46 @@ +/* -*- C++ -*- */ +// @(#)ttcp_i.h 1.1 10/18/96 + + +// ttcp_i.C +// + +#if !defined (TTCP_I_H) +#define TTCP_I_H + +#include "ttcp.hh" + +class ttcp_sequence_i + : virtual public ttcp_sequenceBOAImpl +{ +public: + ttcp_sequence_i(); + + virtual long send (const ttcp_sequence::my_sequence& ttcp_seq, CORBA::Environment &IT_env=CORBA::default_environment); + virtual void start_timer (CORBA::Environment &IT_env=CORBA::default_environment); + virtual void stop_timer (CORBA::Environment &IT_env=CORBA::default_environment); +private: + unsigned long nbytes_; +}; + +// DEF_TIE_ttcp_sequence (ttcp_sequence_i); + +class ttcp_string_i + : virtual public ttcp_stringBOAImpl +{ +public: + ttcp_string_i(); + + virtual long send (const char * ttcp_string, CORBA::Environment &IT_env=CORBA::default_environment); + virtual void start_timer (CORBA::Environment &IT_env=CORBA::default_environment); + virtual void stop_timer (CORBA::Environment &IT_env=CORBA::default_environment); +private: + unsigned long nbytes_; +}; + +#endif defined (TTCP_I_H) + + + + + diff --git a/rpc++/.dependencies b/rpc++/.dependencies new file mode 100644 index 00000000000..9afb79a0c0b --- /dev/null +++ b/rpc++/.dependencies @@ -0,0 +1,131 @@ +xdr++.o: xdr++.cc rpc++/xdr++.h /usr/include/rpc/rpc.h \ + /usr/include/rpc/types.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/sys/types.h \ + /usr/include/sys/feature_tests.h /usr/include/sys/machtypes.h \ + /usr/include/sys/select.h /usr/include/sys/time.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/time.h \ + /usr/include/sys/siginfo.h /usr/include/sys/machsig.h \ + /usr/include/tiuser.h /usr/include/sys/tiuser.h /usr/include/fcntl.h \ + /usr/include/sys/fcntl.h /usr/include/memory.h /usr/include/rpc/xdr.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/sys/byteorder.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/stdio.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/rpc/auth.h \ + /usr/include/sys/cred.h /usr/include/sys/t_lock.h \ + /usr/include/sys/machlock.h /usr/include/sys/dki_lkinfo.h \ + /usr/include/sys/dl.h /usr/include/sys/sleepq.h \ + /usr/include/sys/turnstile.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/sys/param.h \ + /usr/include/sys/unistd.h /usr/include/sys/pirec.h \ + /usr/include/sys/mutex.h /usr/include/rpc/clnt.h \ + /usr/include/rpc/rpc_com.h /usr/include/sys/netconfig.h \ + /usr/include/rpc/rpc_msg.h /usr/include/rpc/auth_sys.h \ + /usr/include/rpc/auth_des.h /usr/include/rpc/auth_kerb.h \ + /usr/include/kerberos/krb.h /usr/include/kerberos/mit-copyright.h \ + /usr/include/kerberos/des.h /usr/include/sys/socket.h \ + /usr/include/netinet/in.h /usr/include/sys/stream.h \ + /usr/include/sys/vnode.h /usr/include/sys/uio.h /usr/include/vm/seg_enum.h \ + /usr/include/sys/poll.h /usr/include/sys/strmdep.h /usr/include/rpc/svc.h \ + /usr/include/rpc/svc_auth.h /usr/include/rpc/rpcb_clnt.h \ + /usr/include/rpc/rpcb_prot.h +service.o: service.cc /pkg/gnu/sparc-sun-solaris2.3/include/assert.h \ + /pkg/gnu/lib/g++-include/stream.h /pkg/gnu/lib/g++-include/iostream.h \ + /pkg/gnu/lib/g++-include/streambuf.h /pkg/gnu/lib/g++-include/libio.h \ + /pkg/gnu/lib/g++-include/_G_config.h /usr/include/memory.h \ + /usr/include/errno.h /usr/include/sys/errno.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/stdlib.h \ + /usr/include/sys/feature_tests.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/sys/types.h \ + /usr/include/sys/machtypes.h /usr/include/sys/select.h \ + /usr/include/sys/time.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/time.h \ + /usr/include/sys/siginfo.h /usr/include/sys/machsig.h \ + /usr/include/sys/socket.h /usr/include/sys/netconfig.h \ + /usr/include/netdb.h /usr/include/rpc/rpc.h /usr/include/rpc/types.h \ + /usr/include/tiuser.h /usr/include/sys/tiuser.h /usr/include/fcntl.h \ + /usr/include/sys/fcntl.h /usr/include/rpc/xdr.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/sys/byteorder.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/stdio.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/rpc/auth.h \ + /usr/include/sys/cred.h /usr/include/sys/t_lock.h \ + /usr/include/sys/machlock.h /usr/include/sys/dki_lkinfo.h \ + /usr/include/sys/dl.h /usr/include/sys/sleepq.h \ + /usr/include/sys/turnstile.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/sys/param.h \ + /usr/include/sys/unistd.h /usr/include/sys/pirec.h \ + /usr/include/sys/mutex.h /usr/include/rpc/clnt.h \ + /usr/include/rpc/rpc_com.h /usr/include/rpc/rpc_msg.h \ + /usr/include/rpc/auth_sys.h /usr/include/rpc/auth_des.h \ + /usr/include/rpc/auth_kerb.h /usr/include/kerberos/krb.h \ + /usr/include/kerberos/mit-copyright.h /usr/include/kerberos/des.h \ + /usr/include/netinet/in.h /usr/include/sys/stream.h \ + /usr/include/sys/vnode.h /usr/include/sys/uio.h /usr/include/vm/seg_enum.h \ + /usr/include/sys/poll.h /usr/include/sys/strmdep.h /usr/include/rpc/svc.h \ + /usr/include/rpc/svc_auth.h /usr/include/rpc/rpcb_clnt.h \ + /usr/include/rpc/rpcb_prot.h rpc++/service.h \ + /pkg/gnu/lib/g++-include/bool.h rpc++/request.h rpc++/xdr++.h \ + rpc++/callback.h +stub.o: stub.cc /pkg/gnu/lib/g++-include/stream.h \ + /pkg/gnu/lib/g++-include/iostream.h /pkg/gnu/lib/g++-include/streambuf.h \ + /pkg/gnu/lib/g++-include/libio.h /pkg/gnu/lib/g++-include/_G_config.h \ + /usr/include/memory.h /pkg/gnu/sparc-sun-solaris2.3/include/assert.h \ + rpc++/stub.h /pkg/gnu/lib/g++-include/bool.h \ + /pkg/gnu/lib/g++-include/String.h /pkg/gnu/lib/g++-include/Regex.h \ + /usr/include/sys/time.h /usr/include/sys/feature_tests.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/sys/types.h \ + /usr/include/sys/machtypes.h /usr/include/sys/select.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/time.h \ + /usr/include/sys/siginfo.h /usr/include/sys/machsig.h rpc++/request.h \ + rpc++/xdr++.h /usr/include/rpc/rpc.h /usr/include/rpc/types.h \ + /usr/include/tiuser.h /usr/include/sys/tiuser.h /usr/include/fcntl.h \ + /usr/include/sys/fcntl.h /usr/include/rpc/xdr.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/sys/byteorder.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/stdio.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/rpc/auth.h \ + /usr/include/sys/cred.h /usr/include/sys/t_lock.h \ + /usr/include/sys/machlock.h /usr/include/sys/dki_lkinfo.h \ + /usr/include/sys/dl.h /usr/include/sys/sleepq.h \ + /usr/include/sys/turnstile.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/sys/param.h \ + /usr/include/sys/unistd.h /usr/include/sys/pirec.h \ + /usr/include/sys/mutex.h /usr/include/rpc/clnt.h \ + /usr/include/rpc/rpc_com.h /usr/include/sys/netconfig.h \ + /usr/include/rpc/rpc_msg.h /usr/include/rpc/auth_sys.h \ + /usr/include/rpc/auth_des.h /usr/include/rpc/auth_kerb.h \ + /usr/include/kerberos/krb.h /usr/include/kerberos/mit-copyright.h \ + /usr/include/kerberos/des.h /usr/include/sys/socket.h \ + /usr/include/netinet/in.h /usr/include/sys/stream.h \ + /usr/include/sys/vnode.h /usr/include/sys/uio.h /usr/include/vm/seg_enum.h \ + /usr/include/sys/poll.h /usr/include/sys/strmdep.h /usr/include/rpc/svc.h \ + /usr/include/rpc/svc_auth.h /usr/include/rpc/rpcb_clnt.h \ + /usr/include/rpc/rpcb_prot.h +request.o: request.cc rpc++/request.h rpc++/xdr++.h /usr/include/rpc/rpc.h \ + /usr/include/rpc/types.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/sys/types.h \ + /usr/include/sys/feature_tests.h /usr/include/sys/machtypes.h \ + /usr/include/sys/select.h /usr/include/sys/time.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/time.h \ + /usr/include/sys/siginfo.h /usr/include/sys/machsig.h \ + /usr/include/tiuser.h /usr/include/sys/tiuser.h /usr/include/fcntl.h \ + /usr/include/sys/fcntl.h /usr/include/memory.h /usr/include/rpc/xdr.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/sys/byteorder.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/stdio.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/rpc/auth.h \ + /usr/include/sys/cred.h /usr/include/sys/t_lock.h \ + /usr/include/sys/machlock.h /usr/include/sys/dki_lkinfo.h \ + /usr/include/sys/dl.h /usr/include/sys/sleepq.h \ + /usr/include/sys/turnstile.h \ + /pkg/gnu/lib/gcc-lib/sparc-sun-solaris2.3/2.6.0/include/sys/param.h \ + /usr/include/sys/unistd.h /usr/include/sys/pirec.h \ + /usr/include/sys/mutex.h /usr/include/rpc/clnt.h \ + /usr/include/rpc/rpc_com.h /usr/include/sys/netconfig.h \ + /usr/include/rpc/rpc_msg.h /usr/include/rpc/auth_sys.h \ + /usr/include/rpc/auth_des.h /usr/include/rpc/auth_kerb.h \ + /usr/include/kerberos/krb.h /usr/include/kerberos/mit-copyright.h \ + /usr/include/kerberos/des.h /usr/include/sys/socket.h \ + /usr/include/netinet/in.h /usr/include/sys/stream.h \ + /usr/include/sys/vnode.h /usr/include/sys/uio.h /usr/include/vm/seg_enum.h \ + /usr/include/sys/poll.h /usr/include/sys/strmdep.h /usr/include/rpc/svc.h \ + /usr/include/rpc/svc_auth.h /usr/include/rpc/rpcb_clnt.h \ + /usr/include/rpc/rpcb_prot.h \ + /pkg/gnu/sparc-sun-solaris2.3/include/assert.h +callback.o: callback.cc rpc++/callback.h diff --git a/rpc++/COPYING b/rpc++/COPYING new file mode 100644 index 00000000000..eb685a5ec98 --- /dev/null +++ b/rpc++/COPYING @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/rpc++/Makefile b/rpc++/Makefile new file mode 100644 index 00000000000..6b4819d2b7a --- /dev/null +++ b/rpc++/Makefile @@ -0,0 +1,55 @@ +TOP = . +SUBDIRS = StdHdrs example + +INSTROOT = ../.. + +CC = gcc +CFLAGS = -ggdb +C++FLAGS = $(CFLAGS) + +LIBHDRS = rpc++/xdr++.h rpc++/request.h rpc++/service.h rpc++/stub.h \ + rpc++/callback.h version.h +LIBSRCS = xdr++.cc service.cc stub.cc request.cc callback.cc + +LIBOBJS = $(LIBSRCS:%.cc=%.o) $(GENSRCS:%.cc=%.o) + +all:: librpc++.a + +subdirs.all:: librpc++.a + +librpc++.a: $(LIBOBJS) + rm -f $@ + ar cq $@ $(LIBOBJS) + if [ -x /bin/ranlib -o -x /usr/bin/ranlib ]; then ranlib $@; fi + +install:: librpc++.a + install -d $(INSTROOT)/lib + if cmp -s librpc++.a $(INSTROOT)/lib/librpc++.a; then : ; \ + else rm -f $(INSTROOT)/lib/librpc++.a; \ + cp -p librpc++.a $(INSTROOT)/lib; \ + chmod 444 $(INSTROOT)/lib/librpc++.a; \ + for f in rpc++/*.h; do \ + rm -f $(INSTROOT)/include/$$f; done; fi + install -d $(INSTROOT)/include/rpc++ + for f in rpc++/*.h; do \ + cmp -s $$f $(INSTROOT)/include/$$f \ + || install -c -m 444 $$f $(INSTROOT)/include/rpc++; done + +DISTLIST = Makefile README.ORIG README COPYING Proj.make rpc++.texi \ + gcc-2.2.2.fix $(LIBHDRS) $(LIBSRCS) + +clean:: + rm -f $(CLEANWILDCARDS) librpc++.a + +include .dependencies + +.dependencies: $(LIBHDRS) $(LIBSRCS) + gcc -M $(CPPFLAGS) $(LIBSRCS) > .dependencies + +distlist:: + @for f in *.[ch] *.cc; do \ + if expr " $(DISTLIST) " : ".* $$f " >/dev/null; then : ; \ + else echo 1>&2 "Warning: c- or h-file \"$$f\" not in DISTLIST"; fi; \ + done + +include $(TOP)/Proj.make diff --git a/rpc++/Proj.make b/rpc++/Proj.make new file mode 100644 index 00000000000..af50f2f11bf --- /dev/null +++ b/rpc++/Proj.make @@ -0,0 +1,68 @@ +# These are included in every Makefile in the project + +CWDPATH = . +CLEANWILDCARDS = core *~ *.o +VERYCLEANWILDCARDS = core *~ *.o +TEXCLEANWILDCARD = *~ *.aux *.log *.bbl *.blg *.toc *.idx *.ind +TEXVERYCLEANWILDCARD = $(TEXCLEANWILDCARD) *.dvi +ifndef SUBDIRS +SUBDIRS = +endif + +# Doing all always means doing the subdirs. +# Make subdirs.all a target to allow forced processing +ifneq ("$(SUBDIRS)", "") +ifneq ("$(SUBDIRSALL)", "NO") +all:: subdirs.all +endif + +subdirs.all:: + @for d in $(SUBDIRS); do \ + (cd $$d; \ + smflags=$(SUBMFLAGS); \ + echo "Making all in $$d with flags: $$smflags ..." ; \ + echo "cd `pwd`"; \ + $(MAKE) $$smflags all); done; \ + echo "cd `pwd`" +else +all::; +endif + +ifneq ("$(SUBDIRS)", "") +clean:: subdirs.clean + +subdirs.clean:: + @for d in $(SUBDIRS); do \ + echo "Cleaning all in $$d..." ; \ + (cd $$d; $(MAKE) clean); done +else +clean::; +endif + +ifneq ("$(SUBDIRS)", "") +veryclean:: subdirs.veryclean + +subdirs.veryclean:: + @for d in $(SUBDIRS); do \ + echo "Verycleaning all in $$d..." ; \ + (cd $$d; $(MAKE) veryclean); done +else +veryclean::; +endif + +# dist.list prints a list of files to be included in the distribution +distlist:: +ifneq ("$(DISTLIST)", "") + @for f in $(DISTLIST); do \ + echo $(CWDPATH)/$$f; done +endif +ifneq ("$(SUBDIRS)", "") +ifneq ("$(SUBDIRSDIST)", "NO") + @for d in $(SUBDIRS); do \ + (cd $$d; $(MAKE) distlist CWDPATH=$(CWDPATH)/$$d); done +endif +endif +ifeq ("$(DISTLIST)$(SUBDIRS)","") + +endif + diff --git a/rpc++/README b/rpc++/README new file mode 100644 index 00000000000..bede31dd376 --- /dev/null +++ b/rpc++/README @@ -0,0 +1,18 @@ +This directory contains the sources for a C++ interface to Sun RPCs. + +As far as I remember, I got the original sources of the rpc++-library +from some newsgroup, though I don't remember which one. I liked the +basic idea but disliked several aspects of the interface details. So I +adapted it to my likes. I intended some minor changes but soon found +myself renaming classes, changing method parameters, introducing new +classes, etc. The result is by no way compatible with the original +version. It is, I hope, nevertheless useful. + +The current version 2.2 of the rpc++ library updates the version 2.1 +posted in March 1991. It is the reaction to gcc-2.2 that finally +allows a sufficiently reliable use of templates (almost, see +Installation in rpc++.texi) + +Michael Lipp + + diff --git a/rpc++/README.ORIG b/rpc++/README.ORIG new file mode 100644 index 00000000000..60aa3f121e1 --- /dev/null +++ b/rpc++/README.ORIG @@ -0,0 +1,9 @@ +This directory contains a collection of classes that provide an +interface to SUN's RPCs. I dubbed the collection the rpc++-library. It +has been tested with gcc-1.40 on a SparcStation running SunOS 4.0. + +There is no documentation. Look at the example in ./example. + +Peter Berens + + diff --git a/rpc++/StdHdrs/Makefile b/rpc++/StdHdrs/Makefile new file mode 100644 index 00000000000..404499ce0cc --- /dev/null +++ b/rpc++/StdHdrs/Makefile @@ -0,0 +1,13 @@ +TOP = .. +SUBDIRS = rpc +SUBDIRSALL = NO +SUBDIRSDIST = NO + +all:: + +clean:: + rm -f $(CLEANWILDCARDS) + +DISTLIST = Makefile README $(wildcard rpc/*.h) + +include $(TOP)/Proj.make diff --git a/rpc++/StdHdrs/README b/rpc++/StdHdrs/README new file mode 100644 index 00000000000..c9f9f5e20e5 --- /dev/null +++ b/rpc++/StdHdrs/README @@ -0,0 +1,3 @@ +This directory contains some of Sun's rpc headers that have been fixed +(though not thoroughly) to work with ANSI C and C++. I have installed +them in my standard C include path. diff --git a/rpc++/StdHdrs/rpc/auth.h b/rpc++/StdHdrs/rpc/auth.h new file mode 100644 index 00000000000..82b22c76b29 --- /dev/null +++ b/rpc++/StdHdrs/rpc/auth.h @@ -0,0 +1,171 @@ +/* @(#)auth.h 2.3 88/08/07 4.0 RPCSRC; from 1.17 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * auth.h, Authentication interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The data structures are completely opaque to the client. The client + * is required to pass a AUTH * to routines that create rpc + * "sessions". + */ + + +#ifndef _rpc_auth_h +#define _rpc_auth_h + +#define MAX_AUTH_BYTES 400 +#define MAXNETNAMELEN 255 /* maximum length of network user's name */ + +/* + * Status returned from authentication check + */ +enum auth_stat { + AUTH_OK=0, + /* + * failed at remote end + */ + AUTH_BADCRED=1, /* bogus credentials (seal broken) */ + AUTH_REJECTEDCRED=2, /* client should begin new session */ + AUTH_BADVERF=3, /* bogus verifier (seal broken) */ + AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */ + AUTH_TOOWEAK=5, /* rejected due to security reasons */ + /* + * failed locally + */ + AUTH_INVALIDRESP=6, /* bogus response verifier */ + AUTH_FAILED=7 /* some unknown reason */ +}; + +#if (__mc68000__ || __sparc__ || __vax__ || __i386__) +typedef u_long u_int32; /* 32-bit unsigned integers */ +#endif + +union des_block { + struct { + u_int32 high; + u_int32 low; + } key; + char c[8]; +}; +typedef union des_block des_block; +extern bool_t xdr_des_block(); + +/* + * Authentication info. Opaque to client. + */ +struct opaque_auth { + enum_t oa_flavor; /* flavor of auth */ + caddr_t oa_base; /* address of more auth stuff */ + u_int oa_length; /* not to exceed MAX_AUTH_BYTES */ +}; + + +/* + * Auth handle, interface to client side authenticators. + */ +typedef struct { + struct opaque_auth ah_cred; + struct opaque_auth ah_verf; + union des_block ah_key; + struct auth_ops { + void (*ah_nextverf)(); + int (*ah_marshal)(); /* nextverf & serialize */ + int (*ah_validate)(); /* validate varifier */ + int (*ah_refresh)(); /* refresh credentials */ + void (*ah_destroy)(); /* destroy this structure */ + } *ah_ops; + caddr_t ah_private; +} AUTH; + + +/* + * Authentication ops. + * The ops and the auth handle provide the interface to the authenticators. + * + * AUTH *auth; + * XDR *xdrs; + * struct opaque_auth verf; + */ +#define AUTH_NEXTVERF(auth) \ + ((*((auth)->ah_ops->ah_nextverf))(auth)) +#define auth_nextverf(auth) \ + ((*((auth)->ah_ops->ah_nextverf))(auth)) + +#define AUTH_MARSHALL(auth, xdrs) \ + ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) +#define auth_marshall(auth, xdrs) \ + ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) + +#define AUTH_VALIDATE(auth, verfp) \ + ((*((auth)->ah_ops->ah_validate))((auth), verfp)) +#define auth_validate(auth, verfp) \ + ((*((auth)->ah_ops->ah_validate))((auth), verfp)) + +#define AUTH_REFRESH(auth) \ + ((*((auth)->ah_ops->ah_refresh))(auth)) +#define auth_refresh(auth) \ + ((*((auth)->ah_ops->ah_refresh))(auth)) + +#define AUTH_DESTROY(auth) \ + ((*((auth)->ah_ops->ah_destroy))(auth)) +#define auth_destroy(auth) \ + ((*((auth)->ah_ops->ah_destroy))(auth)) + + +extern struct opaque_auth _null_auth; + + +/* + * These are the various implementations of client side authenticators. + */ + +/* + * Unix style authentication + * AUTH *authunix_create(machname, uid, gid, len, aup_gids) + * char *machname; + * int uid; + * int gid; + * int len; + * int *aup_gids; + */ +extern AUTH *authunix_create(); +extern AUTH *authunix_create_default(); /* takes no parameters */ +extern AUTH *authnone_create(); /* takes no parameters */ +extern AUTH *authdes_create(); + +#define AUTH_NONE 0 /* no authentication */ +#define AUTH_NULL 0 /* backward compatibility */ +#define AUTH_UNIX 1 /* unix style (uid, gids) */ +#define AUTH_SHORT 2 /* short hand unix style */ +#define AUTH_DES 3 /* des style (encrypted timestamps) */ + +#endif /*!_rpc_auth_h*/ diff --git a/rpc++/StdHdrs/rpc/c_types.h b/rpc++/StdHdrs/rpc/c_types.h new file mode 100644 index 00000000000..eac882f1082 --- /dev/null +++ b/rpc++/StdHdrs/rpc/c_types.h @@ -0,0 +1,79 @@ +#ifndef _rpc_c_types_h_ +#define _rpc_c_types_h_ + +#if defined(__cplusplus) + /* + * Definitions for C++ 2.0 and later require extern "C" { decl; } + */ +# define EXTERN_FUNCTION( rtn, args ) extern "C" { rtn args; } +# define FUN_ARGS( args ) args +# define STRUCT_TAG( tag_name ) /* the tag disappears */ +# define ENUM_BITFIELD( enum_type ) unsigned +# define ENUM_TYPE( enum_sp, enum_ty ) enum_ty + +#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus) +# define NAME_CONFLICT( name ) _##name +#else +# define NAME_CONFLICT( name ) _/**/name +#endif + +# define DOTDOTDOT ... +# define _VOID_ /* anachronism */ +# define CONST const + +/* + * This is not necessary for 2.0 since 2.0 has corrected the void (*) () problem + */ +typedef void (*_PFV_)(); +typedef int (*_PFI_)(); + +#elif defined(c_plusplus) + /* + * Definitions for C++ 1.2 + */ +# define EXTERN_FUNCTION( rtn, args ) rtn args +# define FUN_ARGS( args ) args +# define STRUCT_TAG( tag_name ) /* the tag disappears */ +# define ENUM_BITFIELD( enum_type ) unsigned +# define ENUM_TYPE( enum_sp, enum_ty ) enum_ty +# define NAME_CONFLICT( name ) _/**/name +# define DOTDOTDOT ... +# define _VOID_ /* anachronism */ +# define CONST const + +typedef void (*_PFV_)(); +typedef int (*_PFI_)(); + +#elif defined(__STDC__) + /* + * Definitions for ANSI C + */ +# define EXTERN_FUNCTION( rtn, args ) rtn args +# define FUN_ARGS( args ) args +# define STRUCT_TAG( tag_name ) tag_name +# define ENUM_BITFIELD( enum_type ) unsigned +# define ENUM_TYPE( enum_sp, enum_ty ) enum_sp enum_ty +# define NAME_CONFLICT( name ) name +# define DOTDOTDOT ... +# define _VOID_ void +# define CONST + +#else + /* + * Definitions for Sun/K&R C -- ignore function prototypes, + * but preserve tag names and enum bitfield declarations. + */ +# define EXTERN_FUNCTION( rtn, args ) rtn() +# define FUN_ARGS( args ) () +# define STRUCT_TAG( tag_name ) tag_name +# define ENUM_BITFIELD( enum_type ) enum_type +# define ENUM_TYPE( enum_sp, enum_ty ) enum_sp enum_ty +# define NAME_CONFLICT( name ) name +# define DOTDOTDOT +# define _VOID_ + /* VOID is only used where it disappears anyway */ +# define CONST + +#endif /* Which type of C/C++ compiler are we using? */ + +#endif diff --git a/rpc++/StdHdrs/rpc/clnt.h b/rpc++/StdHdrs/rpc/clnt.h new file mode 100644 index 00000000000..4cb303bc1eb --- /dev/null +++ b/rpc++/StdHdrs/rpc/clnt.h @@ -0,0 +1,347 @@ +/* @(#)clnt.h 2.1 88/07/29 4.0 RPCSRC; from 1.31 88/02/08 SMI*/ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * clnt.h - Client side remote procedure call interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef _rpc_clnt_h +#define _rpc_clnt_h + +/* + * Rpc calls return an enum clnt_stat. This should be looked at more, + * since each implementation is required to live with this (implementation + * independent) list of errors. + */ +enum clnt_stat { + RPC_SUCCESS=0, /* call succeeded */ + /* + * local errors + */ + RPC_CANTENCODEARGS=1, /* can't encode arguments */ + RPC_CANTDECODERES=2, /* can't decode results */ + RPC_CANTSEND=3, /* failure in sending call */ + RPC_CANTRECV=4, /* failure in receiving result */ + RPC_TIMEDOUT=5, /* call timed out */ + /* + * remote errors + */ + RPC_VERSMISMATCH=6, /* rpc versions not compatible */ + RPC_AUTHERROR=7, /* authentication error */ + RPC_PROGUNAVAIL=8, /* program not available */ + RPC_PROGVERSMISMATCH=9, /* program version mismatched */ + RPC_PROCUNAVAIL=10, /* procedure unavailable */ + RPC_CANTDECODEARGS=11, /* decode arguments error */ + RPC_SYSTEMERROR=12, /* generic "other problem" */ + + /* + * callrpc & clnt_create errors + */ + RPC_UNKNOWNHOST=13, /* unknown host name */ + RPC_UNKNOWNPROTO=17, /* unkown protocol */ + + /* + * _ create errors + */ + RPC_PMAPFAILURE=14, /* the pmapper failed in its call */ + RPC_PROGNOTREGISTERED=15, /* remote program is not registered */ + /* + * unspecified error + */ + RPC_FAILED=16 +}; + + +/* + * Error info. + */ +struct rpc_err { + enum clnt_stat re_status; + union { + int RE_errno; /* realated system error */ + enum auth_stat RE_why; /* why the auth error occurred */ + struct { + u_long low; /* lowest verion supported */ + u_long high; /* highest verion supported */ + } RE_vers; + struct { /* maybe meaningful if RPC_FAILED */ + long s1; + long s2; + } RE_lb; /* life boot & debugging only */ + } ru; +#define re_errno ru.RE_errno +#define re_why ru.RE_why +#define re_vers ru.RE_vers +#define re_lb ru.RE_lb +}; + + +/* + * Client rpc handle. + * Created by individual implementations, see e.g. rpc_udp.c. + * Client is responsible for initializing auth, see e.g. auth_none.c. + */ +typedef struct { + AUTH *cl_auth; /* authenticator */ + struct clnt_ops { + enum clnt_stat (*cl_call)(DOTDOTDOT); /* call remote procedure */ + void (*cl_abort)(DOTDOTDOT); /* abort a call */ + void (*cl_geterr)(DOTDOTDOT); /* get specific error code */ + bool_t (*cl_freeres)(DOTDOTDOT); /* frees results */ + void (*cl_destroy)(DOTDOTDOT);/* destroy this structure */ + bool_t (*cl_control)(DOTDOTDOT);/* the ioctl() of rpc */ + } *cl_ops; + caddr_t cl_private; /* private stuff */ +} CLIENT; + + +/* + * client side rpc interface ops + * + * Parameter types are: + * + */ + +/* + * enum clnt_stat + * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout) + * CLIENT *rh; + * u_long proc; + * xdrproc_t xargs; + * caddr_t argsp; + * xdrproc_t xres; + * caddr_t resp; + * struct timeval timeout; + */ +#define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \ + ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs)) +#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \ + ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs)) + +/* + * void + * CLNT_ABORT(rh); + * CLIENT *rh; + */ +#define CLNT_ABORT(rh) ((*(rh)->cl_ops->cl_abort)(rh)) +#define clnt_abort(rh) ((*(rh)->cl_ops->cl_abort)(rh)) + +/* + * struct rpc_err + * CLNT_GETERR(rh); + * CLIENT *rh; + */ +#define CLNT_GETERR(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp)) +#define clnt_geterr(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp)) + + +/* + * bool_t + * CLNT_FREERES(rh, xres, resp); + * CLIENT *rh; + * xdrproc_t xres; + * caddr_t resp; + */ +#define CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp)) +#define clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp)) + +/* + * bool_t + * CLNT_CONTROL(cl, request, info) + * CLIENT *cl; + * u_int request; + * char *info; + */ +#define CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in)) +#define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in)) + +/* + * control operations that apply to both udp and tcp transports + */ +#define CLSET_TIMEOUT 1 /* set timeout (timeval) */ +#define CLGET_TIMEOUT 2 /* get timeout (timeval) */ +#define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */ +/* + * udp only control operations + */ +#define CLSET_RETRY_TIMEOUT 4 /* set retry timeout (timeval) */ +#define CLGET_RETRY_TIMEOUT 5 /* get retry timeout (timeval) */ + +/* + * void + * CLNT_DESTROY(rh); + * CLIENT *rh; + */ +#define CLNT_DESTROY(rh) ((*(rh)->cl_ops->cl_destroy)(rh)) +#define clnt_destroy(rh) ((*(rh)->cl_ops->cl_destroy)(rh)) + + +/* + * RPCTEST is a test program which is accessable on every rpc + * transport/port. It is used for testing, performance evaluation, + * and network administration. + */ + +#define RPCTEST_PROGRAM ((u_long)1) +#define RPCTEST_VERSION ((u_long)1) +#define RPCTEST_NULL_PROC ((u_long)2) +#define RPCTEST_NULL_BATCH_PROC ((u_long)3) + +/* + * By convention, procedure 0 takes null arguments and returns them + */ + +#define NULLPROC ((u_long)0) + +/* + * Below are the client handle creation routines for the various + * implementations of client side rpc. They can return NULL if a + * creation failure occurs. + */ + +/* + * Memory based rpc (for speed check and testing) + * CLIENT * + * clntraw_create(prog, vers) + * u_long prog; + * u_long vers; + */ +EXTERN_FUNCTION(CLIENT *clntraw_create, (u_long prog, u_long vers)); + + +/* + * Generic client creation routine. Supported protocols are "udp" and "tcp" + */ +EXTERN_FUNCTION(CLIENT * +clnt_create, (char* host, u_long prog, u_long vers, char* prot)); +/* + char *host; -- hostname + u_long prog; -- program number + u_long vers; -- version number + char *prot; -- protocol +*/ + + + + +/* + * TCP based rpc + * CLIENT * + * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz) + * struct sockaddr_in *raddr; + * u_long prog; + * u_long version; + * register int *sockp; + * u_int sendsz; + * u_int recvsz; + */ +EXTERN_FUNCTION(CLIENT *clnttcp_create, (struct sockaddr_in *raddr, + u_long prog, + u_long version, + register int *sockp, + u_int sendsz, + u_int recvsz)); + +/* + * UDP based rpc. + * CLIENT * + * clntudp_create(raddr, program, version, wait, sockp) + * struct sockaddr_in *raddr; + * u_long program; + * u_long version; + * struct timeval wait; + * int *sockp; + * + * Same as above, but you specify max packet sizes. + * CLIENT * + * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz) + * struct sockaddr_in *raddr; + * u_long program; + * u_long version; + * struct timeval wait; + * int *sockp; + * u_int sendsz; + * u_int recvsz; + */ +EXTERN_FUNCTION(CLIENT *clntudp_create, (struct sockaddr_in *raddr, + u_long program, + u_long version, + struct timeval wait, + int *sockp)); +EXTERN_FUNCTION(CLIENT *clntudp_bufcreate, (struct sockaddr_in *raddr, + u_long program, + u_long version, + struct timeval wait, + int *sockp, + u_int sendsz, + u_int recvsz)); + +/* + * Print why creation failed + */ +EXTERN_FUNCTION(void clnt_pcreateerror, (char *msg)); /* stderr */ +EXTERN_FUNCTION(char *clnt_spcreateerror, (char *msg)); /* string */ + +/* + * Like clnt_perror(), but is more verbose in its output + */ +EXTERN_FUNCTION(void clnt_perrno, (enum clnt_stat num)); /* stderr */ + +/* + * Print an English error message, given the client error code + */ +EXTERN_FUNCTION(void clnt_perror, (CLIENT *clnt, char *msg)); /* stderr */ +EXTERN_FUNCTION(char *clnt_sperror, (CLIENT *clnt, char *msg)); /* string */ + +/* + * If a creation fails, the following allows the user to figure out why. + */ +struct rpc_createerr { + enum clnt_stat cf_stat; + struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */ +}; + +extern struct rpc_createerr rpc_createerr; + + + +/* + * Copy error message to buffer. + */ +EXTERN_FUNCTION(char *clnt_sperrno, (enum clnt_stat num)); /* string */ + + + +#define UDPMSGSIZE 8800 /* rpc imposed limit on udp msg size */ +#define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */ + +#endif /*!_rpc_clnt_h*/ diff --git a/rpc++/StdHdrs/rpc/pmap_clnt.h b/rpc++/StdHdrs/rpc/pmap_clnt.h new file mode 100644 index 00000000000..0a209e4f00f --- /dev/null +++ b/rpc++/StdHdrs/rpc/pmap_clnt.h @@ -0,0 +1,82 @@ +/* @(#)pmap_clnt.h 2.1 88/07/29 4.0 RPCSRC; from 1.11 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * pmap_clnt.h + * Supplies C routines to get to portmap services. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +/* + * Usage: + * success = pmap_set(program, version, protocol, port); + * success = pmap_unset(program, version); + * port = pmap_getport(address, program, version, protocol); + * head = pmap_getmaps(address); + * clnt_stat = pmap_rmtcall(address, program, version, procedure, + * xdrargs, argsp, xdrres, resp, tout, port_ptr) + * (works for udp only.) + * clnt_stat = clnt_broadcast(program, version, procedure, + * xdrargs, argsp, xdrres, resp, eachresult) + * (like pmap_rmtcall, except the call is broadcasted to all + * locally connected nets. For each valid response received, + * the procedure eachresult is called. Its form is: + * done = eachresult(resp, raddr) + * bool_t done; + * caddr_t resp; + * struct sockaddr_in raddr; + * where resp points to the results of the call and raddr is the + * address if the responder to the broadcast. + */ + +#ifndef _rpc_pmap_clnt_h +#define _rpc_pmap_clnt_h + +#include + +EXTERN_FUNCTION(bool_t pmap_set, (u_long prognum, u_long versnum, + int protocol, u_short port)); +EXTERN_FUNCTION(bool_t pmap_unset, (u_long prognum, u_long versnum)); +EXTERN_FUNCTION(struct pmaplist *pmap_getmaps, (struct sockaddr_in *addr)); +EXTERN_FUNCTION(enum clnt_stat pmap_rmtcall, (struct sockaddr_in *addr, + u_long prognum, u_long versnum, + u_long procnum, + char *in, char *out, + xdrproc_t inproc, + xdrproc_t outproc, + struct timeval timeout, + u_long *portp)); +EXTERN_FUNCTION(enum clnt_stat clnt_broadcast, ()); +EXTERN_FUNCTION(u_short pmap_getport, (struct sockaddr_in *addr, + u_long prognum, u_long versnum, + u_long protocol)); + +#endif /*!_rpc_pmap_clnt_h*/ diff --git a/rpc++/StdHdrs/rpc/svc.h b/rpc++/StdHdrs/rpc/svc.h new file mode 100644 index 00000000000..4e551e55fd5 --- /dev/null +++ b/rpc++/StdHdrs/rpc/svc.h @@ -0,0 +1,286 @@ +/* @(#)svc.h 2.2 88/07/29 4.0 RPCSRC; from 1.20 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * svc.h, Server-side remote procedure call interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef _rpc_svc_h +#define _rpc_svc_h + +#include + +/* + * This interface must manage two items concerning remote procedure calling: + * + * 1) An arbitrary number of transport connections upon which rpc requests + * are received. The two most notable transports are TCP and UDP; they are + * created and registered by routines in svc_tcp.c and svc_udp.c, respectively; + * they in turn call xprt_register and xprt_unregister. + * + * 2) An arbitrary number of locally registered services. Services are + * described by the following four data: program number, version number, + * "service dispatch" function, a transport handle, and a boolean that + * indicates whether or not the exported program should be registered with a + * local binder service; if true the program's number and version and the + * port number from the transport handle are registered with the binder. + * These data are registered with the rpc svc system via svc_register. + * + * A service's dispatch function is called whenever an rpc request comes in + * on a transport. The request's program and version numbers must match + * those of the registered service. The dispatch function is passed two + * parameters, struct svc_req * and SVCXPRT *, defined below. + */ + +enum xprt_stat { + XPRT_DIED, + XPRT_MOREREQS, + XPRT_IDLE +}; + +/* + * Server side transport handle + */ +typedef struct { + int xp_sock; + u_short xp_port; /* associated port number */ + struct xp_ops { + bool_t (*xp_recv)(DOTDOTDOT); /* receive incomming requests */ + enum xprt_stat (*xp_stat)(DOTDOTDOT); /* get transport status */ + bool_t (*xp_getargs)(DOTDOTDOT); /* get arguments */ + bool_t (*xp_reply)(DOTDOTDOT); /* send reply */ + bool_t (*xp_freeargs)(DOTDOTDOT);/* free mem allocated for args */ + void (*xp_destroy)(DOTDOTDOT); /* destroy this struct */ + } *xp_ops; + int xp_addrlen; /* length of remote address */ + struct sockaddr_in xp_raddr; /* remote address */ + struct opaque_auth xp_verf; /* raw response verifier */ + caddr_t xp_p1; /* private */ + caddr_t xp_p2; /* private */ +} SVCXPRT; + +/* + * Approved way of getting address of caller + */ +#define svc_getcaller(x) (&(x)->xp_raddr) + +/* + * Operations defined on an SVCXPRT handle + * + * SVCXPRT *xprt; + * struct rpc_msg *msg; + * xdrproc_t xargs; + * caddr_t argsp; + */ +#define SVC_RECV(xprt, msg) \ + (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) +#define svc_recv(xprt, msg) \ + (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) + +#define SVC_STAT(xprt) \ + (*(xprt)->xp_ops->xp_stat)(xprt) +#define svc_stat(xprt) \ + (*(xprt)->xp_ops->xp_stat)(xprt) + +#define SVC_GETARGS(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) +#define svc_getargs(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) + +#define SVC_REPLY(xprt, msg) \ + (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) +#define svc_reply(xprt, msg) \ + (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) + +#define SVC_FREEARGS(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) +#define svc_freeargs(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) + +#define SVC_DESTROY(xprt) \ + (*(xprt)->xp_ops->xp_destroy)(xprt) +#define svc_destroy(xprt) \ + (*(xprt)->xp_ops->xp_destroy)(xprt) + + +/* + * Service request + */ +struct svc_req { + u_long rq_prog; /* service program number */ + u_long rq_vers; /* service protocol version */ + u_long rq_proc; /* the desired procedure */ + struct opaque_auth rq_cred; /* raw creds from the wire */ + caddr_t rq_clntcred; /* read only cooked cred */ + SVCXPRT *rq_xprt; /* associated transport */ +}; + + +/* + * Service registration + * + * svc_register(xprt, prog, vers, dispatch, protocol) + * SVCXPRT *xprt; + * u_long prog; + * u_long vers; + * void (*dispatch)(); + * int protocol; like TCP or UDP, zero means do not register + */ +EXTERN_FUNCTION(bool_t svc_register, (SVCXPRT *xprt, u_long prog, u_long vers, + void (*dispatch)(struct svc_req *, + SVCXPRT*), + int protocol)); + +/* + * Service un-registration + * + * svc_unregister(prog, vers) + * u_long prog; + * u_long vers; + */ +EXTERN_FUNCTION(void* svc_unregister, (u_long prog, u_long vers)); + +/* + * Transport registration. + * + * xprt_register(xprt) + * SVCXPRT *xprt; + */ +EXTERN_FUNCTION(void xprt_register, (SVCXPRT* xprt)); + +/* + * Transport un-register + * + * xprt_unregister(xprt) + * SVCXPRT *xprt; + */ +EXTERN_FUNCTION(void xprt_unregister, (SVCXPRT* xprt)); + + + + +/* + * When the service routine is called, it must first check to see if it + * knows about the procedure; if not, it should call svcerr_noproc + * and return. If so, it should deserialize its arguments via + * SVC_GETARGS (defined above). If the deserialization does not work, + * svcerr_decode should be called followed by a return. Successful + * decoding of the arguments should be followed the execution of the + * procedure's code and a call to svc_sendreply. + * + * Also, if the service refuses to execute the procedure due to too- + * weak authentication parameters, svcerr_weakauth should be called. + * Note: do not confuse access-control failure with weak authentication! + * + * NB: In pure implementations of rpc, the caller always waits for a reply + * msg. This message is sent when svc_sendreply is called. + * Therefore pure service implementations should always call + * svc_sendreply even if the function logically returns void; use + * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows + * for the abuse of pure rpc via batched calling or pipelining. In the + * case of a batched call, svc_sendreply should NOT be called since + * this would send a return message, which is what batching tries to avoid. + * It is the service/protocol writer's responsibility to know which calls are + * batched and which are not. Warning: responding to batch calls may + * deadlock the caller and server processes! + */ + +EXTERN_FUNCTION(bool_t svc_sendreply, (SVCXPRT *xprt,xdrproc_t outproc, + char *out)); +EXTERN_FUNCTION(void svcerr_decode, (SVCXPRT *xprt)); +EXTERN_FUNCTION(void svcerr_weakauth, (SVCXPRT *xprt)); +EXTERN_FUNCTION(void svcerr_noproc, (SVCXPRT *xprt)); +EXTERN_FUNCTION(void svcerr_progvers, (SVCXPRT *xprt)); +EXTERN_FUNCTION(void svcerr_auth, (SVCXPRT *xprt, enum auth_stat why)); +EXTERN_FUNCTION(void svcerr_noprog, (SVCXPRT *xprt)); +EXTERN_FUNCTION(void svcerr_systemerr, (SVCXPRT *xprt)); + +/* + * Lowest level dispatching -OR- who owns this process anyway. + * Somebody has to wait for incoming requests and then call the correct + * service routine. The routine svc_run does infinite waiting; i.e., + * svc_run never returns. + * Since another (co-existant) package may wish to selectively wait for + * incoming calls or other events outside of the rpc architecture, the + * routine svc_getreq is provided. It must be passed readfds, the + * "in-place" results of a select system call (see select, section 2). + */ + +/* + * Global keeper of rpc service descriptors in use + * dynamic; must be inspected before each call to select + */ +#ifdef FD_SETSIZE +extern fd_set svc_fdset; +#define svc_fds svc_fdset.fds_bits[0] /* compatibility */ +#else +extern int svc_fds; +#endif /* def FD_SETSIZE */ + +/* + * a small program implemented by the svc_rpc implementation itself; + * also see clnt.h for protocol numbers. + */ +EXTERN_FUNCTION(void rpctest_service, ()); +EXTERN_FUNCTION(void svc_getreq, (int rdfds)); +EXTERN_FUNCTION(void svc_getreqset, (fd_set *rdfdsp)); /* takes fdset instead of int */ +EXTERN_FUNCTION(void svc_run, ()); /* never returns */ + +/* + * Socket to use on svcxxx_create call to get default socket + */ +#define RPC_ANYSOCK -1 + +/* + * These are the existing service side transport implementations + */ + +/* + * Memory based rpc for testing and timing. + */ +EXTERN_FUNCTION(SVCXPRT *svcraw_create, ()); + +/* + * Udp based rpc. + */ +EXTERN_FUNCTION(SVCXPRT *svcudp_create, (int sock)); +EXTERN_FUNCTION(SVCXPRT *svcudp_bufcreate, (int sock, u_int sendsz, + u_int recvsz)); + +/* + * Tcp based rpc. + */ +EXTERN_FUNCTION(SVCXPRT *svctcp_create, (int fd, u_int sendsz, u_int recvsz)); + + + +#endif /*!_rpc_svc_h*/ diff --git a/rpc++/StdHdrs/rpc/xdr.h b/rpc++/StdHdrs/rpc/xdr.h new file mode 100644 index 00000000000..25fb07fe68a --- /dev/null +++ b/rpc++/StdHdrs/rpc/xdr.h @@ -0,0 +1,275 @@ +/* @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* @(#)xdr.h 1.19 87/04/22 SMI */ + +/* + * xdr.h, External Data Representation Serialization Routines. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef _rpc_xdr_h +#define _rpc_xdr_h + +#include + +#include +/* + * XDR provides a conventional way for converting between C data + * types and an external bit-string representation. Library supplied + * routines provide for the conversion on built-in C data types. These + * routines and utility routines defined here are used to help implement + * a type encode/decode routine for each user-defined type. + * + * Each data type provides a single procedure which takes two arguments: + * + * bool_t + * xdrproc(xdrs, argresp) + * XDR *xdrs; + * *argresp; + * + * xdrs is an instance of a XDR handle, to which or from which the data + * type is to be converted. argresp is a pointer to the structure to be + * converted. The XDR handle contains an operation field which indicates + * which of the operations (ENCODE, DECODE * or FREE) is to be performed. + * + * XDR_DECODE may allocate space if the pointer argresp is null. This + * data can be freed with the XDR_FREE operation. + * + * We write only one procedure per data type to make it easy + * to keep the encode and decode procedures for a data type consistent. + * In many cases the same code performs all operations on a user defined type, + * because all the hard work is done in the component type routines. + * decode as a series of calls on the nested data types. + */ + +/* + * Xdr operations. XDR_ENCODE causes the type to be encoded into the + * stream. XDR_DECODE causes the type to be extracted from the stream. + * XDR_FREE can be used to release the space allocated by an XDR_DECODE + * request. + */ +enum xdr_op { + XDR_ENCODE=0, + XDR_DECODE=1, + XDR_FREE=2 +}; + +/* + * This is the number of bytes per unit of external data. + */ +#define BYTES_PER_XDR_UNIT (4) +#define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \ + * BYTES_PER_XDR_UNIT) + +/* + * The XDR handle. + * Contains operation which is being applied to the stream, + * an operations vector for the paticular implementation (e.g. see xdr_mem.c), + * and two private fields for the use of the particular impelementation. + */ +typedef struct { + enum xdr_op x_op; /* operation; fast additional param */ + struct xdr_ops { + bool_t (*x_getlong)(); /* get a long from underlying stream */ + bool_t (*x_putlong)(); /* put a long to " */ + bool_t (*x_getbytes)();/* get some bytes from " */ + bool_t (*x_putbytes)();/* put some bytes to " */ + u_int (*x_getpostn)();/* returns bytes off from beginning */ + bool_t (*x_setpostn)();/* lets you reposition the stream */ + long * (*x_inline)(); /* buf quick ptr to buffered data */ + void (*x_destroy)(); /* free privates of this xdr_stream */ + } *x_ops; + caddr_t x_public; /* users' data */ + caddr_t x_private; /* pointer to private data */ + caddr_t x_base; /* private used for position info */ + int x_handy; /* extra private word */ +} XDR; + +/* + * A xdrproc_t exists for each data type which is to be encoded or decoded. + * + * The second argument to the xdrproc_t is a pointer to an opaque pointer. + * The opaque pointer generally points to a structure of the data type + * to be decoded. If this pointer is 0, then the type routines should + * allocate dynamic storage of the appropriate size and return it. + * bool_t (*xdrproc_t)(XDR *, caddr_t *); + */ +typedef bool_t (*xdrproc_t) FUN_ARGS((XDR*, void*)); + +/* + * Operations defined on a XDR handle + * + * XDR *xdrs; + * long *longp; + * caddr_t addr; + * u_int len; + * u_int pos; + */ +#define XDR_GETLONG(xdrs, longp) \ + (*(xdrs)->x_ops->x_getlong)(xdrs, longp) +#define xdr_getlong(xdrs, longp) \ + (*(xdrs)->x_ops->x_getlong)(xdrs, longp) + +#define XDR_PUTLONG(xdrs, longp) \ + (*(xdrs)->x_ops->x_putlong)(xdrs, longp) +#define xdr_putlong(xdrs, longp) \ + (*(xdrs)->x_ops->x_putlong)(xdrs, longp) + +#define XDR_GETBYTES(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) +#define xdr_getbytes(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) + +#define XDR_PUTBYTES(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) +#define xdr_putbytes(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) + +#define XDR_GETPOS(xdrs) \ + (*(xdrs)->x_ops->x_getpostn)(xdrs) +#define xdr_getpos(xdrs) \ + (*(xdrs)->x_ops->x_getpostn)(xdrs) + +#define XDR_SETPOS(xdrs, pos) \ + (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) +#define xdr_setpos(xdrs, pos) \ + (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) + +#define XDR_INLINE(xdrs, len) \ + (*(xdrs)->x_ops->x_inline)(xdrs, len) +#define xdr_inline(xdrs, len) \ + (*(xdrs)->x_ops->x_inline)(xdrs, len) + +#define XDR_DESTROY(xdrs) \ + if ((xdrs)->x_ops->x_destroy) \ + (*(xdrs)->x_ops->x_destroy)(xdrs) +#define xdr_destroy(xdrs) \ + if ((xdrs)->x_ops->x_destroy) \ + (*(xdrs)->x_ops->x_destroy)(xdrs) + +/* + * Support struct for discriminated unions. + * You create an array of xdrdiscrim structures, terminated with + * a entry with a null procedure pointer. The xdr_union routine gets + * the discriminant value and then searches the array of structures + * for a matching value. If a match is found the associated xdr routine + * is called to handle that part of the union. If there is + * no match, then a default routine may be called. + * If there is no match and no default routine it is an error. + */ +#define NULL_xdrproc_t ((xdrproc_t)0) +struct xdr_discrim { + int value; + xdrproc_t proc; +}; + +/* + * In-line routines for fast encode/decode of primitve data types. + * Caveat emptor: these use single memory cycles to get the + * data from the underlying buffer, and will fail to operate + * properly if the data is not aligned. The standard way to use these + * is to say: + * if ((buf = XDR_INLINE(xdrs, count)) == NULL) + * return (FALSE); + * <<< macro calls >>> + * where ``count'' is the number of bytes of data occupied + * by the primitive data types. + * + * N.B. and frozen for all time: each data type here uses 4 bytes + * of external representation. + */ +#define IXDR_GET_LONG(buf) ((long)ntohl((u_long)*(buf)++)) +#define IXDR_PUT_LONG(buf, v) (*(buf)++ = (long)htonl((u_long)v)) + +#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf)) +#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf)) +#define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_LONG(buf)) +#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf)) +#define IXDR_GET_U_SHORT(buf) ((u_short)IXDR_GET_LONG(buf)) + +#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) + +/* + * These are the "generic" xdr routines. + */ +EXTERN_FUNCTION(bool_t xdr_void, ()); +EXTERN_FUNCTION(bool_t xdr_int, ()); +EXTERN_FUNCTION(bool_t xdr_u_int, ()); +EXTERN_FUNCTION(bool_t xdr_long, ()); +EXTERN_FUNCTION(bool_t xdr_u_long, ()); +EXTERN_FUNCTION(bool_t xdr_short, ()); +EXTERN_FUNCTION(bool_t xdr_u_short, ()); +EXTERN_FUNCTION(bool_t xdr_bool, ()); +EXTERN_FUNCTION(bool_t xdr_enum, ()); +EXTERN_FUNCTION(bool_t xdr_array, ()); +EXTERN_FUNCTION(bool_t xdr_bytes, ()); +EXTERN_FUNCTION(bool_t xdr_opaque, ()); +EXTERN_FUNCTION(bool_t xdr_string, ()); +EXTERN_FUNCTION(bool_t xdr_union, ()); +EXTERN_FUNCTION(void xdr_free, ()); +EXTERN_FUNCTION(bool_t xdr_char, ()); +EXTERN_FUNCTION(bool_t xdr_u_char, ()); +EXTERN_FUNCTION(bool_t xdr_vector, ()); +EXTERN_FUNCTION(bool_t xdr_float, ()); +EXTERN_FUNCTION(bool_t xdr_double, ()); +EXTERN_FUNCTION(bool_t xdr_reference, ()); +EXTERN_FUNCTION(bool_t xdr_pointer, ()); +EXTERN_FUNCTION(bool_t xdr_wrapstring, ()); + +/* + * Common opaque bytes objects used by many rpc protocols; + * declared here due to commonality. + */ +#define MAX_NETOBJ_SZ 1024 +struct netobj { + u_int n_len; + char *n_bytes; +}; +typedef struct netobj netobj; +EXTERN_FUNCTION(bool_t xdr_netobj, ()); + +/* + * These are the public routines for the various implementations of + * xdr streams. + */ +EXTERN_FUNCTION(void xdrmem_create, ()); /* XDR using memory buffers */ +EXTERN_FUNCTION(void xdrstdio_create, ()); /* XDR using stdio library */ +EXTERN_FUNCTION(void xdrrec_create, ()); /* XDR pseudo records for tcp */ +EXTERN_FUNCTION(bool_t xdrrec_endofrecord, ());/* make end of xdr record */ +EXTERN_FUNCTION(int xdrrec_readbytes, ()); /* like a read on a pipe */ +EXTERN_FUNCTION(bool_t xdrrec_skiprecord, ()); /* move to beginning of next record */ +EXTERN_FUNCTION(bool_t xdrrec_eof, ()); /* true if no more input */ + +#endif /*!_rpc_xdr_h*/ diff --git a/rpc++/callback.cc b/rpc++/callback.cc new file mode 100644 index 00000000000..1758e8a0740 --- /dev/null +++ b/rpc++/callback.cc @@ -0,0 +1,38 @@ +// -*- c++ -*- +/* +Copyright (C) 1991 Peter Bersen + +This file is part of the rpc++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +Modified and partially rewritten March 1992 by Michael N. Lipp, +mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and +conditions apply without change to any modified or new parts. +*/ + +static char _rpcpp_callback_cc_[] += "callback.cc,v 2.2 1992/06/15 19:12:37 mnl Exp"; + +// callback.cc,v +// Revision 2.2 1992/06/15 19:12:37 mnl +// Fixed a few bugs, clarified interface. +// +// Revision 2.1.1.1 1992/03/08 13:28:42 mnl +// Initial mnl version. +// + +#ifdef __GNUG__ +#pragma implementation +#endif + +#include "rpc++/callback.h" + diff --git a/rpc++/example/Makefile b/rpc++/example/Makefile new file mode 100644 index 00000000000..4abd7b4488f --- /dev/null +++ b/rpc++/example/Makefile @@ -0,0 +1,40 @@ +TOP = .. +SUBDIRS = + +CC = gcc +CPPFLAGS = -I.. +CFLAGS = -ggdb +C++FLAGS = $(CFLAGS) +# for Sun: +#LOADLIBES = -L.. -lrpc++ -lg++ +# for ISC 2.2: +LOADLIBES = -L.. -lrpc++ -lrpclib -lmisc -lg++ -linet -liberty + +HDRS = calcsvc.h +SRCS = server.cc client.cc calcsvc.cc + +all:: server client + +server: server.o calcsvc.o + $(CC) -o $@ server.o calcsvc.o $(LOADLIBES) + +client: client.o calcsvc.o + $(CC) -o $@ client.o calcsvc.o ../request.o $(LOADLIBES) + +DISTLIST = Makefile $(HDRS) $(SRCS) + +clean:: + rm -f $(CLEANWILDCARDS) server client + +include .dependencies + +.dependencies: $(HDRS) $(SRCS) + gcc -M $(CPPFLAGS) $(SRCS) > .dependencies + +distlist:: + @for f in *.[ch] *.cc; do \ + if expr " $(DISTLIST) " : ".* $$f " >/dev/null; then : ; \ + else echo 1>&2 "Warning: c- or h-file \"$$f\" not in DISTLIST"; fi; \ + done + +include $(TOP)/Proj.make diff --git a/rpc++/example/calcsvc.cc b/rpc++/example/calcsvc.cc new file mode 100644 index 00000000000..6ed36594c61 --- /dev/null +++ b/rpc++/example/calcsvc.cc @@ -0,0 +1,30 @@ +// -*- c++ -*- +static char _calcsvc_cc_[] += "calcsvc.cc,v 2.3 1992/06/15 19:13:13 mnl Exp"; + +// calcsvc.cc,v +// Revision 2.3 1992/06/15 19:13:13 mnl +// Fixed a few bugs, clarified interface. +// +// Revision 2.2 1992/06/13 14:27:28 mnl +// Adapted to (patched) gcc-2.2. Fixed several bugs. +// +// Revision 2.1.1.1 1992/03/08 13:28:45 mnl +// Initial mnl version. +// + +#include +#include "calcsvc.h" + +XdrInfo& Xmyint = Xdr::Xint; + +RpcRequest CalcRequests::Add (1, &Xmyint, &Xdr::Xint, &Xdr::Xint); +RpcRequest CalcRequests::Sub (2, &Xdr::Xint, &Xdr::Xint, &Xdr::Xint); +RpcRequest CalcRequests::Times (3, &Xdr::Xint, &Xdr::Xint, &Xdr::Xint); +RpcRequest CalcRequests::Div (4, &Xdr::Xint, &Xdr::Xint, &Xdr::Xint); +RpcRequest CalcRequests::Inc (5, &Xdr::Xint, &Xdr::Xint); +RpcRequest CalcRequests::IToA (6, &Xdr::Xwrapstring, &Xdr::Xint); +RpcRequest CalcRequests::Reset (7, &Xdr::Xvoid); +RpcRequest CalcRequests::Sleep (8, &Xdr::Xnull, &Xdr::Xint, RpcRequest::async); +RpcRequest CalcRequests::Msg (9, &Xdr::Xvoid, &Xdr::Xwrapstring); +RpcRequest CalcRequests::Invalid (100, &Xdr::Xvoid, &Xdr::Xvoid); diff --git a/rpc++/example/calcsvc.h b/rpc++/example/calcsvc.h new file mode 100644 index 00000000000..a70c10fadac --- /dev/null +++ b/rpc++/example/calcsvc.h @@ -0,0 +1,34 @@ +// -*- c++ -*- +#ifndef _CALCSERVICE_H_ +#define _CALCSERVICE_H_ +static char _calcsvc_h_[] += "calcsvc.h,v 2.3 1992/06/15 19:13:15 mnl Exp"; + +// calcsvc.h,v +// Revision 2.3 1992/06/15 19:13:15 mnl +// Fixed a few bugs, clarified interface. +// + +#ifdef __GNUG__ +#pragma interface +#endif + +#include "rpc++/request.h" + +#define CALCSVC 0x20100001 + +struct CalcRequests +{ + static RpcRequest Add; + static RpcRequest Sub; + static RpcRequest Times; + static RpcRequest Div; + static RpcRequest Inc; + static RpcRequest IToA; + static RpcRequest Reset; // for testing proc without args + static RpcRequest Sleep; // for testing async + static RpcRequest Msg; // for testing string passing + static RpcRequest Invalid; // for testing error handling +}; + +#endif diff --git a/rpc++/example/client.cc b/rpc++/example/client.cc new file mode 100644 index 00000000000..f435de61da9 --- /dev/null +++ b/rpc++/example/client.cc @@ -0,0 +1,64 @@ +// -*- c++ -*- +static char _client_cc_[] += "client.cc,v 2.3 1992/06/15 19:13:17 mnl Exp"; + +// client.cc,v +// Revision 2.3 1992/06/15 19:13:17 mnl +// Fixed a few bugs, clarified interface. +// +// Revision 2.2 1992/06/13 14:27:32 mnl +// Adapted to (patched) gcc-2.2. Fixed several bugs. +// +// Revision 2.1.1.1 1992/03/08 13:28:45 mnl +// Initial mnl version. +// + +#include +#include "rpc++/stub.h" + +#include "calcsvc.h" + +class CalcStub : public RpcStub +{ +public: + inline CalcStub (u_long prognum, u_long versnum, + char* hostname = "localhost", + timeval timeout = defaultTimeout, bool connect = TRUE) + : RpcStub (prognum, versnum, hostname, timeout, connect) {} + + inline void Reset () + { Call (CalcRequests::Reset); } + inline int Inc (int i) + { return *(int*)Call (CalcRequests::Inc, &i); } + inline char* IToA (int i) + { return *(char**)Call (CalcRequests::IToA, &i); } + inline int Add (int s1, int s2) + { return *(int*)Call (CalcRequests::Add, &s1, &s2); } + + inline void Msg (char* msg) + { Call (CalcRequests::Msg, &msg); } + inline void Sleep (int secs) + { Call (CalcRequests::Sleep, &secs); } +}; + +main (int argc, char* argv[]) +{ + char* server = argv[1]; + + CalcStub svc (CALCSVC, 1, server); + svc.Reset (); + svc.Msg ("Hello server.\n"); + int i = 0, o; + while (i < 10) + { + o = svc.Inc (i); + cout << svc.IToA (o) << '\n'; + i = o; + } + i = svc.Add (12, 23); + cout << "add (" << 12 << ", " << 23 << ") = " << i << endl; + cout << "Calling Sleep (5) asynchronously.\n"; + svc.Sleep (5); + cout << "Sleep call completed.\n"; + svc.Call (CalcRequests::Invalid); +} diff --git a/rpc++/example/server.cc b/rpc++/example/server.cc new file mode 100644 index 00000000000..f57496c0674 --- /dev/null +++ b/rpc++/example/server.cc @@ -0,0 +1,112 @@ +// -*- c++ -*- +static char _server_cc_[] += "server.cc,v 2.3 1992/06/15 19:13:18 mnl Exp"; + +// server.cc,v +// Revision 2.3 1992/06/15 19:13:18 mnl +// Fixed a few bugs, clarified interface. +// +// Revision 2.2 1992/06/13 14:27:33 mnl +// Adapted to (patched) gcc-2.2. Fixed several bugs. +// +// Revision 2.1.1.1 1992/03/08 13:28:45 mnl +// Initial mnl version. +// + +#include +#include +#include +#include + +#include "rpc++/service.h" +#include "calcsvc.h" + +class Calc +{ +public: + void* Add (void*, void*); + void* Sub (void*, void*); + void* Times (void*, void*); + void* Div (void*, void*); + void* Inc (void*); + void* IToA (void**); + void Reset (RpcService*); +}; + +void* Calc::Add (void* in1, void* in2) +{ + static int res; + res = *(int*)in1 + *(int*)in2; + return &res; +} + +void* Calc::Sub (void* in1, void* in2) +{ + static int res; + res = *(int*)in1 - *(int*)in2; + return &res; +} + +void* Calc::Times (void* in1, void* in2) +{ + static int res; + res = *(int*)in1 * *(int*)in2; + return &res; +} + +void* Calc::Div (void* in1, void* in2) +{ + static int res; + res = *(int*)in1 / *(int*)in2; + return &res; +} + +void* Calc::Inc (void* in) +{ + static int res; + res = *(int*)in + 1; + return &res; +} + +void* Calc::IToA (void** in) +{ + static char *s = 0; + delete s; + char *t = form ("%d", *(int*)in[0]); + s = new char[strlen (t) + 1]; + strcpy (s, t); + return &s; +} + +void Calc::Reset (RpcService* svc) +{ + cout << "Received reset from " << svc->CallerName () << ".\n"; +} + +void printMessage (void* in) +{ + cout << *(char**)in; +} + +void doSleep (void* in) +{ + cout << form ("Sleeping %d secs.\n", *(int*)in); + sleep (*(int*)in); + cout << "Woke up.\n"; +} + +main () +{ + RpcService svc (CALCSVC, 1); + Calc calc; + svc.Register (CalcRequests::Add, RpcMethodCall (&calc, &calc.Add)); + svc.Register (CalcRequests::Sub, RpcMethodCall (&calc, &calc.Sub)); + svc.Register (CalcRequests::Times, RpcMethodCall (&calc, &calc.Times)); + svc.Register (CalcRequests::Div, RpcMethodCall (&calc, &calc.Div)); + svc.Register (CalcRequests::Inc, RpcMethodCall (&calc, &calc.Inc)); + svc.Register (CalcRequests::IToA,RpcMethodCall(&calc, &calc.IToA)); + svc.Register (CalcRequests::Reset, RpcMethodCall (&calc, &calc.Reset)); + svc.Register (CalcRequests::Msg, RpcCallback (printMessage)); + svc.Register (CalcRequests::Sleep, RpcCallback (doSleep)); + svc.Provide (); +} diff --git a/rpc++/gcc-2.2.fix b/rpc++/gcc-2.2.fix new file mode 100644 index 00000000000..f684e5b128b --- /dev/null +++ b/rpc++/gcc-2.2.fix @@ -0,0 +1,252 @@ +To: bug-g++@prep.ai.mit.edu +Subject: gcc-2.2 loops with template-local typedefs (bug&patch) +BCC: mnl,ulf +--text follows this line-- +Hi, + +trying to translate the following fragment on a Sparc running SunOs 4.1.2 +with gcc-2.2 results in gcc infinitly looping. + +--------------------------------------------------------------------------- +// -*- c++ -*- + +class AnyRpcCallback +{ +protected: + +public: + inline virtual ~AnyRpcCallback () {} + inline virtual void Do (void* in, void* out) = 0; +}; + +template class RpcCallback : public AnyRpcCallback +{ + typedef void (T::*Method)(void*, void*); + typedef void (T::*MethodN)(void*, void**); + typedef void (T::*Method1)(void*, void*); + typedef void (T::*Method2)(void*, void*, void*); + +private: + T* object; + void (T::*method)(void*, void*); + +public: + inline RpcCallback (T* o, void* m) + { object = o; method = m; } + inline void Do (void* in, void* out) + { (object->*method)(in, out); } +}; + +class Test +{ +public: + void m (void*, void*); +}; + +main () +{ + Test o; + AnyRpcCallback* cb = new RpcCallback (&o, &Test::m); +} +--------------------------------------------------------------------------- + +PLEASE NOTE that you will get another loop due to a bug that I have +reported together with a patch earlier (it's appended to this mail). +So you won't be able to reproduce the bug reported in this mail unless +you have my previous patch applied. I am, however, definitely sure +(and the explanation below will confirm it) that the bug reported in +this mail is *NOT* caused by my patch! + +The problem is, that the "chain" field of the tree-nodes used by gcc +for its internal representation is used for various purposes, and in +the case of this template-local typedef, someone lost track of its usage. + +After parsing, the TYPE_DECL-node created for the typedef is appended +to the scope via "pushlevel". Types in the current scope are linked +using the "chain" field. At the same time, however, all components of +the template are linked together during parsing using the same "chain" +field. Parsing the second typedef, "pushlevel" makes the first typedef +a successor of the second typedef and the subsequent catenation of +components makes the second typedef a successor of the first typedef +thus creating a loop. + +The resulting list of all components is used in routine +"finish_struct". + +I think the most proper approach would be to use TREE_LIST nodes in +the list of components as indirect references to the typedef-nodes. +This is easy to achieve, it is, however, very hard to modify +finish_struct in a way that it handles these indirection properly. +Actually, I gave up when I tried to understand & modify the routine +that removes the duplicate declarations from the list of components. + +There are two easier approaches: (1) Don't include typedefs in the +list of components, (2) use copies of the typedef-node which have an +unused chain field. The first approach assumes that finish_struct +doesn't do anything with typedefs, so it wouldn't be important if they +are missing from the list of components. If this is the case, however, +it can't hurt to use copies of the typedef-nodes (copies of the +originals that are linked in the scope-list), so the second approach +is safer. It can only fail if finish_struct modifies the typedef-nodes +and this modification is significant for the typedef-nodes in the +scope-list (which are, of course, not modified. Only the copies are). + +So I think the patch is pretty safe. It fixes the problem and doesn't +seem to introduce new ones. I'm aware that typedefs that are local to +templates stretch language features to the limits, but it makes my +C++ interface to RPCs real nice (I'll post it one of these days). + +Michael + +*** .orig/cp-parse.y Mon Jun 15 17:08:58 1992 +--- cp-parse.y Mon Jun 15 19:13:15 1992 +*************** +*** 2211,2217 **** + if (TREE_CODE (t) == ENUMERAL_TYPE && TREE_NONLOCAL_FLAG (t)) + $$ = grok_enum_decls (t, $2); + else +! $$ = $2; + } + end_exception_decls (); + } +--- 2211,2233 ---- + if (TREE_CODE (t) == ENUMERAL_TYPE && TREE_NONLOCAL_FLAG (t)) + $$ = grok_enum_decls (t, $2); + else +! { +! /* if a component is a typedef, it is inserted +! in the list of nodes that make up the valid +! types in the scope. Thus its chain field is +! used and can't be used a second time for linking +! the components of the struct. So, we make a copy +! here. This apparently works. The proper thing +! to do, however, would be to use a TREE_LIST +! node to reference the typedef. I tried to rewrite +! finish_struct accordingly (i.e., ``dereference'' +! components TREE_LIST before use, but I gave up. +! mnl@dtro.e-technik.th-darmstadt.de */ +! if (TREE_CODE ($2) == TYPE_DECL) +! $$ = copy_node ($2); +! else +! $$ = $2; +! } + } + end_exception_decls (); + } + +=========================================================================== +The previous bug: +--------------------------------------------------------------------------- +Return-Path: +Date: Wed, 10 Jun 92 19:31:13 +0200 +From: "Michael N. Lipp" +To: bug-g++@prep.ai.mit.edu +Subject: gcc-2.2 bug&patch: typedef in template + +Hi, + +gcc-2.2 on a sparc running SunOS 4.1.2 enters an infinite loop when +compiling this: + +----------------------------------------------------------------------------- +// -*- c++ -*- + +class AnyRpcCallback +{ +protected: + +public: + inline virtual ~AnyRpcCallback () {} + inline virtual void Do (void* in, void* out) = 0; +}; + +template class RpcCallback : public AnyRpcCallback +{ + typedef void (T::*Method)(void*, void*); + +private: + T* object; + void (T::*method)(void*, void*); + +public: + inline RpcCallback (T* o, void* m) + { object = o; method = m; } + inline void Do (void* in, void* out) + { (object->*method)(in, out); } +}; + +class Test +{ +public: + void m (void*, void*); +}; + +main () +{ + Test o; + AnyRpcCallback* cb = new RpcCallback (&o, &Test::m); +} +----------------------------------------------------------------------------- + +This is quite an improvement over gcc-2.1 which dumped core with this +source. + +I tracked the cause down: grokdeclarator does a pushlevel(0), then +calls start_decl, which in turn calls grokdeclarator again which does +a poplevel_class. This poplevel_class pops the level pushed by +pushlevel(0) and so the poplevel performed by grokdeclarator to match +its pushlevel(0) pops quite a different level! This can easily be +observed by compiling cp-decl.c with -DDEBUG_CP_BINDING_LEVELS. + +Here is a patch that fixes the bug. I don't think it hits the real +cause of this problem, but it works. + +*** .orig/cp-decl.c Wed Jun 10 14:06:26 1992 +--- cp-decl.c Wed Jun 10 15:20:38 1992 +*************** +*** 6874,6882 **** +--- 6874,6889 ---- + tree loc_typedecl; + register int i = sizeof (struct lang_decl_flags) / sizeof (int); + register int *pi; ++ struct binding_level *local_binding_level; + + /* keep `grokdeclarator' from thinking we are in PARM context. */ + pushlevel (0); ++ /* poplevel_class may be called by grokdeclarator which is called in ++ start_decl which is called below. In this case, our pushed level ++ may vanish and poplevel mustn't be called. So remember what we ++ have pushed and pop only if that is matched by ++ current_binding_level later. mnl@dtro.e-technik.th-darmstadt.de */ ++ local_binding_level = current_binding_level; + loc_typedecl = start_decl (declarator, declspecs, initialized, NULL_TREE); + + pi = (int *) permalloc (sizeof (struct lang_decl_flags)); +*************** +*** 6883,6889 **** + while (i > 0) + pi[--i] = 0; + DECL_LANG_SPECIFIC (loc_typedecl) = (struct lang_decl *) pi; +! poplevel (0, 0, 0); + + #if 0 + if (TREE_CODE (TREE_TYPE (loc_typedecl)) == ENUMERAL_TYPE) +--- 6890,6897 ---- + while (i > 0) + pi[--i] = 0; + DECL_LANG_SPECIFIC (loc_typedecl) = (struct lang_decl *) pi; +! if (current_binding_level == local_binding_level) +! poplevel (0, 0, 0); + + #if 0 + if (TREE_CODE (TREE_TYPE (loc_typedecl)) == ENUMERAL_TYPE) + +Michael + +-----------------,------------------------------,------------------------------ +Michael N. Lipp ! Institut fuer Datentechnik ! Phone: 49-6151-163776 + ! Merckstr. 25 ,----------' Fax: 49-6151-164976 + ! D-6100 Darmstadt ! E-Mail: + ! (Germany) ! mnl@dtro.e-technik.th-darmstadt.de +-----------------'-------------------'----------------------------------------- + diff --git a/rpc++/request.cc b/rpc++/request.cc new file mode 100644 index 00000000000..c831bb531b0 --- /dev/null +++ b/rpc++/request.cc @@ -0,0 +1,165 @@ +// -*- c++ -*- +/* +Copyright (C) 1991 Peter Bersen + +This file is part of the rpc++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +Modified and partially rewritten March 1992 by Michael N. Lipp, +mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and +conditions apply without change to any modified or new parts. +*/ + +static char _rpcpp_request_cc_[] += "request.cc,v 2.3 1992/06/15 19:12:39 mnl Exp"; + +// request.cc,v +// Revision 2.3 1992/06/15 19:12:39 mnl +// Fixed a few bugs, clarified interface. +// +// Revision 2.2 1992/06/13 14:27:01 mnl +// Adapted to (patched) gcc-2.2. Fixed several bugs. +// +// Revision 2.1.1.1 1992/03/08 13:28:42 mnl +// Initial mnl version. +// + +#ifdef __GNUG__ +#pragma implementation +#endif + +#include "rpc++/request.h" + +#include + +void RpcRequest::init (u_long req, int pars, int parsz, + const XdrInfo* out, const XdrInfo** in, int rt) +{ + params = pars; + parmsz = parsz; + reqnum = req; + ininfo = in; + ininfo[params] = (XdrInfo*)0; + outinfo = out; + reqtype = rt; + assert (rt == normal || outinfo->Proc () == 0); +} + +RpcRequest::RpcRequest(u_long req, const XdrInfo* out, int t) +{ + init (req, 0, 0, out, new XdrInfo*[1], t); +} + +RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in, + int t) +{ + const XdrInfo** a = new XdrInfo*[2]; + a[0] = in; + init (req, 1, -1, out, a, t); +} + +RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in0, + const XdrInfo* in1, int t) +{ + const XdrInfo** a = new XdrInfo*[3]; + a[0] = in0; + a[1] = in1; + init (req, 2, -1, out, a, t); +} + +RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in0, + const XdrInfo* in1, const XdrInfo* in2, int t) +{ + const XdrInfo** a = new XdrInfo*[4]; + a[0] = in0; + a[1] = in1; + a[2] = in2; + init (req, 3, -1, out, a, t); +} + +RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in0, + const XdrInfo* in1, const XdrInfo* in2, + const XdrInfo* in3, int t) +{ + const XdrInfo** a = new XdrInfo*[5]; + a[0] = in0; + a[1] = in1; + a[2] = in2; + a[3] = in3; + init (req, 4, -1, out, a, t); +} + +RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in0, + const XdrInfo* in1, const XdrInfo* in2, + const XdrInfo* in3, const XdrInfo* in4, int t) +{ + const XdrInfo** a = new XdrInfo*[6]; + a[0] = in0; + a[1] = in1; + a[2] = in2; + a[3] = in3; + a[4] = in4; + init (req, 5, -1, out, a, t); +} + +RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in0, + const XdrInfo* in1, const XdrInfo* in2, + const XdrInfo* in3, const XdrInfo* in4, + const XdrInfo* in5, int t) +{ + const XdrInfo** a = new XdrInfo*[7]; + a[0] = in0; + a[1] = in1; + a[2] = in2; + a[3] = in3; + a[4] = in4; + a[5] = in5; + init (req, 6, -1, out, a, t); +} + +RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo* in0, + const XdrInfo* in1, const XdrInfo* in2, + const XdrInfo* in3, const XdrInfo* in4, + const XdrInfo* in5, const XdrInfo *in6, int t) +{ + const XdrInfo** a = new XdrInfo*[8]; + a[0] = in0; + a[1] = in1; + a[2] = in2; + a[3] = in3; + a[4] = in4; + a[5] = in5; + a[6] = in6; + init (req, 7, -1, out, a, t); +} + +RpcRequest::RpcRequest(u_long req, const XdrInfo* out, const XdrInfo** ins, + int t) +{ + int pars = 0; + for (XdrInfo** p = ins; *p; p++) + pars += 1; + const XdrInfo** a = new XdrInfo* [pars + 1]; + memcpy (a, ins, (pars + 1) * sizeof (XdrInfo*)); + init (req, pars, -1, out, a, t); +} + +int RpcRequest::ParamSize () +{ + if (parmsz < 0) // not yet calculated + { + parmsz = 0; + for (XdrInfo** ip = ininfo; *ip; ip++) + parmsz += (*ip)->Size (); + } + return parmsz; +} diff --git a/rpc++/rpc++.cp b/rpc++/rpc++.cp new file mode 100644 index 00000000000..38f1a39ff2d --- /dev/null +++ b/rpc++/rpc++.cp @@ -0,0 +1,13 @@ +\entry {Overview}{1}{Overview} +\entry {Installation}{2}{Installation} +\entry {XdrInfo}{3}{\code {XdrInfo}} +\entry {RpcRequest}{5}{\code {RpcRequest}} +\entry {Callbacks}{7}{Callbacks} +\entry {RpcCallback}{7}{\code {RpcCallback}} +\entry {RpcMethodCall}{9}{\code {RpcMethodCall}} +\entry {calling conventions}{10}{\code {calling conventions}} +\entry {RpcService}{12}{\code {RpcService}} +\entry {RpcStub}{16}{\code {RpcStub}} +\entry {Caveats}{19}{Caveats} +\entry {Global objects}{19}{Global objects} +\entry {Destruction rules}{19}{Destruction rules} diff --git a/rpc++/rpc++.fn b/rpc++/rpc++.fn new file mode 100644 index 00000000000..562055e0c07 --- /dev/null +++ b/rpc++/rpc++.fn @@ -0,0 +1,63 @@ +\entry {XdrInfo}{3}{\code {XdrInfo}} +\entry {Proc}{3}{\code {Proc}} +\entry {Size}{3}{\code {Size}} +\entry {RpcRequest}{5}{\code {RpcRequest}} +\entry {RpcRequest}{5}{\code {RpcRequest}} +\entry {RpcRequest}{5}{\code {RpcRequest}} +\entry {RpcRequest}{5}{\code {RpcRequest}} +\entry {RpcCallback}{7}{\code {RpcCallback}} +\entry {RpcCallback}{7}{\code {RpcCallback}} +\entry {RpcCallback}{7}{\code {RpcCallback}} +\entry {RpcCallback}{7}{\code {RpcCallback}} +\entry {RpcCallback}{7}{\code {RpcCallback}} +\entry {RpcCallback}{7}{\code {RpcCallback}} +\entry {RpcCallback}{8}{\code {RpcCallback}} +\entry {RpcCallback}{8}{\code {RpcCallback}} +\entry {RpcCallback}{8}{\code {RpcCallback}} +\entry {RpcCallback}{8}{\code {RpcCallback}} +\entry {RpcCallback}{8}{\code {RpcCallback}} +\entry {RpcCallback}{8}{\code {RpcCallback}} +\entry {RpcCallback}{8}{\code {RpcCallback}} +\entry {RpcCallback}{8}{\code {RpcCallback}} +\entry {RpcCallback}{8}{\code {RpcCallback}} +\entry {RpcCallback}{8}{\code {RpcCallback}} +\entry {RpcMethodCall}{9}{\code {RpcMethodCall}} +\entry {RpcMethodCall}{9}{\code {RpcMethodCall}} +\entry {RpcMethodCall}{9}{\code {RpcMethodCall}} +\entry {RpcMethodCall}{9}{\code {RpcMethodCall}} +\entry {RpcMethodCall}{9}{\code {RpcMethodCall}} +\entry {RpcMethodCall}{9}{\code {RpcMethodCall}} +\entry {RpcMethodCall}{9}{\code {RpcMethodCall}} +\entry {RpcMethodCall}{9}{\code {RpcMethodCall}} +\entry {RpcMethodCall}{9}{\code {RpcMethodCall}} +\entry {RpcMethodCall}{9}{\code {RpcMethodCall}} +\entry {RpcMethodCall}{9}{\code {RpcMethodCall}} +\entry {RpcMethodCall}{10}{\code {RpcMethodCall}} +\entry {RpcMethodCall}{10}{\code {RpcMethodCall}} +\entry {RpcMethodCall}{10}{\code {RpcMethodCall}} +\entry {RpcMethodCall}{10}{\code {RpcMethodCall}} +\entry {RpcMethodCall}{10}{\code {RpcMethodCall}} +\entry {RpcService}{12}{\code {RpcService}} +\entry {RpcService}{12}{\code {RpcService}} +\entry {OK}{12}{\code {OK}} +\entry {Program}{12}{\code {Program}} +\entry {Register}{12}{\code {Register}} +\entry {Provide}{13}{\code {Provide}} +\entry {HandleError}{13}{\code {HandleError}} +\entry {Caller}{15}{\code {Caller}} +\entry {CallerName}{15}{\code {CallerName}} +\entry {Reply}{15}{\code {Reply}} +\entry {Reply}{15}{\code {Reply}} +\entry {Interrupt}{15}{\code {Interrupt}} +\entry {RpcStub}{16}{\code {RpcStub}} +\entry {RpcStub}{16}{\code {RpcStub}} +\entry {Reconnect}{16}{\code {Reconnect}} +\entry {OK}{16}{\code {OK}} +\entry {Service}{16}{\code {Service}} +\entry {GetTimeout}{16}{\code {GetTimeout}} +\entry {SetTimeout}{17}{\code {SetTimeout}} +\entry {Call}{17}{\code {Call}} +\entry {Call}{17}{\code {Call}} +\entry {Call}{17}{\code {Call}} +\entry {Call}{17}{\code {Call}} +\entry {HandleError}{17}{\code {HandleError}} diff --git a/rpc++/rpc++.ky b/rpc++/rpc++.ky new file mode 100644 index 00000000000..e69de29bb2d diff --git a/rpc++/rpc++.pg b/rpc++/rpc++.pg new file mode 100644 index 00000000000..e69de29bb2d diff --git a/rpc++/rpc++.texi b/rpc++/rpc++.texi new file mode 100644 index 00000000000..71ed33017b7 --- /dev/null +++ b/rpc++/rpc++.texi @@ -0,0 +1,1519 @@ +\input texinfo @c -*-texinfo-*- +@tex +% They are redefined in texinfo, but I need them +\gdef\`#1{{\accent18 #1}} +\gdef\'#1{{\accent19 #1}} +\gdef\[{{[}} +\gdef\]{{]}} +@end tex +@comment %**start of header (This is for running Texinfo on a region.) +@setfilename rpc++.info +@settitle A C++ Interface to Remote Procedure Calls +@setchapternewpage on +@comment %**end of header (This is for running Texinfo on a region.) + +@c You'll have to define the following additional texinfo-formats to +@c run texinfo on this file. +@c +@c (put '\& 'texinfo-format 'texinfo-format-\&) +@c (defun texinfo-format-\& () +@c (texinfo-discard-command) +@c (insert "&")) +@c +@c (put '\[ 'texinfo-format 'texinfo-format-\[) +@c (defun texinfo-format-\[ () +@c (texinfo-discard-command) +@c (insert "[")) +@c +@c (put '\] 'texinfo-format 'texinfo-format-\]) +@c (defun texinfo-format-\] () +@c (texinfo-discard-command) +@c (insert "]")) + +@ifinfo +This file documents a C++ interface to Sun remote procedure calls. + +Copyright @copyright{} 1992 Michael N. Lipp +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +@ignore +Permission is granted to process this file through @TeX{} and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph +(this paragraph not being relevant to the printed manual). + +@end ignore +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that the +section entitled ``GNU Library General Public License'' is included exactly as +in the original, and provided that the entire resulting derived work is +distributed under the terms of a permission notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that the section entitled ``GNU Library General Public License'' and +this permission notice may be included in translations approved by the +Free Software Foundation instead of in the original English. +@end ifinfo + +@titlepage + +@title A C++ Interface +@title to Sun Remote Procedure Calls +@sp 1 +@subtitle @authorfont{by Michael N. Lipp} +@sp 20 +@subtitle{for version 2.2} +@subtitle{Technische Hochschule Darmstadt, Institut f@"ur Datentechnik} + +@comment The following two commands start the copyright page. +@page +@vskip 0pt plus 1filll +Copyright @copyright{} 1992 Michael N. Lipp + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that the +section entitled ``GNU Library General Public License'' is included exactly as +in the original, and provided that the entire resulting derived work is +distributed under the terms of a permission notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that the section entitled ``GNU Library General Public License'' may be +included in a translation approved by the author instead of in the original +English. +@end titlepage + +@node Top, Overview, (dir), (dir) + +@menu +* Overview:: Overview +* Installation:: Installation +* Classes:: The Classes +* Caveats:: Caveats +* References:: References +* Copying:: GNU LIBRARY GENERAL PUBLIC LICENSE +* Data Type Index:: Data Type Index +* Function Index:: Function and Method Index +* Concept Index:: Concept Index + + --- The Detailed Node Listing --- + +The classes + +* XdrInfo:: @code{XdrInfo} +* RpcRequest:: @code{RpcRequest} +* Callbacks:: @code{Callbacks} +* RpcService:: @code{RpcService} +* RpcStub:: @code{RpcStub} + +Callbacks + +* RpcCallback:: @code{RpcCallback} +* RpcMethodCall:: @code{RpcMethodCall} +* Calling Conventions:: @code{Calling Conventions} + +Caveats + +* Global objects:: Global objects +* Destruction rules:: Destruction rules +* Matching server and clients:: Matching server and clients +@end menu + +@node Overview, Installation, Top, Top +@comment node-name, next, previous, up +@chapter Overview +@cindex Overview + +This document describes my C++ interface to Sun Remote Procedure Calls. +It is based on sources from Peter Bersen that I got from some newsgroup, +though I don't remember which one. I liked the basic idea but disliked +several aspects of the interface details. So I adapted it to my likes. I +intended some minor changes but soon found myself renaming classes, +changing method parameters, introducing new classes, etc. The result is +by no way compatible with the original version. It is, I hope, +nevertheless useful. + +Basically, the interface defines six class: @code{XdrInfo}, +@code{RpcRequest}, @code{RpcCallback}/@code{RpcMethodCall}, +@code{RpcService} and @code{RpcStub}. + +@code{XdrInfo} objects describe the external data representation of a +type. There are predefined @code{XdrInfo}s for the basic types. +@code{RpcRequest} objects describe the available procedure calls. They +are constructed from a unique request number, the @code{XdrInfo}s of the +procedure's arguments and its return type. @code{RpcCallback} is an +object that holds a pointer to a function and information about the +number of its arguments. @code{RpcMethodCall} is a template that in a +similar way holds a pointer to an object and one of its methods and +Information about the number of its arguments. + +An @code{RpcRequest} and its matching @code{RpcCallback} or +@code{RpcMethodCall} may be registered with an @code{RpcService}. +Exactly one object of type @code{RpcService} may be instantiated in a +program that implements an RPC server. Method @code{Provide ()} is a +loop that waits for requests and dispatches them. + +A client program instantiates an object of type @code{RpcStub}. The +constructor establishes a connection to the server specified by its +arguments. Procedures of the server may be invoked using method +@code{Call (@dots{})}. + +@node Installation, Classes, Overview, Top +@comment node-name, next, previous, up +@chapter Installation +@cindex Installation + +The rpc++ library has successfully been tested using a patched gcc-2.2.2 +on a SparcStation running SunOS 4.1.[12] and a 386 system running +Interactive Unix (a SYSV 3.2). Patching gcc-2.2.2 was necessary because +the unpatched version can't handle typedefs that are local to templates. +The bug report with patches can be found in the source directory in file +@code{gcc-2.2.2.fix}. + +As a prerequisite to using RPCs with C++ you need ANSI-C/C++ conformant +header files for RPC. I have provided such files in the directory +@code{StdHdrs/rpc} of the source tree. To avoid any copyright conflicts, +they are derived from the public available RPC source code rather than +from the files that come with SunOS 4.1.X. The differences are minor. +The SunOS 4.1.X files define some additional functions. You have to +either copy the files from @code{StdHdrs/rpc} or patched files from your +@code{/usr/include/rpc} to a directory where gcc can find them. If you +don't want to install them globally in gcc's include directory, you can +include them by using an additional ``@code{-I}'' flag during +compilation. + +In SunOS you can simply type `@code{make install INSTROOT=@dots{}}' +which will make the library and install it in @code{INSTROOT/lib} and +the header files in @code{INSTROOT/include/rpc++}. Other Unices will +probably have problems with the `install' command. Type only `make' and +copy the resulting @code{librpc++.a} to your local library directory and +the files @code{rpc++/*} to an @code{rpc++}-subdirectory of your local +include directory. + +@node Classes, Caveats, Installation, Top +@comment node-name, next, previous, up +@chapter The classes + +@menu +* XdrInfo:: @code{XdrInfo} +* RpcRequest:: @code{RpcRequest} +* Callbacks:: @code{Callbacks} +* RpcService:: @code{RpcService} +* RpcStub:: @code{RpcStub} +@end menu + +@node XdrInfo, RpcRequest, , Classes +@comment node-name, next, previous, up +@section @code{XdrInfo} +@cindex @code{XdrInfo} + +Declared in: @code{"rpc++/xdr++.h"} + +@deftp Class XdrInfo +Class XdrInfo describes serializers. It combines the xdrproc_t with the +size info (the size of the data to be converted) usually needed if you +want to apply a serializer. +@end deftp + +There is only one constructor for @code{XdrInfo}: + +@deftypefn Constructor {} XdrInfo (xdrproc_t @var{t}, size_t @var{s}) +Construct an @code{XdrInfo} for a type. The type can be converted to an +external data representation (serielized) with function @var{t}. Its +size (in bytes, from @code{sizeof (type)}), is @var{s}. +@end deftypefn + +The methods query the information given to the constructor: + +@deftypefn Method xdrproc_t Proc () const +Return the conversion function stored in an @code{XdrInfo}. +@end deftypefn + +@deftypefn Method size_t Size () const +Return the size of the type described by the @code{XdrInfo}. +@end deftypefn + +There are a number of predefined @code{XdrInfo}s. They are defined as +static members of a class @code{Xdr} for scoping reasons. + +@defvr XdrInfo Xdr::Xchar +The conversion and size information for a character. +@end defvr + +@defvr XdrInfo Xdr::Xshort +The conversion and size information for a short integer. +@end defvr + +@defvr XdrInfo Xdr::Xint +The conversion and size information for an integer. +@end defvr + +@defvr XdrInfo Xdr::Xlong +The conversion and size information for a long integer. +@end defvr + +@defvr XdrInfo Xdr::Xuchar +The conversion and size information for an unsigned character. +@end defvr + +@defvr XdrInfo Xdr::Xushort +The conversion and size information for an unsigned short integer. +@end defvr + +@defvr XdrInfo Xdr::Xulong +The conversion and size information for an unsigned long integer. +@end defvr + +@defvr XdrInfo Xdr::Xfloat +The conversion and size information for a float. +@end defvr + +@defvr XdrInfo Xdr::Xdouble +The conversion and size information for a double. +@end defvr + +@defvr XdrInfo Xdr::Xenum_t +The conversion and size information for any enumeration type. +@end defvr + +@defvr XdrInfo Xdr::Xbool_t +The conversion and size information for a bool. +@end defvr + +@defvr XdrInfo Xdr::Xvoid +A special @code{XdrInfo} for the return type of a procedure that returns +nothing. +@end defvr + +@defvr XdrInfo Xdr::Xnull +A special @code{XdrInfo} for the return type of a procedure that is to +be executed batched or asynchronously (@pxref{RpcRequest}). +@end defvr + +@page +@node RpcRequest, Callbacks, XdrInfo, Classes +@comment node-name, next, previous, up +@section @code{RpcRequest} +@cindex @code{RpcRequest} + +Declared in: @code{"rpc++/request.h"} + +@deftp Class RpcRequest +RpcRequest is a class that specifies a request for a procedure that is +part of (registered with) a service. +@end deftp + +There are several constructors for @code{RpcRequest}. They vary in the +number of @code{XdrInfo}s used to describe the input parameters of the +procedure. + +@deftypefn Constructor {} RpcRequest (u_long @var{reqid}, const XdrInfo* @var{out}, ReqType @var{t}=normal) +@end deftypefn +@deftypefn Constructor {} RpcRequest (u_long @var{reqid}, const XdrInfo* @var{out}, const XdrInfo* @var{in1}, ReqType @var{t}=normal) +@end deftypefn +@deftypefn Constructor {} RpcRequest (u_long @var{reqid}, const XdrInfo* @var{out}, const XdrInfo* @var{in1}, const XdrInfo* @var{in2}, ReqType @var{t}=normal) +These constructors construct an @code{RpcRequest} for a procedure with +zero, one or two arguments. Additional similar constructors are defined +for procedures with up to seven arguments. @var{reqid} uniquely +identifies the request (the procedure of the server). @var{reqid} may +not be 0. The @code{XdrInfo*}s following @var{reqid} specify the types of +the input parameters. They are followed by the @code{XdrInfo*} that +describes the type of the value returned by the RPC. If no value is +returned, @code{&Xdr::Xvoid} must be given as argument +(@pxref{XdrInfo}). The final optional argument @var{t} specifies the +call mode: @code{RpcRequest::normal}, @code{RpcRequest::batched} or +@code{RpcRequest::async} (see below). +@end deftypefn + +@deftypefn Constructor {} RpcRequest (u_long @var{reqid}, const XdrInfo* @var{out}, const XdrInfo** @var{intypes}, ReqType @var{t}=normal) +This constructor can be used to construct an @code{RpcRequest} with an +arbitrary number of arguments. The pointers to @code{XdrInfo} are passed +in an array. The number of elements in the array must be one more than +the number of parameters and the last element must be zero. +@end deftypefn + +If the request type @var{t} is @code{RpcRequest::normal}, method +@code{Call} (@pxref{RpcStub}) assembles the message to the server, sends +it, waits for a reply and returns the result. + +If the request type is @code{RpcRequest::batched}, method +@code{RpcStub::Call} assembles the message to the server and puts it in +a buffer. Messages are only flushed if the buffer is full or +@code{RpcStub::Call} is used with a @code{normal} or @code{async} +request. + +If the request type is @code{RpcRequest::async}, method +@code{RpcStub::Call} (@pxref{RpcStub}) assembles the message to the +server and sends it, as with @code{normal}. It does, however, not wait +for a result. Mode @code{async} is implemented by calling the underlying +RPC--function @code{clnt_call} with a timeout of zero. + +As in both non--normal cases (@code{batched} and @code{async}) +@code{RpcStub::Call} does not wait for a return value from the server, +the return type of the @code{RpcRequest} must be specified as +@code{&Xdr::Xnull}. + +Note that requests that are registered for a service are stored in an +array using the request identification as the index, so keep ids small. + +Normally, requests should be specified in a header file included by both +the server and the client program (@pxref{Matching server and clients}). + +@page +@node Callbacks, RpcService, RpcRequest, Classes +@comment node-name, next, previous, up +@section Callbacks +@cindex Callbacks + +If a server receives a request from a client, it needs to know how a +particular procedure is to be invoked. This information is specified +using objects @code{RpcCallback} or @code{RpcMethodCall} when the +procedure resp.@ method is specified. + +The class +@deftp Class AnyRpcCallback +@end deftp +serves as an abstract base class for the two kinds of callbacks. + +The following sections describe the constructors for @code{RpcCallback} +and @code{RpcMethodCall} and the calling conventions for the functions +or methods called back. + +@menu +* RpcCallback:: @code{RpcCallback} +* RpcMethodCall:: @code{RpcMethodCall} +* Calling Conventions:: @code{Calling Conventions} +@end menu + +@node RpcCallback, RpcMethodCall, , Callbacks +@comment node-name, next, previous, up +@subsection @code{RpcCallback} +@cindex @code{RpcCallback} + +Declared in: @code{"rpc++/callback.h"} + +@deftp Class RpcCallback +An @code{RpcCallback} describes a function that is to be called by the +server on request from the client. +@end deftp + +@deftypefn Constructor {} RpcCallback (void* (*)() @var{proc}) +@end deftypefn +@deftypefn Constructor {} RpcCallback (void* (*)(void*) @var{proc}) +@end deftypefn +@deftypefn Constructor {} RpcCallback (void* (*)(void*, void*) @var{proc}) +Construct an @code{RpcCallback} for a function that takes zero, one or +two arguments and returns a result. Constructors for functions with +up to seven arguments are defined. +@end deftypefn +@deftypefn Constructor {} RpcCallback (void* (*)(void**) @var{proc}) +Construct an @code{RpcCallback} for a function that takes an arbitrary +number of arguments and returns a result. +@end deftypefn + +@deftypefn Constructor {} RpcCallback (void (*)() @var{proc}) +@end deftypefn +@deftypefn Constructor {} RpcCallback (void (*)(void*) @var{proc}) +@end deftypefn +@deftypefn Constructor {} RpcCallback (void (*)(void*, void*) @var{proc}) +Construct an @code{RpcCallback} for a function that takes zero, one or +two arguments and returns no result. Constructors for functions with +up to seven arguments are defined. +@end deftypefn +@deftypefn Constructor {} RpcCallback (void (*)(void**) @var{proc}) +Construct an @code{RpcCallback} for a function that takes an arbitrary +number of arguments and return no result. +@end deftypefn + +@deftypefn Constructor {} RpcCallback (void* (*)(RpcService*) @var{proc}) +@end deftypefn +@deftypefn Constructor {} RpcCallback (void* (*)(void*, RpcService*) @var{proc}) +@end deftypefn +@deftypefn Constructor {} RpcCallback (void* (*)(void*, void*, RpcService*) @var{proc}) +Construct an @code{RpcCallback} for a function that takes zero, one or +two arguments and returns a result. Constructors for functions with +up to seven arguments are defined. Upon invocation, a pointer to the +object of type @code{RpcService} that received the request and called +the function is passed as an additional argument. +@end deftypefn +@deftypefn Constructor {} RpcCallback (void* (*)(void**) @var{proc}) +Construct an @code{RpcCallback} for a function that takes an arbitrary +number of arguments and returns a result. Upon invocation, a pointer to the +object of type @code{RpcService} that received the request and called +the function is passed as an additional argument. +@end deftypefn + +@deftypefn Constructor {} RpcCallback (void (*)(RpcService*) @var{proc}) +@end deftypefn +@deftypefn Constructor {} RpcCallback (void (*)(void*, RpcService*) @var{proc}) +@end deftypefn +@deftypefn Constructor {} RpcCallback (void (*)(void*, void*, RpcService*) @var{proc}) +Construct an @code{RpcCallback} for a function that takes zero, one or +two arguments and returns a result. Constructors for functions with +up to seven arguments are defined. Upon invocation, a pointer to the +object of type @code{RpcService} that received the request and called +the function is passed as an additional argument. +@end deftypefn +@deftypefn Constructor {} RpcCallback (void (*)(void**) @var{proc}) +Construct an @code{RpcCallback} for a function that takes an arbitrary +number of arguments and returns a result. Upon invocation, a pointer to the +object of type @code{RpcService} that received the request and called +the function is passed as an additional argument. +@end deftypefn + +@node RpcMethodCall, Calling Conventions, RpcCallback, Callbacks +@comment node-name, next, previous, up +@subsection @code{RpcMethodCall} +@cindex @code{RpcMethodCall} + +Declared in: @code{"rpc++/callback.h"} + +@deftp Class RpcMethodCall +An @code{RpcMethodCall} describes a method of an object that is to be +called by the server on request from the client. +@end deftp + +@deftypefn Constructor {} RpcMethodCall (void* (T::*)() @var{proc}) +@end deftypefn +@deftypefn Constructor {} RpcMethodCall (void* (T::*)(void*) @var{proc}) +@end deftypefn +@deftypefn Constructor {} RpcMethodCall (void* (T::*)(void*, void*) @var{proc}) +Construct an @code{RpcMethodCall} for an object and one of its methods that +takes zero, one or two arguments and returns a result. Constructors for +methods with up to seven arguments are defined. +@end deftypefn +@deftypefn Constructor {} RpcMethodCall (void* (T::*)(void**) @var{proc}) +Construct an @code{RpcMethodCall} for an object and one of its methods +that takes an arbitrary number of arguments and returns a result. +@end deftypefn + +@deftypefn Constructor {} RpcMethodCall (void (T::*)() @var{proc}) +@end deftypefn +@deftypefn Constructor {} RpcMethodCall (void (T::*)(void*) @var{proc}) +@end deftypefn +@deftypefn Constructor {} RpcMethodCall (void (T::*)(void*, void*) @var{proc}) +Construct an @code{RpcMethodCall} for an object and one of its methods +that takes zero, one or two arguments and returns no result. +Constructors for methods with up to seven arguments are defined. +@end deftypefn +@deftypefn Constructor {} RpcMethodCall (void (T::*)(void**) @var{proc}) +Construct an @code{RpcMethodCall} for an object and one of its methods +that takes an arbitrary number of arguments and return no result. +@end deftypefn + +@deftypefn Constructor {} RpcMethodCall (void* (T::*)(RpcService*) @var{proc}) +@end deftypefn +@deftypefn Constructor {} RpcMethodCall (void* (T::*)(void*, RpcService*) @var{proc}) +@end deftypefn +@deftypefn Constructor {} RpcMethodCall (void* (T::*)(void*, void*, RpcService*) @var{proc}) +Construct an @code{RpcMethodCall} for an object and one of its methods +that takes zero, one or two arguments and returns a result. Constructors +for methods with up to seven arguments are defined. Upon invocation, a +pointer to the object of type @code{RpcService} that received the +request and called the method is passed as an additional argument. +@end deftypefn +@deftypefn Constructor {} RpcMethodCall (void* (T::*)(void**) @var{proc}) +Construct an @code{RpcMethodCall} for an object and one of its methods +that takes an arbitrary number of arguments and returns a result. Upon +invocation, a pointer to the object of type @code{RpcService} that +received the request and called the method is passed as an additional +argument. +@end deftypefn + +@deftypefn Constructor {} RpcMethodCall (void (T::*)(RpcService*) @var{proc}) +@end deftypefn +@deftypefn Constructor {} RpcMethodCall (void (T::*)(void*, RpcService*) @var{proc}) +@end deftypefn +@deftypefn Constructor {} RpcMethodCall (void (T::*)(void*, void*, RpcService*) @var{proc}) +Construct an @code{RpcMethodCall} for an object and one of its methods +that takes zero, one or two arguments and returns a result. Constructors +for methods with up to seven arguments are defined. Upon invocation, a +pointer to the object of type @code{RpcService} that received the +request and called the method is passed as an additional argument. +@end deftypefn +@deftypefn Constructor {} RpcMethodCall (void (T::*)(void**) @var{proc}) +Construct an @code{RpcMethodCall} for an object and one of its methods +that takes an arbitrary number of arguments and returns a result. Upon +invocation, a pointer to the object of type @code{RpcService} that +received the request and called the method is passed as an additional +argument. +@end deftypefn + +@node Calling Conventions, , RpcMethodCall, Callbacks +@comment node-name, next, previous, up +@subsection @code{Calling Conventions} +@cindex @code{calling conventions} + +As could be seen from the parameter types in the constructors, functions +and methods that are called in response to a request from a client know +only about pointers to void as arguments and result values because their +real type is coded in the @code{RpcRequest} and not known at compile +time. The only way to avoid this is to implement some kind of rpcgen++. +However, I never liked this kind of tools and I'm willing to risk a bit +of type unsafeness in this case. + +When a procedure (or method) is called, its arguments point to values +(the variants with an arbitrary number of arguments receive an array of +pointers to values) of the types specified in the constructor of the +@code{RpcRequest} that led to the invocation of the procedure. I +recommend to access the values and assign them to local variables of the +procedure in the first statements. E.g.: +@example +void* Add (void* s1p, void* s2p) +@{ + int s1 = *(int*)s1p; + int s2 = *(int*)s2p; + ... +@end example + +The return value of the procedure is a pointer to the result. Therefore, +results may never be put in automatic variables. They must be global or +static. E.g.: +@example + ... + static int sum; + sum = s1 + s2; + return (void*)∑ +@} +@end example + +Note the special case of strings (defined as parameters or return values +using @code{Xdr::Xwrapstring}, @pxref{XdrInfo}). If you think of a +string as being defined as a type ``@code{typedef char* string}'', it is +obvious that a string is passed as argument or returned as result by a +@code{string*}, i.e., a @code{char**}. E.g.: +@example +void* Capitalize (void* strp) +@{ + static char* str; + str = *(char**)strp; + str[0] = toupper (str[0]); + return (void*)&str; +@} +@end example + +@page +@node RpcService, RpcStub, Callbacks, Classes +@comment node-name, next, previous, up +@section @code{RpcService} +@cindex @code{RpcService} + +Declared in: @code{"rpc++/service.h"} + +@deftp Class RpcService +An object of type @code{RpcService} provides the server capabilities +within a program. +@end deftp + +There are two constructors for @code{RpcService}: + +@deftypefn Constructor {} RpcService (u_long @var{prog}, u_long @var{vers}) +Construct an object representing the @var{vers}'th version of program +(service) number @code{prog}. +@end deftypefn +@deftypefn Constructor {} RpcService (u_long @var{vers}) +Construct an object representing the @var{vers}'th version of a transient +program (service). +@end deftypefn + +@deftypefn Method bool OK () +Returns TRUE if the service is ready for operation, i.e., has successfully +been established during construction. +@end deftypefn + +The number of a service, especially a transient service, can be obtained +with method @code{@w{Program ()}}: + +@deftypefn Method u_long Program () +Returns the number of the program (service). This is either the number +passed as an argument to the constructor or a number from the transient +program area. +@end deftypefn + +The next step after the construction of an @code{RpcService} is to +register the requests handled by the service: + +@deftypefn Method {virtual void} Register (const RpcRequest& @var{req}, const AnyRpcCallback& @var{cb}) +Associate request @var{req} with the procedure or object/method pair +specified by @code{cb}. The usual way to call @code{Register} is +@example +@{ + RpcService svc (...); + svc.register (addreq, RpcCallback (Add)); + ... +@} +@end example +@end deftypefn + +After all requests have been registered, the object of type +@code{RpcService} can provide the service: +@deftypefn Method void Provide () +Repeatedly wait for a request and handle it by calling the procedure or +method registered for it. +@end deftypefn + +@deftypefn Method {virtual void*} HandleError () +@code{HandleError} is a protected method that is called when an error +occurs. The cause of the error is stored in a protected member variable +@code{errorState}. If the default error handling (shown below) is not +appropriate for your application, derive your own class from +@code{RpcService} that implements a different error handling policy. If +you consider an error recoverable, reset @code{errorState} to +@code{RpcService::noError} in your error handler. Else, @code{OK ()} +keeps returning FALSE. +@example +void RpcService::HandleError () +@{ + switch (errorState) + @{ + case reconstructionAttempt: + cerr << "rpc++: Attempt to construct another instance of RpcService.\n"; + exit (1); + case cantCreateTCPService: + cerr << "rpc++: can't create tcp service.\n"; + exit(1); + case cantRegisterService: + cerr << form ("rpc++: can't register (%d, %d, tcp).", prog, vers); + exit(1); + case cantSendReply: + cerr << "rpc++: can't reply to RPC call.\n"; + break; + case invalidResult: + cerr << "rpc++: registered routine has return NULL pointer.\n"; + abort (); + case notRegistered: + cerr << "rpc++: requested RPC routine not registered.\n"; + break; + case cantGetArgs: + cerr << "rpc++: can't get procedure arguments.\n"; + break; + case cantFreeArgs: + cerr << "rpc++: can't free XDR arguments.\n"; + break; + @} + errorState = noError; +@} +@end example +@end deftypefn + +If the program that provides the service has other things to do as well, +i.e., does not only handle requests, it usually has its own main loop +that handles events. This loop must be extended to handle RPC events, +i.e., if anything happens on the RPC file descriptors, it must call +@code{svc_getreqset} just as @code{Provide ()} does. +@example +void RpcService::Provide () +@{ + int dtbsz = getdtablesize(); + fd_set readfds; + + for(;;) + @{ + readfds = svc_fdset; + switch(select (dtbsz, &readfds, 0, 0, 0)) + @{ + case -1: + if (errno != EBADF) + continue; + cerr << "PRC++: select: " << sys_errlist[errno] << '\n'; + return; + break; + case 0: + continue; + default: + svc_getreqset (&readfds); + break; + @} + @} +@} +@end example + +The following methods are only available during the execution of a +callback, i.e., they can be applied to @code{RpcService} if a pointer to +the invoking object has been declared as last parameter of a callback +routine. + +@deftypefn Method {struct sockaddr_in*} Caller () +Return the socket address information of the calling host. +@end deftypefn + +@deftypefn Method char* CallerName () +Return the name of the calling host. +@end deftypefn + +@deftypefn Method void Reply () +@end deftypefn +@deftypefn Method void Reply (void* @var{res}) +Normally, a request to the server terminates when the callback completes +(either with or without returning a value, depending on the return +type). In some cases it is desirable to reply to the client before all +the actions related to the request have been completed. This allows the +client to resume execution. The result (if any) must of course not +depend on the functions still to be executed. +@end deftypefn + +@deftypefn Method void Interrupt () +This is the proper way to terminate the loop entered by calling +@code{Provide()}. After return from the callback that invoked +@code{Interrupt()} method @code{Provide()} will return. +@end deftypefn + +@page +@node RpcStub, , RpcService, Classes +@comment node-name, next, previous, up +@section @code{RpcStub} +@cindex @code{RpcStub} + +Declared in: @code{"rpc++/stub.h"} + +@deftp Class RpcStub +An @code{RpcStub} represents the client side of a connection. +@end deftp + +There are two constructors for @code{RpcStub} that vary in the position +of their arguments only: + +@deftypefn Constructor {} RpcStub (u_long @code{prognum}, u_long @code{versnum}, char* @var{hostname}="localhost", timeval @var{timeout}=defaultTimeout, bool @var{connect}=TRUE) +@end deftypefn +@deftypefn Constructor {} RpcStub (u_long @code{prognum}, u_long @code{versnum}, char* @var{hostname}="localhost", bool @var{connect}=TRUE, timeval @var{timeout}=defaultTimeout) +Construct an @code{RpcStub} that connects to the @var{versnum}'th +version of program (service) @var{prognum} on host @var{hostname}. The +timeout for successful completion of communication operations is +@var{timeout} which defaults to 25 seconds. Unless @var{connect} is +false, the constructor makes a connection attempt. +@end deftypefn + +There are various methods: + +@deftypefn Method void Reconnect () +Connect to the server. Usually this method is called if the connection +was not to be established by the constructor or if the connection +attempt failed and is to be repeated. +@end deftypefn + +@deftypefn Method bool OK () +Returns TRUE if the stub is ready for operation, i.e., connected to a +server. +@end deftypefn + +@deftypefn Method CLIENT* Service () +Access to the standard RPC level. Returns the handle that identifies the +server. +@end deftypefn + +@deftypefn Method timeval GetTimeout () const +Returns the default timeout for network operations. +@end deftypefn + +@deftypefn Method void SetTimeout (timeval& @var{timo}) +Sets the default timeout for network operations +@end deftypefn + +@deftypefn Method void* Call (RpcRequest& @var{req}, bool @var{handle_errors}=TRUE) +@end deftypefn +@deftypefn Method void* Call (RpcRequest& @var{req}, void* @var{in1}, bool @var{handle_errors}=TRUE) +@end deftypefn +@deftypefn Method void* Call (RpcRequest& @var{req}, void* @var{in1}, @var{in2} bool @var{handle_errors}=TRUE) +Request the operation specified by @var{req} from the server, passing +zero, one or two arguments. There are declarations of this method for up +two seven arguments. Arguments are passed as pointers to the argument +values. The value returned by @code{Call} is a pointer to the result +returned by the server. The result is valid until @code{Call} is called +again. If @var{handle_errors} is FALSE and an error occurs, @code{Call} +simply returns 0. Else, it calls method @code{HandleError} (see below). +@end deftypefn +@deftypefn Method void* Call (RpcRequest& @var{req}, void** @var{invals}, bool @var{handle_errors}=TRUE) +The variant of @code{Call} that handles an arbitrary number of +arguments. Pointers to the arguments are passed in an array in +parameter @var{invals}. The size of the array must match the number of +arguments given to the constructor of @var{req}. +@end deftypefn + +@deftypefn Method {virtual void*} HandleError () +@code{HandleError} is a protected method that is called when an error +occurs. The cause of the error is stored in a protected member variable +@code{errorState}. If the default error handling policy (shown below) is +not appropriate for your application, derive your own class from +@code{RpcStub} that implements a different one. If you consider an error +recoverable, reset @code{errorState} to @code{RpcStub::noError} in your +error handler. Else, @code{OK ()} keeps returning FALSE. If an error +occurs during a @code{Call} and parameter @var{handle_errors} is TRUE, +@code{Call} invokes @code{HandleError} and returns its result as result +of the call. +@example +void* RpcStub::HandleError () +@{ + switch (errorState) + @{ + case notConnected: + cerr << "rpc++: Stub has not been connected to server.\n"; + case cantCreate: + cerr << clnt_spcreateerror ("rpc++") << '\n'; + break; + case cantCall: + cerr << clnt_sperror (svc, "rpc++") << '\n'; + exit (1); + @} + return 0; +@} +@end example +@end deftypefn + +While no or little improvement of coding quality can be gained from +deriving a service specific class from @code{RpcService}, the opposite +is true for @code{RpcStub}. A service specific derivation may define +methods that have the ``real'' argument lists instead of pointers to +void. These methods are simply implemented by casting the arguments and +(inline) calling one of the @code{Call}--methods. Apart from better +type checking, this has the advantage of keeping details like the +available @code{RpcRequest}s local to the definition of the derived +class (see the example in the @code{example}--directory). + +@node Caveats, References, Classes, Top +@comment node-name, next, previous, up +@chapter Caveats +@cindex Caveats + +@menu +* Global objects:: Global objects +* Destruction rules:: Destruction rules +* Matching server and clients:: Matching server and clients +@end menu + +@node Global objects, Destruction rules, , Caveats +@comment node-name, next, previous, up +@section Global objects +@cindex Global objects + +As a general C++ rule, be careful with global objects. The sequence of +constructor invocations for global objects is not defined. This is the +reason, why @code{RpcRequests} are constructed from pointers to +@code{XdrInfo}s rather than from @code{XdrInfo}s. + +Both @code{XdrInfo}s and @code{RpcRequest}s tend to be instantiated as +global objects or static member variables. If the constructor of +@code{RpcRequest} received @code{XdrInfo}s instead of pointers and +copied the information contained in the @code{XdrInfo} (the solution I +had preferred), it may happen that the @code{XdrInfo} has not been +constructed yet and thus contains invalid data. + +The same problem occurs if you want to define a global +``alias--@code{XdrInfo}'' matching a ``@code{typedef int myint}''. +Don't use @code{XdrInfo Xmyint (Xdr::Xint)} as this may copy the +uninitialized @code{Xdr::Xint}. Use @code{XdrInfo& Xmyint = Xdr::Xint} +instead. + +@node Destruction rules, Matching server and clients, Global objects, Caveats +@comment node-name, next, previous, up +@section Destruction rules +@cindex Destruction rules + +Objects of type @code{XdrInfo} are resources that can be used more than +once, i.e., in different @code{RpcRequest}s. If they were handled +properly, references to @code{XdrInfo} would be counted and the +@code{XdrInfo} destructed automatically if the last reference is +removed (unless it is the @code{XdrInfo} of a predefined type). + +Such a resource management for @code{XdrInfo}s has been considered +unnecessary as @code{XdrInfo}s will rarely be dynamic objects. If the +user allocates an @code{XdrInfo} on the stack or the heap, it is his +responsibility to assure that the object is valid until the last +@code{RpcResource} that uses it has been destructed. + +@node Matching server and clients, , Destruction rules, Caveats +@comment node-name, next, previous, up +@section Matching server and clients + +In order to make sure that the server and the clients agree about the +protocol, all @code{RpcRequest}s for a service should be declared in a +header file and instantiated in a corresponding source file. The header +file and the compiled source file make the ``library'' that provides the +service. Thus a server consists of three files: the server executable, a +header file defining the service that is to be included in client +sources and an object file which must be linked to the client +executable. + +@c ====================================================================== + +@node References, Copying, Caveats, Top +@comment node-name, next, previous, up +@unnumbered References + +Margaret A. Ellis, @cite{The Annotated C++ Reference Manual}, +Addison-Wesley, 1990. + +Stanley B. Lippmann, @cite{A C++ Primer}, Addison-Wesley, 1989. + +Bjarne Stroustrup, @cite{The C++ Programming Language}, Addison-Wesley, +1986. + +Sun Microsystems, @cite{Network Programming}, March 1990. + +@c ====================================================================== + +@node Copying, Data Type Index, References, Top +@appendix GNU LIBRARY GENERAL PUBLIC LICENSE +@center Version 2, June 1991 + +@display +Copyright @copyright{} 1991 Free Software Foundation, Inc. +675 Mass Ave, Cambridge, MA 02139, USA +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. +@end display + +@unnumberedsec Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software---to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +``work based on the library'' and a ``work that uses the library''. The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + +@iftex +@unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +@end iftex +@ifinfo +@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +@end ifinfo + +@enumerate +@item +This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called ``this License''). Each licensee is +addressed as ``you''. + + A ``library'' means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The ``Library'', below, refers to any such software library or work +which has been distributed under these terms. A ``work based on the +Library'' means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term ``modification''.) + + ``Source code'' for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + +@item +You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + +@item +You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + +@enumerate +@item +The modified work must itself be a software library. + +@item +You must cause the files modified to carry prominent notices +stating that you changed the files and the date of any change. + +@item +You must cause the whole of the work to be licensed at no +charge to all third parties under the terms of this License. + +@item +If a facility in the modified Library refers to a function or a +table of data to be supplied by an application program that uses +the facility, other than as an argument passed when the facility +is invoked, then you must make a good faith effort to ensure that, +in the event an application does not supply such function or +table, the facility still operates, and performs whatever part of +its purpose remains meaningful. + +(For example, a function in a library to compute square roots has +a purpose that is entirely well-defined independent of the +application. Therefore, Subsection 2d requires that any +application-supplied function or table used by this function must +be optional: if the application does not supply it, the square +root function must still compute square roots.) +@end enumerate + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +@item +You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + +@item +You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + +@item +A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a ``work that uses the Library''. Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a ``work that uses the Library'' with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a ``work that uses the +library''. The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a ``work that uses the Library'' uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + +@item +As an exception to the Sections above, you may also compile or +link a ``work that uses the Library'' with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + +@enumerate +@item +Accompany the work with the complete corresponding +machine-readable source code for the Library including whatever +changes were used in the work (which must be distributed under +Sections 1 and 2 above); and, if the work is an executable linked +with the Library, with the complete machine-readable ``work that +uses the Library'', as object code and/or source code, so that the +user can modify the Library and then relink to produce a modified +executable containing the modified Library. (It is understood +that the user who changes the contents of definitions files in the +Library will not necessarily be able to recompile the application +to use the modified definitions.) + +@item +Accompany the work with a written offer, valid for at +least three years, to give the same user the materials +specified in Subsection 6a, above, for a charge no more +than the cost of performing this distribution. + +@item +If distribution of the work is made by offering access to copy +from a designated place, offer equivalent access to copy the above +specified materials from the same place. + +@item +Verify that the user has already received a copy of these +materials or that you have already sent this user a copy. +@end enumerate + + For an executable, the required form of the ``work that uses the +Library'' must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + +@item +You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + +@enumerate +@item +Accompany the combined library with a copy of the same work +based on the Library, uncombined with any other library +facilities. This must be distributed under the terms of the +Sections above. + +@item +Give prominent notice with the combined library of the fact +that part of it is a work based on the Library, and explaining +where to find the accompanying uncombined form of the same work. +@end enumerate + +@item +You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + +@item +You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +@item +Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + +@item +If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +@item +If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + +@item +The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +``any later version'', you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + +@item +If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + +@iftex +@heading NO WARRANTY +@end iftex +@ifinfo +@center NO WARRANTY +@end ifinfo + +@item +BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY ``AS IS'' WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +@item +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. +@end enumerate + +@iftex +@heading END OF TERMS AND CONDITIONS +@end iftex +@ifinfo +@center END OF TERMS AND CONDITIONS +@end ifinfo + +@page +@unnumberedsec How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +``copyright'' line and a pointer to where the full notice is found. + +@smallexample +@var{one line to give the library's name and a brief idea of what it does.} +Copyright (C) @var{year} @var{name of author} + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free +Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +@end smallexample + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a ``copyright disclaimer'' for the library, if +necessary. Here is a sample; alter the names: + +@example +Yoyodyne, Inc., hereby disclaims all copyright interest in the +library `Frob' (a library for tweaking knobs) written by James Random Hacker. + +@var{signature of Ty Coon}, 1 April 1990 +Ty Coon, President of Vice +@end example + +That's all there is to it! + +@c ======================================================================== + +@page +@node Data Type Index, Function Index, Copying, Top +@comment node-name, next, previous, up +@unnumbered Data Type Index + +@printindex tp + +@node Function Index, Concept Index, Data Type Index, Top +@comment node-name, next, previous, up +@unnumbered Function and Method Index + +@printindex fn + +@node Concept Index, , Function Index, Top +@comment node-name, next, previous, up +@unnumbered Concept Index + +@printindex cp + +@contents +@bye diff --git a/rpc++/rpc++.toc b/rpc++/rpc++.toc new file mode 100644 index 00000000000..95eea1fd88c --- /dev/null +++ b/rpc++/rpc++.toc @@ -0,0 +1,23 @@ +\chapentry {Overview}{1}{1} +\chapentry {Installation}{2}{2} +\chapentry {The classes}{3}{3} +\secentry {\code {XdrInfo}}{3}{1}{3} +\secentry {\code {RpcRequest}}{3}{2}{5} +\secentry {Callbacks}{3}{3}{7} +\subsecentry {\code {RpcCallback}}{3}{3}{1}{7} +\subsecentry {\code {RpcMethodCall}}{3}{3}{2}{9} +\subsecentry {\code {Calling Conventions}}{3}{3}{3}{10} +\secentry {\code {RpcService}}{3}{4}{12} +\secentry {\code {RpcStub}}{3}{5}{16} +\chapentry {Caveats}{4}{19} +\secentry {Global objects}{4}{1}{19} +\secentry {Destruction rules}{4}{2}{19} +\secentry {Matching server and clients}{4}{3}{19} +\unnumbchapentry {References}{21} +\chapentry {GNU LIBRARY GENERAL PUBLIC LICENSE}{Appendix \char65}{22} +\unnumbsecentry{Preamble}{22} +\unnumbsecentry{TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION}{24} +\unnumbsecentry{How to Apply These Terms to Your New Libraries}{30} +\unnumbchapentry {Data Type Index}{31} +\unnumbchapentry {Function and Method Index}{32} +\unnumbchapentry {Concept Index}{33} diff --git a/rpc++/rpc++.tp b/rpc++/rpc++.tp new file mode 100644 index 00000000000..80265f4d91c --- /dev/null +++ b/rpc++/rpc++.tp @@ -0,0 +1,7 @@ +\entry {XdrInfo}{3}{\code {XdrInfo}} +\entry {RpcRequest}{5}{\code {RpcRequest}} +\entry {AnyRpcCallback}{7}{\code {AnyRpcCallback}} +\entry {RpcCallback}{7}{\code {RpcCallback}} +\entry {RpcMethodCall}{9}{\code {RpcMethodCall}} +\entry {RpcService}{12}{\code {RpcService}} +\entry {RpcStub}{16}{\code {RpcStub}} diff --git a/rpc++/rpc++.vr b/rpc++/rpc++.vr new file mode 100644 index 00000000000..2ad8f41a633 --- /dev/null +++ b/rpc++/rpc++.vr @@ -0,0 +1,13 @@ +\entry {Xdr::Xchar}{3}{\code {Xdr::Xchar}} +\entry {Xdr::Xshort}{3}{\code {Xdr::Xshort}} +\entry {Xdr::Xint}{4}{\code {Xdr::Xint}} +\entry {Xdr::Xlong}{4}{\code {Xdr::Xlong}} +\entry {Xdr::Xuchar}{4}{\code {Xdr::Xuchar}} +\entry {Xdr::Xushort}{4}{\code {Xdr::Xushort}} +\entry {Xdr::Xulong}{4}{\code {Xdr::Xulong}} +\entry {Xdr::Xfloat}{4}{\code {Xdr::Xfloat}} +\entry {Xdr::Xdouble}{4}{\code {Xdr::Xdouble}} +\entry {Xdr::Xenum{\_}t}{4}{\code {Xdr::Xenum{\_}t}} +\entry {Xdr::Xbool{\_}t}{4}{\code {Xdr::Xbool{\_}t}} +\entry {Xdr::Xvoid}{4}{\code {Xdr::Xvoid}} +\entry {Xdr::Xnull}{4}{\code {Xdr::Xnull}} diff --git a/rpc++/rpc++/callback.h b/rpc++/rpc++/callback.h new file mode 100644 index 00000000000..6200178263f --- /dev/null +++ b/rpc++/rpc++/callback.h @@ -0,0 +1,533 @@ +// -*- c++ -*- +/* +Copyright (C) 1991 Peter Bersen + +This file is part of the rpc++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +Modified and partially rewritten March 1992 by Michael N. Lipp, +mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and +conditions apply without change to any modified or new parts. +*/ + +#ifndef _RPCCALLBACK_H_ +#define _RPCCALLBACK_H_ +static char _rpcpp_callback_h_[] += "callback.h,v 2.3 1992/06/15 19:13:26 mnl Exp"; + +// callback.h,v +// Revision 2.3 1992/06/15 19:13:26 mnl +// Fixed a few bugs, clarified interface. +// +// Revision 2.2 1992/06/13 14:27:37 mnl +// Adapted to (patched) gcc-2.2. Fixed several bugs. +// +// Revision 2.1.1.1 1992/03/08 13:28:43 mnl +// Initial mnl version. +// + +// +// The user interface to RpcCallback is quiet simple. The only function +// needed is the constructor "RpcCallback (T* o, void* m)". Given a class +// C with a method m and an object o of Type C, a callback to the method +// can be constructed with "RpcCallback (&O, &C::m)". +// As an alternative, an RpcExtCallback may be constructed with +// "RpcExtCallback (T* o, void* m, RpcService*)". In this case, the method +// is called with a pointer to the RpcService object as a third argument. +// +// A pointer to a callback can be casted to AnyRpcCallback by +// whatever routine receives it and the call can be made by applying "Do" +// to the callback. +// + +class RpcService; + +class AnyRpcCallback +{ + friend class RpcService; + +protected: + int params; + RpcService* svc; + virtual void* Do (void** in) = 0; + +public: + inline virtual ~AnyRpcCallback () {} + inline virtual AnyRpcCallback* CopyToHeap () const = 0; + inline int Params () const + { return params; } + inline void SetService (RpcService* s) + { svc = s; } +}; + +class RpcCallback : public AnyRpcCallback +{ +private: + typedef void* (*ProcN)(void**); + typedef void* (*Proc0)(); + typedef void* (*Proc1)(void*); + typedef void* (*Proc2)(void*, void*); + typedef void* (*Proc3)(void*, void*, void*); + typedef void* (*Proc4)(void*, void*, void*, void*); + typedef void* (*Proc5)(void*, void*, void*, void*, void*); + typedef void* (*Proc6)(void*, void*, void*, void*, void*, void*); + typedef void* (*Proc7)(void*, void*, void*, void*, void*, void*, void*); + + typedef void (*ProcNv)(void**); + typedef void (*Proc0v)(); + typedef void (*Proc1v)(void*); + typedef void (*Proc2v)(void*, void*); + typedef void (*Proc3v)(void*, void*, void*); + typedef void (*Proc4v)(void*, void*, void*, void*); + typedef void (*Proc5v)(void*, void*, void*, void*, void*); + typedef void (*Proc6v)(void*, void*, void*, void*, void*, void*); + typedef void (*Proc7v)(void*, void*, void*, void*, void*, void*, void*); + + typedef void* (*ProcNs)(void**, RpcService*); + typedef void* (*Proc0s)(RpcService*); + typedef void* (*Proc1s)(void*, RpcService*); + typedef void* (*Proc2s)(void*, void*, RpcService*); + typedef void* (*Proc3s)(void*, void*, void*, RpcService*); + typedef void* (*Proc4s)(void*, void*, void*, void*, RpcService*); + typedef void* (*Proc5s)(void*, void*, void*, void*, void*, RpcService*); + typedef void* (*Proc6s)(void*, void*, void*, void*, + void*, void*, RpcService*); + typedef void* (*Proc7s)(void*, void*, void*, void*, + void*, void*, void*, RpcService*); + + typedef void (*ProcNvs)(void**, RpcService*); + typedef void (*Proc0vs)(RpcService*); + typedef void (*Proc1vs)(void*, RpcService*); + typedef void (*Proc2vs)(void*, void*, RpcService*); + typedef void (*Proc3vs)(void*, void*, void*, RpcService*); + typedef void (*Proc4vs)(void*, void*, void*, void*, RpcService*); + typedef void (*Proc5vs)(void*, void*, void*, void*, void*, RpcService*); + typedef void (*Proc6vs)(void*, void*, void*, void*, + void*, void*, RpcService*); + typedef void (*Proc7vs)(void*, void*, void*, void*, + void*, void*, void*, RpcService*); + + typedef void* (RpcCallback::*DoPtr)(void**); + DoPtr todo; + union + { + ProcN procN;ProcNv procNv;ProcNs procNs;ProcNvs procNvs; + Proc0 proc0;Proc0v proc0v;Proc0s proc0s;Proc0vs proc0vs; + Proc1 proc1;Proc1v proc1v;Proc1s proc1s;Proc1vs proc1vs; + Proc2 proc2;Proc2v proc2v;Proc2s proc2s;Proc2vs proc2vs; + Proc3 proc3;Proc3v proc3v;Proc3s proc3s;Proc3vs proc3vs; + Proc4 proc4;Proc4v proc4v;Proc4s proc4s;Proc4vs proc4vs; + Proc5 proc5;Proc5v proc5v;Proc5s proc5s;Proc5vs proc5vs; + Proc6 proc6;Proc6v proc6v;Proc6s proc6s;Proc6vs proc6vs; + Proc7 proc7;Proc7v proc7v;Proc7s proc7s;Proc7vs proc7vs; + }; + inline RpcCallback () {} + inline void* Do (void** in) + { return (this->*todo)(in); } + + inline void* DoN (void** in) + { return (*procN)(in); } + inline void* Do0 (void** in) + { return (*proc0)(); } + inline void* Do1 (void** in) + { return (*proc1)(in[0]); } + inline void* Do2 (void** in) + { return (*proc2)(in[0], in[1]); } + inline void* Do3 (void** in) + { return (*proc3)(in[0], in[1], in[2]); } + inline void* Do4 (void** in) + { return (*proc4)(in[0], in[1], in[2], in[3]); } + inline void* Do5 (void** in) + { return (*proc5)(in[0], in[1], in[2], in[3], in[4]); } + inline void* Do6 (void** in) + { return (*proc6)(in[0], in[1], in[2], in[3], in[4], in[5]); } + inline void* Do7 (void** in) + { return (*proc7)(in[0], in[1], in[2], in[3], in[4], in[5], in[6]); } + inline void* DoNv (void** in) + { (*procNv)(in); return (void*)0; } + inline void* Do0v (void** in) + { (*proc0v)(); return (void*)0; } + inline void* Do1v (void** in) + { (*proc1v)(in[0]); return (void*)0; } + inline void* Do2v (void** in) + { (*proc2v)(in[0], in[1]); return (void*)0; } + inline void* Do3v (void** in) + { (*proc3v)(in[0], in[1], in[2]); return (void*)0; } + inline void* Do4v (void** in) + { (*proc4v)(in[0], in[1], in[2], in[3]); return (void*)0; } + inline void* Do5v (void** in) + { (*proc5v)(in[0], in[1], in[2], in[3], in[4]); return (void*)0; } + inline void* Do6v (void** in) + { (*proc6v)(in[0], in[1], in[2], in[3], in[4], in[5]); return (void*)0; } + inline void* Do7v (void** in) + { (*proc7v)(in[0], in[1], in[2], in[3], in[4], in[5], in[6]); + return (void*)0; } + + inline void* DoNs (void** in) + { return (*procNs)(in, svc); } + inline void* Do0s (void** in) + { return (*proc0s)(svc); } + inline void* Do1s (void** in) + { return (*proc1s)(in[0], svc); } + inline void* Do2s (void** in) + { return (*proc2s)(in[0], in[1], svc); } + inline void* Do3s (void** in) + { return (*proc3s)(in[0], in[1], in[2], svc); } + inline void* Do4s (void** in) + { return (*proc4s)(in[0], in[1], in[2], in[3], svc); } + inline void* Do5s (void** in) + { return (*proc5s)(in[0], in[1], in[2], in[3], in[4], svc); } + inline void* Do6s (void** in) + { return (*proc6s)(in[0], in[1], in[2], in[3], in[4], in[5], svc); } + inline void* Do7s (void** in) + { return (*proc7s)(in[0], in[1], in[2], in[3], in[4], in[5], in[6], svc); } + inline void* DoNvs (void** in) + { (*procNvs)(in, svc); return (void*)0; } + inline void* Do0vs (void** in) + { (*proc0vs)(svc); return (void*)0; } + inline void* Do1vs (void** in) + { (*proc1vs)(in[0], svc); return (void*)0; } + inline void* Do2vs (void** in) + { (*proc2vs)(in[0], in[1], svc); return (void*)0; } + inline void* Do3vs (void** in) + { (*proc3vs)(in[0], in[1], in[2], svc); return (void*)0; } + inline void* Do4vs (void** in) + { (*proc4vs)(in[0], in[1], in[2], in[3], svc); return (void*)0; } + inline void* Do5vs (void** in) + { (*proc5vs)(in[0], in[1], in[2], in[3], in[4], svc); return (void*)0; } + inline void* Do6vs (void** in) + { (*proc6vs)(in[0], in[1], in[2], in[3], in[4], in[5], svc); + return (void*)0; } + inline void* Do7vs (void** in) + { (*proc7vs)(in[0], in[1], in[2], in[3], + in[4], in[5], in[6], svc); return (void*)0; } + +public: + inline RpcCallback (ProcN p) + { todo = &this->DoN; procN = p; params = -1; } + inline RpcCallback (Proc0 p) + { todo = &this->Do0; proc0 = p; params = 0; } + inline RpcCallback (Proc1 p) + { todo = &this->Do1; proc1 = p; params = 1; } + inline RpcCallback (Proc2 p) + { todo = &this->Do2; proc2 = p; params = 2; } + inline RpcCallback (Proc3 p) + { todo = &this->Do3; proc3 = p; params = 3; } + inline RpcCallback (Proc4 p) + { todo = &this->Do4; proc4 = p; params = 4; } + inline RpcCallback (Proc5 p) + { todo = &this->Do5; proc5 = p; params = 5; } + inline RpcCallback (Proc6 p) + { todo = &this->Do6; proc6 = p; params = 6; } + inline RpcCallback (Proc7 p) + { todo = &this->Do7; proc7 = p; params = 7; } + + inline RpcCallback (ProcNv p) + { todo = &this->DoNv; procNv = p; params = -1; } + inline RpcCallback (Proc0v p) + { todo = &this->Do0v; proc0v = p; params = 0; } + inline RpcCallback (Proc1v p) + { todo = &this->Do1v; proc1v = p; params = 1; } + inline RpcCallback (Proc2v p) + { todo = &this->Do2v; proc2v = p; params = 2; } + inline RpcCallback (Proc3v p) + { todo = &this->Do3v; proc3v = p; params = 3; } + inline RpcCallback (Proc4v p) + { todo = &this->Do4v; proc4v = p; params = 4; } + inline RpcCallback (Proc5v p) + { todo = &this->Do5v; proc5v = p; params = 5; } + inline RpcCallback (Proc6v p) + { todo = &this->Do6v; proc6v = p; params = 6; } + inline RpcCallback (Proc7v p) + { todo = &this->Do7v; proc7v = p; params = 7; } + + inline RpcCallback (ProcNs p) + { todo = &this->DoNs; procNs = p; params = -1; } + inline RpcCallback (Proc0s p) + { todo = &this->Do0s; proc0s = p; params = 0; } + inline RpcCallback (Proc1s p) + { todo = &this->Do1s; proc1s = p; params = 1; } + inline RpcCallback (Proc2s p) + { todo = &this->Do2s; proc2s = p; params = 2; } + inline RpcCallback (Proc3s p) + { todo = &this->Do3s; proc3s = p; params = 3; } + inline RpcCallback (Proc4s p) + { todo = &this->Do4s; proc4s = p; params = 4; } + inline RpcCallback (Proc5s p) + { todo = &this->Do5s; proc5s = p; params = 5; } + inline RpcCallback (Proc6s p) + { todo = &this->Do6s; proc6s = p; params = 6; } + inline RpcCallback (Proc7s p) + { todo = &this->Do7s; proc7s = p; params = 7; } + + inline RpcCallback (ProcNvs p) + { todo = &this->DoNvs; procNvs = p; params = -1; } + inline RpcCallback (Proc0vs p) + { todo = &this->Do0vs; proc0vs = p; params = 0; } + inline RpcCallback (Proc1vs p) + { todo = &this->Do1vs; proc1vs = p; params = 1; } + inline RpcCallback (Proc2vs p) + { todo = &this->Do2vs; proc2vs = p; params = 2; } + inline RpcCallback (Proc3vs p) + { todo = &this->Do3vs; proc3vs = p; params = 3; } + inline RpcCallback (Proc4vs p) + { todo = &this->Do4vs; proc4vs = p; params = 4; } + inline RpcCallback (Proc5vs p) + { todo = &this->Do5vs; proc5vs = p; params = 5; } + inline RpcCallback (Proc6vs p) + { todo = &this->Do6vs; proc6vs = p; params = 6; } + inline RpcCallback (Proc7vs p) + { todo = &this->Do7vs; proc7vs = p; params = 7; } + + inline virtual AnyRpcCallback* CopyToHeap () const + { + RpcCallback* p = new RpcCallback (); + *p = *this; + return p; + } +}; + +template class RpcMethodCall : public AnyRpcCallback +{ +private: + typedef void* (T::*MethodN)(void**); + typedef void* (T::*Method0)(); + typedef void* (T::*Method1)(void*); + typedef void* (T::*Method2)(void*, void*); + typedef void* (T::*Method3)(void*, void*, void*); + typedef void* (T::*Method4)(void*, void*, void*, void*); + typedef void* (T::*Method5)(void*, void*, void*, void*, void*); + typedef void* (T::*Method6)(void*, void*, void*, void*, void*, void*); + typedef void* (T::*Method7)(void*, void*, void*, void*, void*, void*, void*); + + typedef void (T::*MethodNv)(void**); + typedef void (T::*Method0v)(); + typedef void (T::*Method1v)(void*); + typedef void (T::*Method2v)(void*, void*); + typedef void (T::*Method3v)(void*, void*, void*); + typedef void (T::*Method4v)(void*, void*, void*, void*); + typedef void (T::*Method5v)(void*, void*, void*, void*, void*); + typedef void (T::*Method6v)(void*, void*, void*, void*, void*, void*); + typedef void (T::*Method7v)(void*, void*, void*, void*, void*, void*, void*); + + typedef void* (T::*MethodNs)(void**, RpcService*); + typedef void* (T::*Method0s)(RpcService*); + typedef void* (T::*Method1s)(void*, RpcService*); + typedef void* (T::*Method2s)(void*, void*, RpcService*); + typedef void* (T::*Method3s)(void*, void*, void*, RpcService*); + typedef void* (T::*Method4s)(void*, void*, void*, void*, RpcService*); + typedef void* (T::*Method5s)(void*, void*, void*, void*, void*, RpcService*); + typedef void* (T::*Method6s)(void*, void*, void*, void*, + void*, void*, RpcService*); + typedef void* (T::*Method7s)(void*, void*, void*, void*, + void*, void*, void*, RpcService*); + + typedef void (T::*MethodNvs)(void**, RpcService*); + typedef void (T::*Method0vs)(RpcService*); + typedef void (T::*Method1vs)(void*, RpcService*); + typedef void (T::*Method2vs)(void*, void*, RpcService*); + typedef void (T::*Method3vs)(void*, void*, void*, RpcService*); + typedef void (T::*Method4vs)(void*, void*, void*, void*, RpcService*); + typedef void (T::*Method5vs)(void*, void*, void*, void*, void*, RpcService*); + typedef void (T::*Method6vs)(void*, void*, void*, void*, + void*, void*, RpcService*); + typedef void (T::*Method7vs)(void*, void*, void*, void*, + void*, void*, void*, RpcService*); + + typedef void* (RpcMethodCall::*DoPtr)(void**); + DoPtr todo; + T* object; + union + { + MethodN methodN;MethodNv methodNv;MethodNs methodNs;MethodNvs methodNvs; + Method0 method0;Method0v method0v;Method0s method0s;Method0vs method0vs; + Method1 method1;Method1v method1v;Method1s method1s;Method1vs method1vs; + Method2 method2;Method2v method2v;Method2s method2s;Method2vs method2vs; + Method3 method3;Method3v method3v;Method3s method3s;Method3vs method3vs; + Method4 method4;Method4v method4v;Method4s method4s;Method4vs method4vs; + Method5 method5;Method5v method5v;Method5s method5s;Method5vs method5vs; + Method6 method6;Method6v method6v;Method6s method6s;Method6vs method6vs; + Method7 method7;Method7v method7v;Method7s method7s;Method7vs method7vs; + }; + inline RpcMethodCall () {} + inline void* Do (void** in) + { return (this->*todo)(in); } + + inline void* DoN (void** in) + { return (object->*methodN)(in); } + inline void* Do0 (void** in) + { return (object->*method0)(); } + inline void* Do1 (void** in) + { return (object->*method1)(in[0]); } + inline void* Do2 (void** in) + { return (object->*method2)(in[0], in[1]); } + inline void* Do3 (void** in) + { return (object->*method3)(in[0], in[1], in[2]); } + inline void* Do4 (void** in) + { return (object->*method4)(in[0], in[1], in[2], in[3]); } + inline void* Do5 (void** in) + { return (object->*method5)(in[0], in[1], in[2], in[3], in[4]); } + inline void* Do6 (void** in) + { return (object->*method6)(in[0], in[1], in[2], in[3], in[4], in[5]); } + inline void* Do7 (void** in) + { return (object->*method7)(in[0], in[1], in[2], + in[3], in[4], in[5], in[6]); } + inline void* DoNv (void** in) + { (object->*methodNv)(in); return (void*)0; } + inline void* Do0v (void** in) + { (object->*method0v)(); return (void*)0; } + inline void* Do1v (void** in) + { (object->*method1v)(in[0]); return (void*)0; } + inline void* Do2v (void** in) + { (object->*method2v)(in[0], in[1]); return (void*)0; } + inline void* Do3v (void** in) + { (object->*method3v)(in[0], in[1], in[2]); return (void*)0; } + inline void* Do4v (void** in) + { (object->*method4v)(in[0], in[1], in[2], in[3]); return (void*)0; } + inline void* Do5v (void** in) + { (object->*method5v)(in[0], in[1], in[2], in[3], in[4]); + return (void*)0; } + inline void* Do6v (void** in) + { (object->*method6v)(in[0], in[1], in[2], in[3], in[4], in[5]); + return (void*)0; } + inline void* Do7v (void** in) + { (object->*method7v)(in[0], in[1], in[2], in[3], in[4], in[5], in[6]); + return (void*)0; } + + inline void* DoNs (void** in) + { return (object->*methodNs)(in, svc); } + inline void* Do0s (void** in) + { return (object->*method0s)(svc); } + inline void* Do1s (void** in) + { return (object->*method1s)(in[0], svc); } + inline void* Do2s (void** in) + { return (object->*method2s)(in[0], in[1], svc); } + inline void* Do3s (void** in) + { return (object->*method3s)(in[0], in[1], in[2], svc); } + inline void* Do4s (void** in) + { return (object->*method4s)(in[0], in[1], in[2], in[3], svc); } + inline void* Do5s (void** in) + { return (object->*method5s)(in[0], in[1], in[2], in[3], in[4], svc); } + inline void* Do6s (void** in) + { return (object->*method6s)(in[0], in[1], in[2], + in[3], in[4], in[5], svc); } + inline void* Do7s (void** in) + { return (object->*method7s)(in[0], in[1], in[2], + in[3], in[4], in[5], in[6], svc); } + inline void* DoNvs (void** in) + { (object->*methodNvs)(in, svc); return (void*)0; } + inline void* Do0vs (void** in) + { (object->*method0vs)(svc); return (void*)0; } + inline void* Do1vs (void** in) + { (object->*method1vs)(in[0], svc); return (void*)0; } + inline void* Do2vs (void** in) + { (object->*method2vs)(in[0], in[1], svc); return (void*)0; } + inline void* Do3vs (void** in) + { (object->*method3vs)(in[0], in[1], in[2], svc); return (void*)0; } + inline void* Do4vs (void** in) + { (object->*method4vs)(in[0], in[1], in[2], in[3], svc); return (void*)0; } + inline void* Do5vs (void** in) + { (object->*method5vs)(in[0], in[1], in[2], in[3], in[4], svc); + return (void*)0; } + inline void* Do6vs (void** in) + { (object->*method6vs)(in[0], in[1], in[2], in[3], in[4], in[5], svc); + return (void*)0; } + inline void* Do7vs (void** in) + { (object->*method7vs)(in[0], in[1], in[2], in[3], + in[4], in[5], in[6], svc); return (void*)0; } + +public: + inline RpcMethodCall (T* o, MethodN m) + { todo = &this->DoN; object = o; methodN = m; params = -1; } + inline RpcMethodCall (T* o, Method0 m) + { todo = &this->Do0; object = o; method0 = m; params = 0; } + inline RpcMethodCall (T* o, Method1 m) + { todo = &this->Do1; object = o; method1 = m; params = 1; } + inline RpcMethodCall (T* o, Method2 m) + { todo = &this->Do2; object = o; method2 = m; params = 2; } + inline RpcMethodCall (T* o, Method3 m) + { todo = &this->Do3; object = o; method3 = m; params = 3; } + inline RpcMethodCall (T* o, Method4 m) + { todo = &this->Do4; object = o; method4 = m; params = 4; } + inline RpcMethodCall (T* o, Method5 m) + { todo = &this->Do5; object = o; method5 = m; params = 5; } + inline RpcMethodCall (T* o, Method6 m) + { todo = &this->Do6; object = o; method6 = m; params = 6; } + inline RpcMethodCall (T* o, Method7 m) + { todo = &this->Do7; object = o; method7 = m; params = 7; } + + inline RpcMethodCall (T* o, MethodNv m) + { todo = &this->DoNv; object = o; methodNv = m; params = -1; } + inline RpcMethodCall (T* o, Method0v m) + { todo = &this->Do0v; object = o; method0v = m; params = 0; } + inline RpcMethodCall (T* o, Method1v m) + { todo = &this->Do1v; object = o; method1v = m; params = 1; } + inline RpcMethodCall (T* o, Method2v m) + { todo = &this->Do2v; object = o; method2v = m; params = 2; } + inline RpcMethodCall (T* o, Method3v m) + { todo = &this->Do3v; object = o; method3v = m; params = 3; } + inline RpcMethodCall (T* o, Method4v m) + { todo = &this->Do4v; object = o; method4v = m; params = 4; } + inline RpcMethodCall (T* o, Method5v m) + { todo = &this->Do5v; object = o; method5v = m; params = 5; } + inline RpcMethodCall (T* o, Method6v m) + { todo = &this->Do6v; object = o; method6v = m; params = 6; } + inline RpcMethodCall (T* o, Method7v m) + { todo = &this->Do7v; object = o; method7v = m; params = 7; } + + inline RpcMethodCall (T* o, MethodNs m) + { todo = &this->DoNs; object = o; methodNs = m; params = -1; } + inline RpcMethodCall (T* o, Method0s m) + { todo = &this->Do0s; object = o; method0s = m; params = 0; } + inline RpcMethodCall (T* o, Method1s m) + { todo = &this->Do1s; object = o; method1s = m; params = 1; } + inline RpcMethodCall (T* o, Method2s m) + { todo = &this->Do2s; object = o; method2s = m; params = 2; } + inline RpcMethodCall (T* o, Method3s m) + { todo = &this->Do3s; object = o; method3s = m; params = 3; } + inline RpcMethodCall (T* o, Method4s m) + { todo = &this->Do4s; object = o; method4s = m; params = 4; } + inline RpcMethodCall (T* o, Method5s m) + { todo = &this->Do5s; object = o; method5s = m; params = 5; } + inline RpcMethodCall (T* o, Method6s m) + { todo = &this->Do6s; object = o; method6s = m; params = 6; } + inline RpcMethodCall (T* o, Method7s m) + { todo = &this->Do7s; object = o; method7s = m; params = 7; } + + inline RpcMethodCall (T* o, MethodNvs m) + { todo = &this->DoNvs; object = o; methodNvs = m; params = -1; } + inline RpcMethodCall (T* o, Method0vs m) + { todo = &this->Do0vs; object = o; method0vs = m; params = 0; } + inline RpcMethodCall (T* o, Method1vs m) + { todo = &this->Do1vs; object = o; method1vs = m; params = 1; } + inline RpcMethodCall (T* o, Method2vs m) + { todo = &this->Do2vs; object = o; method2vs = m; params = 2; } + inline RpcMethodCall (T* o, Method3vs m) + { todo = &this->Do3vs; object = o; method3vs = m; params = 3; } + inline RpcMethodCall (T* o, Method4vs m) + { todo = &this->Do4vs; object = o; method4vs = m; params = 4; } + inline RpcMethodCall (T* o, Method5vs m) + { todo = &this->Do5vs; object = o; method5vs = m; params = 5; } + inline RpcMethodCall (T* o, Method6vs m) + { todo = &this->Do6vs; object = o; method6vs = m; params = 6; } + inline RpcMethodCall (T* o, Method7vs m) + { todo = &this->Do7vs; object = o; method7vs = m; params = 7; } + + inline virtual AnyRpcCallback* CopyToHeap () const + { + RpcMethodCall* p = new RpcMethodCall (); + *p = *this; + return p; + } +}; + +#endif diff --git a/rpc++/rpc++/request.h b/rpc++/rpc++/request.h new file mode 100644 index 00000000000..04250bb3105 --- /dev/null +++ b/rpc++/rpc++/request.h @@ -0,0 +1,121 @@ +// -*- c++ -*- +/* +Copyright (C) 1991 Peter Bersen + +This file is part of the rpc++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +Modified and partially rewritten March 1992 by Michael N. Lipp, +mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and +conditions apply without change to any modified or new parts. +*/ + +#ifndef _RPCREQUEST_H_ +#define _RPCREQUEST_H_ +static char _rpcpp_request_h_[] += "request.h,v 2.3 1992/06/15 19:13:28 mnl Exp"; + +// request.h,v +// Revision 2.3 1992/06/15 19:13:28 mnl +// Fixed a few bugs, clarified interface. +// +// Revision 2.2 1992/06/13 14:27:39 mnl +// Adapted to (patched) gcc-2.2. Fixed several bugs. +// +// Revision 2.1.1.1 1992/03/08 13:28:43 mnl +// Initial mnl version. +// + +#ifdef __GNUG__ +#pragma interface +#endif + +#include "xdr++.h" + +// RpcRequest is a class that specifies an individual request that is +// part of a service. Three parameters are required to specify a request: +// - the request number +// - the serializer (XdrInfo) for the input to the request +// - the serializer (XdrInfo) for the output from the request +class RpcRequest +{ +private: + void init (u_long req, int pars, int parsz, + const XdrInfo* out, const XdrInfo** in, int rt); + +public: + // Construct a new request from a request id, the information about + // the input data and the information about the output data. + // Note that requests that are registered for a service are stored + // in an array using the request id as the index, so keep indices + // small. + typedef enum { normal, batched, async } ReqType; + // No input arg: + RpcRequest (u_long req, const XdrInfo* out, int t = normal); + // One input arg: + RpcRequest (u_long req, const XdrInfo* out, const XdrInfo* in, + int t = normal); + // Two input args: + RpcRequest (u_long req, const XdrInfo* out, const XdrInfo*, const XdrInfo*, + int t = normal); + // ... + RpcRequest (u_long req, const XdrInfo* out, const XdrInfo*, const XdrInfo*, + const XdrInfo*, int t = normal); + RpcRequest (u_long req, const XdrInfo* out, const XdrInfo*, const XdrInfo*, + const XdrInfo*, const XdrInfo*, int t = normal); + RpcRequest (u_long req, const XdrInfo* out, const XdrInfo*, const XdrInfo*, + const XdrInfo*, const XdrInfo*, const XdrInfo*, int t = normal); + RpcRequest (u_long req, const XdrInfo* out, const XdrInfo*, const XdrInfo*, + const XdrInfo*, const XdrInfo*, const XdrInfo*, const XdrInfo*, + int t = normal); + RpcRequest (u_long req, const XdrInfo* out, const XdrInfo*, const XdrInfo*, + const XdrInfo*, const XdrInfo*, const XdrInfo*, const XdrInfo*, + const XdrInfo*, int t = normal); + // N input args, conversion routines given as a NULL terminated array + // of XdrInfo*: + RpcRequest (u_long req, const XdrInfo* out, const XdrInfo**, int t = normal); + ~RpcRequest (); + int RequestNumber () const; + const XdrInfo** InInfo (); + const XdrInfo* OutInfo (); + ReqType Type (); + int Params () const; + int ParamSize (); + +protected: + int params; + int parmsz; + u_long reqnum; + const XdrInfo** ininfo; + const XdrInfo* outinfo; + ReqType reqtype; +}; + +inline RpcRequest::~RpcRequest () +{ delete [] ininfo; } + +inline int RpcRequest::Params () const +{ return params; } + +inline int RpcRequest::RequestNumber () const +{ return reqnum; } + +inline const XdrInfo** RpcRequest::InInfo () +{ return ininfo; } + +inline const XdrInfo* RpcRequest::OutInfo () +{ return outinfo; } + +inline RpcRequest::ReqType RpcRequest::Type () +{ return reqtype; } + +#endif diff --git a/rpc++/rpc++/service.h b/rpc++/rpc++/service.h new file mode 100644 index 00000000000..327c965ced3 --- /dev/null +++ b/rpc++/rpc++/service.h @@ -0,0 +1,132 @@ +// -*- c++ -*- +/* +Copyright (C) 1991 Peter Bersen + +This file is part of the rpc++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +Modified and partially rewritten March 1992 by Michael N. Lipp, +mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and +conditions apply without change to any modified or new parts. +*/ + +#ifndef _RPCSERVICE_H_ +#define _RPCSERVICE_H_ +static char _rpcpp_service_h_[] += "service.h,v 2.3 1992/06/15 19:13:30 mnl Exp"; + +// service.h,v +// Revision 2.3 1992/06/15 19:13:30 mnl +// Fixed a few bugs, clarified interface. +// +// Revision 2.2 1992/06/13 14:27:41 mnl +// Adapted to (patched) gcc-2.2. Fixed several bugs. +// +// Revision 2.1.1.1 1992/03/08 13:28:43 mnl +// Initial mnl version. +// + +#ifdef __GNUG__ +#pragma interface +#endif + +#undef TRUE +#undef FALSE +#include +#include "request.h" +#include "callback.h" + +class RpcRegistered; + +class RpcService +{ +public: + typedef enum + { noError, reconstructionAttempt, cantCreateTCPService, + cantRegisterService, notRegistered, cantGetArgs, + invalidResult, cantSendReply, cantFreeArgs, selectError, + } errorCode; + + // Get state + inline virtual bool OK () + { return errorState == noError; } + // Construct a service object for service prog, version vers + RpcService (u_long prog, u_long vers); + // Construct a transient service object for version vers + RpcService (u_long vers); + // Destruct the service + virtual ~RpcService (); + + // Get the program number (normally used after construction of transient) + u_long Program (); + + // Register an object and its method to be called on request + virtual void Register (const RpcRequest&, const AnyRpcCallback&); + + // The link to RPC + virtual void Dispatch (svc_req* req, SVCXPRT* transp); + // Provide the service. Never returns. + void Provide (); + + // Get caller. May be called during execution of a service routine. + inline struct sockaddr_in* Caller () + { return svc_getcaller (xprt); } + char* CallerName (); + // Reply before return + void Reply (void* res); + void Reply (); + // Quit provide loop + void Interrupt (); + +private: + // Save the address of the one and only RpcService in the process. + // There may be only one RpcService, because we can register a program + // with svc_register (method RpcServiceCallback) but we can't make + // the svc function give an argument to this function when doing a + // callback, which means that we can't have it distinguish between + // various instances of RpcService. + static RpcService* me; + static inline void RpcServiceCallback (svc_req* req, SVCXPRT* transp) + { RpcService::me->Dispatch (req, transp); } + +protected: + void init (); + void HandleError (errorCode e); + errorCode errorState; + u_long prog; + u_long vers; + RpcRegistered** handlers; + int maxHandlerIndex; + SVCXPRT* xprt; + RpcRequest* rpcreq; + bool quitLoop; + char* inbuf; + int inmax; + bool haveReplied; + + // Default error handling prints a message and exit(2)s. + virtual void HandleError (); +}; + +inline void RpcService::HandleError (errorCode e) +{ errorState = e; HandleError (); } + +inline u_long RpcService::Program () +{ return prog; } + +inline void RpcService::Reply () +{ Reply (0); } + +inline void RpcService::Interrupt () +{ quitLoop = TRUE; } + +#endif diff --git a/rpc++/rpc++/stub.h b/rpc++/rpc++/stub.h new file mode 100644 index 00000000000..22d467f2441 --- /dev/null +++ b/rpc++/rpc++/stub.h @@ -0,0 +1,145 @@ +// -*- c++ -*- +/* +Copyright (C) 1991 Peter Bersen + +This file is part of the rpc++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +Modified and partially rewritten March 1992 by Michael N. Lipp, +mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and +conditions apply without change to any modified or new parts. +*/ + +#ifndef _RPCSTUB_H_ +#define _RPCSTUB_H_ +static char _rpcpp_stub_h_[] += "stub.h,v 2.3 1992/06/15 19:13:31 mnl Exp"; + +// stub.h,v +// Revision 2.3 1992/06/15 19:13:31 mnl +// Fixed a few bugs, clarified interface. +// +// Revision 2.2 1992/06/13 14:27:43 mnl +// Adapted to (patched) gcc-2.2. Fixed several bugs. +// +// Revision 2.1.1.1 1992/03/08 13:28:43 mnl +// Initial mnl version. +// + +#ifdef __GNUG__ +#pragma interface +#endif + +#undef TRUE +#undef FALSE +#include +#include +#include +#include "request.h" + +class RpcStub +{ +protected: + static timeval defaultTimeout; + static void* res; + static size_t resmax; + static xdrproc_t resproc; + void init (u_long prognum, u_long versnum, + char* hostname, timeval timeout, bool connect); + +public: + typedef enum + { noError, notConnected, cantCreate, cantCall, + } errorCode; + + // Construct a new stub + RpcStub (u_long prognum, u_long versnum, + char* hostname = "localhost", + timeval timeout = defaultTimeout, bool connect = TRUE); + RpcStub (u_long prognum, u_long versnum, + char* hostname = "localhost", + bool connect = TRUE, timeval timeout = defaultTimeout); + virtual ~RpcStub (); + + // Reconnect (in case of failure or delayed connection) + void Reconnect (); + + // Various inquiries + virtual bool OK (); + CLIENT* Service (); + + // Get/set timeout + timeval GetTimeout () const; + void SetTimeout (timeval& timo); + + // Make a call, either with or without an argument. If handle_errors + // is true, "Call" will call the error handler in case of an error. + // Else, it returns 0 as result and it is up to the client to handle + // the error. + // Call with one arg: + void* Call (RpcRequest&, bool handle_errors = TRUE); + // Call with two args: + void* Call (RpcRequest&, void* in, bool handle_errors = TRUE); + // ... + void* Call (RpcRequest& req, void*, void*, bool handle_errors = TRUE); + void* Call (RpcRequest& req, void*, void*, void*, bool handle_errors = TRUE); + void* Call (RpcRequest& req, void*, void*, void*, void*, + bool handle_errors = TRUE); + void* Call (RpcRequest& req, void*, void*, void*, void*, void*, + bool handle_errors = TRUE); + void* Call (RpcRequest& req, void*, void*, void*, void*, void*, void*, + bool handle_errors = TRUE); + void* Call (RpcRequest& req, void*, void*, void*, void*, void*, void*, void*, + bool handle_errors = TRUE); + // Call with N args: + void* Call (RpcRequest& req, void**, bool handle_errors = TRUE); + +protected: + void* HandleError (errorCode e); + errorCode errorState; + u_long program; + u_long version; + String server; + timeval timeout; + CLIENT* svc; + // Default error handling prints a message and exit(2)s. + virtual void* HandleError (); + void* DoCall (RpcRequest& req, void** args, bool handle_errors); +}; + +inline RpcStub::RpcStub (u_long prognum, u_long versnum, + char* hostname, timeval timeout, bool connect) +{ init (prognum, versnum, hostname, timeout, connect); } + +inline RpcStub::RpcStub (u_long prognum, u_long versnum, + char* hostname, bool connect, timeval timeout) +{ init (prognum, versnum, hostname, timeout, connect); } + +inline virtual bool RpcStub::OK () +{ return errorState == noError; } + +inline CLIENT* RpcStub::Service () +{ return svc; } + +inline timeval RpcStub::GetTimeout () const +{ return timeout; } + +inline void RpcStub::SetTimeout (timeval& timo) +{ timeout = timo; } + +inline void* RpcStub::Call (RpcRequest& req, bool handle_errors = TRUE) +{ return Call (req, (void*)0, handle_errors); } + +inline void* RpcStub::HandleError (errorCode e) +{ errorState = e; return HandleError (); } + +#endif diff --git a/rpc++/rpc++/xdr++.h b/rpc++/rpc++/xdr++.h new file mode 100644 index 00000000000..72da1cb1d4c --- /dev/null +++ b/rpc++/rpc++/xdr++.h @@ -0,0 +1,98 @@ +// -*- c++ -*- +/* +Copyright (C) 1991 Peter Bersen + +This file is part of the rpc++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +Modified and partially rewritten March 1992 by Michael N. Lipp, +mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and +conditions apply without change to any modified or new parts. +*/ + +#ifndef _XDRPLPL_H_ +#define _XDRPLPL_H_ +static char _rpcpp_xdrpp_h_[] += "xdr++.h,v 2.3 1992/06/15 19:13:33 mnl Exp"; + +// xdr++.h,v +// Revision 2.3 1992/06/15 19:13:33 mnl +// Fixed a few bugs, clarified interface. +// +// Revision 2.2 1992/06/13 14:27:44 mnl +// Adapted to (patched) gcc-2.2. Fixed several bugs. +// +// Revision 2.1.1.1 1992/03/08 13:28:43 mnl +// Initial mnl version. +// + +#ifdef __GNUG__ +#pragma interface +#endif + +/* +** Class XdrInfo describes serializers. It combines the xdrproc_t with the +** size info usually needed if you want to apply a serializer. +*/ + +#include + +class XdrInfo +{ +protected: + xdrproc_t proc; + size_t size; +public: + inline XdrInfo (xdrproc_t p, size_t s) + { proc = p; size = s; } + inline xdrproc_t Proc () const + { return proc; } + inline size_t Size () const + { return size; } +}; + +struct XdrSeqInfo +{ + XdrInfo** infos; + void** data; +}; + +/* +** Class Xdr provides a unique (C++-like) name scope for the predefined +** xdr routines by defining them as static members of type XdrInfo. +*/ + +class Xdr +{ +public: + static XdrInfo Xnull; + static XdrInfo Xchar; + static XdrInfo Xshort; + static XdrInfo Xint; + static XdrInfo Xlong; + static XdrInfo Xuchar; + static XdrInfo Xushort; + static XdrInfo Xuint; + static XdrInfo Xulong; + static XdrInfo Xfloat; + static XdrInfo Xdouble; + + static XdrInfo Xenum_t; + static XdrInfo Xbool_t; + static XdrInfo Xvoid; + + static XdrInfo Xwrapstring; + + static bool_t XdrParams (XDR* xdrs, XdrSeqInfo* xsi); +}; + +#endif diff --git a/rpc++/service.cc b/rpc++/service.cc new file mode 100644 index 00000000000..8d548397a87 --- /dev/null +++ b/rpc++/service.cc @@ -0,0 +1,316 @@ +// -*- c++ -*- +/* +Copyright (C) 1991 Peter Bersen + +This file is part of the rpc++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +Modified and partially rewritten March 1992 by Michael N. Lipp, +mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and +conditions apply without change to any modified or new parts. +*/ + +static char _rpcpp_service_cc_[] += "service.cc,v 2.3 1992/06/15 19:12:44 mnl Exp"; + +// service.cc,v +// Revision 2.3 1992/06/15 19:12:44 mnl +// Fixed a few bugs, clarified interface. +// +// Revision 2.2 1992/06/13 14:27:02 mnl +// Adapted to (patched) gcc-2.2. Fixed several bugs. +// +// Revision 2.1.1.1 1992/03/08 13:28:42 mnl +// Initial mnl version. +// + +#ifdef __GNUG__ +#pragma implementation +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rpc++/service.h" +#include "rpc++/request.h" + +extern "C" { + extern int getdtablesize(); +} + +// +// RpcRegistered +// + +class RpcRegistered +{ +public: + RpcRequest request; + AnyRpcCallback* callback; + + inline RpcRegistered (const RpcRequest& req, AnyRpcCallback* cb) + : request (req), callback (cb) { } + inline ~RpcRegistered () + { delete callback; } +}; + +// +// RpcService +// + +RpcService* RpcService::me = 0; + +RpcService::RpcService (u_long pnum, u_long vnum) +{ + init (); + prog = pnum; + vers = vnum; + // find out if we have been started by inetd and set transp accoringly. + sockaddr_in sa; + int sasz = sizeof (sa); + // if started by inetd, stdin is a socket + if (! getsockname (0, (sockaddr*)&sa, &sasz)) + { // yup, inetd is our parent + xprt = svctcp_create(0, 0, 0); + } + else + { // we are standalone + (void) pmap_unset(prog, vers); + xprt = svctcp_create(RPC_ANYSOCK, 0, 0); + } + if (xprt == NULL) + { + HandleError (cantCreateTCPService); + return; + } + if (!svc_register(xprt, prog, vers, RpcServiceCallback, IPPROTO_TCP)) + { + HandleError (cantRegisterService); + return; + } +} + +RpcService::RpcService (u_long vnum) +{ + init (); + vers = vnum; + prog = 0x40000000; + xprt = svctcp_create(RPC_ANYSOCK, 0, 0); + if (xprt == NULL) + { + HandleError (cantCreateTCPService); + return; + } + while (! pmap_set (prog, vers, IPPROTO_TCP, xprt->xp_port)) + prog++; + if (!svc_register(xprt, prog, vers, RpcServiceCallback, IPPROTO_TCP)) + { + HandleError (cantRegisterService); + return; + } +} + +void RpcService::init () +{ + errorState = noError; + if (me) + { + HandleError (reconstructionAttempt); + return; + } + me = this; + handlers = 0; + maxHandlerIndex = -1; + inbuf = 0; + inmax = 0; +} + +RpcService::~RpcService () +{ + svc_unregister (prog, vers); + for (int i = 0; i <= maxHandlerIndex; i++) + delete handlers[i]; + delete [] handlers; + delete [] inbuf; + me = 0; +} + +void RpcService::HandleError () +{ + switch (errorState) + { + case reconstructionAttempt: + cerr << "rpc++: Attempt to construct another instance of RpcService.\n"; + exit (1); + case cantCreateTCPService: + cerr << "rpc++: can't create tcp service.\n"; + exit(1); + case cantRegisterService: + cerr << form ("rpc++: can't register (%d, %d, tcp).", prog, vers); + exit(1); + case cantSendReply: + cerr << "rpc++: can't reply to RPC call.\n"; + break; + case invalidResult: + cerr << "rpc++: registered routine has return NULL pointer.\n"; + abort (); + case notRegistered: + cerr << "rpc++: requested RPC routine not registered.\n"; + break; + case cantGetArgs: + cerr << "rpc++: can't get procedure arguments.\n"; + break; + case cantFreeArgs: + cerr << "rpc++: can't free XDR arguments.\n"; + break; + } + errorState = noError; +} + +void RpcService::Register (const RpcRequest& req, const AnyRpcCallback& cb) +{ + assert (req.Params () == -1 || cb.Params () == -1 + || req.Params () == cb.Params ()); + AnyRpcCallback* cbp = cb.CopyToHeap (); + cbp->SetService (this); + if (req.RequestNumber () > maxHandlerIndex) + { + RpcRegistered** reg = new RpcRegistered*[req.RequestNumber () + 10]; + memcpy (reg, handlers, (maxHandlerIndex + 1) * sizeof (RpcRegistered*)); + memset (®[maxHandlerIndex + 1], 0, + (req.RequestNumber () + 10 - (maxHandlerIndex + 1)) + * sizeof (RpcRegistered*)); + delete handlers; + handlers = reg; + maxHandlerIndex = req.RequestNumber () + 10 - 1; + } + handlers[req.RequestNumber ()] = new RpcRegistered (req, cbp); +} + +void RpcService::Dispatch (svc_req* req, SVCXPRT* transp) +{ + xprt = transp; + if (req->rq_proc == NULLPROC) + { + if (! svc_sendreply (xprt, xdr_void, 0)) + { + svcerr_systemerr (xprt); + HandleError (cantSendReply); + } + return; + } + RpcRegistered* handler = ((req->rq_proc > maxHandlerIndex) + ? 0 + : handlers[req->rq_proc]); + if (! handler) + { + svcerr_noproc (xprt); + HandleError (notRegistered); + return; + } + rpcreq = &handler->request; + + int insz = rpcreq->ParamSize (); + if (insz > inmax) // does in-data fit in available buffer? + { // if not, increase buffer space + delete [] inbuf; + inbuf = new char[inmax = insz]; + } + void* dataps[rpcreq->Params ()]; + void** dp = dataps; + *dp = inbuf; + for (XdrInfo** ip = rpcreq->InInfo(); *ip; ip++, dp++) + dp[1] = (char*)dp[0] + (*ip)->Size (); + + memset (inbuf, 0, insz); + XdrSeqInfo xsi = { rpcreq->InInfo (), dataps }; + if (!svc_getargs (xprt, Xdr::XdrParams, &xsi)) + { + if (rpcreq->Type () == RpcRequest::normal) // errors can be reported + svcerr_decode (xprt); // only if the client waits for a result + HandleError (cantGetArgs); + return; + } + haveReplied = FALSE; + void* res = handler->callback->Do (dataps); + if (! haveReplied) + Reply (res); + if (!svc_freeargs (xprt, Xdr::XdrParams, &xsi)) + HandleError (cantFreeArgs); + xprt = 0; +} + +void RpcService::Reply (void* res) +{ + haveReplied = TRUE; + if (rpcreq->Type () == RpcRequest::normal) // i.e., result expected + { + xdrproc_t outproc = rpcreq->OutInfo()->Proc (); + if (outproc == (xdrproc_t)0) + { + cerr << "rpc++: RpcRequest has invalid xdrproc_t (0) in out-Info"; + abort (); + } + if (res == 0 && outproc != (xdrproc_t)xdr_void) + { + svcerr_systemerr (xprt); + HandleError (); + } + else if (!svc_sendreply + (xprt, rpcreq->OutInfo()->Proc (), res)) + { + svcerr_systemerr (xprt); + HandleError (cantSendReply); + } + } +} + +void RpcService::Provide () +{ + int dtbsz = getdtablesize(); + fd_set readfds; + + quitLoop = FALSE; + while (! quitLoop) + { + readfds = svc_fdset; + switch(select (dtbsz, &readfds, 0, 0, 0)) + { + case -1: + if (errno != EBADF) + continue; + cerr << "PRC++: select: " << sys_errlist[errno] << '\n'; + return; + break; + case 0: + continue; + default: + svc_getreqset (&readfds); + break; + } + } +} + +char* RpcService::CallerName () +{ + struct sockaddr_in *sa = Caller (); + struct hostent* he = gethostbyaddr (&sa->sin_addr, sizeof (sa->sin_addr), + sa->sin_family); + return he->h_name; +} diff --git a/rpc++/stub.cc b/rpc++/stub.cc new file mode 100644 index 00000000000..38320d06a8a --- /dev/null +++ b/rpc++/stub.cc @@ -0,0 +1,207 @@ +// -*- c++ -*- +/* +Copyright (C) 1991 Peter Bersen + +This file is part of the rpc++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +Modified and partially rewritten March 1992 by Michael N. Lipp, +mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and +conditions apply without change to any modified or new parts. +*/ + +static char _rpcpp_stub_cc_[] += "stub.cc,v 2.3 1992/06/15 19:12:46 mnl Exp"; + +// stub.cc,v +// Revision 2.3 1992/06/15 19:12:46 mnl +// Fixed a few bugs, clarified interface. +// +// Revision 2.2 1992/06/13 14:27:04 mnl +// Adapted to (patched) gcc-2.2. Fixed several bugs. +// +// Revision 2.1.1.1 1992/03/08 13:28:42 mnl +// Initial mnl version. +// + +#ifdef __GNUG__ +#pragma implementation +#endif + +#include +#include +#include +#include "rpc++/stub.h" + +timeval RpcStub::defaultTimeout = { 25, 0 }; +void* RpcStub::res = 0; +size_t RpcStub::resmax = 0; +xdrproc_t RpcStub::resproc = 0; + +void RpcStub::init (u_long prog, u_long vers, + char* srv, timeval timo, bool connect) +{ + errorState = noError; + program = prog; + version = vers; + server = srv; + timeout = timo; + svc = 0; + if (connect) + Reconnect (); + else + errorState = notConnected; +} + +RpcStub::~RpcStub () +{ + if (resproc) // "Call" has been called at least once, + clnt_freeres (svc, resproc, res); // free any data allocated by clnt_call + if (svc) + clnt_destroy (svc); +} + +void* RpcStub::HandleError () +{ + switch (errorState) + { + case notConnected: + cerr << "rpc++: Stub has not been connected to server.\n"; + case cantCreate: + cerr << clnt_spcreateerror ("rpc++") << '\n'; + break; + case cantCall: + cerr << clnt_sperror (svc, "rpc++") << '\n'; + exit (1); + } + return 0; // suppress compiler warning +} + +void RpcStub::Reconnect () +{ + if (svc) + clnt_destroy (svc); + svc = clnt_create (server, program, version, "tcp"); // connect to client + if (svc == 0) // failed ? + { + HandleError (cantCreate); + errorState = notConnected; + return; + } + errorState = noError; +} + +void* RpcStub::Call (RpcRequest& req, void* in, bool handle_errors) +{ + void* args[] = { in }; + return DoCall (req, args, handle_errors); +} + +void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, bool handle_errors) +{ + void* args[] = { in0, in1 }; + return DoCall (req, args, handle_errors); +} + +void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2, + bool handle_errors) +{ + void* args[] = { in0, in1, in2 }; + return DoCall (req, args, handle_errors); +} + +void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2, + void* in3, bool handle_errors) +{ + void* args[] = { in0, in1, in2, in3 }; + return DoCall (req, args, handle_errors); +} + +void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2, + void* in3, void* in4, bool handle_errors) +{ + void* args[] = { in0, in1, in2, in3, in4 }; + return DoCall (req, args, handle_errors); +} + +void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2, + void* in3, void* in4, void* in5, bool handle_errors) +{ + void* args[] = { in0, in1, in2, in3, in4, in5 }; + return DoCall (req, args, handle_errors); +} + +void* RpcStub::Call (RpcRequest& req, void* in0, void* in1, void* in2, + void* in3, void* in4, void* in5, void* in6, + bool handle_errors) +{ + void* args[] = { in0, in1, in2, in3, in4, in5, in6 }; + return DoCall (req, args, handle_errors); +} + +void* RpcStub::Call (RpcRequest& req, void** ins, bool handle_errors) +{ + return DoCall (req, ins, handle_errors); +} + +void* RpcStub::DoCall (RpcRequest& req, void** args, bool handle_errors) +{ + static timeval nullTimeout = { 0, 0 }; + + if (! OK () ) + { + if (! handle_errors) + return 0; + return HandleError (); + } + if (resproc) // "Call" has been called previously, + clnt_freeres (svc, resproc, res); // free any data allocated by clnt_call + resproc = req.OutInfo()->Proc (); // current output deserializer + if (req.OutInfo()->Size () > resmax) // enough space for result? + { + delete res; // delete old result buffer + res = new char[resmax = req.OutInfo()->Size ()]; // get a new one + } + if (req.OutInfo()->Size () > 0 ) // preset result (everyone does it, why?) + memset (res, 0, req.OutInfo()->Size ()); + + XdrSeqInfo xsi = { req.InInfo (), args }; + if (req.Type () == RpcRequest::normal) + { + if (clnt_call (svc, req.RequestNumber (), // do call + Xdr::XdrParams, &xsi, + req.OutInfo()->Proc (), res, + timeout) != RPC_SUCCESS) + { + if (! handle_errors) + return 0; + return HandleError (cantCall); + } + return res; + } + + // req.Type () is batched or async + enum clnt_stat callres; + callres = clnt_call (svc, req.RequestNumber (), // do call + Xdr::XdrParams, &xsi, + (req.Type () == RpcRequest::batched + ? (xdrproc_t)0 : xdr_void), res, + nullTimeout); + if (callres != RPC_SUCCESS && callres != RPC_TIMEDOUT) + { + if (! handle_errors) + return 0; + return HandleError (cantCall); + } + return res; +} + diff --git a/rpc++/version.h b/rpc++/version.h new file mode 100644 index 00000000000..88a78665b13 --- /dev/null +++ b/rpc++/version.h @@ -0,0 +1,4 @@ +// version.h,v 2.2 1992/06/15 19:12:47 mnl Exp +#ifndef _RPCPLPL_VERSION_H_ +static char* version = "rpc++-library, version 2.2" +#endif diff --git a/rpc++/xdr++.cc b/rpc++/xdr++.cc new file mode 100644 index 00000000000..25f54d2e990 --- /dev/null +++ b/rpc++/xdr++.cc @@ -0,0 +1,75 @@ +// -*- c++ -*- +/* +Copyright (C) 1991 Peter Bersen + +This file is part of the rpc++ Library. This library is free +software; you can redistribute it and/or modify it under the terms of +the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your +option) any later version. This library is distributed in the hope +that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU Library General Public License for more details. +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +Modified and partially rewritten March 1992 by Michael N. Lipp, +mnl@dtro.e-technik.th-darmstadt.de. The original copyright terms and +conditions apply without change to any modified or new parts. +*/ + +static char _rpcpp_xdrpp_cc_[] += "xdr++.cc,v 2.3 1992/06/15 19:12:49 mnl Exp"; + +// xdr++.cc,v +// Revision 2.3 1992/06/15 19:12:49 mnl +// Fixed a few bugs, clarified interface. +// +// Revision 2.2 1992/06/13 14:27:06 mnl +// Adapted to (patched) gcc-2.2. Fixed several bugs. +// +// Revision 2.1.1.1 1992/03/08 13:28:42 mnl +// Initial mnl version. +// + +#ifdef __GNUG__ +#pragma implementation +#endif + +/* +** See Xdr.h. +*/ + +#include "rpc++/xdr++.h" + +XdrInfo Xdr::Xnull ((xdrproc_t)0, 0); +XdrInfo Xdr::Xchar ((xdrproc_t)xdr_char, sizeof (char)); +XdrInfo Xdr::Xshort ((xdrproc_t)xdr_short, sizeof (short)); +XdrInfo Xdr::Xint ((xdrproc_t)xdr_int, sizeof (int)); +XdrInfo Xdr::Xlong ((xdrproc_t)xdr_long, sizeof (long)); +XdrInfo Xdr::Xuchar ((xdrproc_t)xdr_u_char, sizeof (u_char)); +XdrInfo Xdr::Xushort ((xdrproc_t)xdr_u_short, sizeof (u_short)); +XdrInfo Xdr::Xuint ((xdrproc_t)xdr_u_int, sizeof (u_int)); +XdrInfo Xdr::Xulong ((xdrproc_t)xdr_u_long, sizeof (u_long)); +XdrInfo Xdr::Xfloat ((xdrproc_t)xdr_float, sizeof (float)); +XdrInfo Xdr::Xdouble ((xdrproc_t)xdr_double, sizeof (double)); + +XdrInfo Xdr::Xenum_t ((xdrproc_t)xdr_enum, sizeof (enum_t)); +XdrInfo Xdr::Xbool_t ((xdrproc_t)xdr_bool, sizeof (bool_t)); +XdrInfo Xdr::Xvoid ((xdrproc_t)xdr_void, 0); +XdrInfo Xdr::Xwrapstring ((xdrproc_t)xdr_wrapstring, sizeof (char*)); + +bool_t Xdr::XdrParams (XDR* xdrs, XdrSeqInfo* xsi) +{ + XdrInfo** infop = xsi->infos; + void** datap = xsi->data; + + while (*infop) + { + if (! (*infop->Proc ()) (xdrs, *datap)) + return FALSE; + infop++, datap++; + } + return TRUE; +} diff --git a/tests/Barrier_Test.cpp b/tests/Barrier_Test.cpp new file mode 100644 index 00000000000..44b7f871214 --- /dev/null +++ b/tests/Barrier_Test.cpp @@ -0,0 +1,98 @@ +// ============================================================================ +// @(#)Barrier_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Barrier_Test.cpp +// +// = DESCRIPTION +// This program illustrates how the ACE barrier synchronization +// mechanisms work. +// +// = AUTHOR +// Prashant Jain and Doug Schmidt +// +// ============================================================================ + +#include "ace/Log_Msg.h" +#include "ace/Synch.h" +#include "ace/Thread_Manager.h" +#include "ace/Service_Config.h" +#include "test_config.h" + +#if defined (ACE_HAS_THREADS) + +struct Tester_Args + // = TITLE + // These arguments are passed into each test thread. +{ + Tester_Args (ACE_Barrier &tb, int i) + : tester_barrier_ (tb), + n_iterations_ (i) {} + + ACE_Barrier &tester_barrier_; + // Reference to the tester barrier. This controls each miteration of + // the tester function running in every thread. + + int n_iterations_; + // Number of iterations to run. +}; + +// Iterate time printing off a message and "waiting" +// for all other threads to complete this iteration. + +static void * +tester (Tester_Args *args) +{ + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); // Insert thread into thread_manager + ACE_NEW_THREAD; + + for (int iterations = 1; + iterations <= args->n_iterations_; + iterations++) + { + ACE_DEBUG ((LM_DEBUG, "(%t) in iteration %d\n", iterations)); + + // Block until all other threads have waited, then continue. + args->tester_barrier_.wait (); + } + + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + + ACE_Service_Config daemon (argv[0]); + + int n_threads = ACE_MAX_THREADS; + int n_iterations = ACE_MAX_ITERATIONS; + + ACE_Barrier tester_barrier (n_threads); + + Tester_Args args (tester_barrier, n_iterations); + + if (ACE_Service_Config::thr_mgr ()->spawn_n + (n_threads, ACE_THR_FUNC (tester), + (void *) &args, THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn_n"), 1); + + // Wait for all the threads to reach their exit point. + ACE_Service_Config::thr_mgr ()->wait (); + + ACE_END_TEST; + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/tests/Buffer_Stream_Test.cpp b/tests/Buffer_Stream_Test.cpp new file mode 100644 index 00000000000..18bea9e3bc3 --- /dev/null +++ b/tests/Buffer_Stream_Test.cpp @@ -0,0 +1,234 @@ +// ============================================================================ +// @(#)Buffer_Stream_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Buffer_Stream_Test.cpp +// +// = DESCRIPTION +// This program illustrates an implementation of the classic +// "bounded buffer" program using an ASX STREAM containing two +// Modules. Each ACE_Module contains two Tasks. Each ACE_Task +// contains a ACE_Message_Queue and a pointer to a +// ACE_Thread_Manager. Note how the use of these reusable +// components reduces the reliance on global variables. +// +// = AUTHOR +// Prashant Jain and Doug Schmidt +// +// ============================================================================ + +#include "ace/Log_Msg.h" +#include "ace/Service_Config.h" +#include "ace/Synch.h" +#include "ace/Stream.h" +#include "ace/Module.h" +#include "ace/Task.h" +#include "test_config.h" + +#if defined (ACE_HAS_THREADS) + +typedef ACE_Stream MT_Stream; +typedef ACE_Module MT_Module; +typedef ACE_Task MT_Task; + +// Control groups of threads. +static ACE_Thread_Manager thread_manager; + +class Common_Task : public MT_Task + // = TITLE + // Methods that are common to the producer and consumer. +{ +public: + Common_Task (void) {} + // ACE_Task hooks + virtual int open (void * = 0); + virtual int close (u_long = 0); + virtual int put (ACE_Message_Block *, ACE_Time_Value * = 0) { return 0; } + + // ACE_Service_Object hooks + virtual int init (int, char **) { return 0; } + virtual int fini (void) { return 0; } + virtual int info (char **, size_t) const { return 0; } +}; + +// Define the Producer interface. + +class Producer : public Common_Task +{ +public: + Producer (void) {} + + // Read data from stdin and pass to consumer. + virtual int svc (void); +}; + +class Consumer : public Common_Task + // = TITLE + // Define the Consumer interface. +{ +public: + Consumer (void) {} + + // Enqueue the message on the ACE_Message_Queue for subsequent + // handling in the svc() method. + virtual int put (ACE_Message_Block *mb, ACE_Time_Value *tv = 0); + + // Receive message from producer and print to stdout. + virtual int svc (void); + +private: + + ACE_Time_Value timeout_; +}; + +// Spawn off a new thread. + +int +Common_Task::open (void *) +{ + if (this->activate (THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), -1); + return 0; +} + +int +Common_Task::close (u_long exit_status) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) thread is exiting with status %d in module %s\n", + exit_status, this->name ())); + + // Can do anything here that is required when a thread exits, e.g., + // storing thread-specific information in some other storage + // location, etc. + return 0; +} + +// The Producer reads data from the stdin stream, creates a message, +// and then queues the message in the message list, where it is +// removed by the consumer thread. A 0-sized message is enqueued when +// there is no more data to read. The consumer uses this as a flag to +// know when to exit. + +int +Producer::svc (void) +{ + ACE_NEW_THREAD; + + // Keep reading stdin, until we reach EOF. + for (char c = 'a'; c <= 'z'; c++) + { + // Allocate a new message. + char d[2]; + d[0] = c; + d[1] = '\0'; + + ACE_Message_Block *mb = new ACE_Message_Block (2); + ACE_OS::strcpy (mb->rd_ptr (), d); + + mb->wr_ptr (2); + + if (this->put_next (mb) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "put_next")); + } + + return 0; +} + +// Simply enqueue the Message_Block into the end of the queue. + +int +Consumer::put (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + return this->putq (mb, tv); +} + +// The consumer dequeues a message from the ACE_Message_Queue, writes +// the message to the stderr stream, and deletes the message. The +// Consumer sends a 0-sized message to inform the consumer to stop +// reading and exit. + +int +Consumer::svc (void) +{ + ACE_NEW_THREAD; + + ACE_Message_Block *mb = 0; + int result = 0; + char c = 'a'; + char *output; + + // Keep looping, reading a message out of the queue, until we + // timeout or get a message with a length == 0, which signals us to + // quit. + + for (;;) + { + this->timeout_.sec (ACE_OS::time (0) + 4); // Wait for upto 4 seconds + + if ((result = this->getq (mb, &this->timeout_)) == -1) + break; + + int length = mb->length (); + + if (length > 0) + { + output = mb->rd_ptr (); + ACE_ASSERT (c == output[0]); + c++; + } + delete mb; + + if (length == 0) + { + break; + } + } + + ACE_ASSERT (result == -1 && errno == EWOULDBLOCK); + return 0; +} + +// Main driver function. + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + + ACE_Service_Config daemon (argv[0]); + + // Control hierachically-related active objects + MT_Stream stream; + MT_Module *cm = new MT_Module ("Consumer", new Consumer); + MT_Module *pm = new MT_Module ("Producer", new Producer); + + // Create Producer and Consumer Modules and push them onto the + // STREAM. All processing is performed in the STREAM. + + if (stream.push (cm) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push"), 1); + else if (stream.push (pm) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push"), 1); + + // Barrier synchronization: wait for the threads to exit, then exit + // ourselves. + ACE_Service_Config::thr_mgr ()->wait (); + + ACE_END_TEST; + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ + + + diff --git a/tests/CPP_Test.cpp b/tests/CPP_Test.cpp new file mode 100644 index 00000000000..59c02cded6c --- /dev/null +++ b/tests/CPP_Test.cpp @@ -0,0 +1,263 @@ +// ============================================================================ +// @(#)CPP_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// CPP_Test.cpp +// +// = DESCRIPTION +// This is a simple test of the ACE_SOCK_Acceptor and +// AC_SOCK_Connector classes. The test forks two processes or +// spawns two threads (depending upon the platform) and then executes +// client and server allowing them to connect and exchange +// data. No user input is required as far as command line +// arguments are concerned. +// +// = AUTHOR +// Prashant Jain and Doug Schmidt +// +// ============================================================================ + +#include "ace/OS.h" +#include "ace/Thread.h" +#include "ace/Thread_Manager.h" +#include "ace/SOCK_Connector.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/SOCK_Stream.h" +#include "ace/INET_Addr.h" +#include "ace/Handle_Set.h" +#include "test_config.h" + +static char *host = ACE_DEFAULT_SERVER_HOST; +static u_short port = ACE_DEFAULT_SERVER_PORT; +static int timeout = ACE_DEFAULT_TIMEOUT; +// Global thread manager. +static ACE_Thread_Manager thr_mgr; + +static void * +client (void *dummy) +{ +#if defined (ACE_WIN32) + // Insert thread into thr_mgr + ACE_Thread_Control thread_control (&thr_mgr); + ACE_NEW_THREAD; +#endif + + char buf[BUFSIZ]; + + ACE_SOCK_Stream cli_stream; + ACE_INET_Addr remote_addr (port, host); + ACE_SOCK_Connector con; + + ACE_DEBUG ((LM_DEBUG, "starting non-blocking connect\n")); + // Initiate timed, non-blocking connection with server. + ACE_OS::sleep (3); + + // Attempt a non-blocking connect to the server, reusing the local + // addr if necessary. + if (con.connect (cli_stream, remote_addr, + (ACE_Time_Value *) &ACE_Time_Value::zero) == -1) + { + if (errno != EWOULDBLOCK) + ACE_ERROR ((LM_ERROR, "%p\n", "connection failed")); + + ACE_DEBUG ((LM_DEBUG, "starting timed connect\n")); + + // Check if non-blocking connection is in progress, + // and wait up to timeout seconds for it to complete. + ACE_Time_Value tv (timeout); + + if (con.complete (cli_stream, &remote_addr, &tv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "connection failed")); + else + ACE_DEBUG ((LM_DEBUG, "connected to %s\n", remote_addr.get_host_name ())); + } + + if (cli_stream.disable (ACE_NONBLOCK) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "disable")); + + // Send data to server (correctly handles "incomplete writes"). + + for (char c = 'a'; c <= 'z'; c++) + if (cli_stream.send_n (&c, 1) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "send_n")); + + // Explicitly close the writer-side of the connection. + if (cli_stream.close_writer () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "close_writer")); + + // Wait for handshake with server. + if (cli_stream.recv_n (buf, 1) != 1) + ACE_ERROR ((LM_ERROR, "%p\n", "recv_n")); + + // Close the connection completely. + if (cli_stream.close () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "close")); + +#if !defined (ACE_WIN32) + ACE_OS::exit (0); +#endif + return 0; +} + +static void * +server (void *dummy) +{ +#if defined (ACE_WIN32) + // Insert thread into thr_mgr + ACE_Thread_Control thread_control (&thr_mgr); + ACE_NEW_THREAD; +#endif + ACE_SOCK_Acceptor peer_acceptor; + + // Create a server address. + ACE_INET_Addr server_addr (port); + + // Create a server, reuse the address. + if (peer_acceptor.open (server_addr, 1) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "open")); + else if (peer_acceptor.enable (ACE_NONBLOCK) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "enable")); + else if (peer_acceptor.get_local_addr (server_addr) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "get_local_addr")); + + ACE_DEBUG ((LM_DEBUG, "starting server at port %d\n", + server_addr.get_port_number ())); + + // Keep these objects out here to prevent excessive constructor calls... + ACE_SOCK_Stream new_stream; + ACE_INET_Addr cli_addr; + ACE_Handle_Set handle_set; + ACE_Time_Value tv (timeout); + // Performs the iterative server activities. + + for (;;) + { + char buf[BUFSIZ]; + int result = 0; + char t = 'a'; + + handle_set.reset (); + handle_set.set_bit (peer_acceptor.get_handle ()); + + if ((result = ACE_OS::select (int (peer_acceptor.get_handle ()) + 1, + handle_set, + 0, 0, &tv)) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "select")); + else if (result == 0) + { + ACE_DEBUG ((LM_DEBUG, "select timed out\n")); + continue; + } + + // Create a new ACE_SOCK_Stream endpoint (note automatic restart + // if errno == EINTR). + + while ((result = peer_acceptor.accept (new_stream, &cli_addr)) != -1) + { + ACE_DEBUG ((LM_DEBUG, "client %s connected from %d\n", + cli_addr.get_host_name (), cli_addr.get_port_number ())); + + // Enable non-blocking I/O. + if (new_stream.enable (ACE_NONBLOCK) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "enable")); + + handle_set.reset (); + handle_set.set_bit (new_stream.get_handle ()); + + // Read data from client (terminate on error). + + for (ssize_t r_bytes; ;) + { + if (ACE_OS::select (int (new_stream.get_handle ()) + 1, + handle_set, + 0, 0, 0) == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "select")); + ACE_OS::exit (1); + } + + while ((r_bytes = new_stream.recv_n (buf, 1)) > 0) + { + ACE_ASSERT (t == buf[0]); + t++; + } + + if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, "reached end of input, connection closed by client\n")); + return 0; + } + else if (r_bytes == -1) + { + if (errno == EWOULDBLOCK) + ACE_DEBUG ((LM_DEBUG, "no input available, going back to reading\n")); + else + ACE_ERROR ((LM_ERROR, "%p\n", "ACE::write")); + } + + if (new_stream.send_n ("", 1) != 1) + ACE_ERROR ((LM_ERROR, "%p\n", "send_n")); + } + + // Close new endpoint (listening endpoint stays open). + if (new_stream.close () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "close")); + } + + if (result == -1) + { + if (errno == EWOULDBLOCK) + ACE_DEBUG ((LM_DEBUG, "no connections available, going back to accepting\n")); + else + ACE_ERROR ((LM_ERROR, "%p\n", "ACE::write")); + } + } + return 0; +} + +void +spawn () +{ +#if !defined (ACE_WIN32) + switch (ACE_OS::fork ()) + { + case -1: + ACE_ERROR ((LM_ERROR, "%p\n%a", "fork failed")); + exit (-1); + case 0: + client (0); + default: + server (0); + } +#elif defined (ACE_HAS_THREADS) + if (thr_mgr.spawn (ACE_THR_FUNC (client), + (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "thread create failed")); + + if (thr_mgr.spawn (ACE_THR_FUNC (server), + (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "thread create failed")); + thr_mgr.wait (); +#else + ACE_ERROR ((LM_ERROR, "only one thread may be run in a process on this platform\n%a", 1)); +#endif /* ACE_HAS_THREADS */ +} + +int +main (int, char *argv[]) +{ + ACE_START_TEST; + ACE_DEBUG ((LM_DEBUG, "starting %s test at %u\n", argv[0], ACE_OS::time (0))); + + spawn (); + + ACE_END_TEST; + return 0; +} + diff --git a/tests/Future_Test.cpp b/tests/Future_Test.cpp new file mode 100644 index 00000000000..ec4b9ee70f7 --- /dev/null +++ b/tests/Future_Test.cpp @@ -0,0 +1,427 @@ +// ============================================================================ +// @(#)Future_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Future_Test.cpp +// +// = DESCRIPTION +// This example tests the ACE Future. +// +// = AUTHOR +// Andres Kruse and Douglas C. Schmidt +// +// +// ============================================================================ + +#include +#include "ace/Task.h" +#include "ace/Log_Msg.h" +#include "ace/Synch.h" +#include "ace/Message_Queue.h" +#include "ace/Future.h" +#include "ace/Method_Object.h" +#include "ace/Activation_Queue.h" +#include "ace/Auto_Ptr.h" +#include "test_config.h" + +#if defined (ACE_HAS_THREADS) + +typedef ACE_Atomic_Op ATOMIC_INT; + +// a counter for the tasks.. +static ATOMIC_INT task_count (0); + +// a counter for the futures.. +static ATOMIC_INT future_count (0); +static ATOMIC_INT future_no (0); + +// a counter for the capsules.. +static ATOMIC_INT capsule_count (0); +static ATOMIC_INT capsule_no (0); + +// a counter for the method objects... +static ATOMIC_INT methodobject_count (0); +static ATOMIC_INT methodobject_no (0); + +class Scheduler : public ACE_Task + // = TITLE + // Active Object Scheduler. +{ + friend class Method_ObjectWork; +public: + Scheduler (const char *, Scheduler * = 0); + ~Scheduler (void); + + virtual int open (void *args = 0); + virtual int close (u_long flags = 0); + virtual int put (ACE_Message_Block *mb, ACE_Time_Value *tv = 0); + virtual int svc (void); + + ACE_Future work (double param, int count); + ACE_Future name (void); + void end (void); + + double work_i (double, int); + const char *name_i (void); + +private: + const char *name_; + ACE_Activation_Queue activation_queue_; + Scheduler *scheduler_; + +}; + +class Method_Object_work : public ACE_Method_Object + // = TITLE + // Reification of the method. +{ +public: + Method_Object_work (Scheduler *, double, int, ACE_Future &); + ~Method_Object_work (void); + virtual int call (void); + +private: + Scheduler *scheduler_; + double param_; + int count_; + ACE_Future future_result_; +}; + +Method_Object_work::Method_Object_work (Scheduler* new_Scheduler, + double new_param, + int new_count, + ACE_Future &new_result) + : scheduler_ (new_Scheduler), + param_ (new_param), + count_ (new_count), + future_result_ (new_result) +{ + ACE_DEBUG ((LM_DEBUG, + "(%t) Method_Object_work created\n")); +} + +Method_Object_work::~Method_Object_work (void) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) Method_Object_work will be deleted.\n")); +} + + +int +Method_Object_work::call (void) +{ + return this->future_result_.set (this->scheduler_->work_i (this->param_, this->count_)); +} + +class Method_Object_name : public ACE_Method_Object + // = TITLE + // Reification of the method. +{ +public: + Method_Object_name (Scheduler *, ACE_Future &); + ~Method_Object_name (void); + virtual int call (void); + +private: + Scheduler *scheduler_; + ACE_Future future_result_; +}; + +Method_Object_name::Method_Object_name (Scheduler *new_scheduler, + ACE_Future &new_result) + : scheduler_ (new_scheduler), + future_result_ (new_result) +{ + ACE_DEBUG ((LM_DEBUG, + "(%t) Method_Object_name created\n")); +}; + +Method_Object_name::~Method_Object_name (void) +{ + ACE_DEBUG ((LM_DEBUG, + "(%t) Method_Object_name will be deleted.\n")); +} + +int +Method_Object_name::call (void) +{ + return future_result_.set (scheduler_->name_i ()); +} + +class Method_Object_end : public ACE_Method_Object + // = TITLE + // Reification of the method. +{ +public: + Method_Object_end (Scheduler *new_Scheduler): scheduler_ (new_Scheduler) {} + ~Method_Object_end (void) {} + virtual int call (void) { this->scheduler_->close (); return -1; } + +private: + Scheduler *scheduler_; +}; + +// constructor +Scheduler::Scheduler (const char *newname, Scheduler *new_Scheduler) +{ + ACE_NEW (this->name_, char[ACE_OS::strlen (newname) + 1]); + ACE_OS::strcpy ((char *) this->name_, newname); + this->scheduler_ = new_Scheduler; + ACE_DEBUG ((LM_DEBUG, "(%t) Scheduler %s created\n", this->name_)); +} + +// Destructor +Scheduler::~Scheduler (void) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) Scheduler %s will be destroyed\n", this->name_)); +} + +// open +int +Scheduler::open (void *args) +{ + task_count++; + ACE_DEBUG ((LM_DEBUG, "(%t) Scheduler %s open\n", this->name_)); + return this->activate (THR_BOUND); +} + +// close +int +Scheduler::close (u_long flags) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) Scheduler %s close\n", this->name_)); + task_count--; + return 0; +} + +// put... ?? +int +Scheduler::put (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + return 0; +} + +// service.. +int +Scheduler::svc (void) +{ + ACE_NEW_THREAD; + + for (;;) + { + // Dequeue the next method object (we use an auto pointer in + // case an exception is thrown in the ). + auto_ptr mo (this->activation_queue_.dequeue ()); + + ACE_DEBUG ((LM_DEBUG, "(%t) calling method object\n")); + // Call it. + if (mo->call () == -1) + break; + // Destructor automatically deletes it. + } + + /* NOTREACHED */ + return 0; +} + +void +Scheduler::end (void) +{ + this->activation_queue_.enqueue (new Method_Object_end (this)); +} + + +// Here's where the Work takes place. +double +Scheduler::work_i (double param, + int count) +{ + double x = 0, y = 0; + + // @@ We should probably do something fun here, like compute the + // Fibonacci sequence or something. + + for (int j = 0; j < count; j++) + { + x = x + param; + y = y + ::sin (x); + } + + return y; +} + +const char * +Scheduler::name_i (void) +{ + char *the_name; + + the_name = new char[ACE_OS::strlen (this->name_) + 1]; + ACE_OS::strcpy (the_name, this->name_); + + return the_name; +} + +ACE_Future +Scheduler::name (void) +{ + if (this->scheduler_) + // Delegate to the Scheduler. + return this->scheduler_->name (); + else + { + ACE_Future new_future; + + // @@ What happens if new fails here? + this->activation_queue_.enqueue + (new Method_Object_name (this, new_future)); + + return new_future; + } +} + +ACE_Future +Scheduler::work (double newparam, int newcount) +{ + if (this->scheduler_) { + return this->scheduler_->work (newparam, newcount); + } + else { + ACE_Future new_future; + + this->activation_queue_.enqueue + (new Method_Object_work (this, newparam, newcount, new_future)); + return new_future; + } +} + +// @@ These values should be set by the command line options! + +// Total number of iterations to +static int n_iterations = 50000; + +// Total number of loops. +static int n_loops = 100; + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + + Scheduler *andres, *peter, *helmut, *matias; + + // Create active objects.. + // @@ Should "open" be subsumed within the constructor of + // Scheduler()? + andres = new Scheduler ("andres"); + andres->open (); + peter = new Scheduler ("peter"); + peter->open (); + helmut = new Scheduler ("helmut"); + helmut->open (); + + // Matias passes all asynchronous method calls on to Andres... + matias = new Scheduler ("matias", andres); + matias->open (); + + for (int i = 0; i < n_loops; i++) + { + { + ACE_Future fresulta, fresultb, fresultc, fresultd, fresulte; + ACE_Future fname; + + ACE_DEBUG ((LM_DEBUG, "(%t) going to do a non-blocking call\n")); + + fresulta = andres->work (0.01, 100 + (n_iterations * (i % 2))); + fresultb = peter->work (0.01, 100 + (n_iterations * (i % 2))); + fresultc = helmut->work (0.01, 100 + (n_iterations * (i % 2))); + fresultd = matias->work (0.02, 100 + (n_iterations * (i % 2))); + fname = andres->name (); + + // see if the result is available... + if (fresulta.ready ()) + ACE_DEBUG ((LM_DEBUG, "(%t) wow.. work is ready.....\n")); + + ACE_DEBUG ((LM_DEBUG, "(%t) non-blocking call done... now blocking...\n")); + + // Save the result of fresulta. + + fresulte = fresulta; + + if (i % 3 == 0) + { + // Every 3rd time... disconnect the futures... + // but "fresulte" should still contain the result... + fresulta.cancel (10.0); + fresultb.cancel (20.0); + fresultc.cancel (30.0); + fresultd.cancel (40.0); + } + + double resulta = 0, resultb = 0, resultc = 0, resultd = 0, resulte = 0; + + fresulta.get (resulta); + fresultb.get (resultb); + fresultc.get (resultc); + fresultd.get (resultd); + fresulte.get (resulte); + + ACE_DEBUG ((LM_DEBUG, "(%t) result a %f\n", resulte)); + ACE_DEBUG ((LM_DEBUG, "(%t) result b %f\n", resulta)); + ACE_DEBUG ((LM_DEBUG, "(%t) result c %f\n", resultb)); + ACE_DEBUG ((LM_DEBUG, "(%t) result d %f\n", resultc)); + ACE_DEBUG ((LM_DEBUG, "(%t) result e %f\n", resultd)); + + const char *name; + + fname.get (name); + + ACE_DEBUG ((LM_DEBUG, "(%t) name %s\n", name)); + + } + + ACE_DEBUG ((LM_DEBUG, + "(%t) task_count %d future_count %d capsule_count %d methodobject_count %d\n", + (u_long) task_count, + (u_long) future_count, + (u_long) capsule_count, + (u_long) methodobject_count)); + } + + // Close things down. + andres->end (); + peter->end (); + helmut->end (); + matias->end (); + + ACE_OS::sleep (2); + + ACE_DEBUG ((LM_DEBUG, + "(%t) task_count %d future_count %d capsule_count %d methodobject_count %d\n", + (u_long) task_count, + (u_long) future_count, + (u_long) capsule_count, + (u_long) methodobject_count)); + + ACE_DEBUG ((LM_DEBUG,"(%t) th' that's all folks!\n")); + + ACE_OS::sleep (5); + ACE_END_TEST; + + return 0; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Atomic_Op; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ + +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/tests/Handle_Set_Test.cpp b/tests/Handle_Set_Test.cpp new file mode 100644 index 00000000000..fec448d65c3 --- /dev/null +++ b/tests/Handle_Set_Test.cpp @@ -0,0 +1,78 @@ +// ============================================================================ +// @(#)Handle_Set_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Handle_Set_Test.cpp +// +// = DESCRIPTION +// This test illustrates the use of ACE_Handle_Set to maintain a +// set of handles. No command line arguments are needed to run +// the test. +// +// = AUTHOR +// Prashant Jain +// +// ============================================================================ + +#include "ace/Log_Msg.h" +#include "ace/Handle_Set.h" +#include "test_config.h" + +#define IS_ODD(X) (((X) & 1) != 0) + +void +run_test (int count) +{ + int duplicates = 0; + int sets = 0; + int clears = 0; + + ACE_Handle_Set handle_set; + + ACE_OS::srand (ACE_OS::time (0L)); + + for (int i = 0; i < count; i++) + { + int i = int (ACE_OS::rand () % ACE_Handle_Set::MAXSIZE); + + if (IS_ODD (i)) + { + if (handle_set.is_set ((ACE_HANDLE) i)) + duplicates++; + + handle_set.set_bit ((ACE_HANDLE) i); + sets++; + } + else + { + if (handle_set.is_set ((ACE_HANDLE) i)) + duplicates--; + + handle_set.clr_bit ((ACE_HANDLE) i); + clears++; + } + } + + ACE_ASSERT (count == sets + clears); + ACE_ASSERT (handle_set.num_set () + duplicates == sets); + +// ACE_DEBUG ((LM_DEBUG, "count = %d, set_size = %d, duplicates = %d\n", +// count, handle_set.num_set (), (sets - clears) == duplicates)); +} + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + + int count = argc > 1 ? ACE_OS::atoi (argv[1]) : ACE_Handle_Set::MAXSIZE; + run_test (count); + + ACE_END_TEST; + return 0; +} + diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 00000000000..784aa48a0b6 --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,1105 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for all the ACE ``one-button' tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = Barrier_Test \ + Buffer_Stream_Test \ + CPP_Test \ + Future_Test \ + Handle_Set_Test \ + Mem_Map_Test \ + Mutex_Test \ + Naming_Test \ + Priority_Buffer_Test \ + Reactors_Test \ + Reactor_Timer_Test \ + Reader_Writer_Test \ + Recursive_Mutex_Test \ + Shared_Memory_MM_Test \ + Shared_Memory_SV_Test \ + SPIPE_Test \ + SString_Test \ + SV_Shared_Memory_Test \ + Task_Test \ + Thread_Manager_Test \ + Thread_Pool_Test \ + Time_Service_Test \ + Time_Value_Test \ + Timer_Queue_Test \ + Tokens_Test \ + TSS_Test \ + UPIPE_SAP_Test + +CFLAGS += -I. +LIBS += -lm + +LSRC = $(addsuffix .cpp,$(BIN)) +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/Barrier_Test.o .shobj/Barrier_Test.so: Barrier_Test.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + test_config.h +.obj/Buffer_Stream_Test.o .shobj/Buffer_Stream_Test.so: Buffer_Stream_Test.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + test_config.h +.obj/CPP_Test.o .shobj/CPP_Test.so: CPP_Test.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + test_config.h +.obj/Future_Test.o .shobj/Future_Test.so: Future_Test.cpp \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Future.h \ + $(WRAPPER_ROOT)/ace/Method_Object.h \ + $(WRAPPER_ROOT)/ace/Activation_Queue.h \ + $(WRAPPER_ROOT)/ace/Auto_Ptr.h \ + test_config.h +.obj/Handle_Set_Test.o .shobj/Handle_Set_Test.so: Handle_Set_Test.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + test_config.h +.obj/Mem_Map_Test.o .shobj/Mem_Map_Test.so: Mem_Map_Test.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + test_config.h +.obj/Mutex_Test.o .shobj/Mutex_Test.so: Mutex_Test.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + test_config.h +.obj/Naming_Test.o .shobj/Naming_Test.so: Naming_Test.cpp \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Naming_Context.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Name_Proxy.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Name_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Name_Space.h \ + test_config.h +.obj/Priority_Buffer_Test.o .shobj/Priority_Buffer_Test.so: Priority_Buffer_Test.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + test_config.h +.obj/Reactors_Test.o .shobj/Reactors_Test.so: Reactors_Test.cpp \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + test_config.h +.obj/Reactor_Timer_Test.o .shobj/Reactor_Timer_Test.so: Reactor_Timer_Test.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + test_config.h +.obj/Reader_Writer_Test.o .shobj/Reader_Writer_Test.so: Reader_Writer_Test.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + test_config.h +.obj/Recursive_Mutex_Test.o .shobj/Recursive_Mutex_Test.so: Recursive_Mutex_Test.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + test_config.h +.obj/Shared_Memory_MM_Test.o .shobj/Shared_Memory_MM_Test.so: Shared_Memory_MM_Test.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Shared_Memory_MM.h \ + $(WRAPPER_ROOT)/ace/Shared_Memory.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + test_config.h +.obj/Shared_Memory_SV_Test.o .shobj/Shared_Memory_SV_Test.so: Shared_Memory_SV_Test.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Shared_Memory_SV.h \ + $(WRAPPER_ROOT)/ace/Shared_Memory.h \ + $(WRAPPER_ROOT)/ace/SV_Shared_Memory.h \ + test_config.h +.obj/SPIPE_Test.o .shobj/SPIPE_Test.so: SPIPE_Test.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Connector.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Connector.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Acceptor.h \ + test_config.h +.obj/SString_Test.o .shobj/SString_Test.so: SString_Test.cpp \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + test_config.h +.obj/SV_Shared_Memory_Test.o .shobj/SV_Shared_Memory_Test.so: SV_Shared_Memory_Test.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/SV_Shared_Memory.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + test_config.h +.obj/Task_Test.o .shobj/Task_Test.so: Task_Test.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + test_config.h +.obj/Thread_Manager_Test.o .shobj/Thread_Manager_Test.so: Thread_Manager_Test.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + test_config.h +.obj/Thread_Pool_Test.o .shobj/Thread_Pool_Test.so: Thread_Pool_Test.cpp \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + test_config.h +.obj/Time_Service_Test.o .shobj/Time_Service_Test.so: Time_Service_Test.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + test_config.h \ + $(WRAPPER_ROOT)/ace/Process.h \ + $(WRAPPER_ROOT)/ace/ARGV.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h +.obj/Time_Value_Test.o .shobj/Time_Value_Test.so: Time_Value_Test.cpp \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + test_config.h +.obj/Timer_Queue_Test.o .shobj/Timer_Queue_Test.so: Timer_Queue_Test.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + test_config.h +.obj/Tokens_Test.o .shobj/Tokens_Test.so: Tokens_Test.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Process.h \ + $(WRAPPER_ROOT)/ace/ARGV.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Stack.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Token_Collection.h \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/Remote_Tokens.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Token_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Token_Invariants.h \ + test_config.h +.obj/TSS_Test.o .shobj/TSS_Test.so: TSS_Test.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + test_config.h +.obj/UPIPE_SAP_Test.o .shobj/UPIPE_SAP_Test.so: UPIPE_SAP_Test.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Stream.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Module.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/UPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/UPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Addr.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.h \ + $(WRAPPER_ROOT)/ace/SPIPE_Stream.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Acceptor.i \ + $(WRAPPER_ROOT)/ace/UPIPE_Connector.h \ + $(WRAPPER_ROOT)/ace/UPIPE_Connector.i \ + test_config.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/tests/Mem_Map_Test.cpp b/tests/Mem_Map_Test.cpp new file mode 100644 index 00000000000..d55b1806ddd --- /dev/null +++ b/tests/Mem_Map_Test.cpp @@ -0,0 +1,157 @@ +// ============================================================================ +// @(#)Mem_Map_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Mem_Map_Test.cpp +// +// = DESCRIPTION +// This test illustrates the use of ACE_Mem_Map to reverse a +// file. The test first creates a dummy file for testing, then +// reverses the file and then reverses it again to get back the +// original file. +// +// = AUTHOR +// Prashant Jain +// +// ============================================================================ + +#include "ace/Log_Msg.h" +#include "ace/Mem_Map.h" +#include "test_config.h" + +static int size = 10; +static int num_lines = 15; + +static void +reverse_file (ACE_HANDLE file_handle, + char *array, + int size) +{ + int count = 0; + size--; + + if (array[size] == '\0') + array[size] = '\n'; + + while (--size >= 0) + { + if (array[size] == '\n') + { + ACE_OS::write (file_handle, array + size + 1, count); + ACE_OS::write (file_handle, "\n", 1); + count = 0; + } + else + count++; + } + ACE_OS::write (file_handle, array, count+1); +} + +int +create_test_file () +{ + ACE_HANDLE file_handle; + char *mybuf = new char[size+1]; + char c = 'a'; + char d = c; + + if ((file_handle = ACE_OS::open (ACE_DEFAULT_TEST_FILE, + O_RDWR | O_CREAT | O_TRUNC, + 0666)) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "Open failed\n"), -1); + + for (int j = 0; j < num_lines; j++) + { + for (int i = 0; i < size; i++) + { + mybuf[i] = c; + c++; + } + mybuf[size] = '\0'; + c = ++d; + if (ACE_OS::write (file_handle, mybuf, size) != size) + ACE_ERROR_RETURN ((LM_ERROR, "write to file failed\n"), -1); + + if (ACE_OS::write (file_handle, "\n", 1) != 1) + ACE_ERROR_RETURN ((LM_ERROR, "write to file failed\n"), -1); + } + + ACE_OS::close (file_handle); + return 0; +} + +int +main (int argc, char **argv) +{ + ACE_START_TEST; + + ACE_LOG_MSG->open (argv[0]); + + ACE_HANDLE temp_file_handle; + + // First create a test file to work on + if (create_test_file () != 0) + ACE_ERROR_RETURN ((LM_ERROR, "Create test file failed\n"), -1); + + ACE_Mem_Map mmap; + + // First memory map the test file + if (mmap.map (ACE_DEFAULT_TEST_FILE) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n%a", "mmap"), -1); + + // Now create a temporary file for intermediate processing + if ((temp_file_handle = ACE_OS::open (ACE_TEMP_FILE_NAME, + O_RDWR | O_TRUNC | O_CREAT, + 0666)) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "Open failed\n"), -1); + + // Reverse the original file and write the output to the temporary + // file + reverse_file (temp_file_handle, + (char *) mmap.addr (), + mmap.size ()); + + ACE_OS::close (temp_file_handle); + + ACE_Mem_Map temp_mmap; + + // Now memory map the temporary file + if (temp_mmap.map (ACE_TEMP_FILE_NAME) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n%a", "mmap"), -1); + + char temp_file_name[BUFSIZ]; + + // Create another temporary file that would hold the output of + // reversing the first temporary file + ACE_OS::sprintf (temp_file_name, "%s%s", ACE_TEMP_FILE_NAME, "2"); + if ((temp_file_handle = ACE_OS::open (temp_file_name, + O_RDWR | O_TRUNC | O_CREAT, + 0666)) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "Open failed\n"), -1); + + // Now reverse the temporary file and write everything to the second + // temporary file + reverse_file (temp_file_handle, + (char *) temp_mmap.addr (), + temp_mmap.size ()); + + ACE_OS::close (temp_file_handle); + + // Memory map the second temporary file + ACE_Mem_Map temp_mmap2; + if (temp_mmap2.map (temp_file_name) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n%a", "mmap"), -1); + + // Now do a memcmp -- the orig file and the second temporary file + // should be identical. + ACE_ASSERT (ACE_OS::memcmp (temp_mmap2.addr (), + mmap.addr (), + mmap.size ()) == 0); + + ACE_END_TEST; + return 0; +} diff --git a/tests/Mutex_Test.cpp b/tests/Mutex_Test.cpp new file mode 100644 index 00000000000..2f172b6917e --- /dev/null +++ b/tests/Mutex_Test.cpp @@ -0,0 +1,48 @@ +// ============================================================================ +// @(#)Mutex_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Mutex_Test.cpp +// +// = DESCRIPTION +// This is a simple test to illustrate the functionality of +// ACE_Process_Mutex. The test acquires and releases mutexes. No +// command line arguments are needed to run the test. +// +// = AUTHOR +// Prashant Jain and Doug Schmidt +// +// ============================================================================ + +#include "ace/Synch.h" +#include "ace/Log_Msg.h" +#include "test_config.h" + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + + char *name = argc == 1 ? "hello" : argv[1]; + + ACE_Process_Mutex pm (name); + + for (int i = 0; i < ACE_MAX_ITERATIONS; i++) + { + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = trying to acquire\n")); + ACE_ASSERT (pm.acquire () == 0); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = acquired\n")); + + ACE_OS::sleep (5); + + ACE_ASSERT (pm.release () == 0); + ACE_DEBUG ((LM_DEBUG, "(%P|%t) = released\n")); + } + ACE_END_TEST; + return 0; +} + diff --git a/tests/Naming_Test.cpp b/tests/Naming_Test.cpp new file mode 100644 index 00000000000..232f11af216 --- /dev/null +++ b/tests/Naming_Test.cpp @@ -0,0 +1,146 @@ +// ============================================================================ +// @(#)Naming_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Naming_Test.cpp +// +// = DESCRIPTION +// This is a test to illustrate the Naming Services. The test +// does binds, rebinds, finds, and unbinds on name bindings using +// the local naming context. +// +// = AUTHOR +// Prashant Jain +// +// ============================================================================ + +#include "ace/SString.h" +#include "ace/Naming_Context.h" +#include "test_config.h" + +static char name[BUFSIZ]; +static char value[BUFSIZ]; +static char type[BUFSIZ]; + +void +bind (ACE_Naming_Context *ns_context, int result) +{ + // do the binds + for (int i = 1; i <= ACE_NS_MAX_ENTRIES; i++) + { + sprintf (name, "%s%d", "name", i); + ACE_WString w_name (name); + + sprintf (value, "%s%d", "value", i); + ACE_WString w_value (value); + + sprintf (type, "%s%d", "type", i); + ACE_ASSERT (ns_context->bind (w_name, w_value, type) == result); + } +} + +void +rebind (ACE_Naming_Context *ns_context, int result) +{ + // do the rebinds + for (int i = 1; i <= ACE_NS_MAX_ENTRIES; i++) + { + sprintf (name, "%s%d", "name", i); + ACE_WString w_name (name); + sprintf (value, "%s%d", "value", -i); + ACE_WString w_value (value); + sprintf (type, "%s%d", "type", -i); + ACE_ASSERT (ns_context->rebind (w_name, w_value, type) == result); + } +} + +void +unbind (ACE_Naming_Context *ns_context, int result) +{ + // do the unbinds + for (int i = 1; i <= ACE_NS_MAX_ENTRIES; i++) + { + sprintf (name, "%s%d", "name", i); + ACE_WString w_name (name); + ACE_ASSERT (ns_context->unbind (w_name) == result); + } +} + +void +find (ACE_Naming_Context *ns_context, int sign, int result) +{ + char temp_val[BUFSIZ]; + char temp_type[BUFSIZ]; + + // do the finds + for (int i = 1; i <= ACE_NS_MAX_ENTRIES; i++) + { + sprintf (name, "%s%d", "name", i); + ACE_WString w_name (name); + + ACE_WString w_value; + char *type_out; + + if (sign == 1) + { + sprintf (temp_val, "%s%d", "value", i); + sprintf (temp_type, "%s%d", "type", i); + } + else + { + sprintf (temp_val, "%s%d", "value", -i); + sprintf (temp_type, "%s%d", "type", -i); + } + + ACE_WString val (temp_val); + + ACE_ASSERT (ns_context->resolve (w_name, w_value, type_out) == result); + if (w_value.char_rep ()) + { + ACE_ASSERT (w_value == val); + cerr << "Name: " << name << "\tValue: " << w_value.char_rep () << "\tType: " << type_out << endl; + if (type_out) + { + ACE_ASSERT (::strcmp (type_out, temp_type) == 0); + delete[] type_out; + } + } + } +} + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + + ACE_Naming_Context *ns_context = new ACE_Naming_Context (); + ACE_Name_Options *name_options = ns_context->name_options (); + name_options->parse_args (argc, argv); + name_options->database (ACE::basename (name_options->process_name (), + ACE_DIRECTORY_SEPARATOR_CHAR)); + ns_context->open (ACE_Naming_Context::PROC_LOCAL); + + // Add some bindings to the database + bind (ns_context, 0); + rebind (ns_context, 1); + bind (ns_context, 1); + bind (ns_context, 1); + rebind (ns_context, 1); + + // Remove all bindings from database + unbind (ns_context, 0); + + rebind (ns_context, 0); + unbind (ns_context, 0); + + // No more bindings in database so find should return -1 + find (ns_context, -1, -1); + + ACE_END_TEST; + return 0; +} + diff --git a/tests/Priority_Buffer_Test.cpp b/tests/Priority_Buffer_Test.cpp new file mode 100644 index 00000000000..1b117a4de9a --- /dev/null +++ b/tests/Priority_Buffer_Test.cpp @@ -0,0 +1,158 @@ +// ============================================================================ +// @(#)Priority_Buffer_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Priority_Buffer_Test.cpp +// +// = DESCRIPTION +// This is a simple test to illustrate the priority mechanism of +// ACE Message_Queues. The producer uses an ASX Message_Queue to +// enqueue a bunch of messages with different priorities which +// are then dequeued by the consumer. +// +// = AUTHOR +// Prashant Jain and Doug Schmidt +// +// ============================================================================ + +#include "ace/Log_Msg.h" +#include "ace/Message_Queue.h" +#include "ace/Thread_Manager.h" +#include "ace/Service_Config.h" +#include "test_config.h" + +#if defined (ACE_HAS_THREADS) + +// Global thread manager. +static ACE_Thread_Manager thr_mgr; +static int count = 0; + +// Make the queue be capable of being *very* large. +static const long max_queue = LONG_MAX; + +// The consumer dequeues a message from the ACE_Message_Queue, writes +// the message to the stderr stream, and deletes the message. The +// producer sends a 0-sized message to inform the consumer to stop +// reading and exit. + +static void * +consumer (ACE_Message_Queue *msg_queue) +{ + int cur_priority = 27; + int local_count = 0; + + // Keep looping, reading a message out of the queue, until we + // get a message with a length == 0, which signals us to quit. + for (char c = 'z'; ; c--) + { + ACE_Message_Block *mb = 0; + + int result = msg_queue->dequeue_head (mb); + + if (result == -1) + break; + + local_count++; + + int length = mb->length (); + ACE_ASSERT (mb->msg_priority () < cur_priority); + cur_priority = mb->msg_priority (); + + if (length > 0) + ACE_ASSERT (c == *mb->rd_ptr ()); + + // Free up the buffer memory and the Message_Block. Note that + // the destructor of Message Block will delete the the actual + // buffer. + delete mb; + + if (length == 0) + break; + } + ACE_ASSERT (local_count == count); + return 0; +} + +// The producer reads data from the stdin stream, creates a message, +// and then queues the message in the message list, where it is +// removed by the consumer thread. A 0-sized message is enqueued when +// there is no more data to read. The consumer uses this as a flag to +// know when to exit. + +static void * +producer (ACE_Message_Queue *msg_queue) +{ + // Insert thread into thr_mgr. + ACE_Thread_Control thread_control (&thr_mgr); + ACE_NEW_THREAD; + + ACE_Message_Block *mb = 0; + + for (char c = 'a'; c <= 'z'; c++) + { + count++; + + // Allocate a new message + + ACE_NEW_RETURN (mb, ACE_Message_Block (1), 0); + *mb->rd_ptr () = c; + + // Set the priority. + mb->msg_priority (count); + mb->wr_ptr (1); + + // Enqueue in priority order. + if (msg_queue->enqueue (mb) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "put_next"), 0); + } + + // Now send a 0-sized shutdown message to the other thread + ACE_NEW_RETURN (mb, ACE_Message_Block ((size_t) 0), 0); + + if (msg_queue->enqueue_tail (mb) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "put_next")); + + count++; + + // Now read all the items out in priority order (i.e., ordered by + // the size of the lines!). + consumer (msg_queue); + + // The destructor of ACE_Thread_Control removes the exiting thread + // from the thr_mgr automatically. + return 0; +} + +// Spawn off one thread that copies stdin to stdout in order of the +// size of each line. + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + + // Message queue. + ACE_Message_Queue msg_queue (max_queue); + + if (thr_mgr.spawn (ACE_THR_FUNC (producer), (void *) &msg_queue, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), 1); + + // Wait for producer and consumer threads to exit. + thr_mgr.wait (); + + ACE_END_TEST; + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/tests/README b/tests/README new file mode 100644 index 00000000000..bbe467f05fb --- /dev/null +++ b/tests/README @@ -0,0 +1,51 @@ +This directory contains a battery of tests that exercise all the +functionality of ACE on Win32 and UNIX. These tests can be executed +in a single pass via a shell script run_tests.sh (on UNIX) or a batch +file run_tests.bat (on Win32). + +We had problems running the batch file on Windows 95 and Windows NT +using the native DOS prompt. However we were able to get around this +problem by using a program called "4DOS for Windows NT" which also +displays a DOS prompt but allows us to run batch files through it. + +The tests have been run on UNIX, Windows NT, and Windows 95 and they +all work with the following exceptions: + +1. Name_Server_Test on Windows 95: this does not work on Windows 95 + since Windows 95 has a different model for shared memory and does + not support explicitly selecting shared memory addresses. + +2. UPIPE_Test and SPIPE_Test on Windows 95: these do not work on + Windows 95 since Windows 95 does not support the server side + functionality of accepting connections from clients using named pipes. + +3. Proactor_Test (to be added) on Windows 95: this does not work on + Windows 95 also since Windows 95 does not support I/O completion + ports and overlapped I/O. + +Notes: + +1. Each test creates a log file and writes it to the log + directory. The log directory can be changed in the test_config.h + file. + +2. Each log file contains a time stamp of when the test began and also + a time stamp indicating when the test ended. If the ending time stamp + is missing, it can be assumed that the test did not succeed. + +3. None of the tests require any command line parameters. This is in + accordance with the keeping the test-suite a one-button test. If + any of the tests require any variable parameters these are + specified in test_config.h. + +4. Time_Service_Test executes the Time Server and Clerk components + as two processes and so the executable "main" need to be present in the + netsvcs/bin directory. These components rely on config files. Two + sample config files are also present in the test-suite, namely + server.conf and clerk.conf (and for Win32, NTserver.conf and + NTclerk.conf). + +If you have any questions/suggestions, please let me know. + +Prashant Jain +(pjain@cs.wustl.edu) diff --git a/tests/Reactor_Timer_Test.cpp b/tests/Reactor_Timer_Test.cpp new file mode 100644 index 00000000000..61144b01f58 --- /dev/null +++ b/tests/Reactor_Timer_Test.cpp @@ -0,0 +1,95 @@ +// ============================================================================ +// @(#)Reactor_Timer_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Reactor_Timer_Test.cpp +// +// = DESCRIPTION +// This is a simple test that illustrates the timer mechanism of +// the reactor. Scheduling timers, handling expired timers and +// cancelling scheduled timers are all tested in this test. No +// command line arguments are needed to run the test. +// +// = AUTHOR +// Prashant Jain and Doug C. Schmidt +// +// ============================================================================ + +#include "ace/Log_Msg.h" +#include "ace/Timer_Queue.h" +#include "ace/Reactor.h" +#include "test_config.h" + +static int done = 0; +static int count = 0; +static int odd = 0; + +class Reactor_Timer : public ACE_Event_Handler +{ +public: + virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg) + { + ACE_ASSERT ((int) arg == count); + if (odd == 1) + count += 2; + else + count += 1; + ACE_DEBUG ((LM_DEBUG, "%d: Timer #%d timed out!\n", count, int (arg))); + if ((int) arg == ACE_MAX_TIMERS - 1) + done = 1; + return 0; + } + +private: +}; + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + + ACE_Reactor reactor; + Reactor_Timer rt[ACE_MAX_TIMERS]; + int t_id[ACE_MAX_TIMERS]; + int i; + + for (i = 0; i < ACE_MAX_TIMERS; i++) + { + t_id[i] = reactor.schedule_timer (&(rt[i]), (const void *) i, ACE_Time_Value (2 * i + 1)); + } + while (!done) + reactor.handle_events (); + + done = 0; + count = 0; + + // Now try multiple timers for ONE event handler (should produce the same result) + for (i = 0; i < ACE_MAX_TIMERS; i++) + { + t_id[i] = reactor.schedule_timer (&(rt[0]), (const void *) i, ACE_Time_Value (2 * i + 1)); + } + while (!done) + reactor.handle_events (); + + done = 0; + count = 1; + odd = 1; + // Cancel even numbered timers + for (i = 0; i < ACE_MAX_TIMERS; i++) + { + t_id[i] = reactor.schedule_timer (&(rt[0]), (const void *) i, ACE_Time_Value (2 * i + 1)); + if (((i+2) % 2) == 0) + reactor.cancel_timer (t_id[i]); + } + while (!done) + reactor.handle_events (); + + ACE_END_TEST; + + return 0; +} + diff --git a/tests/Reactors_Test.cpp b/tests/Reactors_Test.cpp new file mode 100644 index 00000000000..5a393c762d0 --- /dev/null +++ b/tests/Reactors_Test.cpp @@ -0,0 +1,215 @@ +// ============================================================================ +// @(#)Reactors_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Reactors_Test.cpp +// +// = DESCRIPTION +// This is a test that performs a torture test of multiple +// ACE_Reactors and ACE_Tasks in the same process. +// +// = AUTHOR +// Prashant Jain and Detlef Becker +// +// ============================================================================ + +#include "ace/Reactor.h" +#include "ace/Synch.h" +#include "ace/Service_Config.h" +#include "ace/Task.h" +#include "test_config.h" + +#if defined (ACE_HAS_THREADS) + +static const int NUM_INVOCATIONS = 10; +static const int MAX_TASKS = 20; + +class Test_Task : public ACE_Task +{ +public: + Test_Task (void); + ~Test_Task (void); + + virtual int open (void *args = 0); + virtual int close (u_long flags = 0); + virtual int put (ACE_Message_Block *, ACE_Time_Value *tv = 0); + virtual int svc (void); + + virtual int handle_input (ACE_HANDLE handle); + virtual int handle_close (ACE_HANDLE fd, + ACE_Reactor_Mask close_mask); + +private: + ACE_Reactor *r_; + int handled_; + + static int task_count_; +}; + +int Test_Task::task_count_ = 0; + +static ACE_Atomic_Op done_count = MAX_TASKS * 2; + +static ACE_Recursive_Thread_Mutex reclock_; + +Test_Task::Test_Task (void) + : handled_ (0) +{ + ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, reclock_); + + Test_Task::task_count_++; + ACE_DEBUG ((LM_DEBUG, + "(%t) TT+ Test_Task::task_count_ = %d\n", + Test_Task::task_count_)); +} + +Test_Task::~Test_Task (void) +{ + ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, reclock_); + + ACE_ASSERT (Test_Task::task_count_ == 0); + ACE_DEBUG ((LM_DEBUG, + "(%t) TT- Test_Task::task_count_ = %d\n", + Test_Task::task_count_)); +} + +int +Test_Task::open (void *args) +{ + r_ = (ACE_Reactor *) args; + return this->activate (THR_NEW_LWP); +} + +int +Test_Task::close (u_long flags) +{ + ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, reclock_, -1); + + Test_Task::task_count_--; + ACE_DEBUG ((LM_DEBUG, + "(%t) close Test_Task::task_count_ = %d\n", + Test_Task::task_count_)); + return 0; +} + +int +Test_Task::put (ACE_Message_Block *mb, + ACE_Time_Value *tv) +{ + return 0; +} + +int +Test_Task::svc (void) +{ + ACE_NEW_THREAD; + + for (int i = 0; i < NUM_INVOCATIONS; i++) + { + ACE_OS::thr_yield (); + + if (r_->notify (this, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "notify"), -1); + } + + return 0; +} + +int +Test_Task::handle_close (ACE_HANDLE fd, + ACE_Reactor_Mask close_mask) +{ + return 0; +} + +int +Test_Task::handle_input (ACE_HANDLE fd) +{ + this->handled_++; + + if (this->handled_ == NUM_INVOCATIONS) + { + done_count--; + ACE_DEBUG ((LM_DEBUG, + "(%t) handle_input, handled_ = %d, done_count = %d\n", + this->handled_, (u_long) done_count)); + } + + ACE_OS::thr_yield (); + return -1; +} + +static void * +worker (void *args) +{ + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + ACE_NEW_THREAD; + + ACE_Reactor *reactor = (ACE_Reactor *) args; + + reactor->owner (ACE_Thread::self ()); + + ACE_Time_Value timeout (4); + + for (;;) + { + switch (reactor->handle_events (timeout)) + { + case -1: + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "reactor"), 0); + /* NOTREACHED */ + case 0: + ACE_ERROR_RETURN ((LM_ERROR, "timeout\n"), 0); + /* NOTREACHED */ + } + } + + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + + ACE_Reactor *react1 = ACE_Service_Config::reactor (); + ACE_Reactor *react2 = new ACE_Reactor (); + Test_Task tt1[MAX_TASKS]; + Test_Task tt2[MAX_TASKS]; + + for (int i = 0; i < MAX_TASKS; i++) + { + tt1[i].open (react1); + tt2[i].open (react2); + } + + if (ACE_Service_Config::thr_mgr ()->spawn + (ACE_THR_FUNC (worker), (void *) react1, THR_NEW_LWP) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), -1); + + else if (ACE_Service_Config::thr_mgr ()->spawn + (ACE_THR_FUNC (worker), (void *) react2, THR_NEW_LWP) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), -1); + + ACE_Service_Config::thr_mgr ()->wait (); + + ACE_DEBUG ((LM_DEBUG, "Ending %s test at %u\n", argv[0], ACE_OS::time (0))); + return 0; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Atomic_Op; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ + +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/tests/Reader_Writer_Test.cpp b/tests/Reader_Writer_Test.cpp new file mode 100644 index 00000000000..88aca96547d --- /dev/null +++ b/tests/Reader_Writer_Test.cpp @@ -0,0 +1,216 @@ +// ============================================================================ +// @(#)Reader_Writer_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Reader_Writer_Test.cpp +// +// = DESCRIPTION +// This test program verifies the functionality of the ACE_OS +// implementation of readers/writer locks on Win32 and Posix +// pthreads. +// +// = AUTHOR +// Prashant Jain and Doug C. Schmidt +// +// ============================================================================ + +#include "ace/Log_Msg.h" +#include "ace/Synch.h" +#include "ace/Thread.h" +#include "ace/Thread_Manager.h" +#include "ace/Get_Opt.h" +#include "test_config.h" + +#if defined (ACE_HAS_THREADS) + +// Default number of iterations. +static size_t n_iterations = 1000; + +// Default number of loops. +static size_t n_loops = 100; + +// Default number of readers. +static size_t n_readers = 6; + +// Default number of writers. +static size_t n_writers = 4; + +// Thread id of last writer. +volatile static int shared_data; + +// Lock for shared_data. +static ACE_RW_Mutex rw_mutex; + +// Count of the number of readers and writers. +ACE_Atomic_Op current_readers, current_writers; + +// Thread manager +static ACE_Thread_Manager thr_mgr; + +// Explain usage and exit. +static void +print_usage_and_die (void) +{ + ACE_DEBUG ((LM_DEBUG, + "usage: %n [-r n_readers] [-w n_writers] [-n iteration_count]\n")); + ACE_OS::exit (1); +} + +// Parse the command-line arguments and set options. +static void +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opt (argc, argv, "r:w:n:l:"); + + int c; + + while ((c = get_opt ()) != -1) + switch (c) + { + case 'r': + n_readers = ACE_OS::atoi (get_opt.optarg); + break; + case 'w': + n_writers = ACE_OS::atoi (get_opt.optarg); + break; + case 'n': + n_iterations = ACE_OS::atoi (get_opt.optarg); + break; + case 'l': + n_loops = ACE_OS::atoi (get_opt.optarg); + break; + default: + print_usage_and_die (); + break; + } +} + +// Iterate each time checking that nobody modifies the data +// while we have a read lock. + +static void * +reader (void *) +{ + ACE_Thread_Control tc (&thr_mgr); + ACE_NEW_THREAD; + + ACE_DEBUG ((LM_DEBUG, "(%t) reader starting\n")); + + for (int iterations = 1; iterations <= n_iterations; iterations++) + { + ACE_Read_Guard g(rw_mutex); + int n = ++current_readers; + //ACE_DEBUG ((LM_DEBUG, "(%t) I'm reader number %d\n", n)); + + if (current_writers > 0) + ACE_DEBUG ((LM_DEBUG, "(%t) writers found!!!\n")); + + int data = shared_data; + + for (int loop = 1; loop <= n_loops; loop++) + { + ACE_Thread::yield(); + if (shared_data != data) + ACE_DEBUG ((LM_DEBUG, + "(%t) somebody changed %d to %d\n", + data, shared_data)); + } + + --current_readers; + //ACE_DEBUG ((LM_DEBUG, "(%t) done with reading guarded data\n")); + + ACE_Thread::yield (); + } + return 0; +} + +// Iterate each time modifying the global data +// and checking that nobody steps on it while we can write it. + +static void * +writer (void *) +{ + ACE_Thread_Control tc (&thr_mgr); + ACE_NEW_THREAD; + + ACE_DEBUG ((LM_DEBUG, "(%t) writer starting\n")); + + for (int iterations = 1; iterations <= n_iterations; iterations++) + { + ACE_Write_Guard g(rw_mutex); + + ++current_writers; + //ACE_DEBUG ((LM_DEBUG, "(%t) writing to guarded data\n")); + + if (current_writers > 1) + ACE_DEBUG ((LM_DEBUG, "(%t) other writers found!!!\n")); + + if (current_readers > 0) + ACE_DEBUG ((LM_DEBUG, "(%t) readers found!!!\n")); + + int self = (int) ACE_Thread::self (); + shared_data = self; + + for (int loop = 1; loop <= n_loops; loop++) + { + ACE_Thread::yield(); + if (shared_data != self) + ACE_DEBUG ((LM_DEBUG, "(%t) somebody wrote on my data %d\n", shared_data)); + } + + --current_writers; + + //ACE_DEBUG ((LM_DEBUG, "(%t) done with guarded data\n")); + ACE_Thread::yield (); + } + return 0; +} + +// Spawn off threads. + +int main (int argc, char *argv[]) +{ + ACE_START_TEST; + + ACE_LOG_MSG->open (argv[0]); + + current_readers = 0; // Possibly already done + current_writers = 0; // Possibly already done + + ACE_DEBUG ((LM_DEBUG, "(%t) main thread starting\n")); + + if (thr_mgr.spawn_n (n_readers, + ACE_THR_FUNC (reader), + 0, + THR_NEW_LWP) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn_n"), 1); + else if (thr_mgr.spawn_n (n_writers, + ACE_THR_FUNC (writer), + 0, + THR_NEW_LWP) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn_n"), 1); + + thr_mgr.wait (); + + ACE_DEBUG ((LM_DEBUG, "(%t) exiting main thread\n")); + ACE_END_TEST; + return 0; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Atomic_Op; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ + +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ + diff --git a/tests/Recursive_Mutex_Test.cpp b/tests/Recursive_Mutex_Test.cpp new file mode 100644 index 00000000000..60914bc227b --- /dev/null +++ b/tests/Recursive_Mutex_Test.cpp @@ -0,0 +1,88 @@ +// ============================================================================ +// @(#)Recursive_Mutex_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Recursive_Mutex_Test.cpp +// +// = DESCRIPTION +// This test program verifies the functionality of the ACE_OS +// implementation of recursive mutexes on Win32 and Posix +// pthreads. +// +// = AUTHOR +// Prashant Jain and Doug C. Schmidt +// +// ============================================================================ +#include "ace/Log_Msg.h" + +#if defined (ACE_HAS_THREADS) + +#include "ace/Service_Config.h" +#include "ace/Get_Opt.h" +#include "ace/Synch.h" +#include "test_config.h" + +// Total number of iterations. +static size_t n_iterations = 100; +static size_t n_threads = ACE_MAX_THREADS; + +static void +recursive_worker (size_t nesting_level, + ACE_Recursive_Thread_Mutex *rm) +{ + if (nesting_level < n_iterations) + { + ACE_ASSERT (rm->acquire () == 0); + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) = acquired, nesting = %d, thread id = %u\n", + rm->get_nesting_level (), rm->get_thread_id ())); + + recursive_worker (nesting_level + 1, rm); + + ACE_ASSERT (rm->release () == 0); + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) = released, nesting = %d, thread id = %u\n", + rm->get_nesting_level (), rm->get_thread_id ())); + } +} + +static void * +worker (void *arg) +{ + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + ACE_NEW_THREAD; + + ACE_Recursive_Thread_Mutex *rm = (ACE_Recursive_Thread_Mutex *) arg; + recursive_worker (0, rm); + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + + ACE_Service_Config daemon (argv[0]); + ACE_Recursive_Thread_Mutex rm; + ACE_Service_Config::thr_mgr ()->spawn_n (n_threads, + ACE_THR_FUNC (worker), + (void *) &rm); + + ACE_Service_Config::thr_mgr ()->wait (); + + ACE_END_TEST; + return 0; +} +#else +int +main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "ACE doesn't support support process mutexes on this platform (yet)\n"), + -1); +} +#endif /* ACE_WIN32 */ diff --git a/tests/SPIPE_Test.cpp b/tests/SPIPE_Test.cpp new file mode 100644 index 00000000000..cafe1a31dda --- /dev/null +++ b/tests/SPIPE_Test.cpp @@ -0,0 +1,146 @@ +// ============================================================================ +// @(#)SPIPE_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// SPIPE_Test.cpp +// +// = DESCRIPTION +// This is a simple test of Named Pipes that uses +// ACE_SPIPE_Acceptor and ACE_SPIPE_Connector classes. The test +// forks two processes or spawns two threads (depending upon the +// platform) and then executes the client and server allowing +// them to use the named pipe to exchange data. No user input is +// required as far as command line arguments are concerned. +// +// = AUTHOR +// Prashant Jain +// +// ============================================================================ + +#include "ace/OS.h" +#include "ace/Thread.h" +#include "ace/Thread_Manager.h" +#include "ace/SPIPE_Addr.h" +#include "ace/Time_Value.h" +#include "ace/SPIPE_Connector.h" +#include "ace/SPIPE_Acceptor.h" +#include "test_config.h" + +// pipe name to use +static char *pipe_name = "acepipe"; + +// Global thread manager. +static ACE_Thread_Manager thr_mgr; + +static void * +client (void *dummy) +{ +#if defined (ACE_WIN32) + ACE_Thread_Control thread_control (&thr_mgr); // Insert thread into thr_mgr + ACE_NEW_THREAD; +#endif + char *rendezvous = "ace_pipe_name"; + ACE_SPIPE_Stream cli_stream; + ACE_SPIPE_Connector con; + + ACE_OS::sleep (3); + + if (con.connect (cli_stream, ACE_SPIPE_Addr (rendezvous)) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", rendezvous)); + + for (char c = 'a'; c <= 'z'; c++) + if (cli_stream.send (&c, 1) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "send_n")); + + if (cli_stream.close () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "close")); + +#if !defined (ACE_WIN32) + ACE_OS::exit (0); +#endif + return 0; +} + +static void * +server (void *dummy) +{ +#if defined (ACE_WIN32) + ACE_Thread_Control thread_control (&thr_mgr); // Insert thread into thr_mgr + ACE_NEW_THREAD; +#endif + ACE_SPIPE_Acceptor acceptor; + ACE_SPIPE_Stream new_stream; + char buf[BUFSIZ]; + int n; + char t = 'a'; + + char *rendezvous = "ace_pipe_name"; + + // Initialize named pipe listener + + if (acceptor.open (ACE_SPIPE_Addr (rendezvous)) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "open")); + + ACE_DEBUG ((LM_DEBUG, "waiting for connection\n")); + + // Accept a client connection + if (acceptor.accept (new_stream, 0) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "accept")); + + ACE_DEBUG ((LM_DEBUG, "Accepted connection\n")); + + while ((n = new_stream.recv (buf, 1)) > 0) + { + ACE_ASSERT (t == buf[0]); + t++; + } + ACE_DEBUG ((LM_DEBUG, "End of connection. Closing handle\n")); + new_stream.close (); + return 0; +} + +void +spawn () +{ +#if !defined (ACE_WIN32) + switch (ACE_OS::fork ()) + { + case -1: + ACE_ERROR ((LM_ERROR, "%p\n%a", "fork failed")); + exit (-1); + case 0: + client (0); + default: + server (0); + } +#elif defined (ACE_HAS_THREADS) + if (thr_mgr.spawn (ACE_THR_FUNC (client), + (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "thread create failed")); + + if (thr_mgr.spawn (ACE_THR_FUNC (server), + (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "thread create failed")); + thr_mgr.wait (); +#else + ACE_ERROR ((LM_ERROR, "only one thread may be run in a process on this platform\n%a", 1)); +#endif /* ACE_HAS_THREADS */ +} + +int +main (int, char *argv[]) +{ + ACE_START_TEST; + + spawn (); + + ACE_END_TEST; + return 0; +} + diff --git a/tests/SString_Test.cpp b/tests/SString_Test.cpp new file mode 100644 index 00000000000..86e4a1cc0ec --- /dev/null +++ b/tests/SString_Test.cpp @@ -0,0 +1,45 @@ +// ============================================================================ +// @(#)SString_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// SString_Test.cpp +// +// = DESCRIPTION +// This is a simple test that illustrates the use of ACE_CString +// and ACE_WString. No command line arguments are needed to run +// the test. +// +// = AUTHOR +// Prashant Jain +// +// ============================================================================ + +#include "ace/SString.h" +#include "test_config.h" + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + + ACE_CString s1 ("hello"); + ACE_CString s2 ("world"); + ACE_CString s3 ("el"); + ACE_WString s4 ("hello"); + ACE_WString s5 ("world"); + ACE_WString s6 ("el"); + + ACE_ASSERT (s1 != s2); + ACE_ASSERT (s1.strstr (s2) == -1); + ACE_ASSERT (s1.strstr (s2) == -1); + ACE_ASSERT (s1.strstr (s3)); + ACE_ASSERT (s4.strstr (s5) == -1); + ACE_ASSERT (s5.strstr (s6)); + + ACE_END_TEST; + return 0; +} diff --git a/tests/SV_Shared_Memory_Test.cpp b/tests/SV_Shared_Memory_Test.cpp new file mode 100644 index 00000000000..b8aec00f6c2 --- /dev/null +++ b/tests/SV_Shared_Memory_Test.cpp @@ -0,0 +1,86 @@ +// ============================================================================ +// @(#)SV_Shared_Memory_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// SV_Shared_Memory_Test.cpp +// +// = DESCRIPTION +// This is a simple test of ACE_SV_Shared_Memory +// +// = AUTHOR +// Prashant Jain and Doug Schmidt +// +// ============================================================================ + +#include "ace/OS.h" +#include "ace/SV_Shared_Memory.h" +#include "test_config.h" + +#define SHMSZ 27 +#define SEM_KEY 1234 +#define SHM_KEY 5678 + +static void +client (void) +{ + ACE_SV_Shared_Memory shm_client; + char t = 'a'; + + if (shm_client.open_and_attach (SHM_KEY, SHMSZ) == -1) + ACE_OS::perror ("open"), ACE_OS::exit (1); + + for (char *s = (char *) shm_client.get_segment_ptr (); *s != '\0'; s++) + { + ACE_ASSERT (t == s[0]); + t++; + } + + *(char *) shm_client.get_segment_ptr () = '*'; + ACE_OS::exit (0); +} + +static void +server (void) +{ + ACE_SV_Shared_Memory shm_server; + + if (shm_server.open_and_attach (SHM_KEY, SHMSZ, ACE_SV_Shared_Memory::ACE_CREATE) == -1) + ACE_OS::perror ("open"), ACE_OS::exit (1); + + char *s = (char *) shm_server.get_segment_ptr (); + + for (char c = 'a'; c <= 'z'; c++) + *s++ = c; + + *s = '\0'; + + for (s = (char *) shm_server.get_segment_ptr (); *s != '*'; ) + ACE_OS::sleep (1); + + if (shm_server.remove () < 0) + ACE_OS::perror ("remove"), ACE_OS::exit (1); + return; +} + +int +main (int, char *argv[]) +{ + ACE_START_TEST; + switch (ACE_OS::fork ()) + { + case -1: + ACE_OS::perror (argv[0]), ACE_OS::exit (1); + case 0: + ACE_OS::sleep (1); + client (); + default: + server (); + } + ACE_END_TEST; + return 0; +} + diff --git a/tests/Shared_Memory_MM_Test.cpp b/tests/Shared_Memory_MM_Test.cpp new file mode 100644 index 00000000000..6999ea6c321 --- /dev/null +++ b/tests/Shared_Memory_MM_Test.cpp @@ -0,0 +1,132 @@ +// ============================================================================ +// @(#)Shared_Memory_MM_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Shared_Memory_MM_Test.cpp +// +// = DESCRIPTION +// This is a simple test of ACE_Shared_Memory_MM. The test forks +// two processes or spawns two threads (depending upon the +// platform) and then executes client and server allowing them to +// exchange data using shared memory. No user input is required as +// far as command line arguments are concerned. +// +// = AUTHOR +// Prashant Jain and Doug Schmidt +// +// ============================================================================ + +#include "ace/Log_Msg.h" +#include "ace/Shared_Memory_MM.h" +#include "ace/Thread.h" +#include "ace/Thread_Manager.h" +#include "test_config.h" + +#define SHMSZ 27 +static char shm_key[] = "/tmp/fooXXXXXX"; + +// Global thread manager. +static ACE_Thread_Manager thr_mgr; + +static void * +client (void *dummy) +{ +#if defined (ACE_WIN32) + // Insert thread into thr_mgr + ACE_Thread_Control thread_control (&thr_mgr); + ACE_NEW_THREAD; +#endif + + ACE_OS::sleep (3); + char t = 'a'; + ACE_Shared_Memory *shm_client = new ACE_Shared_Memory_MM (shm_key); + char *shm = (char *) shm_client->malloc (); + + for (char *s = shm; *s != '\0'; s++) + { + ACE_ASSERT (t == s[0]); + t++; + } + *shm = '*'; +#if !defined (ACE_WIN32) + ACE_OS::exit (0); +#endif + return 0; +} + +static void * +server (void *dummy) +{ +#if defined (ACE_WIN32) + // Insert thread into thr_mgr + ACE_Thread_Control thread_control (&thr_mgr); + ACE_NEW_THREAD; +#endif + + ACE_Shared_Memory *shm_server = new ACE_Shared_Memory_MM (shm_key, SHMSZ); + char *shm = (char *) shm_server->malloc (); + char *s = shm; + + for (char c = 'a'; c <= 'z'; c++) + *s++ = c; + + *s = '\0'; + + // Perform a busy wait (ugh) + while (*shm != '*') + ACE_OS::sleep (1); + + if (shm_server->remove () < 0) + ACE_ERROR ((LM_ERROR, "%p\n", "remove")); + ACE_OS::unlink (shm_key); + return 0; +} + +void +spawn () +{ +#if !defined (ACE_WIN32) + switch (ACE_OS::fork ()) + { + case -1: + ACE_ERROR ((LM_ERROR, "%p\n%a", "fork failed")); + exit (-1); + case 0: + client (0); + default: + server (0); + } +#elif defined (ACE_HAS_THREADS) + if (thr_mgr.spawn (ACE_THR_FUNC (client), + (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "thread create failed")); + + if (thr_mgr.spawn (ACE_THR_FUNC (server), + (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "thread create failed")); + thr_mgr.wait (); +#else + ACE_ERROR ((LM_ERROR, "only one thread may be run in a process on this platform\n%a", 1)); +#endif /* ACE_HAS_THREADS */ +} + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + + if (ACE_OS::mktemp (shm_key) == 0 || (ACE_OS::unlink (shm_key) == -1 && errno == EPERM)) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", shm_key), 1); + + spawn (); + + ACE_END_TEST; + return 0; +} + diff --git a/tests/Shared_Memory_SV_Test.cpp b/tests/Shared_Memory_SV_Test.cpp new file mode 100644 index 00000000000..bc97f2d04f2 --- /dev/null +++ b/tests/Shared_Memory_SV_Test.cpp @@ -0,0 +1,81 @@ +// ============================================================================ +// @(#)Shared_Memory_SV_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Shared_Memory_SV_Test.cpp +// +// = DESCRIPTION +// This is a simple test of ACE_Shared_Memory_SV +// +// = AUTHOR +// Prashant Jain and Doug Schmidt +// +// ============================================================================ + +#include "ace/Log_Msg.h" +#include "ace/Shared_Memory_SV.h" +#include "test_config.h" + +#define SHMSZ 27 +#define SHM_KEY 5678 + +static void +client (void) +{ + char t = 'a'; + ACE_Shared_Memory_SV shm_client (SHM_KEY, SHMSZ); + char *shm = (char *) shm_client.malloc (); + + for (char *s = shm; *s != '\0'; s++) + { + ACE_ASSERT (t == s[0]); + t++; + } + *shm = '*'; + ACE_OS::exit (0); +} + +static void +server (void) +{ + ACE_Shared_Memory_SV shm_server (SHM_KEY, SHMSZ, + ACE_Shared_Memory_SV::ACE_CREATE); + char *shm = (char *) shm_server.malloc (); + char *s = shm; + + for (char c = 'a'; c <= 'z'; c++) + *s++ = c; + + *s = '\0'; + + while (*shm != '*') + ACE_OS::sleep (1); + + if (shm_server.remove () < 0) + ACE_ERROR ((LM_ERROR, "%p\n", "remove")); +} + +int +main (int argc, char *argv []) +{ + ACE_START_TEST; + switch (ACE_OS::fork ()) + { + case -1: + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "fork"), 1); + case 0: + ACE_OS::sleep (1); + client (); + break; + default: + server (); + break; + } + ACE_END_TEST; + return 0; +} + diff --git a/tests/TSS_Test.cpp b/tests/TSS_Test.cpp new file mode 100644 index 00000000000..0b76e4dc016 --- /dev/null +++ b/tests/TSS_Test.cpp @@ -0,0 +1,218 @@ +// ============================================================================ +// @(#)TSS_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// TSS_Test.cpp +// +// = DESCRIPTION +// This program tests thread specific storage of data. The ACE_TSS +// wrapper transparently ensures that the objects of this class +// will be placed in thread-specific storage. All calls on +// ACE_TSS::operator->() are delegated to the appropriate method +// in the Errno class. +// +// = AUTHOR +// Prashant Jain and Doug Schmidt +// +// ============================================================================ + +#include "ace/Service_Config.h" +#include "ace/Synch.h" +#include "ace/Log_Msg.h" +#include "test_config.h" + +static int iterations = 100; + +class Errno +{ +public: + int error (void) { return this->errno_; } + void error (int i) { this->errno_ = i; } + + int line (void) { return this->lineno_; } + void line (int l) { this->lineno_ = l; } + + // Errno::flags_ is a static variable, so we've got to protect it + // with a mutex since it isn't kept in thread-specific storage. + int flags (void) { + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_Mon, Errno::lock_, -1)); + + return Errno::flags_; + } + int flags (int f) + { + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, Errno::lock_, -1)); + + Errno::flags_ = f; + return 0; + } + +private: + // = errno_ and lineno_ will be thread-specific data so they don't + // need a lock. + int errno_; + int lineno_; + + static int flags_; +#if defined (ACE_HAS_THREADS) + // flags_ needs a lock. + static ACE_Thread_Mutex lock_; +#endif /* ACE_HAS_THREADS */ +}; + +// Static variables. +ACE_MT (ACE_Thread_Mutex Errno::lock_); +int Errno::flags_; + +// This is our thread-specific error handler... +static ACE_TSS TSS_Error; + +#if defined (ACE_HAS_THREADS) +// Serializes output via cout. +static ACE_Thread_Mutex lock; + +typedef ACE_TSS_Guard GUARD; +#else +// Serializes output via cout. +static ACE_Null_Mutex lock; + +typedef ACE_Guard GUARD; +#endif /* ACE_HAS_THREADS */ + +static void +cleanup (void *ptr) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) in cleanup, ptr = %x\n", ptr)); + + delete ptr; +} + +// This worker function is the entry point for each thread. + +static void * +worker (void *c) +{ + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + ACE_NEW_THREAD; + + int count = int (c); + + ACE_thread_key_t key = 0; + int *ip = 0; + + // Make one key that will be available when the thread exits so that + // we'll have something to cleanup! + + if (ACE_OS::thr_keycreate (&key, cleanup) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_keycreate")); + + ip = new int; + + if (ACE_OS::thr_setspecific (key, (void *) ip) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_setspecific")); + + for (int i = 0; i < count; i++) + { + if (ACE_OS::thr_keycreate (&key, cleanup) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_keycreate")); + + ip = new int; + + ACE_DEBUG ((LM_DEBUG, "(%t) in worker 1, key = %d, ip = %x\n", key, ip)); + + if (ACE_OS::thr_setspecific (key, (void *) ip) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_setspecific")); + + if (ACE_OS::thr_getspecific (key, (void **) &ip) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_setspecific")); + + if (ACE_OS::thr_setspecific (key, (void *) 0) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_setspecific")); + + delete ip; + + if (ACE_OS::thr_keyfree (key) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_keyfree")); + + // Cause an error. + ACE_OS::read (ACE_INVALID_HANDLE, 0, 0); + + // The following two lines set the thread-specific state. + TSS_Error->error (errno); + TSS_Error->line (__LINE__); + + // This sets the static state (note how C++ makes it easy to do + // both). + TSS_Error->flags (count); + + { + // Use the guard to serialize access + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, lock, 0)); + ACE_ASSERT (TSS_Error->flags () == iterations); + } + key = 0; + + if (ACE_OS::thr_keycreate (&key, cleanup) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_keycreate")); + + ip = new int; + + ACE_DEBUG ((LM_DEBUG, "(%t) in worker 2, key = %d, ip = %x\n", key, ip)); + + if (ACE_OS::thr_setspecific (key, (void *) ip) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_setspecific")); + + if (ACE_OS::thr_getspecific (key, (void **) &ip) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_setspecific")); + + if (ACE_OS::thr_setspecific (key, (void *) 0) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_setspecific")); + + delete ip; + + if (ACE_OS::thr_keyfree (key) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", "ACE_OS::thr_keyfree")); + } + return 0; +} + +static void +handler (int signum) +{ + ACE_DEBUG ((LM_DEBUG, "signal = %S\n", signum)); + ACE_Service_Config::thr_mgr ()->exit (0); +} + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + int threads = ACE_MAX_THREADS; + + signal (SIGINT, ACE_SignalHandler (handler)); + +#if defined (ACE_HAS_THREADS) + if (ACE_Service_Config::thr_mgr ()->spawn_n (threads, + ACE_THR_FUNC (&worker), + (void *) iterations, + THR_BOUND | THR_DETACHED) == -1) + ACE_OS::perror ("ACE_Thread_Manager::spawn_n"); + + ACE_Service_Config::thr_mgr ()->wait (); +#else + worker ((void *) iterations); +#endif /* ACE_HAS_THREADS */ + + ACE_END_TEST; + return 0; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_TSS; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/tests/Task_Test.cpp b/tests/Task_Test.cpp new file mode 100644 index 00000000000..75961bd5706 --- /dev/null +++ b/tests/Task_Test.cpp @@ -0,0 +1,117 @@ +// ============================================================================ +// @(#)Task_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Task_Test.cpp +// +// = DESCRIPTION +// This test program illustrates how the ACE barrier +// synchronization mechanisms work in conjunction with the +// ACE_Task and the ACE_Thread_Manager. +// +// = AUTHOR +// Prashant Jain and Doug C. Schmidt +// +// ============================================================================ + +#include "ace/Log_Msg.h" + +#if defined (ACE_HAS_THREADS) + +#include "ace/Service_Config.h" +#include "ace/Task.h" +#include "test_config.h" + +class Barrier_Task : public ACE_Task +{ +public: + Barrier_Task (ACE_Thread_Manager *thr_mgr, + int n_threads, + int n_iterations); + + virtual int svc (void); + // Iterate time printing off a message and "waiting" + // for all other threads to complete this iteration. + +private: + ACE_Barrier barrier_; + // Reference to the tester barrier. This controls each + // iteration of the tester function running in every thread. + + int n_iterations_; + // Number of iterations to run. + + // = Not needed for this test. + virtual int open (void *) { return 0; } + virtual int close (u_long) { return 0; } + virtual int put (ACE_Message_Block *, ACE_Time_Value *) { return 0; } +}; + +Barrier_Task::Barrier_Task (ACE_Thread_Manager *thr_mgr, + int n_threads, + int n_iterations) + : ACE_Task (thr_mgr), + barrier_ (n_threads), + n_iterations_ (n_iterations) +{ + // Create worker threads. + if (this->activate (THR_NEW_LWP, n_threads) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "activate failed")); +} + +// Iterate time printing off a message and "waiting" +// for all other threads to complete this iteration. + +int +Barrier_Task::svc (void) +{ + // Note that the ACE_Task::svc_run() method automatically adds us to + // the Thread_Manager when the thread begins. + ACE_NEW_THREAD; + + for (int iterations = 1; + iterations <= this->n_iterations_; + iterations++) + { + ACE_DEBUG ((LM_DEBUG, "(%t) in iteration %d\n", iterations)); + + // Block until all other threads have waited, then continue. + this->barrier_.wait (); + } + + // Note that the ACE_Task::svc_run() method automatically removes us + // from the Thread_Manager when the thread exits. + + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + + int n_threads = ACE_MAX_THREADS; + int n_iterations = ACE_MAX_ITERATIONS; + + Barrier_Task barrier_task (ACE_Service_Config::thr_mgr (), + n_threads, + n_iterations); + + // Wait for all the threads to reach their exit point. + ACE_Service_Config::thr_mgr ()->wait (); + + ACE_END_TEST; + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/tests/Thread_Manager_Test.cpp b/tests/Thread_Manager_Test.cpp new file mode 100644 index 00000000000..13c240b43b6 --- /dev/null +++ b/tests/Thread_Manager_Test.cpp @@ -0,0 +1,123 @@ +// ============================================================================ +// @(#)Thread_Manager_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Thread_Manager_Test.cpp +// +// = DESCRIPTION +// This program tests out the group management mechanisms +// provided by the ACE_Thread_Manager, including the group signal +// handling, group suspension and resumption, and cooperative +// thread cancellation mechanisms. +// +// = AUTHOR +// Prashant Jain and Doug C. Schmidt +// +// ============================================================================ + +#include "ace/Log_Msg.h" + +#if defined (ACE_HAS_THREADS) + +#include "ace/Service_Config.h" +#include "ace/Thread_Manager.h" +#include "test_config.h" + +static void +handler (int signum) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) received signal %d\n", signum)); +} + +static void * +worker (int iterations) +{ + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + ACE_NEW_THREAD; + + for (int i = 0; i < iterations; i++) + { + if ((i % 1000) == 0) + { + if (ACE_Service_Config::thr_mgr ()->testcancel (ACE_Thread::self ()) != 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%t) has been cancelled before iteration %d!\n", + i)); + break; + } + } + } + + // Destructor removes thread from Thread_Manager. + return 0; +} + +static const int DEFAULT_THREADS = ACE_MAX_THREADS; +static const int DEFAULT_ITERATIONS = 100000; + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + + ACE_Service_Config daemon; + + daemon.open (argv[0]); + + // Register a signal handler + ACE_SignalHandler sh (handler); + ACE_Sig_Action sa (sh, SIGINT); + + int n_threads = argc > 1 ? ACE_OS::atoi (argv[1]) : DEFAULT_THREADS; + int n_iterations = argc > 2 ? ACE_OS::atoi (argv[2]) : DEFAULT_ITERATIONS; + + ACE_Thread_Manager *thr_mgr = ACE_Service_Config::thr_mgr (); + + int grp_id = thr_mgr->spawn_n (n_threads, ACE_THR_FUNC (worker), + (void *) n_iterations, + THR_NEW_LWP | THR_DETACHED); + + // Wait for 1 second and then suspend every thread in the group. + ACE_OS::sleep (1); + ACE_DEBUG ((LM_DEBUG, "(%t) suspending group\n")); + if (thr_mgr->suspend_grp (grp_id) == -1) + ACE_ERROR ((LM_DEBUG, "(%t) %p\n", "suspend_grp")); + + // Wait for 1 more second and then resume every thread in the + // group. + ACE_OS::sleep (ACE_Time_Value (1)); + ACE_DEBUG ((LM_DEBUG, "(%t) resuming group\n")); + if (thr_mgr->resume_grp (grp_id) == -1) + ACE_ERROR ((LM_DEBUG, "(%t) %p\n", "resume_grp")); + + // Wait for 1 more second and then send a SIGINT to every thread in + // the group. + ACE_OS::sleep (ACE_Time_Value (1)); + ACE_DEBUG ((LM_DEBUG, "(%t) signaling group\n")); + if (thr_mgr->kill_grp (grp_id, SIGINT) == -1) + ACE_ERROR ((LM_DEBUG, "(%t) %p\n", "kill_grp")); + + // Wait for 1 more second and then cancel all the threads. + ACE_OS::sleep (ACE_Time_Value (1)); + ACE_DEBUG ((LM_DEBUG, "(%t) cancelling group\n")); + if (thr_mgr->cancel_grp (grp_id) == -1) + ACE_ERROR ((LM_DEBUG, "(%t) %p\n", "cancel_grp")); + + // Perform a barrier wait until all the threads have shut down. + thr_mgr->wait (); + + ACE_END_TEST; + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, "threads not supported on this platform\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/tests/Thread_Pool_Test.cpp b/tests/Thread_Pool_Test.cpp new file mode 100644 index 00000000000..c80375b49bf --- /dev/null +++ b/tests/Thread_Pool_Test.cpp @@ -0,0 +1,221 @@ +// ============================================================================ +// @(#)Thread_Pool_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Thread_Pool_Test.cpp +// +// = DESCRIPTION +// This test program illustrates how the ACE task synchronization +// mechanisms work in conjunction with the ACE_Task and the +// ACE_Thread_Manager. If the manual flag is not set input comes +// from stdin until the user enters a return only. This stops +// all workers via a message block of length 0. This is an +// alternative shutdown of workers compared to queue deactivate. +// +// = AUTHOR +// Karlheinz Dorn, Doug Schmidt, and Prashant Jain +// +// ============================================================================ + +#include "ace/Task.h" +#include "ace/Service_Config.h" +#include "ace/Log_Msg.h" +#include "ace/Task.h" +#include "test_config.h" + +#if defined (ACE_HAS_THREADS) + +// Number of iterations to run the test. +static size_t n_iterations = 100; + +class Thread_Pool : public ACE_Task +{ +public: + Thread_Pool (ACE_Thread_Manager *thr_mgr, int n_threads); + + virtual int svc (void); + // Iterate time printing off a message and "waiting" + // for all other threads to complete this iteration. + + virtual int put (ACE_Message_Block *mb, ACE_Time_Value *tv=0); + // This allows the producer to pass messages to the . + +private: + virtual int close (u_long); + + // = Not needed for this test. + virtual int open (void *) { return 0; } +}; + +int +Thread_Pool::close (u_long) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) close of worker\n")); + return 0; +} + +Thread_Pool::Thread_Pool (ACE_Thread_Manager *thr_mgr, + int n_threads) + : ACE_Task (thr_mgr) +{ + // Create worker threads. + if (this->activate (THR_NEW_LWP, n_threads) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "activate failed")); +} + +// Simply enqueue the Message_Block into the end of the queue. + +int +Thread_Pool::put (ACE_Message_Block *mb, ACE_Time_Value *tv) +{ + return this->putq (mb, tv); +} + +// Iterate time printing off a message and "waiting" +// for all other threads to complete this iteration. + +int +Thread_Pool::svc (void) +{ + ACE_NEW_THREAD; + // Note that the ACE_Task::svc_run () method automatically adds us to + // the Thread_Manager when the thread begins. + + int result = 0; + int count = 1; + + // Keep looping, reading a message out of the queue, until we get a + // message with a length == 0, which signals us to quit. + + for (;; count++) + { + ACE_Message_Block *mb; + + ACE_ASSERT (this->getq (mb) != -1); + + int length = mb->length (); + + if (length > 0) + ACE_DEBUG ((LM_DEBUG, + "(%t) in iteration %d, length = %d, text = \"%*s\"\n", + count, length, length - 1, mb->rd_ptr ())); + + // We're responsible for deallocating this. + delete mb; + + if (length == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%t) in iteration %d, got NULL message, exiting\n", + count)); + break; + } + } + + // Note that the ACE_Task::svc_run () method automatically removes + // us from the Thread_Manager when the thread exits. + return 0; +} + +static void +produce (Thread_Pool &thread_pool) +{ + ACE_DEBUG ((LM_DEBUG, "(%t) producer start, dumping the Thread_Pool\n")); + thread_pool.dump (); + + for (int n;;) + { + // Allocate a new message. + ACE_Message_Block *mb = new ACE_Message_Block (BUFSIZ); + +#if defined (manual) + ACE_DEBUG ((LM_DEBUG, + "(%t) press chars and enter to put a new message into task queue...")); + n = ACE_OS::read (ACE_STDIN, mb->rd_ptr (), mb->size ()); +#else // Automatically generate messages. + static int count = 0; + + ACE_OS::sprintf (mb->rd_ptr (), "%d\n", count); + + n = ACE_OS::strlen (mb->rd_ptr ()); + + if (count == n_iterations) + n = 1; // Indicate that we need to shut down. + else + count++; + + if (count == 0 || (count % 20 == 0)) + ACE_OS::sleep (1); +#endif /* manual */ + if (n > 1) + { + // Send a normal message to the waiting threads and continue + // producing. + mb->wr_ptr (n); + + // Pass the message to the Thread_Pool. + if (thread_pool.put (mb) == -1) + ACE_ERROR ((LM_ERROR, " (%t) %p\n", "put")); + } + else + { + // Send a shutdown message to the waiting threads and exit. + ACE_DEBUG ((LM_DEBUG, "\n(%t) start loop, dump of task:\n")); + thread_pool.dump (); + + for (int i = thread_pool.thr_count (); i > 0; i--) + { + ACE_DEBUG ((LM_DEBUG, + "(%t) EOF, enqueueing NULL block for thread = %d\n", + i)); + + // Enqueue a NULL message to flag each consumer to + // shutdown. + if (thread_pool.put (new ACE_Message_Block) == -1) + ACE_ERROR ((LM_ERROR, " (%t) %p\n", "put")); + } + + ACE_DEBUG ((LM_DEBUG, "\n(%t) end loop, dump of task:\n")); + thread_pool.dump (); + break; + } + } +} + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + int n_threads = ACE_MAX_THREADS; + + ACE_DEBUG ((LM_DEBUG, "(%t) argc = %d, threads = %d\n", + argc, n_threads)); + + // Create the worker tasks. + Thread_Pool thread_pool (ACE_Service_Config::thr_mgr (), + n_threads); + + // Create work for the worker tasks to process in their own threads. + produce (thread_pool); + + // Wait for all the threads to reach their exit point. + + ACE_DEBUG ((LM_DEBUG, "(%t) waiting with thread manager...\n")); + ACE_Service_Config::thr_mgr ()->wait (); + + ACE_DEBUG ((LM_DEBUG, "(%t) destroying worker tasks and exiting...\n")); + ACE_END_TEST; + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); + return 0; +} +#endif /* ACE_HAS_THREADS */ diff --git a/tests/Time_Service_Test.cpp b/tests/Time_Service_Test.cpp new file mode 100644 index 00000000000..c937ec0a006 --- /dev/null +++ b/tests/Time_Service_Test.cpp @@ -0,0 +1,77 @@ +// ============================================================================ +// @(#)Time_Service_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Time_Service_Test +// +// = DESCRIPTION +// This example tests the Time Service server and clerk +// components. The test forks and execs two processes to run both +// the clerk and the time server. The clerk and the server +// communicate for a short duration after which the main process +// kills both the processes. No command line arguments are needed +// to run the test. +// +// = AUTHOR +// Prashant Jain +// +// ============================================================================ + +#include "ace/OS.h" +#include "ace/Log_Msg.h" +#include "test_config.h" +#include "ace/Process.h" + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + + char app[BUFSIZ]; + char server_conf[BUFSIZ]; + char clerk_conf[BUFSIZ]; + + ACE_OS::sprintf (server_conf, "%s", ACE_PLATFORM "server.conf"); + ACE_OS::sprintf (clerk_conf, "%s", ACE_PLATFORM "clerk.conf"); + + ACE_OS::sprintf (app, ".." ACE_DIRECTORY_SEPARATOR_STR "netsvcs" ACE_DIRECTORY_SEPARATOR_STR + "servers" ACE_DIRECTORY_SEPARATOR_STR "main" ACE_PLATFORM_EXE_SUFFIX); + + char *s_argv[4]; + s_argv[0] = app; + s_argv[1] = "-f"; + s_argv[2] = server_conf; + s_argv[3] = 0; + + ACE_Process server; + if (server.start (s_argv) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p.\n", "Server fork failed"), 0); + else + ACE_DEBUG ((LM_DEBUG, "Server forked with pid = %d.\n", server.getpid ())); + + ACE_OS::sleep (3); + s_argv[2] = clerk_conf; + + ACE_Process clerk; + if (clerk.start (s_argv) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p.\n", "Server fork failed"), 0); + else + ACE_DEBUG ((LM_DEBUG, "Server forked with pid = %d.\n", clerk.getpid ())); + + ACE_DEBUG ((LM_DEBUG, "Sleeping...\n")); + ACE_OS::sleep (10); + + if (clerk.kill () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "Kill failed.\n"), -1); + + if (server.kill () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "Kill failed.\n"), -1); + + ACE_END_TEST; + + return 42; +} diff --git a/tests/Time_Value_Test.cpp b/tests/Time_Value_Test.cpp new file mode 100644 index 00000000000..deb937a59fd --- /dev/null +++ b/tests/Time_Value_Test.cpp @@ -0,0 +1,49 @@ +// ============================================================================ +// @(#)Time_Value_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Time_Value_Test.cpp +// +// = DESCRIPTION +// This is a simple test of ACE_Time_Value. No command line +// arguments are needed to run the test. +// +// = AUTHOR +// Prashant Jain +// +// ============================================================================ + +#include "ace/ACE.h" +#include "ace/Log_Msg.h" +#include "test_config.h" + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + + ACE_Time_Value tv1; + ACE_Time_Value tv2 (2); + ACE_Time_Value tv3 (100); + ACE_Time_Value tv4 (1, 1000000); + ACE_Time_Value tv5 (2); + ACE_Time_Value tv6 (1, -1000000); + + ACE_ASSERT (tv1 == ACE_Time_Value (0)); + ACE_ASSERT (tv2 < tv3); + ACE_ASSERT (tv2 <= tv2); + ACE_ASSERT (tv2 >= tv4); + ACE_ASSERT (tv5 >= tv6); + ACE_ASSERT (tv2 == ACE_Time_Value (1, 1000000)); + ACE_ASSERT (tv5 == tv4); + ACE_ASSERT (tv2 == tv4); + ACE_ASSERT (tv1 != tv2); + ACE_ASSERT (tv6 == tv1); + + ACE_END_TEST; + return 0; +} diff --git a/tests/Timer_Queue_Test.cpp b/tests/Timer_Queue_Test.cpp new file mode 100644 index 00000000000..c709535f655 --- /dev/null +++ b/tests/Timer_Queue_Test.cpp @@ -0,0 +1,65 @@ +// ============================================================================ +// @(#)Timer_Queue_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Timer_Queue_Test.cpp +// +// = DESCRIPTION +// This is a simple test of ACE_Timer_Queue. The test sets up a +// bunch of timers and then adds them to a timer queue. The +// functionality of the timer queue is then tested. No command line +// arguments are needed to run the test. +// +// = AUTHOR +// Prashant Jain +// +// ============================================================================ + +#include "ace/Log_Msg.h" +#include "ace/Timer_Queue.h" +#include "test_config.h" + +class Example_Handler : public ACE_Event_Handler +{ +public: + virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg) + { + ACE_ASSERT ((int) arg == 42); + return 0; + } +}; + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + + ACE_Timer_Queue tq; + Example_Handler eh; + + ACE_ASSERT (tq.is_empty ()); + ACE_ASSERT (ACE_Time_Value::zero == ACE_Time_Value (0)); + int timer_id; + + timer_id = tq.schedule (&eh, (const void *) 1, ACE_OS::gettimeofday ()); + tq.schedule (&eh, (const void *) 42, ACE_OS::gettimeofday ()); + tq.schedule (&eh, (const void *) 42, ACE_OS::gettimeofday ()); + tq.cancel (timer_id); + ACE_ASSERT (!tq.is_empty ()); + + tq.expire (ACE_OS::gettimeofday ()); + + tq.schedule (&eh, (const void *) 4, ACE_OS::gettimeofday ()); + tq.schedule (&eh, (const void *) 5, ACE_OS::gettimeofday ()); + tq.cancel (&eh); + ACE_ASSERT (tq.is_empty ()); + tq.expire (ACE_OS::gettimeofday ()); + + ACE_END_TEST; + return 0; +} + diff --git a/tests/Tokens_Test.cpp b/tests/Tokens_Test.cpp new file mode 100644 index 00000000000..70d81055742 --- /dev/null +++ b/tests/Tokens_Test.cpp @@ -0,0 +1,251 @@ +// ============================================================================ +// @(#)Tokens_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// Tokens_Test.cpp +// +// = DESCRIPTION +// This application tests the ACE Token library including local +// and remote readers/writer and mutex locks, and token +// collections. This is accomplished with the ACE Token Invariant +// utilities that allow and application to check that +// readers/writer and mutex lock invariants are always satisfied. +// Throughout this test, ACE_ASSERTs are used in conjunction with +// Token Invariant operations, so that errors are reported using +// the ACE tests convention. This application performs a local +// test and then fork_execs a token server and performs the same +// test remotely. +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#include "ace/OS.h" +#include "ace/Process.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/Local_Tokens.h" +#include "ace/Token_Collection.h" +#include "ace/Remote_Tokens.h" +#include "ace/Thread_Manager.h" +#include "ace/Service_Config.h" +#include "ace/Token_Invariants.h" +#include "test_config.h" + +typedef ACE_Token_Invariant_Manager TOKEN_INVARIANTS; + +#if defined (ACE_HAS_THREADS) + +static char *server_host = "localhost"; +static int server_port = 23456; + +struct Test_Params +{ +public: + ACE_Token_Proxy *token1_; + ACE_Token_Proxy *token2_; + const char *collection_name_; +}; + +static void * +run_thread (void *vp) +{ + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + ACE_NEW_THREAD; + Test_Params *tp = (Test_Params *) vp; + const char *name1 = tp->token1_->name (); + const char *name2 = tp->token2_->name (); + ACE_Token_Collection collection (1, tp->collection_name_); + collection.insert (*(tp->token1_)); + collection.insert (*(tp->token2_)); + + ACE_DEBUG ((LM_DEBUG, "(%t) new thread.\n")); + + int count = 50; + while (count--) + { + if (collection.acquire () == -1) + { + if (ACE_OS::last_error () == EDEADLK) + { + ACE_DEBUG ((LM_DEBUG, "deadlock detected in acquire")); + continue; + } + ACE_ERROR ((LM_ERROR, "(%t) %p acquire failed\n","run_thread")); + return (void *) -1; + } + + ACE_ASSERT ((TOKEN_INVARIANTS::instance ()->acquired (tp->token1_) == 1) || + (TOKEN_INVARIANTS::instance ()->acquired (tp->token2_) == 1)); + + ACE_DEBUG ((LM_DEBUG, "(%t) %s acquired.\n", collection.name ())); + + TOKEN_INVARIANTS::instance ()->releasing (tp->token1_); + TOKEN_INVARIANTS::instance ()->releasing (tp->token2_); + + if (collection.renew () == -1) + { + if (ACE_OS::last_error () == EDEADLK) + { + ACE_DEBUG ((LM_DEBUG, "deadlock detected")); + goto deadlock; + } + ACE_ERROR ((LM_ERROR, "(%t) %p renew failed\n","run_thread")); + return (void *) -1; + } + + ACE_ASSERT ((TOKEN_INVARIANTS::instance ()->acquired (tp->token1_) == 1) || + (TOKEN_INVARIANTS::instance ()->acquired (tp->token2_) == 1)); + + ACE_DEBUG ((LM_DEBUG, "(%t) %s renewed.\n", collection.name ())); + + deadlock: + + TOKEN_INVARIANTS::instance ()->releasing (tp->token1_); + TOKEN_INVARIANTS::instance ()->releasing (tp->token2_); + + if (collection.release () == -1) + { + ACE_ERROR ((LM_ERROR, "(%t) %p release failed\n","run_thread")); + return (void *) -1; + } + + ACE_DEBUG ((LM_DEBUG, "(%t) %s released.\n", collection.name ())); + } + + + ACE_DEBUG ((LM_DEBUG, "(%t) thread exiting.\n")); + return 0; +} + +#if defined (ACE_HAS_PTHREADS) +#define SUSPEND 0 +#else +#define SUSPEND THR_SUSPENDED +#endif + +static int +run_test (ACE_Token_Proxy *A, + ACE_Token_Proxy *B, + ACE_Token_Proxy *R, + ACE_Token_Proxy *W) +{ + // Parameters to be passed to the threads. + Test_Params tp1, tp2, tp3; + + // tp1 and tp2 can run concurrently. Neither tp1 or tp3 can run + // when tp2 is running. + tp1.collection_name_ = "A and Reader"; + tp1.token1_ = A; + tp1.token2_ = R; + + tp2.collection_name_ = "A and Writer"; + tp2.token1_ = A; + tp2.token2_ = W; + + tp3.collection_name_ = "B and Reader"; + tp3.token1_ = B; + tp3.token2_ = R; + + // Spawn off three threads. + ACE_Thread_Manager *mgr = ACE_Service_Config::thr_mgr (); + + if (mgr->spawn (ACE_THR_FUNC (run_thread), + (void *) &tp1, THR_BOUND | SUSPEND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn 1 failed"), -1); + + if (mgr->spawn (ACE_THR_FUNC (run_thread), + (void *) &tp2, THR_BOUND | SUSPEND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn 2 failed"), -1); + + if (mgr->spawn (ACE_THR_FUNC (run_thread), + (void *) &tp3, THR_BOUND | SUSPEND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn 3 failed"), -1); + +#if ! defined (ACE_HAS_PTHREADS) + if (mgr->resume_all () == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "resume failed"), -1); +#endif + + // Wait for all threads to exit. + mgr->wait (); + + ACE_DEBUG ((LM_DEBUG, "Test finished.\n")); + return 0; +} + +int +main (int argc, char* argv[]) +{ + ACE_DEBUG ((LM_DEBUG, "%s starting.\n", argv[0])); + ACE_START_TEST; + ACE_Token_Proxy *A, *B, *R, *W; + + A = new ACE_Local_Mutex ("L Mutex A", 0, 0); + B = new ACE_Local_Mutex ("L Mutex B", 0, 0); + R = new ACE_Local_RLock ("L Reader Lock", 0, 0); + W = new ACE_Local_WLock ("L Writer Lock", 0, 0); + + run_test (A,B,R,W); + + // Fork token server. + char *s_argv[4]; + + s_argv[0] = + ".." ACE_DIRECTORY_SEPARATOR_STR + "netsvcs" ACE_DIRECTORY_SEPARATOR_STR + "servers" ACE_DIRECTORY_SEPARATOR_STR + "main" ACE_PLATFORM_EXE_SUFFIX; + + s_argv[1] = "-f"; + s_argv[2] = ACE_PLATFORM "tokens.conf"; + s_argv[3] = 0; + + ACE_DEBUG ((LM_DEBUG, "Forking %s %s %s.\n", + s_argv[0], s_argv[1], s_argv[2])); + + // Start up the token server. + ACE_Process new_process; + if (new_process.start (s_argv) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p fork failed.\n", "Tokens_Tests.cpp"), 0); + else + ACE_DEBUG ((LM_DEBUG, "Server forked with pid = %d.\n", new_process.getpid ())); + + // Wait for the server to start. + ACE_OS::sleep (3); + + ACE_DEBUG ((LM_DEBUG, "Using Token Server on %s at port %d.\n", server_host, server_port)); + ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port, server_host)); + A = new ACE_Remote_Mutex ("R Mutex A", 0, 1); + B = new ACE_Remote_Mutex ("R Mutex B", 0, 1); + R = new ACE_Remote_RLock ("R Reader Lock", 0, 1); + W = new ACE_Remote_WLock ("R Writer Lock", 0, 1); + + run_test (A,B,R,W); + + // Wait for the server to finish. + ACE_OS::sleep (3); + + // Kill the token server. + if (new_process.kill () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "Kill failed.\n"), -1); + + ACE_DEBUG ((LM_DEBUG, "(%t) main thread exiting.\n")); + + ACE_END_TEST; + return 42; +} + +#else +int +main (int, char *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "threads not supported on this platform\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/tests/UNIXclerk.conf b/tests/UNIXclerk.conf new file mode 100644 index 00000000000..86d1f33a0f0 --- /dev/null +++ b/tests/UNIXclerk.conf @@ -0,0 +1,3 @@ +# Note: hostname and port number need to be concatenated separated by ":" +dynamic Logging_Strategy Service_Object * ../netsvcs/lib/libnet_svcs.so:_make_ACE_Logging_Strategy() "-s log/Time_Service_Test_Clerk.log -f OSTREAM" +dynamic Time_Server_test Service_Object *../netsvcs/lib/libnet_svcs.so:_make_ACE_TS_Clerk_Processor () "-h merengue:10222 -t 4" diff --git a/tests/UNIXserver.conf b/tests/UNIXserver.conf new file mode 100644 index 00000000000..424ebc07ee5 --- /dev/null +++ b/tests/UNIXserver.conf @@ -0,0 +1,10 @@ +# These are the services that can be linked into ACE. +# Note that you can replace the hardcoded "../lib/libnet_svcs.so" with +# a relative path if you set your LD search path correctly -- ACE will +# locate this for you automatically by reading your LD search path! +# In addition, you can replace the hardcoded "-p 20xxx" with "-p +# $PORTxxx" if you set your environment variables correctly. + +dynamic Logging_Strategy Service_Object * ../netsvcs/lib/libnet_svcs.so:_make_ACE_Logging_Strategy() "-s log/Time_Service_Test_Server.log -f OSTREAM" +dynamic Time_Service Service_Object * ../netsvcs/lib/libnet_svcs.so:_make_ACE_TS_Server_Acceptor() "-p 10222" + diff --git a/tests/UNIXtokens.conf b/tests/UNIXtokens.conf new file mode 100644 index 00000000000..f770f302b40 --- /dev/null +++ b/tests/UNIXtokens.conf @@ -0,0 +1,6 @@ +# Solaris version +# + +dynamic Logging_Strategy Service_Object * ../netsvcs/lib/libnet_svcs.so:_make_ACE_Logging_Strategy() "-s log/Tokens_Test_Server.log -f OSTREAM" +dynamic Token_Service Service_Object * ../netsvcs/lib/libnet_svcs.so:_make_ACE_Token_Acceptor() "-p 23456" + diff --git a/tests/UPIPE_SAP_Test.cpp b/tests/UPIPE_SAP_Test.cpp new file mode 100644 index 00000000000..9e5e62613e8 --- /dev/null +++ b/tests/UPIPE_SAP_Test.cpp @@ -0,0 +1,168 @@ +// ============================================================================ +// @(#)UPIPE_SAP_Test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// tests +// +// = FILENAME +// UPIPE_SAP_Test.cpp +// +// = DESCRIPTION +// This is a test that uses ACE_UPIPE_SAP and ACE_Thread for +// intra-process communication. +// +// = AUTHOR +// Gerhard Lenzer, Douglas C. Schmidt, and Prashant Jain +// +// ============================================================================ + +#include "ace/Log_Msg.h" +#include "ace/Stream.h" +#include "ace/UPIPE_Acceptor.h" +#include "ace/UPIPE_Connector.h" +#include "test_config.h" + +#if defined (ACE_HAS_THREADS) + +// Global thread manager. +static ACE_Thread_Manager thr_mgr; + +// Global pattern +static ACE_UPIPE_Addr addr ("pattern"); + +// peer1 thread. + +static void * +peer1 (void *) +{ + // Insert thread into thr_mgr. + ACE_Thread_Control thread_control (&thr_mgr); + ACE_NEW_THREAD; + + ACE_UPIPE_Stream c_stream; + + ACE_DEBUG ((LM_DEBUG, "(%t) peer1 starting connect\n")); + ACE_UPIPE_Connector con; + + if (con.connect (c_stream, addr) == -1) + ACE_DEBUG ((LM_DEBUG, "(%t) peer1 ACE_UPIPE_Connector failed\n")); + + ACE_Message_Block *mb = new ACE_Message_Block (20); + mb->copy ("hello", 6); + + if (c_stream.send (mb) == -1) + ACE_DEBUG ((LM_DEBUG, "(%t) error peer1 send\n")); + + if (c_stream.recv (mb) == -1) + ACE_DEBUG ((LM_DEBUG, "(%t) error peer1 recv\n")); + + ACE_ASSERT (ACE_OS::strcmp (mb->rd_ptr (), "thanks") == 0); + + // Free up the memory block. + delete mb; + + // Now try the send()/recv() interface. + char mytext[] = "This string is sent by peer1 as buffer"; + + ACE_DEBUG ((LM_DEBUG, "(%t) peer1 sending text\n")); + if (c_stream.send (mytext, sizeof mytext) == -1) + ACE_DEBUG ((LM_DEBUG, + "(%t) buffer send from peer1 failed\n")); + + char conbuf[30]; // Buffer to receive response. + + int i = 0; + + for (char c = ' '; c != '!'; i++) + { + if (c_stream.recv (&c, 1) == -1) + ACE_DEBUG ((LM_DEBUG, + "(%t) buffer recv from peer1 failed\n")); + else + conbuf[i] = c; + } + + conbuf[i] = '\0'; + ACE_ASSERT (ACE_OS::strcmp (conbuf, "this is the peer2 response!") + == 0); + c_stream.close (); + return 0; +} + +static void * +peer2 (void *) +{ + // Insert thread into thr_mgr. + ACE_Thread_Control thread_control (&thr_mgr); + ACE_NEW_THREAD; + + ACE_UPIPE_Acceptor acc (addr); + ACE_UPIPE_Stream s_stream; + + // Spawn a peer1 thread. + if (thr_mgr.spawn (ACE_THR_FUNC (peer1), (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), 0); + + ACE_DEBUG ((LM_DEBUG, "(%t) peer2 starting accept\n")); + + if (acc.accept (s_stream) == -1) + ACE_DEBUG ((LM_DEBUG, + "(%t) ACE_UPIPE_Acceptor.accept failed\n")); + + ACE_Message_Block *mb = 0; + + if (s_stream.recv (mb) == -1) + ACE_DEBUG ((LM_DEBUG, "(%t) peer2 recv failed\n")); + + ACE_ASSERT (ACE_OS::strcmp (mb->rd_ptr (), "hello") == 0); + + mb->wr_ptr (mb->rd_ptr ()); + mb->copy ("thanks", 7); + + if (s_stream.send (mb) == -1) + ACE_DEBUG ((LM_DEBUG, "(%t) peer2 send failed\n")); + + char s_buf[42]; + ACE_DEBUG ((LM_DEBUG, "(%t) peer2 sleeping on recv\n")); + + if (s_stream.recv (s_buf, sizeof s_buf) == -1) + ACE_DEBUG ((LM_DEBUG, "(%t) peer2 recv failed\n")); + else + ACE_ASSERT (ACE_OS::strcmp (s_buf, + "This string is sent by peer1 as buffer") == 0); + + ACE_OS::strcpy (s_buf, "this is the peer2 response!"); + + if (s_stream.send (s_buf, 30) == -1) + ACE_DEBUG ((LM_DEBUG, "(%t) peer2 send failed\n")); + + s_stream.close (); + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_START_TEST; + + // Spawn a peer2 thread. + if (thr_mgr.spawn (ACE_THR_FUNC (peer2), (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), 1); + + // Wait for peer2 and peer1 threads to exit. + thr_mgr.wait (); + + ACE_END_TEST; + + return 0; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, "threads not supported on this platform\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/tests/Win32clerk.conf b/tests/Win32clerk.conf new file mode 100644 index 00000000000..48fd13cdd04 --- /dev/null +++ b/tests/Win32clerk.conf @@ -0,0 +1,3 @@ +# Note: hostname and port number need to be concatenated separated by ":" +dynamic Logging_Strategy Service_Object * lib.dll:_make_ACE_Logging_Strategy() "-s c:\temp\log\Time_Client.log -f OSTREAM" +dynamic Time_Server_test Service_Object * lib.dll:_make_ACE_TS_Clerk_Processor () "-h localhost:10222 -t 4" diff --git a/tests/Win32server.conf b/tests/Win32server.conf new file mode 100644 index 00000000000..a6f97ecfe67 --- /dev/null +++ b/tests/Win32server.conf @@ -0,0 +1,10 @@ +# These are the services that can be linked into ACE. +# Note that you can replace the hardcoded "../lib/libnet_svcs.so" with +# a relative path if you set your LD search path correctly -- ACE will +# locate this for you automatically by reading your LD search path! +# In addition, you can replace the hardcoded "-p 20xxx" with "-p +# $PORTxxx" if you set your environment variables correctly. + +dynamic Logging_Strategy Service_Object * lib.dll:_make_ACE_Logging_Strategy() "-s c:\temp\log\Time_Server.log -f OSTREAM" +dynamic Time_Service Service_Object * lib.dll:_make_ACE_TS_Server_Acceptor() "-p 10222" + diff --git a/tests/Win32tokens.conf b/tests/Win32tokens.conf new file mode 100644 index 00000000000..ecf1a7604d7 --- /dev/null +++ b/tests/Win32tokens.conf @@ -0,0 +1,6 @@ +# NT version +# + +dynamic Logging_Strategy Service_Object * netsvcs.dll:_make_ACE_Logging_Strategy() "-s c:\temp\log\Tokens_Test_Server.log -f OSTREAM" +dynamic Token_Service Service_Object * netsvcs.dll:_make_ACE_Token_Acceptor() "-p 23456" + diff --git a/tests/run_tests.bat b/tests/run_tests.bat new file mode 100644 index 00000000000..71714312f3e --- /dev/null +++ b/tests/run_tests.bat @@ -0,0 +1,32 @@ +@echo off +@echo This is the NT version of the one-button ACE tests. +@echo on +@echo Starting tests... + +Barrier_Test +Buffer_Stream_Test +CPP_Test +Future_Test +Handle_Set_Test +Mem_Map_Test +Mutex_Test +Naming_Test +Priority_Buffer_Test +Reactors_Test +Reactor_Timer_Test +Reader_Writer_Test +Recursive_Mutex_Test +Shared_Memory_MM_Test +SPIPE_Test +SString_Test +Task_Test +Thread_Manager_Test +Thread_Pool_Test +Timer_Queue_Test +Time_Service_Test +Time_Value_Test +Tokens_Test +TSS_Test +UPIPE_SAP_Test + +@echo Tests complete... diff --git a/tests/run_tests.sh b/tests/run_tests.sh new file mode 100755 index 00000000000..861e240f842 --- /dev/null +++ b/tests/run_tests.sh @@ -0,0 +1,66 @@ +#!/bin/sh -f +# This is the UNIX version of the one-button ACE tests. +# Contributed by Michael Rueger + +run() +{ + echo running $1 + + ./$1 + + if [ ! $? ]; then + echo exit status failed - exiting + exit 1 + fi + + if [ -e core ]; then + echo dumped core - exiting + exit 1 + fi + + grep "^starting.* at " log/$1.log >/dev/null + + if [ ! $? ]; then + echo start comment not in log file - exiting + exit 1 + fi + + grep "^Exiting.* at " log/$1.log >/dev/null + + if [ ! $? ]; then + echo Exiting comment not in log file - exiting + exit 1 + fi +} + +echo "Starting tests..." +rm -f core + +run Barrier_Test +run Buffer_Stream_Test +run CPP_Test +run Handle_Set_Test +run Mem_Map_Test +run Mutex_Test +run Naming_Test +run Priority_Buffer_Test +run Reactors_Test +run Reactor_Timer_Test +run Reader_Writer_Test +run Recursive_Mutex_Test +run Shared_Memory_MM_Test +run Shared_Memory_SV_Test +run SPIPE_Test +run SString_Test +run SV_Shared_Memory_Test +run Task_Test +run Thread_Manager_Test +run Thread_Pool_Test +run Timer_Queue_Test +run Time_Service_Test +run Time_Value_Test +run TSS_Test +run UPIPE_SAP_Test + +echo "Tests complete..." + diff --git a/tests/test_config.h b/tests/test_config.h new file mode 100644 index 00000000000..d646e676e46 --- /dev/null +++ b/tests/test_config.h @@ -0,0 +1,95 @@ +/* -*- C++ -*- */ +// @(#)test_config.h 1.1 10/18/96 + +// ============================================================================ +// = FILENAME +// test_config.h +// +// = AUTHOR +// Prashant Jain and Tim Harrison +// +// ============================================================================ + +#if !defined (ACE_TEST_CONFIG_H) +#define ACE_TEST_CONFIG_H + +#include +#include + +#if defined (ACE_WIN32) +#define ACE_DEFAULT_TEST_FILE "C:\\temp\\ace_test_file" +#define ACE_TEMP_FILE_NAME "C:\\temp\\ace_temp_file" +#define ACE_LOG_DIRECTORY "C:\\temp\\log\\" +#define MAKE_PIPE_NAME(X) "\\\\.\\pipe\\"#X + +#else +#define ACE_DEFAULT_TEST_FILE "/tmp/ace_test_file" +#define ACE_TEMP_FILE_NAME "/tmp/ace_temp_file" +#define ACE_LOG_DIRECTORY "log/" +#define MAKE_PIPE_NAME(X) X + +#endif /* ACE_WIN32 */ + +const int ACE_NS_MAX_ENTRIES = 2000; +const int ACE_MAX_TIMERS = 4; +const int ACE_MAX_THREADS = 4; +const int ACE_MAX_DELAY = 10; +const int ACE_MAX_INTERVAL = 0; +const int ACE_MAX_ITERATIONS = 10; + +class ACE_Test_Output +{ +public: + ACE_Test_Output (void): output_file_ (0) + { + } + + ~ACE_Test_Output (void) + { + delete this->output_file_; + } + + void set_output (char *filename) + { + char temp[BUFSIZ]; + ACE_OS::sprintf (temp, "%s%s%s", + ACE_LOG_DIRECTORY, + ACE::basename (filename, ACE_DIRECTORY_SEPARATOR_CHAR), + ".log"); + this->output_file_ = new ofstream (temp); + + ACE_Log_Msg::instance()->msg_ostream (this->output_file_); + ACE_Log_Msg::instance()->clr_flags (ACE_Log_Msg::STDERR | ACE_Log_Msg::LOGGER ); + ACE_Log_Msg::instance()->set_flags (ACE_Log_Msg::OSTREAM); + } + + ofstream *output_file (void) + { + return this->output_file_; + } + + void flush (void) + { + this->output_file_->flush (); + } + +private: + ofstream *output_file_; +}; + +static ACE_Test_Output ace_file_stream; + +#define ACE_START_TEST \ + ace_file_stream.set_output (argv[0]); \ + ACE_DEBUG ((LM_DEBUG, "starting %s test at %T\n", argv[0])); + +#define ACE_END_TEST \ + ACE_DEBUG ((LM_DEBUG, "Ending %s test at %T\n", argv[0])); \ + ace_file_stream.flush (); + +#define ACE_NEW_THREAD \ + ACE_Log_Msg::instance()->msg_ostream (ace_file_stream.output_file ()); \ + ACE_Log_Msg::instance()->clr_flags (ACE_Log_Msg::STDERR | ACE_Log_Msg::LOGGER ); \ + ACE_Log_Msg::instance()->set_flags (ACE_Log_Msg::OSTREAM); + +#endif /* ACE_TEST_CONFIG_H */ diff --git a/tests/tests.mak b/tests/tests.mak new file mode 100644 index 00000000000..f72f77c7039 --- /dev/null +++ b/tests/tests.mak @@ -0,0 +1,3941 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +!IF "$(CFG)" == "" +CFG=Tokens_Test - Win32 Debug +!MESSAGE No configuration specified. Defaulting to Tokens_Test - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "CPP_Test - Win32 Debug" && "$(CFG)" !=\ + "Handle_Set_Test - Win32 Debug" && "$(CFG)" != "Mem_Map_Test - Win32 Debug" &&\ + "$(CFG)" != "Mutex_Test - Win32 Debug" && "$(CFG)" !=\ + "Naming_Test - Win32 Debug" && "$(CFG)" != "Reactor_Timer_Test - Win32 Debug"\ + && "$(CFG)" != "Reactors_Test - Win32 Debug" && "$(CFG)" !=\ + "SString_Test - Win32 Debug" && "$(CFG)" != "Time_Value_Test - Win32 Debug" &&\ + "$(CFG)" != "Timer_Queue_Test - Win32 Debug" && "$(CFG)" !=\ + "UPIPE_SAP_Test - Win32 Debug" && "$(CFG)" !=\ + "Priority_Buffer_Test - Win32 Debug" && "$(CFG)" !=\ + "Time_Service_Test - Win32 Debug" && "$(CFG)" != "SPIPE_Test - Win32 Debug" &&\ + "$(CFG)" != "Buffer_Stream_Test - Win32 Debug" && "$(CFG)" !=\ + "Barrier_Test - Win32 Debug" && "$(CFG)" != "Reader_Writer_Test - Win32 Debug"\ + && "$(CFG)" != "Recursive_Mutex_Test - Win32 Debug" && "$(CFG)" !=\ + "Task_Test - Win32 Debug" && "$(CFG)" != "Thread_Manager_Test - Win32 Debug" &&\ + "$(CFG)" != "TSS_Test - Win32 Debug" && "$(CFG)" !=\ + "Shared_Memory_MM_Test - Win32 Debug" && "$(CFG)" !=\ + "Thread_Pool_Test - Win32 Debug" && "$(CFG)" != "Future_Test - Win32 Debug" &&\ + "$(CFG)" != "Tokens_Test - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "tests.mak" CFG="Tokens_Test - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "CPP_Test - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "Handle_Set_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "Mem_Map_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "Mutex_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "Naming_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "Reactor_Timer_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "Reactors_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "SString_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "Time_Value_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "Timer_Queue_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "UPIPE_SAP_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "Priority_Buffer_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "Time_Service_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "SPIPE_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "Buffer_Stream_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "Barrier_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "Reader_Writer_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "Recursive_Mutex_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "Task_Test - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "Thread_Manager_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "TSS_Test - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "Shared_Memory_MM_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "Thread_Pool_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "Future_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "Tokens_Test - Win32 Debug" (based on\ + "Win32 (x86) Console Application") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "Priority_Buffer_Test - Win32 Debug" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "CPP_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "CPP_Test\Debug" +# PROP BASE Intermediate_Dir "CPP_Test\Debug" +# PROP BASE Target_Dir "CPP_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "CPP_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\CPP_Test.exe" + +CLEAN : + -@erase ".\CPP_Test.exe" + -@erase ".\Debug\CPP_Test.obj" + -@erase ".\CPP_Test.ilk" + -@erase ".\CPP_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/CPP_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/CPP_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/CPP_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/CPP_Test.obj" + +"$(OUTDIR)\CPP_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Handle_Set_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Handle_Set_Test\Debug" +# PROP BASE Intermediate_Dir "Handle_Set_Test\Debug" +# PROP BASE Target_Dir "Handle_Set_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Handle_Set_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Handle_Set_Test.exe" + +CLEAN : + -@erase ".\Handle_Set_Test.exe" + -@erase ".\Debug\Handle_Set_Test.obj" + -@erase ".\Handle_Set_Test.ilk" + -@erase ".\Handle_Set_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Handle_Set_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/Handle_Set_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/Handle_Set_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Handle_Set_Test.obj" + +"$(OUTDIR)\Handle_Set_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Mem_Map_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Mem_Map_Test\Debug" +# PROP BASE Intermediate_Dir "Mem_Map_Test\Debug" +# PROP BASE Target_Dir "Mem_Map_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Mem_Map_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Mem_Map_Test.exe" + +CLEAN : + -@erase ".\Mem_Map_Test.exe" + -@erase ".\Debug\Mem_Map_Test.obj" + -@erase ".\Mem_Map_Test.ilk" + -@erase ".\Mem_Map_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Mem_Map_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/Mem_Map_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/Mem_Map_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Mem_Map_Test.obj" + +"$(OUTDIR)\Mem_Map_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Mutex_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Mutex_Test\Debug" +# PROP BASE Intermediate_Dir "Mutex_Test\Debug" +# PROP BASE Target_Dir "Mutex_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Mutex_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Mutex_Test.exe" + +CLEAN : + -@erase ".\Mutex_Test.exe" + -@erase ".\Debug\Mutex_Test.obj" + -@erase ".\Mutex_Test.ilk" + -@erase ".\Mutex_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Mutex_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/Mutex_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/Mutex_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Mutex_Test.obj" + +"$(OUTDIR)\Mutex_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Naming_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Naming_Test\Debug" +# PROP BASE Intermediate_Dir "Naming_Test\Debug" +# PROP BASE Target_Dir "Naming_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Naming_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Naming_Test.exe" + +CLEAN : + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + -@erase ".\Naming_Test.exe" + -@erase ".\Debug\Naming_Test.obj" + -@erase ".\Naming_Test.ilk" + -@erase ".\Naming_Test.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Naming_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/Naming_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/Naming_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Naming_Test.obj" + +"$(OUTDIR)\Naming_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Reactor_Timer_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Reactor_Timer_Test\Debug" +# PROP BASE Intermediate_Dir "Reactor_Timer_Test\Debug" +# PROP BASE Target_Dir "Reactor_Timer_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Reactor_Timer_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Reactor_Timer_Test.exe" + +CLEAN : + -@erase ".\Reactor_Timer_Test.exe" + -@erase ".\Debug\Reactor_Timer_Test.obj" + -@erase ".\Reactor_Timer_Test.ilk" + -@erase ".\Reactor_Timer_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Reactor_Timer_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/Reactor_Timer_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/Reactor_Timer_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Reactor_Timer_Test.obj" + +"$(OUTDIR)\Reactor_Timer_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Reactors_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Reactors_Test\Debug" +# PROP BASE Intermediate_Dir "Reactors_Test\Debug" +# PROP BASE Target_Dir "Reactors_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Reactors_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Reactors_Test.exe" + +CLEAN : + -@erase ".\Reactors_Test.exe" + -@erase ".\Debug\Reactors_Test.obj" + -@erase ".\Reactors_Test.ilk" + -@erase ".\Reactors_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Reactors_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/Reactors_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/Reactors_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Reactors_Test.obj" + +"$(OUTDIR)\Reactors_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "SString_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "SString_Test\Debug" +# PROP BASE Intermediate_Dir "SString_Test\Debug" +# PROP BASE Target_Dir "SString_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "SString_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\SString_Test.exe" + +CLEAN : + -@erase ".\SString_Test.exe" + -@erase ".\Debug\SString_Test.obj" + -@erase ".\SString_Test.ilk" + -@erase ".\SString_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/SString_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/SString_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/SString_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/SString_Test.obj" + +"$(OUTDIR)\SString_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Time_Value_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Time_Value_Test\Debug" +# PROP BASE Intermediate_Dir "Time_Value_Test\Debug" +# PROP BASE Target_Dir "Time_Value_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Time_Value_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Time_Value_Test.exe" + +CLEAN : + -@erase ".\Time_Value_Test.exe" + -@erase ".\Debug\Time_Value_Test.obj" + -@erase ".\Time_Value_Test.ilk" + -@erase ".\Time_Value_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Time_Value_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/Time_Value_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/Time_Value_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Time_Value_Test.obj" + +"$(OUTDIR)\Time_Value_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Timer_Queue_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Timer_Queue_Test\Debug" +# PROP BASE Intermediate_Dir "Timer_Queue_Test\Debug" +# PROP BASE Target_Dir "Timer_Queue_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Timer_Queue_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Timer_Queue_Test.exe" + +CLEAN : + -@erase ".\Timer_Queue_Test.exe" + -@erase ".\Debug\Timer_Queue_Test.obj" + -@erase ".\Timer_Queue_Test.ilk" + -@erase ".\Timer_Queue_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Timer_Queue_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/Timer_Queue_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/Timer_Queue_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Timer_Queue_Test.obj" + +"$(OUTDIR)\Timer_Queue_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "UPIPE_SAP_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "UPIPE_SAP_Test\Debug" +# PROP BASE Intermediate_Dir "UPIPE_SAP_Test\Debug" +# PROP BASE Target_Dir "UPIPE_SAP_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "UPIPE_SAP_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\UPIPE_SAP_Test.exe" + +CLEAN : + -@erase ".\UPIPE_SAP_Test.exe" + -@erase ".\Debug\UPIPE_SAP_Test.obj" + -@erase ".\UPIPE_SAP_Test.ilk" + -@erase ".\UPIPE_SAP_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/UPIPE_SAP_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=wsock32.lib ace.lib odbc32.lib odbccp32.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/UPIPE_SAP_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/UPIPE_SAP_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/UPIPE_SAP_Test.obj" + +"$(OUTDIR)\UPIPE_SAP_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Priority_Buffer_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Priority_Buffer_Test\Debug" +# PROP BASE Intermediate_Dir "Priority_Buffer_Test\Debug" +# PROP BASE Target_Dir "Priority_Buffer_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Priority_Buffer_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Priority_Buffer_Test.exe" + +CLEAN : + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + -@erase ".\Priority_Buffer_Test.exe" + -@erase ".\Debug\Priority_Buffer_Test.obj" + -@erase ".\Priority_Buffer_Test.ilk" + -@erase ".\Priority_Buffer_Test.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Priority_Buffer_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/Priority_Buffer_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/Priority_Buffer_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Priority_Buffer_Test.obj" + +"$(OUTDIR)\Priority_Buffer_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Time_Service_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Time_Service_Test\Debug" +# PROP BASE Intermediate_Dir "Time_Service_Test\Debug" +# PROP BASE Target_Dir "Time_Service_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Time_Service_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Time_Service_Test.exe" + +CLEAN : + -@erase ".\Time_Service_Test.exe" + -@erase ".\Debug\Time_Service_Test.obj" + -@erase ".\Time_Service_Test.ilk" + -@erase ".\Time_Service_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Time_Service_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/Time_Service_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/Time_Service_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Time_Service_Test.obj" + +"$(OUTDIR)\Time_Service_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "SPIPE_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "SPIPE_Test\SPIPE_Te" +# PROP BASE Intermediate_Dir "SPIPE_Test\SPIPE_Te" +# PROP BASE Target_Dir "SPIPE_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "SPIPE_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\SPIPE_Test.exe" + +CLEAN : + -@erase ".\SPIPE_Test.exe" + -@erase ".\Debug\SPIPE_Test.obj" + -@erase ".\SPIPE_Test.ilk" + -@erase ".\SPIPE_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/SPIPE_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/SPIPE_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/SPIPE_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/SPIPE_Test.obj" + +"$(OUTDIR)\SPIPE_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Buffer_Stream_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Buffer_Stream_Test\Debug" +# PROP BASE Intermediate_Dir "Buffer_Stream_Test\Debug" +# PROP BASE Target_Dir "Buffer_Stream_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Buffer_Stream_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Buffer_Stream_Test.exe" + +CLEAN : + -@erase ".\Buffer_Stream_Test.exe" + -@erase ".\Debug\Buffer_Stream_Test.obj" + -@erase ".\Buffer_Stream_Test.ilk" + -@erase ".\Buffer_Stream_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Buffer_Stream_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/Buffer_Stream_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/Buffer_Stream_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Buffer_Stream_Test.obj" + +"$(OUTDIR)\Buffer_Stream_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Barrier_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Barrier_Test\Debug" +# PROP BASE Intermediate_Dir "Barrier_Test\Debug" +# PROP BASE Target_Dir "Barrier_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Barrier_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Barrier_Test.exe" + +CLEAN : + -@erase ".\Barrier_Test.exe" + -@erase ".\Debug\Barrier_Test.obj" + -@erase ".\Barrier_Test.ilk" + -@erase ".\Barrier_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Barrier_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/Barrier_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/Barrier_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Barrier_Test.obj" + +"$(OUTDIR)\Barrier_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Reader_Writer_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Reader_Writer_Test\Debug" +# PROP BASE Intermediate_Dir "Reader_Writer_Test\Debug" +# PROP BASE Target_Dir "Reader_Writer_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Reader_Writer_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Reader_Writer_Test.exe" + +CLEAN : + -@erase ".\Reader_Writer_Test.exe" + -@erase ".\Debug\Reader_Writer_Test.obj" + -@erase ".\Reader_Writer_Test.ilk" + -@erase ".\Reader_Writer_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Reader_Writer_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/Reader_Writer_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/Reader_Writer_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Reader_Writer_Test.obj" + +"$(OUTDIR)\Reader_Writer_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Recursive_Mutex_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Recursive_Mutex_Test\Debug" +# PROP BASE Intermediate_Dir "Recursive_Mutex_Test\Debug" +# PROP BASE Target_Dir "Recursive_Mutex_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Recursive_Mutex_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Recursive_Mutex_Test.exe" + +CLEAN : + -@erase ".\Recursive_Mutex_Test.exe" + -@erase ".\Debug\Recursive_Mutex_Test.obj" + -@erase ".\Recursive_Mutex_Test.ilk" + -@erase ".\Recursive_Mutex_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Recursive_Mutex_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/Recursive_Mutex_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/Recursive_Mutex_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Recursive_Mutex_Test.obj" + +"$(OUTDIR)\Recursive_Mutex_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Task_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Task_Test\Debug" +# PROP BASE Intermediate_Dir "Task_Test\Debug" +# PROP BASE Target_Dir "Task_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Task_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Task_Test.exe" + +CLEAN : + -@erase ".\Task_Test.exe" + -@erase ".\Debug\Task_Test.obj" + -@erase ".\Task_Test.ilk" + -@erase ".\Task_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Task_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/Task_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/Task_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Task_Test.obj" + +"$(OUTDIR)\Task_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Thread_Manager_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Thread_Manager_Test\Debug" +# PROP BASE Intermediate_Dir "Thread_Manager_Test\Debug" +# PROP BASE Target_Dir "Thread_Manager_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Thread_Manager_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Thread_Manager_Test.exe" + +CLEAN : + -@erase ".\Thread_Manager_Test.exe" + -@erase ".\Debug\Thread_Manager_Test.obj" + -@erase ".\Thread_Manager_Test.ilk" + -@erase ".\Thread_Manager_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Thread_Manager_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/Thread_Manager_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/Thread_Manager_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Thread_Manager_Test.obj" + +"$(OUTDIR)\Thread_Manager_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "TSS_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "TSS_Test\Debug" +# PROP BASE Intermediate_Dir "TSS_Test\Debug" +# PROP BASE Target_Dir "TSS_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "TSS_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\TSS_Test.exe" + +CLEAN : + -@erase ".\TSS_Test.exe" + -@erase ".\Debug\TSS_Test.obj" + -@erase ".\TSS_Test.ilk" + -@erase ".\TSS_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/TSS_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/TSS_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/TSS_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/TSS_Test.obj" + +"$(OUTDIR)\TSS_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Shared_Memory_MM_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Shared_Memory_MM_Test\Debug" +# PROP BASE Intermediate_Dir "Shared_Memory_MM_Test\Debug" +# PROP BASE Target_Dir "Shared_Memory_MM_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Shared_Memory_MM_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Shared_Memory_MM_Test.exe" + +CLEAN : + -@erase ".\Shared_Memory_MM_Test.exe" + -@erase ".\Debug\Shared_Memory_MM_Test.obj" + -@erase ".\Shared_Memory_MM_Test.ilk" + -@erase ".\Shared_Memory_MM_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Shared_Memory_MM_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=odbc32.lib odbccp32.lib wsock32.lib ace.lib kernel32.lib\ + user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib\ + ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/Shared_Memory_MM_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/Shared_Memory_MM_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Shared_Memory_MM_Test.obj" + +"$(OUTDIR)\Shared_Memory_MM_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Thread_Pool_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Thread_Pool_Test\Debug" +# PROP BASE Intermediate_Dir "Thread_Pool_Test\Debug" +# PROP BASE Target_Dir "Thread_Pool_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Thread_Pool_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Thread_Pool_Test.exe" + +CLEAN : + -@erase ".\Thread_Pool_Test.exe" + -@erase ".\Debug\Thread_Pool_Test.obj" + -@erase ".\Thread_Pool_Test.ilk" + -@erase ".\Thread_Pool_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Thread_Pool_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ace.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib\ + winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib\ + uuid.lib ace.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/Thread_Pool_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/Thread_Pool_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Thread_Pool_Test.obj" + +"$(OUTDIR)\Thread_Pool_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Future_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Future_Test\Debug" +# PROP BASE Intermediate_Dir "Future_Test\Debug" +# PROP BASE Target_Dir "Future_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Future_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Future_Test.exe" + +CLEAN : + -@erase ".\Future_Test.exe" + -@erase ".\Debug\Future_Test.obj" + -@erase ".\Future_Test.ilk" + -@erase ".\Future_Test.pdb" + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Future_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ace.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib\ + winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib\ + uuid.lib ace.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/Future_Test.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)/Future_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Future_Test.obj" + +"$(OUTDIR)\Future_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "Tokens_Test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Tokens_Test\Debug" +# PROP BASE Intermediate_Dir "Tokens_Test\Debug" +# PROP BASE Target_Dir "Tokens_Test" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "." +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "Tokens_Test" +OUTDIR=.\. +INTDIR=.\Debug + +ALL : "$(OUTDIR)\Tokens_Test.exe" + +CLEAN : + -@erase ".\Debug\vc40.pdb" + -@erase ".\Debug\vc40.idb" + -@erase ".\Tokens_Test.exe" + -@erase ".\Debug\Tokens_Test.obj" + -@erase ".\Tokens_Test.ilk" + -@erase ".\Tokens_Test.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +"$(INTDIR)" : + if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +CPP_OBJS=.\Debug/ +CPP_SBRS= +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/Tokens_Test.bsc" +BSC32_SBRS= +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ace.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ace.lib /nologo\ + /subsystem:console /incremental:yes /pdb:"$(OUTDIR)/Tokens_Test.pdb" /debug\ + /machine:I386 /out:"$(OUTDIR)/Tokens_Test.exe" +LINK32_OBJS= \ + "$(INTDIR)/Tokens_Test.obj" + +"$(OUTDIR)\Tokens_Test.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\ + /Fp"$(INTDIR)/CPP_Test.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +################################################################################ +# Begin Target + +# Name "CPP_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\CPP_Test.cpp + +!IF "$(CFG)" == "CPP_Test - Win32 Debug" + +DEP_CPP_CPP_T=\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\SOCK_Connector.h"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\SOCK_Connector.i"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + + +"$(INTDIR)\CPP_Test.obj" : $(SOURCE) $(DEP_CPP_CPP_T) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Handle_Set_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Handle_Set_Test.cpp + +!IF "$(CFG)" == "Handle_Set_Test - Win32 Debug" + +DEP_CPP_HANDL=\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + + +"$(INTDIR)\Handle_Set_Test.obj" : $(SOURCE) $(DEP_CPP_HANDL) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Mem_Map_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Mem_Map_Test.cpp + +!IF "$(CFG)" == "Mem_Map_Test - Win32 Debug" + +DEP_CPP_MEM_M=\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + + +"$(INTDIR)\Mem_Map_Test.obj" : $(SOURCE) $(DEP_CPP_MEM_M) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Mutex_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Mutex_Test.cpp + +!IF "$(CFG)" == "Mutex_Test - Win32 Debug" + +DEP_CPP_MUTEX=\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + + +"$(INTDIR)\Mutex_Test.obj" : $(SOURCE) $(DEP_CPP_MUTEX) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Naming_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Naming_Test.cpp + +!IF "$(CFG)" == "Naming_Test - Win32 Debug" + +DEP_CPP_NAMIN=\ + {$(INCLUDE)}"\ace\SString.h"\ + {$(INCLUDE)}"\ace\Naming_Context.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\SString.i"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Name_Proxy.h"\ + {$(INCLUDE)}"\ace\Name_Space.h"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Connector.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Name_Request_Reply.h"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\SOCK_Connector.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + +NODEP_CPP_NAMIN=\ + ".\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\Naming_Test.obj" : $(SOURCE) $(DEP_CPP_NAMIN) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Reactor_Timer_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Reactor_Timer_Test.cpp + +!IF "$(CFG)" == "Reactor_Timer_Test - Win32 Debug" + +DEP_CPP_REACT=\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + +NODEP_CPP_REACT=\ + ".\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\Reactor_Timer_Test.obj" : $(SOURCE) $(DEP_CPP_REACT) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Reactors_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Reactors_Test.cpp + +!IF "$(CFG)" == "Reactors_Test - Win32 Debug" + +DEP_CPP_REACTO=\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Task.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Message_Queue.h"\ + {$(INCLUDE)}"\ace\Task.i"\ + {$(INCLUDE)}"\ace\Task.cpp"\ + {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\ + {$(INCLUDE)}"\ace\Message_Queue.i"\ + {$(INCLUDE)}"\ace\Message_Queue.cpp"\ + {$(INCLUDE)}"\ace\Module.h"\ + {$(INCLUDE)}"\ace\Module.i"\ + {$(INCLUDE)}"\ace\Module.cpp"\ + {$(INCLUDE)}"\ace\Stream_Modules.h"\ + {$(INCLUDE)}"\ace\Stream_Modules.i"\ + {$(INCLUDE)}"\ace\Stream_Modules.cpp"\ + +NODEP_CPP_REACTO=\ + ".\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\Reactors_Test.obj" : $(SOURCE) $(DEP_CPP_REACTO) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "SString_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\SString_Test.cpp + +!IF "$(CFG)" == "SString_Test - Win32 Debug" + +DEP_CPP_SSTRI=\ + {$(INCLUDE)}"\ace\SString.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\SString.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + + +"$(INTDIR)\SString_Test.obj" : $(SOURCE) $(DEP_CPP_SSTRI) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Time_Value_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Time_Value_Test.cpp + +!IF "$(CFG)" == "Time_Value_Test - Win32 Debug" + +DEP_CPP_TIME_=\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + + +"$(INTDIR)\Time_Value_Test.obj" : $(SOURCE) $(DEP_CPP_TIME_) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Timer_Queue_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Timer_Queue_Test.cpp + +!IF "$(CFG)" == "Timer_Queue_Test - Win32 Debug" + +DEP_CPP_TIMER=\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread.i"\ + + +"$(INTDIR)\Timer_Queue_Test.obj" : $(SOURCE) $(DEP_CPP_TIMER) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "UPIPE_SAP_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\UPIPE_SAP_Test.cpp + +!IF "$(CFG)" == "UPIPE_SAP_Test - Win32 Debug" + +DEP_CPP_UPIPE=\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Stream.h"\ + {$(INCLUDE)}"\ace\UPIPE_Acceptor.h"\ + {$(INCLUDE)}"\ace\UPIPE_Connector.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Module.h"\ + {$(INCLUDE)}"\ace\Stream.i"\ + {$(INCLUDE)}"\ace\Stream.cpp"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\Task.h"\ + {$(INCLUDE)}"\ace\Module.i"\ + {$(INCLUDE)}"\ace\Module.cpp"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Message_Queue.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Task.i"\ + {$(INCLUDE)}"\ace\Task.cpp"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Message_Queue.i"\ + {$(INCLUDE)}"\ace\Message_Queue.cpp"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\Stream_Modules.h"\ + {$(INCLUDE)}"\ace\Stream_Modules.i"\ + {$(INCLUDE)}"\ace\Stream_Modules.cpp"\ + {$(INCLUDE)}"\ace\UPIPE_Stream.h"\ + {$(INCLUDE)}"\ace\SPIPE_Acceptor.h"\ + {$(INCLUDE)}"\ace\UPIPE_Acceptor.i"\ + {$(INCLUDE)}"\ace\SPIPE.h"\ + {$(INCLUDE)}"\ace\UPIPE_Addr.h"\ + {$(INCLUDE)}"\ace\UPIPE_Stream.i"\ + {$(INCLUDE)}"\ace\SPIPE_Addr.h"\ + {$(INCLUDE)}"\ace\SPIPE.i"\ + {$(INCLUDE)}"\ace\SPIPE_Addr.i"\ + {$(INCLUDE)}"\ace\SPIPE_Stream.h"\ + {$(INCLUDE)}"\ace\Str_Buf.h"\ + {$(INCLUDE)}"\ace\SPIPE_Stream.i"\ + {$(INCLUDE)}"\ace\UPIPE_Connector.i"\ + +NODEP_CPP_UPIPE=\ + ".\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\UPIPE_SAP_Test.obj" : $(SOURCE) $(DEP_CPP_UPIPE) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Priority_Buffer_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Priority_Buffer_Test.cpp +DEP_CPP_PRIOR=\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Message_Queue.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\ + {$(INCLUDE)}"\ace\Message_Queue.i"\ + {$(INCLUDE)}"\ace\Message_Queue.cpp"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + +NODEP_CPP_PRIOR=\ + ".\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\Priority_Buffer_Test.obj" : $(SOURCE) $(DEP_CPP_PRIOR) "$(INTDIR)" + + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Time_Service_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Time_Service_Test.cpp + +!IF "$(CFG)" == "Time_Service_Test - Win32 Debug" + +DEP_CPP_TIME_S=\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\Process.h"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\ARGV.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Svc_Handler.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Acceptor.h"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.h"\ + {$(INCLUDE)}"\ace\Process.i"\ + {$(INCLUDE)}"\ace\ARGV.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Task.h"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\Svc_Handler.i"\ + {$(INCLUDE)}"\ace\Svc_Handler.cpp"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Message_Queue.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Task.i"\ + {$(INCLUDE)}"\ace\Task.cpp"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\ + {$(INCLUDE)}"\ace\Message_Queue.i"\ + {$(INCLUDE)}"\ace\Message_Queue.cpp"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Module.h"\ + {$(INCLUDE)}"\ace\Module.i"\ + {$(INCLUDE)}"\ace\Module.cpp"\ + {$(INCLUDE)}"\ace\Stream_Modules.h"\ + {$(INCLUDE)}"\ace\Stream_Modules.i"\ + {$(INCLUDE)}"\ace\Stream_Modules.cpp"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Dynamic.h"\ + {$(INCLUDE)}"\ace\Dynamic.i"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Strategies.h"\ + {$(INCLUDE)}"\ace\Acceptor.i"\ + {$(INCLUDE)}"\ace\Acceptor.cpp"\ + {$(INCLUDE)}"\ace\Strategies.cpp"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.i"\ + +NODEP_CPP_TIME_S=\ + ".\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\Time_Service_Test.obj" : $(SOURCE) $(DEP_CPP_TIME_S) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "SPIPE_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\SPIPE_Test.cpp + +!IF "$(CFG)" == "SPIPE_Test - Win32 Debug" + +DEP_CPP_SPIPE=\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\SPIPE_Addr.h"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\ace\SPIPE_Connector.h"\ + {$(INCLUDE)}"\ace\SPIPE_Acceptor.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\SPIPE_Addr.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\SPIPE_Stream.h"\ + {$(INCLUDE)}"\ace\SPIPE_Connector.i"\ + {$(INCLUDE)}"\ace\SPIPE.h"\ + {$(INCLUDE)}"\ace\Str_Buf.h"\ + {$(INCLUDE)}"\ace\SPIPE_Stream.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SPIPE.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + + +"$(INTDIR)\SPIPE_Test.obj" : $(SOURCE) $(DEP_CPP_SPIPE) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Buffer_Stream_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Buffer_Stream_Test.cpp + +!IF "$(CFG)" == "Buffer_Stream_Test - Win32 Debug" + +DEP_CPP_BUFFE=\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Stream.h"\ + {$(INCLUDE)}"\ace\Module.h"\ + {$(INCLUDE)}"\ace\Task.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\ + {$(INCLUDE)}"\ace\Stream.i"\ + {$(INCLUDE)}"\ace\Stream.cpp"\ + {$(INCLUDE)}"\ace\Stream_Modules.h"\ + {$(INCLUDE)}"\ace\Stream_Modules.i"\ + {$(INCLUDE)}"\ace\Stream_Modules.cpp"\ + {$(INCLUDE)}"\ace\Module.i"\ + {$(INCLUDE)}"\ace\Module.cpp"\ + {$(INCLUDE)}"\ace\Message_Queue.h"\ + {$(INCLUDE)}"\ace\Task.i"\ + {$(INCLUDE)}"\ace\Task.cpp"\ + {$(INCLUDE)}"\ace\Message_Queue.i"\ + {$(INCLUDE)}"\ace\Message_Queue.cpp"\ + +NODEP_CPP_BUFFE=\ + ".\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\Buffer_Stream_Test.obj" : $(SOURCE) $(DEP_CPP_BUFFE) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Barrier_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Barrier_Test.cpp +DEP_CPP_BARRI=\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + +NODEP_CPP_BARRI=\ + ".\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\Barrier_Test.obj" : $(SOURCE) $(DEP_CPP_BARRI) "$(INTDIR)" + + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Reader_Writer_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Reader_Writer_Test.cpp + +!IF "$(CFG)" == "Reader_Writer_Test - Win32 Debug" + +DEP_CPP_READE=\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Get_Opt.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Get_Opt.i"\ + + +"$(INTDIR)\Reader_Writer_Test.obj" : $(SOURCE) $(DEP_CPP_READE) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Recursive_Mutex_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Recursive_Mutex_Test.cpp + +!IF "$(CFG)" == "Recursive_Mutex_Test - Win32 Debug" + +DEP_CPP_RECUR=\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Get_Opt.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\Get_Opt.i"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + +NODEP_CPP_RECUR=\ + ".\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\Recursive_Mutex_Test.obj" : $(SOURCE) $(DEP_CPP_RECUR) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Task_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Task_Test.cpp + +!IF "$(CFG)" == "Task_Test - Win32 Debug" + +DEP_CPP_TASK_=\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Task.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\Message_Queue.h"\ + {$(INCLUDE)}"\ace\Task.i"\ + {$(INCLUDE)}"\ace\Task.cpp"\ + {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\ + {$(INCLUDE)}"\ace\Message_Queue.i"\ + {$(INCLUDE)}"\ace\Message_Queue.cpp"\ + {$(INCLUDE)}"\ace\Module.h"\ + {$(INCLUDE)}"\ace\Module.i"\ + {$(INCLUDE)}"\ace\Module.cpp"\ + {$(INCLUDE)}"\ace\Stream_Modules.h"\ + {$(INCLUDE)}"\ace\Stream_Modules.i"\ + {$(INCLUDE)}"\ace\Stream_Modules.cpp"\ + +NODEP_CPP_TASK_=\ + ".\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\Task_Test.obj" : $(SOURCE) $(DEP_CPP_TASK_) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Thread_Manager_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Thread_Manager_Test.cpp + +!IF "$(CFG)" == "Thread_Manager_Test - Win32 Debug" + +DEP_CPP_THREA=\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + +NODEP_CPP_THREA=\ + ".\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\Thread_Manager_Test.obj" : $(SOURCE) $(DEP_CPP_THREA) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "TSS_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\TSS_Test.cpp + +!IF "$(CFG)" == "TSS_Test - Win32 Debug" + +DEP_CPP_TSS_T=\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + +NODEP_CPP_TSS_T=\ + ".\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\TSS_Test.obj" : $(SOURCE) $(DEP_CPP_TSS_T) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Shared_Memory_MM_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Shared_Memory_MM_Test.cpp + +!IF "$(CFG)" == "Shared_Memory_MM_Test - Win32 Debug" + +DEP_CPP_SHARE=\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Shared_Memory_MM.h"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Shared_Memory.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Shared_Memory_MM.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + + +"$(INTDIR)\Shared_Memory_MM_Test.obj" : $(SOURCE) $(DEP_CPP_SHARE) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Thread_Pool_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Thread_Pool_Test.cpp + +!IF "$(CFG)" == "Thread_Pool_Test - Win32 Debug" + +DEP_CPP_THREAD=\ + {$(INCLUDE)}"\ace\Task.h"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Message_Queue.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\Task.i"\ + {$(INCLUDE)}"\ace\Task.cpp"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\ + {$(INCLUDE)}"\ace\Message_Queue.i"\ + {$(INCLUDE)}"\ace\Message_Queue.cpp"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Module.h"\ + {$(INCLUDE)}"\ace\Module.i"\ + {$(INCLUDE)}"\ace\Module.cpp"\ + {$(INCLUDE)}"\ace\Stream_Modules.h"\ + {$(INCLUDE)}"\ace\Stream_Modules.i"\ + {$(INCLUDE)}"\ace\Stream_Modules.cpp"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + +NODEP_CPP_THREAD=\ + ".\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\Thread_Pool_Test.obj" : $(SOURCE) $(DEP_CPP_THREAD) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Future_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Future_Test.cpp + +!IF "$(CFG)" == "Future_Test - Win32 Debug" + +DEP_CPP_FUTUR=\ + {$(INCLUDE)}"\ace\Task.h"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Message_Queue.h"\ + {$(INCLUDE)}"\ace\Future.h"\ + {$(INCLUDE)}"\ace\Method_Object.h"\ + {$(INCLUDE)}"\ace\Activation_Queue.h"\ + {$(INCLUDE)}"\ace\Auto_Ptr.h"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\Task.i"\ + {$(INCLUDE)}"\ace\Task.cpp"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Module.h"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Module.i"\ + {$(INCLUDE)}"\ace\Module.cpp"\ + {$(INCLUDE)}"\ace\Stream_Modules.h"\ + {$(INCLUDE)}"\ace\Stream_Modules.i"\ + {$(INCLUDE)}"\ace\Stream_Modules.cpp"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\ + {$(INCLUDE)}"\ace\Message_Queue.i"\ + {$(INCLUDE)}"\ace\Message_Queue.cpp"\ + {$(INCLUDE)}"\ace\Future.cpp"\ + {$(INCLUDE)}"\ace\Auto_Ptr.i"\ + {$(INCLUDE)}"\ace\Auto_Ptr.cpp"\ + +NODEP_CPP_FUTUR=\ + ".\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\Future_Test.obj" : $(SOURCE) $(DEP_CPP_FUTUR) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +################################################################################ +# Begin Target + +# Name "Tokens_Test - Win32 Debug" +################################################################################ +# Begin Source File + +SOURCE=.\Tokens_Test.cpp + +!IF "$(CFG)" == "Tokens_Test - Win32 Debug" + +DEP_CPP_TOKEN=\ + {$(INCLUDE)}"\ace\OS.h"\ + {$(INCLUDE)}"\ace\Process.h"\ + {$(INCLUDE)}"\ace\Log_Msg.h"\ + {$(INCLUDE)}"\ace\Get_Opt.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.h"\ + {$(INCLUDE)}"\ace\Token_Collection.h"\ + {$(INCLUDE)}"\ace\Remote_Tokens.h"\ + {$(INCLUDE)}"\ace\Thread_Manager.h"\ + {$(INCLUDE)}"\ace\Service_Config.h"\ + {$(INCLUDE)}"\ace\Token_Invariants.h"\ + ".\test_config.h"\ + {$(INCLUDE)}"\ace\Time_Value.h"\ + {$(INCLUDE)}"\sys\TYPES.H"\ + {$(INCLUDE)}"\sys\STAT.H"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\ace\Trace.h"\ + {$(INCLUDE)}"\ace\OS.i"\ + {$(INCLUDE)}"\ace\config.h"\ + {$(INCLUDE)}"\ace\Time_Value.i"\ + {$(INCLUDE)}"\ace\ARGV.h"\ + {$(INCLUDE)}"\ace\ACE.h"\ + {$(INCLUDE)}"\ace\Mem_Map.h"\ + {$(INCLUDE)}"\ace\Svc_Handler.h"\ + {$(INCLUDE)}"\ace\Synch.h"\ + {$(INCLUDE)}"\ace\Acceptor.h"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.h"\ + {$(INCLUDE)}"\ace\Process.i"\ + {$(INCLUDE)}"\ace\ARGV.i"\ + {$(INCLUDE)}"\ace\ACE.i"\ + {$(INCLUDE)}"\ace\Mem_Map.i"\ + {$(INCLUDE)}"\ace\Synch_Options.h"\ + {$(INCLUDE)}"\ace\Task.h"\ + {$(INCLUDE)}"\ace\Synch_T.h"\ + {$(INCLUDE)}"\ace\Svc_Handler.i"\ + {$(INCLUDE)}"\ace\Svc_Handler.cpp"\ + {$(INCLUDE)}"\ace\Service_Object.h"\ + {$(INCLUDE)}"\ace\Message_Queue.h"\ + {$(INCLUDE)}"\ace\Task.i"\ + {$(INCLUDE)}"\ace\Task.cpp"\ + {$(INCLUDE)}"\ace\Shared_Object.h"\ + {$(INCLUDE)}"\ace\Event_Handler.h"\ + {$(INCLUDE)}"\ace\Service_Object.i"\ + {$(INCLUDE)}"\ace\Shared_Object.i"\ + {$(INCLUDE)}"\ace\Event_Handler.i"\ + {$(INCLUDE)}"\ace\Message_Block.h"\ + {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\ + {$(INCLUDE)}"\ace\Message_Queue.i"\ + {$(INCLUDE)}"\ace\Message_Queue.cpp"\ + {$(INCLUDE)}"\ace\Malloc.h"\ + {$(INCLUDE)}"\ace\Message_Block.i"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\ + {$(INCLUDE)}"\ace\Malloc.i"\ + {$(INCLUDE)}"\ace\Malloc_T.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\ + {$(INCLUDE)}"\ace\Malloc_T.i"\ + {$(INCLUDE)}"\ace\Malloc_T.cpp"\ + {$(INCLUDE)}"\ace\Signal.h"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\ + {$(INCLUDE)}"\ace\Memory_Pool.i"\ + {$(INCLUDE)}"\ace\Set.h"\ + {$(INCLUDE)}"\ace\Signal.i"\ + {$(INCLUDE)}"\ace\Set.i"\ + {$(INCLUDE)}"\ace\Set.cpp"\ + {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\ + {$(INCLUDE)}"\ace\Module.h"\ + {$(INCLUDE)}"\ace\Module.i"\ + {$(INCLUDE)}"\ace\Module.cpp"\ + {$(INCLUDE)}"\ace\Stream_Modules.h"\ + {$(INCLUDE)}"\ace\Stream_Modules.i"\ + {$(INCLUDE)}"\ace\Stream_Modules.cpp"\ + {$(INCLUDE)}"\ace\Synch_T.i"\ + {$(INCLUDE)}"\ace\Synch_T.cpp"\ + {$(INCLUDE)}"\ace\Thread.h"\ + {$(INCLUDE)}"\ace\Thread.i"\ + {$(INCLUDE)}"\ace\Dynamic.h"\ + {$(INCLUDE)}"\ace\Dynamic.i"\ + {$(INCLUDE)}"\ace\Synch.i"\ + {$(INCLUDE)}"\ace\Strategies.h"\ + {$(INCLUDE)}"\ace\Acceptor.i"\ + {$(INCLUDE)}"\ace\Acceptor.cpp"\ + {$(INCLUDE)}"\ace\Strategies.cpp"\ + {$(INCLUDE)}"\ace\SOCK_Stream.h"\ + {$(INCLUDE)}"\ace\SOCK_Acceptor.i"\ + {$(INCLUDE)}"\ace\SOCK_IO.h"\ + {$(INCLUDE)}"\ace\INET_Addr.h"\ + {$(INCLUDE)}"\ace\SOCK_Stream.i"\ + {$(INCLUDE)}"\ace\SOCK.h"\ + {$(INCLUDE)}"\ace\SOCK_IO.i"\ + {$(INCLUDE)}"\ace\Addr.h"\ + {$(INCLUDE)}"\ace\IPC_SAP.h"\ + {$(INCLUDE)}"\ace\SOCK.i"\ + {$(INCLUDE)}"\ace\Addr.i"\ + {$(INCLUDE)}"\ace\IPC_SAP.i"\ + {$(INCLUDE)}"\ace\INET_Addr.i"\ + {$(INCLUDE)}"\ace\Log_Record.h"\ + {$(INCLUDE)}"\ace\Log_Priority.h"\ + {$(INCLUDE)}"\ace\Log_Record.i"\ + {$(INCLUDE)}"\ace\Get_Opt.i"\ + {$(INCLUDE)}"\ace\Stack.h"\ + {$(INCLUDE)}"\ace\Map_Manager.h"\ + {$(INCLUDE)}"\ace\Local_Tokens.i"\ + {$(INCLUDE)}"\ace\Stack.i"\ + {$(INCLUDE)}"\ace\Stack.cpp"\ + {$(INCLUDE)}"\ace\Map_Manager.i"\ + {$(INCLUDE)}"\ace\Map_Manager.cpp"\ + {$(INCLUDE)}"\ace\SString.h"\ + {$(INCLUDE)}"\ace\Token_Collection.i"\ + {$(INCLUDE)}"\ace\SString.i"\ + {$(INCLUDE)}"\ace\SOCK_Connector.h"\ + {$(INCLUDE)}"\ace\Token_Request_Reply.h"\ + {$(INCLUDE)}"\ace\Remote_Tokens.i"\ + {$(INCLUDE)}"\ace\SOCK_Connector.i"\ + {$(INCLUDE)}"\ace\Token_Request_Reply.i"\ + {$(INCLUDE)}"\ace\Thread_Manager.i"\ + {$(INCLUDE)}"\ace\Proactor.h"\ + {$(INCLUDE)}"\ace\ReactorEx.h"\ + {$(INCLUDE)}"\ace\Service_Config.i"\ + {$(INCLUDE)}"\ace\Reactor.h"\ + {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\ + {$(INCLUDE)}"\ace\Timer_Queue.h"\ + {$(INCLUDE)}"\ace\Proactor.i"\ + {$(INCLUDE)}"\ace\Timer_Queue.i"\ + {$(INCLUDE)}"\ace\Token.h"\ + {$(INCLUDE)}"\ace\ReactorEx.i"\ + {$(INCLUDE)}"\ace\Token.i"\ + {$(INCLUDE)}"\ace\Handle_Set.h"\ + {$(INCLUDE)}"\ace\Pipe.h"\ + {$(INCLUDE)}"\ace\Reactor.i"\ + {$(INCLUDE)}"\ace\Handle_Set.i"\ + {$(INCLUDE)}"\ace\Pipe.i"\ + {$(INCLUDE)}"\ace\Token_Invariants.i"\ + +NODEP_CPP_TOKEN=\ + ".\..\ace\ace\Sync_T.h"\ + + +"$(INTDIR)\Tokens_Test.obj" : $(SOURCE) $(DEP_CPP_TOKEN) "$(INTDIR)" + + +!ENDIF + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/tests/tests.mdp b/tests/tests.mdp new file mode 100644 index 00000000000..384901514ca Binary files /dev/null and b/tests/tests.mdp differ -- cgit v1.2.1