summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1996-10-21 21:41:34 +0000
committerlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1996-10-21 21:41:34 +0000
commita5fdebc5f6375078ec1763850a4ca23ec7fe6458 (patch)
treebcf0a25c3d45a209a6e3ac37b233a4812f29c732
downloadATCD-a5fdebc5f6375078ec1763850a4ca23ec7fe6458.tar.gz
Initial revision
-rw-r--r--ACE-categories430
-rw-r--r--ACE-install.sh365
-rw-r--r--BIBLIOGRAPHY618
-rw-r--r--ChangeLog-9352
-rw-r--r--ChangeLog-941027
-rw-r--r--ChangeLog-954179
-rw-r--r--ChangeLog-96a3888
-rw-r--r--ChangeLog-96b2760
-rw-r--r--FAQ1877
-rw-r--r--INSTALL440
-rw-r--r--Makefile80
-rw-r--r--README615
-rw-r--r--VERSION4
-rw-r--r--ace/ACE.cpp738
-rw-r--r--ace/ACE.h237
-rw-r--r--ace/ACE.i61
-rw-r--r--ace/ARGV.cpp202
-rw-r--r--ace/ARGV.h80
-rw-r--r--ace/ARGV.i32
-rw-r--r--ace/Acceptor.cpp969
-rw-r--r--ace/Acceptor.h479
-rw-r--r--ace/Acceptor.i4
-rw-r--r--ace/Activation_Queue.cpp70
-rw-r--r--ace/Activation_Queue.h63
-rw-r--r--ace/Addr.cpp44
-rw-r--r--ace/Addr.h93
-rw-r--r--ace/Addr.i77
-rw-r--r--ace/Auto_Ptr.cpp50
-rw-r--r--ace/Auto_Ptr.h101
-rw-r--r--ace/Auto_Ptr.i151
-rw-r--r--ace/CORBA_Handler.cpp522
-rw-r--r--ace/CORBA_Handler.h238
-rw-r--r--ace/CORBA_Handler.i56
-rw-r--r--ace/CORBA_Ref.cpp86
-rw-r--r--ace/CORBA_Ref.h80
-rw-r--r--ace/CORBA_Ref.i4
-rw-r--r--ace/Connector.cpp533
-rw-r--r--ace/Connector.h279
-rw-r--r--ace/Connector.i4
-rw-r--r--ace/DEV.cpp54
-rw-r--r--ace/DEV.h71
-rw-r--r--ace/DEV.i6
-rw-r--r--ace/DEV_Addr.cpp65
-rw-r--r--ace/DEV_Addr.h75
-rw-r--r--ace/DEV_Addr.i65
-rw-r--r--ace/DEV_Connector.cpp40
-rw-r--r--ace/DEV_Connector.h86
-rw-r--r--ace/DEV_Connector.i25
-rw-r--r--ace/DEV_IO.cpp97
-rw-r--r--ace/DEV_IO.h104
-rw-r--r--ace/DEV_IO.i102
-rw-r--r--ace/Date_Time.cpp5
-rw-r--r--ace/Date_Time.h92
-rw-r--r--ace/Date_Time.i140
-rw-r--r--ace/Dump.cpp132
-rw-r--r--ace/Dump.h166
-rw-r--r--ace/Dump_T.cpp35
-rw-r--r--ace/Dump_T.h61
-rw-r--r--ace/Dynamic.cpp16
-rw-r--r--ace/Dynamic.h52
-rw-r--r--ace/Dynamic.i18
-rw-r--r--ace/Dynamic_Service.cpp46
-rw-r--r--ace/Dynamic_Service.h47
-rw-r--r--ace/Dynamic_Service.i4
-rw-r--r--ace/Event_Handler.cpp11
-rw-r--r--ace/Event_Handler.h150
-rw-r--r--ace/Event_Handler.i135
-rw-r--r--ace/Event_Handler_T.cpp54
-rw-r--r--ace/Event_Handler_T.h180
-rw-r--r--ace/Event_Handler_T.i187
-rw-r--r--ace/FIFO.cpp67
-rw-r--r--ace/FIFO.h66
-rw-r--r--ace/FIFO.i23
-rw-r--r--ace/FIFO_Recv.cpp63
-rw-r--r--ace/FIFO_Recv.h67
-rw-r--r--ace/FIFO_Recv.i18
-rw-r--r--ace/FIFO_Recv_Msg.cpp41
-rw-r--r--ace/FIFO_Recv_Msg.h72
-rw-r--r--ace/FIFO_Recv_Msg.i55
-rw-r--r--ace/FIFO_Send.cpp36
-rw-r--r--ace/FIFO_Send.h58
-rw-r--r--ace/FIFO_Send.i18
-rw-r--r--ace/FIFO_Send_Msg.cpp62
-rw-r--r--ace/FIFO_Send_Msg.h72
-rw-r--r--ace/FIFO_Send_Msg.i41
-rw-r--r--ace/FILE.cpp72
-rw-r--r--ace/FILE.h83
-rw-r--r--ace/FILE.i6
-rw-r--r--ace/FILE_Addr.cpp23
-rw-r--r--ace/FILE_Addr.h75
-rw-r--r--ace/FILE_Addr.i93
-rw-r--r--ace/FILE_Connector.cpp43
-rw-r--r--ace/FILE_Connector.h87
-rw-r--r--ace/FILE_Connector.i25
-rw-r--r--ace/FILE_IO.cpp100
-rw-r--r--ace/FILE_IO.h109
-rw-r--r--ace/FILE_IO.i101
-rw-r--r--ace/Future.cpp346
-rw-r--r--ace/Future.h167
-rw-r--r--ace/Get_Opt.cpp133
-rw-r--r--ace/Get_Opt.h161
-rw-r--r--ace/Get_Opt.i23
-rw-r--r--ace/Handle_Set.cpp213
-rw-r--r--ace/Handle_Set.h153
-rw-r--r--ace/Handle_Set.i107
-rw-r--r--ace/High_Res_Timer.cpp74
-rw-r--r--ace/High_Res_Timer.h86
-rw-r--r--ace/High_Res_Timer.i37
-rw-r--r--ace/INET_Addr.cpp413
-rw-r--r--ace/INET_Addr.h169
-rw-r--r--ace/INET_Addr.i56
-rw-r--r--ace/IO_Cntl_Msg.cpp34
-rw-r--r--ace/IO_Cntl_Msg.h85
-rw-r--r--ace/IO_Cntl_Msg.i4
-rw-r--r--ace/IO_SAP.cpp124
-rw-r--r--ace/IO_SAP.h70
-rw-r--r--ace/IO_SAP.i33
-rw-r--r--ace/IPC_SAP.cpp148
-rw-r--r--ace/IPC_SAP.h67
-rw-r--r--ace/IPC_SAP.i31
-rw-r--r--ace/LSOCK.cpp121
-rw-r--r--ace/LSOCK.h70
-rw-r--r--ace/LSOCK.i39
-rw-r--r--ace/LSOCK_Acceptor.cpp98
-rw-r--r--ace/LSOCK_Acceptor.h84
-rw-r--r--ace/LSOCK_Acceptor.i4
-rw-r--r--ace/LSOCK_CODgram.cpp54
-rw-r--r--ace/LSOCK_CODgram.h65
-rw-r--r--ace/LSOCK_CODgram.i27
-rw-r--r--ace/LSOCK_Connector.cpp49
-rw-r--r--ace/LSOCK_Connector.h97
-rw-r--r--ace/LSOCK_Connector.i29
-rw-r--r--ace/LSOCK_Dgram.cpp60
-rw-r--r--ace/LSOCK_Dgram.h61
-rw-r--r--ace/LSOCK_Dgram.i20
-rw-r--r--ace/LSOCK_Stream.cpp69
-rw-r--r--ace/LSOCK_Stream.h57
-rw-r--r--ace/LSOCK_Stream.i25
-rw-r--r--ace/Local_Name_Space.cpp155
-rw-r--r--ace/Local_Name_Space.h113
-rw-r--r--ace/Local_Name_Space_T.cpp673
-rw-r--r--ace/Local_Name_Space_T.h219
-rw-r--r--ace/Local_Tokens.cpp1408
-rw-r--r--ace/Local_Tokens.h974
-rw-r--r--ace/Local_Tokens.i363
-rw-r--r--ace/Local_Tokens_T.cpp56
-rw-r--r--ace/Local_Tokens_T.h95
-rw-r--r--ace/Local_Tokens_T.i65
-rw-r--r--ace/Log_Msg.cpp895
-rw-r--r--ace/Log_Msg.h359
-rw-r--r--ace/Log_Msg.i6
-rw-r--r--ace/Log_Priority.h73
-rw-r--r--ace/Log_Record.cpp136
-rw-r--r--ace/Log_Record.h135
-rw-r--r--ace/Log_Record.i88
-rw-r--r--ace/Makefile2107
-rw-r--r--ace/Malloc.cpp81
-rw-r--r--ace/Malloc.h217
-rw-r--r--ace/Malloc.i4
-rw-r--r--ace/Malloc_T.cpp574
-rw-r--r--ace/Malloc_T.h337
-rw-r--r--ace/Malloc_T.i150
-rw-r--r--ace/Map_Manager.cpp575
-rw-r--r--ace/Map_Manager.h262
-rw-r--r--ace/Map_Manager.i4
-rw-r--r--ace/Mem_Map.cpp218
-rw-r--r--ace/Mem_Map.h179
-rw-r--r--ace/Mem_Map.i166
-rw-r--r--ace/Memory_Pool.cpp587
-rw-r--r--ace/Memory_Pool.h352
-rw-r--r--ace/Memory_Pool.i181
-rw-r--r--ace/Message_Block.cpp249
-rw-r--r--ace/Message_Block.h268
-rw-r--r--ace/Message_Block.i234
-rw-r--r--ace/Message_Queue.cpp508
-rw-r--r--ace/Message_Queue.h217
-rw-r--r--ace/Message_Queue.i122
-rw-r--r--ace/Method_Object.cpp14
-rw-r--r--ace/Method_Object.h43
-rw-r--r--ace/Module.cpp168
-rw-r--r--ace/Module.h139
-rw-r--r--ace/Module.i62
-rw-r--r--ace/Multiplexor.cpp13
-rw-r--r--ace/Multiplexor.h76
-rw-r--r--ace/Multiplexor.i88
-rw-r--r--ace/Name_Proxy.cpp175
-rw-r--r--ace/Name_Proxy.h82
-rw-r--r--ace/Name_Request_Reply.cpp491
-rw-r--r--ace/Name_Request_Reply.h253
-rw-r--r--ace/Name_Space.cpp60
-rw-r--r--ace/Name_Space.h145
-rw-r--r--ace/Naming_Context.cpp531
-rw-r--r--ace/Naming_Context.h312
-rw-r--r--ace/OS.cpp1224
-rw-r--r--ace/OS.h2174
-rw-r--r--ace/OS.i5297
-rw-r--r--ace/Obstack.cpp119
-rw-r--r--ace/Obstack.h79
-rw-r--r--ace/Obstack.i4
-rw-r--r--ace/Parse_Node.cpp545
-rw-r--r--ace/Parse_Node.h256
-rw-r--r--ace/Parse_Node.i6
-rw-r--r--ace/Pipe.cpp132
-rw-r--r--ace/Pipe.h73
-rw-r--r--ace/Pipe.i18
-rw-r--r--ace/Proactor.cpp536
-rw-r--r--ace/Proactor.h256
-rw-r--r--ace/Proactor.i54
-rw-r--r--ace/Process.cpp197
-rw-r--r--ace/Process.h106
-rw-r--r--ace/Process.i19
-rw-r--r--ace/Process_Manager.cpp331
-rw-r--r--ace/Process_Manager.h250
-rw-r--r--ace/Process_Manager.i4
-rw-r--r--ace/Profile_Timer.cpp226
-rw-r--r--ace/Profile_Timer.h142
-rw-r--r--ace/Profile_Timer.i48
-rw-r--r--ace/README784
-rw-r--r--ace/Reactor.cpp1614
-rw-r--r--ace/Reactor.h642
-rw-r--r--ace/Reactor.i135
-rw-r--r--ace/ReactorEx.cpp282
-rw-r--r--ace/ReactorEx.h231
-rw-r--r--ace/ReactorEx.i28
-rw-r--r--ace/Read_Buffer.cpp155
-rw-r--r--ace/Read_Buffer.h93
-rw-r--r--ace/Read_Buffer.i23
-rw-r--r--ace/Remote_Name_Space.cpp312
-rw-r--r--ace/Remote_Name_Space.h126
-rw-r--r--ace/Remote_Tokens.cpp445
-rw-r--r--ace/Remote_Tokens.h283
-rw-r--r--ace/Remote_Tokens.i98
-rw-r--r--ace/SOCK.cpp97
-rw-r--r--ace/SOCK.h95
-rw-r--r--ace/SOCK.i28
-rw-r--r--ace/SOCK_Acceptor.cpp125
-rw-r--r--ace/SOCK_Acceptor.h81
-rw-r--r--ace/SOCK_Acceptor.i8
-rw-r--r--ace/SOCK_CODgram.cpp100
-rw-r--r--ace/SOCK_CODgram.h55
-rw-r--r--ace/SOCK_CODgram.i12
-rw-r--r--ace/SOCK_Connector.cpp152
-rw-r--r--ace/SOCK_Connector.h101
-rw-r--r--ace/SOCK_Connector.i35
-rw-r--r--ace/SOCK_Dgram.cpp118
-rw-r--r--ace/SOCK_Dgram.h92
-rw-r--r--ace/SOCK_Dgram.i45
-rw-r--r--ace/SOCK_Dgram_Bcast.cpp243
-rw-r--r--ace/SOCK_Dgram_Bcast.h106
-rw-r--r--ace/SOCK_Dgram_Bcast.i23
-rw-r--r--ace/SOCK_Dgram_Mcast.cpp108
-rw-r--r--ace/SOCK_Dgram_Mcast.h112
-rw-r--r--ace/SOCK_Dgram_Mcast.i31
-rw-r--r--ace/SOCK_IO.cpp114
-rw-r--r--ace/SOCK_IO.h74
-rw-r--r--ace/SOCK_IO.i85
-rw-r--r--ace/SOCK_Stream.cpp16
-rw-r--r--ace/SOCK_Stream.h69
-rw-r--r--ace/SOCK_Stream.i81
-rw-r--r--ace/SPIPE.cpp58
-rw-r--r--ace/SPIPE.h76
-rw-r--r--ace/SPIPE.i6
-rw-r--r--ace/SPIPE_Acceptor.cpp212
-rw-r--r--ace/SPIPE_Acceptor.h78
-rw-r--r--ace/SPIPE_Acceptor.i4
-rw-r--r--ace/SPIPE_Addr.cpp110
-rw-r--r--ace/SPIPE_Addr.h101
-rw-r--r--ace/SPIPE_Addr.i70
-rw-r--r--ace/SPIPE_Connector.cpp68
-rw-r--r--ace/SPIPE_Connector.h88
-rw-r--r--ace/SPIPE_Connector.i7
-rw-r--r--ace/SPIPE_Stream.cpp93
-rw-r--r--ace/SPIPE_Stream.h117
-rw-r--r--ace/SPIPE_Stream.i160
-rw-r--r--ace/SString.cpp596
-rw-r--r--ace/SString.h265
-rw-r--r--ace/SString.i141
-rw-r--r--ace/SV_Message.cpp18
-rw-r--r--ace/SV_Message.h51
-rw-r--r--ace/SV_Message.i31
-rw-r--r--ace/SV_Message_Queue.cpp34
-rw-r--r--ace/SV_Message_Queue.h86
-rw-r--r--ace/SV_Message_Queue.i78
-rw-r--r--ace/SV_Semaphore_Complex.cpp240
-rw-r--r--ace/SV_Semaphore_Complex.h149
-rw-r--r--ace/SV_Semaphore_Complex.i83
-rw-r--r--ace/SV_Semaphore_Simple.cpp179
-rw-r--r--ace/SV_Semaphore_Simple.h138
-rw-r--r--ace/SV_Semaphore_Simple.i132
-rw-r--r--ace/SV_Shared_Memory.cpp82
-rw-r--r--ace/SV_Shared_Memory.h107
-rw-r--r--ace/SV_Shared_Memory.i105
-rw-r--r--ace/Service_Config.cpp928
-rw-r--r--ace/Service_Config.h353
-rw-r--r--ace/Service_Config.i32
-rw-r--r--ace/Service_Main.cpp37
-rw-r--r--ace/Service_Manager.cpp267
-rw-r--r--ace/Service_Manager.h74
-rw-r--r--ace/Service_Manager.i4
-rw-r--r--ace/Service_Object.cpp71
-rw-r--r--ace/Service_Object.h94
-rw-r--r--ace/Service_Object.i26
-rw-r--r--ace/Service_Record.cpp340
-rw-r--r--ace/Service_Record.h153
-rw-r--r--ace/Service_Record.i91
-rw-r--r--ace/Service_Repository.cpp281
-rw-r--r--ace/Service_Repository.h130
-rw-r--r--ace/Service_Repository.i27
-rw-r--r--ace/Set.cpp502
-rw-r--r--ace/Set.h321
-rw-r--r--ace/Set.i24
-rw-r--r--ace/Shared_Memory.h43
-rw-r--r--ace/Shared_Memory_MM.cpp52
-rw-r--r--ace/Shared_Memory_MM.h95
-rw-r--r--ace/Shared_Memory_MM.i81
-rw-r--r--ace/Shared_Memory_SV.cpp29
-rw-r--r--ace/Shared_Memory_SV.h87
-rw-r--r--ace/Shared_Memory_SV.i73
-rw-r--r--ace/Shared_Object.cpp46
-rw-r--r--ace/Shared_Object.h45
-rw-r--r--ace/Shared_Object.i4
-rw-r--r--ace/Signal.cpp632
-rw-r--r--ace/Signal.h350
-rw-r--r--ace/Signal.i213
-rw-r--r--ace/Singleton.cpp78
-rw-r--r--ace/Singleton.h65
-rw-r--r--ace/Singleton.i4
-rw-r--r--ace/Stack.cpp428
-rw-r--r--ace/Stack.h280
-rw-r--r--ace/Stack.i100
-rw-r--r--ace/Strategies.cpp504
-rw-r--r--ace/Strategies.h445
-rw-r--r--ace/Strategies.i4
-rw-r--r--ace/Stream.cpp512
-rw-r--r--ace/Stream.h185
-rw-r--r--ace/Stream.i35
-rw-r--r--ace/Stream_Modules.cpp330
-rw-r--r--ace/Stream_Modules.h118
-rw-r--r--ace/Stream_Modules.i4
-rw-r--r--ace/Svc_Conf.h81
-rw-r--r--ace/Svc_Conf.l77
-rw-r--r--ace/Svc_Conf.y342
-rw-r--r--ace/Svc_Conf_Tokens.h23
-rw-r--r--ace/Svc_Conf_l.cpp1504
-rw-r--r--ace/Svc_Conf_y.cpp923
-rw-r--r--ace/Svc_Handler.cpp282
-rw-r--r--ace/Svc_Handler.h178
-rw-r--r--ace/Svc_Handler.i5
-rw-r--r--ace/Synch.cpp839
-rw-r--r--ace/Synch.h1019
-rw-r--r--ace/Synch.i421
-rw-r--r--ace/Synch_Options.cpp93
-rw-r--r--ace/Synch_Options.h135
-rw-r--r--ace/Synch_Options.i4
-rw-r--r--ace/Synch_T.cpp626
-rw-r--r--ace/Synch_T.h613
-rw-r--r--ace/Synch_T.i176
-rw-r--r--ace/System_Time.cpp86
-rw-r--r--ace/System_Time.h73
-rw-r--r--ace/TLI.cpp172
-rw-r--r--ace/TLI.h98
-rw-r--r--ace/TLI.i41
-rw-r--r--ace/TLI_Acceptor.cpp456
-rw-r--r--ace/TLI_Acceptor.h109
-rw-r--r--ace/TLI_Acceptor.i5
-rw-r--r--ace/TLI_Connector.cpp211
-rw-r--r--ace/TLI_Connector.h104
-rw-r--r--ace/TLI_Connector.i29
-rw-r--r--ace/TLI_Stream.cpp99
-rw-r--r--ace/TLI_Stream.h93
-rw-r--r--ace/TLI_Stream.i105
-rw-r--r--ace/TTY_IO.cpp211
-rw-r--r--ace/TTY_IO.h67
-rw-r--r--ace/Task.cpp305
-rw-r--r--ace/Task.h299
-rw-r--r--ace/Task.i160
-rw-r--r--ace/Thread.cpp68
-rw-r--r--ace/Thread.h183
-rw-r--r--ace/Thread.i266
-rw-r--r--ace/Thread_Manager.cpp767
-rw-r--r--ace/Thread_Manager.h403
-rw-r--r--ace/Thread_Manager.i83
-rw-r--r--ace/Time_Request_Reply.cpp187
-rw-r--r--ace/Time_Request_Reply.h119
-rw-r--r--ace/Time_Value.cpp231
-rw-r--r--ace/Time_Value.h247
-rw-r--r--ace/Time_Value.i166
-rw-r--r--ace/Timer_Queue.cpp332
-rw-r--r--ace/Timer_Queue.h154
-rw-r--r--ace/Timer_Queue.i4
-rw-r--r--ace/Token.cpp346
-rw-r--r--ace/Token.h173
-rw-r--r--ace/Token.i41
-rw-r--r--ace/Token_Collection.cpp292
-rw-r--r--ace/Token_Collection.h216
-rw-r--r--ace/Token_Collection.i11
-rw-r--r--ace/Token_Invariants.cpp338
-rw-r--r--ace/Token_Invariants.h217
-rw-r--r--ace/Token_Invariants.i4
-rw-r--r--ace/Token_Manager.cpp259
-rw-r--r--ace/Token_Manager.h124
-rw-r--r--ace/Token_Manager.i19
-rw-r--r--ace/Token_Request_Reply.cpp167
-rw-r--r--ace/Token_Request_Reply.h230
-rw-r--r--ace/Token_Request_Reply.i190
-rw-r--r--ace/Trace.cpp115
-rw-r--r--ace/Trace.h77
-rw-r--r--ace/Trace.i7
-rw-r--r--ace/Typed_SV_Message.cpp21
-rw-r--r--ace/Typed_SV_Message.h88
-rw-r--r--ace/Typed_SV_Message.i91
-rw-r--r--ace/Typed_SV_Message_Queue.cpp46
-rw-r--r--ace/Typed_SV_Message_Queue.h78
-rw-r--r--ace/Typed_SV_Message_Queue.i63
-rw-r--r--ace/UNIX_Addr.cpp104
-rw-r--r--ace/UNIX_Addr.h85
-rw-r--r--ace/UNIX_Addr.i61
-rw-r--r--ace/UPIPE_Acceptor.cpp115
-rw-r--r--ace/UPIPE_Acceptor.h81
-rw-r--r--ace/UPIPE_Acceptor.i11
-rw-r--r--ace/UPIPE_Addr.h25
-rw-r--r--ace/UPIPE_Connector.cpp86
-rw-r--r--ace/UPIPE_Connector.h92
-rw-r--r--ace/UPIPE_Connector.i30
-rw-r--r--ace/UPIPE_Stream.cpp206
-rw-r--r--ace/UPIPE_Stream.h117
-rw-r--r--ace/UPIPE_Stream.i12
-rw-r--r--ace/XtReactor.cpp327
-rw-r--r--ace/XtReactor.h96
-rw-r--r--ace/ace.mak2197
-rw-r--r--ace/ace.mdpbin0 -> 47104 bytes
-rw-r--r--ace/config-aix-3.2.5.h47
-rw-r--r--ace/config-aix-4.1.x.h105
-rw-r--r--ace/config-hpux-10.x-g++.h99
-rw-r--r--ace/config-hpux-10.x.h110
-rw-r--r--ace/config-hpux-9.x-orbix.h89
-rw-r--r--ace/config-hpux-9.x.h83
-rw-r--r--ace/config-irix5.2.h62
-rw-r--r--ace/config-irix5.3-g++.h121
-rw-r--r--ace/config-irix5.3-sgic++.h118
-rw-r--r--ace/config-irix6.2-sgic++.h151
-rw-r--r--ace/config-linux-pthread.h99
-rw-r--r--ace/config-linux.h91
-rw-r--r--ace/config-m88k.h223
-rw-r--r--ace/config-osf1-3.2.h165
-rw-r--r--ace/config-osf1-4.0.h182
-rw-r--r--ace/config-sco-4.2-nothread.h105
-rw-r--r--ace/config-sunos4-g++.h94
-rw-r--r--ace/config-sunos4-lucid3.2.h83
-rw-r--r--ace/config-sunos4-sun3.x.h71
-rw-r--r--ace/config-sunos4-sun4.1.4.h82
-rw-r--r--ace/config-sunos4-sun4.x-orbix.h82
-rw-r--r--ace/config-sunos4-sun4.x.h76
-rw-r--r--ace/config-sunos5.4-centerline-2.x.h152
-rw-r--r--ace/config-sunos5.4-g++.h180
-rw-r--r--ace/config-sunos5.4-sunc++-4.x-orbix.h168
-rw-r--r--ace/config-sunos5.4-sunc++-4.x.h165
-rw-r--r--ace/config-sunos5.5-g++.h171
-rw-r--r--ace/config-sunos5.5-sunc++-4.x-orbix.h166
-rw-r--r--ace/config-sunos5.5-sunc++-4.x.h161
-rw-r--r--ace/config-sunx86-sunc++-4.x.h142
-rw-r--r--ace/config-unixware-2.01-g++.h95
-rw-r--r--ace/config-vxworks-ghs-1.8.h46
-rw-r--r--ace/config-win32-msvc2.0.h133
-rw-r--r--ace/config-win32-msvc4.0.h167
-rw-r--r--ace/makefile-light883
-rw-r--r--apps/Gateway/Gateway/Channel.cpp713
-rw-r--r--apps/Gateway/Gateway/Channel.h281
-rw-r--r--apps/Gateway/Gateway/Channel_Connector.cpp92
-rw-r--r--apps/Gateway/Gateway/Channel_Connector.h41
-rw-r--r--apps/Gateway/Gateway/Config_Files.cpp170
-rw-r--r--apps/Gateway/Gateway/Config_Files.h91
-rw-r--r--apps/Gateway/Gateway/File_Parser.cpp142
-rw-r--r--apps/Gateway/Gateway/File_Parser.h76
-rw-r--r--apps/Gateway/Gateway/Gateway.cpp561
-rw-r--r--apps/Gateway/Gateway/Gateway.h30
-rw-r--r--apps/Gateway/Gateway/Makefile505
-rw-r--r--apps/Gateway/Gateway/Peer_Message.h89
-rw-r--r--apps/Gateway/Gateway/README22
-rw-r--r--apps/Gateway/Gateway/Routing_Entry.cpp47
-rw-r--r--apps/Gateway/Gateway/Routing_Entry.h53
-rw-r--r--apps/Gateway/Gateway/Routing_Table.cpp69
-rw-r--r--apps/Gateway/Gateway/Routing_Table.h67
-rw-r--r--apps/Gateway/Gateway/Thr_Channel.cpp204
-rw-r--r--apps/Gateway/Gateway/Thr_Channel.h65
-rw-r--r--apps/Gateway/Gateway/cc_config10
-rw-r--r--apps/Gateway/Gateway/gatewayd.cpp34
-rw-r--r--apps/Gateway/Gateway/rt_config7
-rw-r--r--apps/Gateway/Gateway/svc.conf3
-rw-r--r--apps/Gateway/Makefile26
-rw-r--r--apps/Gateway/Peer/Gateway_Handler.cpp653
-rw-r--r--apps/Gateway/Peer/Gateway_Handler.h154
-rw-r--r--apps/Gateway/Peer/Makefile137
-rw-r--r--apps/Gateway/Peer/Peer_Message.h44
-rw-r--r--apps/Gateway/Peer/peerd.cpp36
-rw-r--r--apps/Gateway/Peer/svc.conf3
-rw-r--r--apps/Gateway/README80
-rw-r--r--apps/Makefile30
-rw-r--r--apps/Orbix-Examples/Event_Comm/Consumer/Input_Handler.cpp130
-rw-r--r--apps/Orbix-Examples/Event_Comm/Consumer/Input_Handler.h71
-rw-r--r--apps/Orbix-Examples/Event_Comm/Consumer/Makefile165
-rw-r--r--apps/Orbix-Examples/Event_Comm/Consumer/Notification_Receiver_Handler.cpp114
-rw-r--r--apps/Orbix-Examples/Event_Comm/Consumer/Notification_Receiver_Handler.h62
-rw-r--r--apps/Orbix-Examples/Event_Comm/Consumer/consumer.cpp114
-rw-r--r--apps/Orbix-Examples/Event_Comm/Makefile26
-rw-r--r--apps/Orbix-Examples/Event_Comm/README109
-rw-r--r--apps/Orbix-Examples/Event_Comm/Supplier/Input_Handler.cpp120
-rw-r--r--apps/Orbix-Examples/Event_Comm/Supplier/Input_Handler.h70
-rw-r--r--apps/Orbix-Examples/Event_Comm/Supplier/Makefile164
-rw-r--r--apps/Orbix-Examples/Event_Comm/Supplier/Notifier_Handler.cpp66
-rw-r--r--apps/Orbix-Examples/Event_Comm/Supplier/Notifier_Handler.h57
-rw-r--r--apps/Orbix-Examples/Event_Comm/Supplier/supplier.cpp116
-rw-r--r--apps/Orbix-Examples/Event_Comm/include/Event_Comm.hh887
-rw-r--r--apps/Orbix-Examples/Event_Comm/include/Event_Comm_i.h37
-rw-r--r--apps/Orbix-Examples/Event_Comm/include/Notification_Receiver_i.h48
-rw-r--r--apps/Orbix-Examples/Event_Comm/include/Notifier_i.h82
-rw-r--r--apps/Orbix-Examples/Event_Comm/libsrc/Event_Comm.hh887
-rw-r--r--apps/Orbix-Examples/Event_Comm/libsrc/Event_Comm.idl92
-rw-r--r--apps/Orbix-Examples/Event_Comm/libsrc/Event_CommC.cpp351
-rw-r--r--apps/Orbix-Examples/Event_Comm/libsrc/Event_CommS.cpp166
-rw-r--r--apps/Orbix-Examples/Event_Comm/libsrc/Event_Comm_i.h38
-rw-r--r--apps/Orbix-Examples/Event_Comm/libsrc/Makefile113
-rw-r--r--apps/Orbix-Examples/Event_Comm/libsrc/Notification.idl42
-rw-r--r--apps/Orbix-Examples/Event_Comm/libsrc/Notification_Receiver.idl42
-rw-r--r--apps/Orbix-Examples/Event_Comm/libsrc/Notification_Receiver_i.cpp39
-rw-r--r--apps/Orbix-Examples/Event_Comm/libsrc/Notification_Receiver_i.h48
-rw-r--r--apps/Orbix-Examples/Event_Comm/libsrc/Notifier.idl49
-rw-r--r--apps/Orbix-Examples/Event_Comm/libsrc/Notifier_i.cpp324
-rw-r--r--apps/Orbix-Examples/Event_Comm/libsrc/Notifier_i.h82
-rw-r--r--apps/Orbix-Examples/Logger/Logger.cpp131
-rw-r--r--apps/Orbix-Examples/Logger/Logger.h56
-rw-r--r--apps/Orbix-Examples/Logger/Makefile63
-rw-r--r--apps/Orbix-Examples/Logger/Orbix.hostgroups1
-rw-r--r--apps/Orbix-Examples/Logger/Orbix.hosts3
-rw-r--r--apps/Orbix-Examples/Logger/README35
-rw-r--r--apps/Orbix-Examples/Logger/a1.tex232
-rw-r--r--apps/Orbix-Examples/Logger/client.cpp142
-rw-r--r--apps/Orbix-Examples/Logger/logger.hh434
-rw-r--r--apps/Orbix-Examples/Logger/logger.idl56
-rw-r--r--apps/Orbix-Examples/Logger/loggerS.cpp141
-rw-r--r--apps/Orbix-Examples/Logger/logger_i.cpp120
-rw-r--r--apps/Orbix-Examples/Logger/logger_i.h75
-rw-r--r--apps/Orbix-Examples/Logger/server.cpp40
-rw-r--r--apps/Orbix-Examples/Makefile25
-rw-r--r--apps/README19
-rw-r--r--apps/gperf/COPYING249
-rw-r--r--apps/gperf/ChangeLog1335
-rw-r--r--apps/gperf/Makefile25
-rw-r--r--apps/gperf/README24
-rw-r--r--apps/gperf/gperf.123
-rw-r--r--apps/gperf/gperf.info1127
-rw-r--r--apps/gperf/gperf.texi1184
-rw-r--r--apps/gperf/src/Bool_Array.cpp89
-rw-r--r--apps/gperf/src/Bool_Array.h65
-rw-r--r--apps/gperf/src/Gen_Perf.cpp345
-rw-r--r--apps/gperf/src/Gen_Perf.h65
-rw-r--r--apps/gperf/src/Hash_Table.cpp84
-rw-r--r--apps/gperf/src/Hash_Table.h50
-rw-r--r--apps/gperf/src/Iterator.cpp90
-rw-r--r--apps/gperf/src/Iterator.h67
-rw-r--r--apps/gperf/src/Key_List.cpp1345
-rw-r--r--apps/gperf/src/Key_List.h116
-rw-r--r--apps/gperf/src/List_Node.cpp110
-rw-r--r--apps/gperf/src/List_Node.h65
-rw-r--r--apps/gperf/src/Makefile155
-rw-r--r--apps/gperf/src/Options.cpp616
-rw-r--r--apps/gperf/src/Options.h140
-rw-r--r--apps/gperf/src/Vectors.cpp33
-rw-r--r--apps/gperf/src/Vectors.h44
-rw-r--r--apps/gperf/src/Version.cpp25
-rw-r--r--apps/gperf/src/gperf.cpp66
-rw-r--r--apps/gperf/src/new.cpp75
-rw-r--r--apps/gperf/tests/Makefile.in72
-rw-r--r--apps/gperf/tests/ada-pred.exp54
-rw-r--r--apps/gperf/tests/ada-res.exp63
-rw-r--r--apps/gperf/tests/ada.gperf63
-rw-r--r--apps/gperf/tests/adadefs.gperf54
-rw-r--r--apps/gperf/tests/c++.gperf47
-rw-r--r--apps/gperf/tests/c-parse.gperf56
-rw-r--r--apps/gperf/tests/c.exp32
-rw-r--r--apps/gperf/tests/c.gperf32
-rw-r--r--apps/gperf/tests/configure.in26
-rw-r--r--apps/gperf/tests/gpc.gperf48
-rw-r--r--apps/gperf/tests/gplus.gperf76
-rw-r--r--apps/gperf/tests/irc.gperf63
-rw-r--r--apps/gperf/tests/makeinfo.gperf116
-rw-r--r--apps/gperf/tests/modula.exp106
-rw-r--r--apps/gperf/tests/modula2.gperf40
-rw-r--r--apps/gperf/tests/modula3.gperf106
-rw-r--r--apps/gperf/tests/pascal.exp36
-rw-r--r--apps/gperf/tests/pascal.gperf36
-rw-r--r--apps/gperf/tests/test-1.exp140
-rw-r--r--apps/gperf/tests/test-2.exp183
-rw-r--r--apps/gperf/tests/test-3.exp169
-rw-r--r--apps/gperf/tests/test-4.exp138
-rw-r--r--apps/gperf/tests/test-5.exp111
-rw-r--r--apps/gperf/tests/test-6.exp74
-rw-r--r--apps/gperf/tests/test-7.exp32
-rw-r--r--apps/gperf/tests/test.c28
-rw-r--r--bin/Makefile37
-rw-r--r--bin/README.html136
-rwxr-xr-xbin/class2hxxcxx80
-rwxr-xr-xbin/class2hxxcxxsingle80
-rwxr-xr-xbin/class2info197
-rw-r--r--bin/class2info.awk1594
-rwxr-xr-xbin/class2man78
-rwxr-xr-xbin/class2mml79
-rwxr-xr-xbin/class2src79
-rwxr-xr-xbin/classinfo.ps868
-rw-r--r--bin/clone.1297
-rw-r--r--bin/clone.cpp955
-rw-r--r--bin/clone.csh26
-rwxr-xr-xbin/g++dep80
-rw-r--r--bin/hiding.fmt20
-rwxr-xr-xbin/html-windex33
-rwxr-xr-xbin/info2doc.awk2181
-rw-r--r--bin/info2doc.fmt23
-rwxr-xr-xbin/info2head166
-rw-r--r--bin/info2head.fmt23
-rwxr-xr-xbin/info2headsrc326
-rwxr-xr-xbin/info2man169
-rwxr-xr-xbin/info2mml166
-rwxr-xr-xbin/info2src133
-rwxr-xr-xbin/info2src.awk630
-rwxr-xr-xbin/man2html88
-rw-r--r--bin/man2html1.awk139
-rw-r--r--bin/man2html2.awk18
-rwxr-xr-xbin/rename-ace.pl175
-rwxr-xr-xbin/vendor.fmt101
-rw-r--r--examples/ASX/CCM_App/CCM_App.cpp123
-rw-r--r--examples/ASX/CCM_App/Makefile176
-rw-r--r--examples/ASX/CCM_App/SC_Client.cpp9
-rw-r--r--examples/ASX/CCM_App/SC_Server.cpp63
-rw-r--r--examples/ASX/CCM_App/svc.conf21
-rw-r--r--examples/ASX/Event_Server/Event_Server/Consumer_Router.cpp132
-rw-r--r--examples/ASX/Event_Server/Event_Server/Consumer_Router.h46
-rw-r--r--examples/ASX/Event_Server/Event_Server/Event_Analyzer.cpp68
-rw-r--r--examples/ASX/Event_Server/Event_Server/Event_Analyzer.h34
-rw-r--r--examples/ASX/Event_Server/Event_Server/Makefile433
-rw-r--r--examples/ASX/Event_Server/Event_Server/Options.cpp186
-rw-r--r--examples/ASX/Event_Server/Event_Server/Options.h75
-rw-r--r--examples/ASX/Event_Server/Event_Server/Options.i137
-rw-r--r--examples/ASX/Event_Server/Event_Server/Peer_Router.cpp279
-rw-r--r--examples/ASX/Event_Server/Event_Server/Peer_Router.h121
-rw-r--r--examples/ASX/Event_Server/Event_Server/Supplier_Router.cpp134
-rw-r--r--examples/ASX/Event_Server/Event_Server/Supplier_Router.h51
-rw-r--r--examples/ASX/Event_Server/Event_Server/event_server.cpp125
-rw-r--r--examples/ASX/Event_Server/Makefile23
-rw-r--r--examples/ASX/Event_Server/README38
-rw-r--r--examples/ASX/Event_Server/Transceiver/Makefile135
-rw-r--r--examples/ASX/Event_Server/Transceiver/transceiver.cpp187
-rw-r--r--examples/ASX/Makefile25
-rw-r--r--examples/ASX/Message_Queue/Makefile218
-rw-r--r--examples/ASX/Message_Queue/bounded_buffer.cpp130
-rw-r--r--examples/ASX/Message_Queue/buffer_stream.cpp215
-rw-r--r--examples/ASX/Message_Queue/priority_buffer.cpp139
-rw-r--r--examples/ASX/UPIPE_Event_Server/Consumer_Router.cpp126
-rw-r--r--examples/ASX/UPIPE_Event_Server/Consumer_Router.h48
-rw-r--r--examples/ASX/UPIPE_Event_Server/Event_Analyzer.cpp68
-rw-r--r--examples/ASX/UPIPE_Event_Server/Event_Analyzer.h34
-rw-r--r--examples/ASX/UPIPE_Event_Server/Makefile455
-rw-r--r--examples/ASX/UPIPE_Event_Server/Options.cpp191
-rw-r--r--examples/ASX/UPIPE_Event_Server/Options.h83
-rw-r--r--examples/ASX/UPIPE_Event_Server/Options.i161
-rw-r--r--examples/ASX/UPIPE_Event_Server/Peer_Router.cpp273
-rw-r--r--examples/ASX/UPIPE_Event_Server/Peer_Router.h116
-rw-r--r--examples/ASX/UPIPE_Event_Server/Supplier_Router.cpp126
-rw-r--r--examples/ASX/UPIPE_Event_Server/Supplier_Router.h52
-rw-r--r--examples/ASX/UPIPE_Event_Server/event_server.cpp252
-rw-r--r--examples/CORBA/Makefile65
-rw-r--r--examples/CORBA/Test.idl6
-rw-r--r--examples/CORBA/Test_i.cpp10
-rw-r--r--examples/CORBA/Test_i.h14
-rw-r--r--examples/CORBA/client.cpp26
-rw-r--r--examples/CORBA/server.cpp37
-rw-r--r--examples/Connection/Makefile26
-rw-r--r--examples/Connection/blocking/Makefile414
-rw-r--r--examples/Connection/blocking/README36
-rw-r--r--examples/Connection/blocking/SPIPE-acceptor.cpp179
-rw-r--r--examples/Connection/blocking/SPIPE-acceptor.h63
-rw-r--r--examples/Connection/blocking/SPIPE-connector.cpp182
-rw-r--r--examples/Connection/blocking/SPIPE-connector.h75
-rw-r--r--examples/Connection/blocking/test_spipe_acceptor.cpp22
-rw-r--r--examples/Connection/blocking/test_spipe_connector.cpp22
-rw-r--r--examples/Connection/misc/Makefile0
-rw-r--r--examples/Connection/misc/test_upipe.cpp176
-rw-r--r--examples/Connection/non_blocking/CPP-acceptor.cpp172
-rw-r--r--examples/Connection/non_blocking/CPP-acceptor.h70
-rw-r--r--examples/Connection/non_blocking/CPP-connector.cpp219
-rw-r--r--examples/Connection/non_blocking/CPP-connector.h77
-rw-r--r--examples/Connection/non_blocking/Makefile756
-rw-r--r--examples/Connection/non_blocking/README24
-rw-r--r--examples/Connection/non_blocking/test_sock_acceptor.cpp25
-rw-r--r--examples/Connection/non_blocking/test_sock_connector.cpp25
-rw-r--r--examples/Connection/non_blocking/test_spipe_acceptor.cpp25
-rw-r--r--examples/Connection/non_blocking/test_spipe_connector.cpp25
-rw-r--r--examples/Connection/non_blocking/test_tli_acceptor.cpp33
-rw-r--r--examples/Connection/non_blocking/test_tli_connector.cpp33
-rw-r--r--examples/IPC_SAP/DEV_SAP/Makefile22
-rw-r--r--examples/IPC_SAP/DEV_SAP/README23
-rw-r--r--examples/IPC_SAP/DEV_SAP/reader/Makefile71
-rw-r--r--examples/IPC_SAP/DEV_SAP/reader/reader.cpp49
-rw-r--r--examples/IPC_SAP/DEV_SAP/writer/Makefile71
-rw-r--r--examples/IPC_SAP/DEV_SAP/writer/writer.cpp54
-rw-r--r--examples/IPC_SAP/FIFO_SAP/FIFO-Msg-client.cpp36
-rw-r--r--examples/IPC_SAP/FIFO_SAP/FIFO-Msg-server.cpp40
-rw-r--r--examples/IPC_SAP/FIFO_SAP/FIFO-client.cpp24
-rw-r--r--examples/IPC_SAP/FIFO_SAP/FIFO-server.cpp25
-rw-r--r--examples/IPC_SAP/FIFO_SAP/FIFO-test.cpp92
-rw-r--r--examples/IPC_SAP/FIFO_SAP/Makefile132
-rw-r--r--examples/IPC_SAP/FILE_SAP/Makefile62
-rw-r--r--examples/IPC_SAP/FILE_SAP/client.cpp57
-rw-r--r--examples/IPC_SAP/FILE_SAP/testfile1
-rw-r--r--examples/IPC_SAP/Makefile27
-rw-r--r--examples/IPC_SAP/SOCK_SAP/C-inclient.cpp60
-rw-r--r--examples/IPC_SAP/SOCK_SAP/C-inserver.cpp84
-rw-r--r--examples/IPC_SAP/SOCK_SAP/CPP-inclient.cpp73
-rw-r--r--examples/IPC_SAP/SOCK_SAP/CPP-inserver-poll.cpp101
-rw-r--r--examples/IPC_SAP/SOCK_SAP/CPP-inserver.cpp136
-rw-r--r--examples/IPC_SAP/SOCK_SAP/CPP-unclient.cpp50
-rw-r--r--examples/IPC_SAP/SOCK_SAP/CPP-unserver.cpp78
-rw-r--r--examples/IPC_SAP/SOCK_SAP/FD-unclient.cpp51
-rw-r--r--examples/IPC_SAP/SOCK_SAP/FD-unserver.cpp60
-rw-r--r--examples/IPC_SAP/SOCK_SAP/Makefile246
-rw-r--r--examples/IPC_SAP/SOCK_SAP/README35
-rw-r--r--examples/IPC_SAP/SOCK_SAP/local_data1
-rw-r--r--examples/IPC_SAP/SPIPE_SAP/Makefile218
-rw-r--r--examples/IPC_SAP/SPIPE_SAP/NPClient.cpp46
-rw-r--r--examples/IPC_SAP/SPIPE_SAP/NPServer.cpp54
-rw-r--r--examples/IPC_SAP/SPIPE_SAP/client.cpp42
-rw-r--r--examples/IPC_SAP/SPIPE_SAP/consumer_msg.cpp53
-rw-r--r--examples/IPC_SAP/SPIPE_SAP/consumer_read.cpp50
-rw-r--r--examples/IPC_SAP/SPIPE_SAP/producer_msg.cpp52
-rw-r--r--examples/IPC_SAP/SPIPE_SAP/producer_read.cpp49
-rw-r--r--examples/IPC_SAP/SPIPE_SAP/server.cpp116
-rw-r--r--examples/IPC_SAP/SPIPE_SAP/shared.h6
-rw-r--r--examples/IPC_SAP/TLI_SAP/CPP-client.cpp68
-rw-r--r--examples/IPC_SAP/TLI_SAP/CPP-server.cpp68
-rw-r--r--examples/IPC_SAP/TLI_SAP/Makefile197
-rw-r--r--examples/IPC_SAP/TLI_SAP/db-client.cpp52
-rw-r--r--examples/IPC_SAP/TLI_SAP/db-server.cpp111
-rw-r--r--examples/IPC_SAP/TLI_SAP/ftp-client.cpp45
-rw-r--r--examples/IPC_SAP/TLI_SAP/ftp-server.cpp75
-rw-r--r--examples/IPC_SAP/TLI_SAP/signal_thread.c53
-rw-r--r--examples/IPC_SAP/UPIPE_SAP/Makefile300
-rw-r--r--examples/IPC_SAP/UPIPE_SAP/auto_builtin_ptr.h20
-rw-r--r--examples/IPC_SAP/UPIPE_SAP/ex1.cpp155
-rw-r--r--examples/IPC_SAP/UPIPE_SAP/ex2.cpp153
-rw-r--r--examples/IPC_SAP/UPIPE_SAP/ex3.cpp147
-rw-r--r--examples/Log_Msg/Makefile55
-rw-r--r--examples/Log_Msg/test_log_msg.cpp105
-rw-r--r--examples/Logger/Acceptor-server/Makefile107
-rw-r--r--examples/Logger/Acceptor-server/server_loggerd.cpp268
-rw-r--r--examples/Logger/Makefile27
-rw-r--r--examples/Logger/README32
-rw-r--r--examples/Logger/client/Makefile43
-rw-r--r--examples/Logger/client/logging_app.cpp53
-rw-r--r--examples/Logger/simple-server/Logging_Acceptor.cpp64
-rw-r--r--examples/Logger/simple-server/Logging_Acceptor.h49
-rw-r--r--examples/Logger/simple-server/Logging_Handler.cpp139
-rw-r--r--examples/Logger/simple-server/Logging_Handler.h64
-rw-r--r--examples/Logger/simple-server/Makefile116
-rw-r--r--examples/Logger/simple-server/Reactor_Singleton.h27
-rw-r--r--examples/Logger/simple-server/server_loggerd.cpp61
-rw-r--r--examples/Makefile39
-rw-r--r--examples/Mem_Map/IO-tests/IO_Test.cpp186
-rw-r--r--examples/Mem_Map/IO-tests/IO_Test.h71
-rw-r--r--examples/Mem_Map/IO-tests/Makefile63
-rw-r--r--examples/Mem_Map/IO-tests/test_io.cpp155
-rw-r--r--examples/Mem_Map/Makefile22
-rw-r--r--examples/Mem_Map/file-reverse/Makefile58
-rw-r--r--examples/Mem_Map/file-reverse/file-reverse.cpp45
-rw-r--r--examples/Misc/Makefile283
-rw-r--r--examples/Misc/test_XtReactor1.cpp138
-rw-r--r--examples/Misc/test_XtReactor2.cpp70
-rw-r--r--examples/Misc/test_dump.cpp71
-rw-r--r--examples/Misc/test_profile_timer.cpp33
-rw-r--r--examples/Misc/test_read_buffer.cpp30
-rw-r--r--examples/Misc/test_sstring.cpp22
-rw-r--r--examples/Misc/test_trace.cpp52
-rw-r--r--examples/OS/Makefile21
-rw-r--r--examples/OS/Process/Makefile47
-rw-r--r--examples/OS/Process/Process.mak311
-rw-r--r--examples/OS/Process/Process.mdpbin0 -> 44032 bytes
-rw-r--r--examples/OS/Process/README10
-rw-r--r--examples/OS/Process/process.cpp64
-rw-r--r--examples/README74
-rw-r--r--examples/Reactor/Dgram/CODgram.cpp121
-rw-r--r--examples/Reactor/Dgram/Dgram.cpp121
-rw-r--r--examples/Reactor/Dgram/Makefile135
-rw-r--r--examples/Reactor/Makefile24
-rw-r--r--examples/Reactor/Misc/Makefile378
-rw-r--r--examples/Reactor/Misc/notification.cpp249
-rw-r--r--examples/Reactor/Misc/pingpong.cpp241
-rw-r--r--examples/Reactor/Misc/signal_tester.cpp221
-rw-r--r--examples/Reactor/Misc/test_event_handler_t.cpp45
-rw-r--r--examples/Reactor/Misc/test_handle_set.cpp75
-rw-r--r--examples/Reactor/Misc/test_reactors.cpp205
-rw-r--r--examples/Reactor/Misc/test_signals.cpp226
-rw-r--r--examples/Reactor/Misc/test_time_value.cpp69
-rw-r--r--examples/Reactor/Misc/test_timer_queue.cpp47
-rw-r--r--examples/Reactor/Multicast/Log_Wrapper.cpp75
-rw-r--r--examples/Reactor/Multicast/Log_Wrapper.h59
-rw-r--r--examples/Reactor/Multicast/Makefile69
-rw-r--r--examples/Reactor/Multicast/README15
-rw-r--r--examples/Reactor/Multicast/client.cpp110
-rw-r--r--examples/Reactor/Multicast/server.cpp157
-rw-r--r--examples/Reactor/Ntalker/Makefile91
-rw-r--r--examples/Reactor/Ntalker/ntalker.cpp188
-rw-r--r--examples/Reactor/README20
-rw-r--r--examples/Reactor/ReactorEx/README204
-rw-r--r--examples/Reactor/ReactorEx/reactorex.mak535
-rw-r--r--examples/Reactor/ReactorEx/reactorex.mdpbin0 -> 51200 bytes
-rw-r--r--examples/Reactor/ReactorEx/test_reactorEx.cpp444
-rw-r--r--examples/Reactor/ReactorEx/test_remove_handler.cpp94
-rw-r--r--examples/Reactor/WFMO_Reactor/README204
-rw-r--r--examples/Reactor/WFMO_Reactor/reactorex.mak535
-rw-r--r--examples/Reactor/WFMO_Reactor/reactorex.mdpbin0 -> 51200 bytes
-rw-r--r--examples/Reactor/WFMO_Reactor/test_reactorEx.cpp444
-rw-r--r--examples/Reactor/WFMO_Reactor/test_remove_handler.cpp94
-rw-r--r--examples/Service_Configurator/IPC-tests/Makefile24
-rw-r--r--examples/Service_Configurator/IPC-tests/README112
-rw-r--r--examples/Service_Configurator/IPC-tests/client/Makefile306
-rw-r--r--examples/Service_Configurator/IPC-tests/client/broadcast_client_test.cpp56
-rw-r--r--examples/Service_Configurator/IPC-tests/client/local_data22
-rw-r--r--examples/Service_Configurator/IPC-tests/client/local_dgram_client_test.cpp94
-rw-r--r--examples/Service_Configurator/IPC-tests/client/local_fifo_client_test.cpp85
-rw-r--r--examples/Service_Configurator/IPC-tests/client/local_pipe_client_test.cpp122
-rw-r--r--examples/Service_Configurator/IPC-tests/client/local_spipe_client_test.cpp88
-rw-r--r--examples/Service_Configurator/IPC-tests/client/local_stream_client_test.cpp85
-rw-r--r--examples/Service_Configurator/IPC-tests/client/remote_data22
-rw-r--r--examples/Service_Configurator/IPC-tests/client/remote_data122
-rw-r--r--examples/Service_Configurator/IPC-tests/client/remote_data222
-rw-r--r--examples/Service_Configurator/IPC-tests/client/remote_data322
-rw-r--r--examples/Service_Configurator/IPC-tests/client/remote_data422
-rw-r--r--examples/Service_Configurator/IPC-tests/client/remote_dgram_client_test.cpp78
-rw-r--r--examples/Service_Configurator/IPC-tests/client/remote_service_directory_test.cpp80
-rw-r--r--examples/Service_Configurator/IPC-tests/client/remote_stream_client_test.cpp105
-rw-r--r--examples/Service_Configurator/IPC-tests/client/remote_thr_stream_client_test.cpp96
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_Broadcast.cpp36
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_Broadcast.h41
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_Broadcast.i110
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_L_CODgram.cpp36
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_L_CODgram.h41
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_L_CODgram.i113
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_L_Dgram.cpp15
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_L_Dgram.h43
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_L_Dgram.i109
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_L_FIFO.cpp36
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_L_FIFO.h42
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_L_FIFO.i94
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_L_Pipe.cpp36
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_L_Pipe.h44
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_L_Pipe.i136
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_L_SPIPE.cpp16
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_L_SPIPE.h45
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_L_SPIPE.i118
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_L_Stream.cpp17
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_L_Stream.h48
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_L_Stream.i134
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_R_Dgram.cpp36
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_R_Dgram.h40
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_R_Dgram.i106
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_R_Stream.cpp39
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_R_Stream.h46
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_R_Stream.i124
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_Thr_Stream.cpp200
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_Thr_Stream.h76
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_Thr_Stream.i1
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_Timeout.cpp34
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_Timeout.h36
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Handle_Timeout.i74
-rw-r--r--examples/Service_Configurator/IPC-tests/server/Makefile1016
-rw-r--r--examples/Service_Configurator/IPC-tests/server/server_test.cpp31
-rw-r--r--examples/Service_Configurator/IPC-tests/server/svc.conf19
-rw-r--r--examples/Service_Configurator/Makefile22
-rw-r--r--examples/Service_Configurator/Misc/Makefile105
-rw-r--r--examples/Service_Configurator/Misc/Timer_Service.cpp40
-rw-r--r--examples/Service_Configurator/Misc/Timer_Service.h16
-rw-r--r--examples/Service_Configurator/Misc/main.cpp24
-rw-r--r--examples/Service_Configurator/Misc/svc.conf1
-rw-r--r--examples/Shared_Malloc/Makefile96
-rw-r--r--examples/Shared_Malloc/Malloc.cpp80
-rw-r--r--examples/Shared_Malloc/Malloc.h25
-rw-r--r--examples/Shared_Malloc/Options.cpp186
-rw-r--r--examples/Shared_Malloc/Options.h81
-rw-r--r--examples/Shared_Malloc/test_malloc.cpp195
-rw-r--r--examples/Shared_Malloc/test_persistence.cpp246
-rw-r--r--examples/Shared_Memory/Makefile76
-rw-r--r--examples/Shared_Memory/test_MM.cpp63
-rw-r--r--examples/Shared_Memory/test_SV.cpp60
-rw-r--r--examples/System_V_IPC/Makefile26
-rw-r--r--examples/System_V_IPC/README13
-rw-r--r--examples/System_V_IPC/SV_Message_Queues/MQ_Client.cpp29
-rw-r--r--examples/System_V_IPC/SV_Message_Queues/MQ_Server.cpp51
-rw-r--r--examples/System_V_IPC/SV_Message_Queues/Makefile101
-rw-r--r--examples/System_V_IPC/SV_Message_Queues/TMQ_Client.cpp43
-rw-r--r--examples/System_V_IPC/SV_Message_Queues/TMQ_Server.cpp59
-rw-r--r--examples/System_V_IPC/SV_Message_Queues/test.h42
-rw-r--r--examples/System_V_IPC/SV_Semaphores/Makefile116
-rw-r--r--examples/System_V_IPC/SV_Semaphores/Semaphore_Client.cpp31
-rw-r--r--examples/System_V_IPC/SV_Semaphores/Semaphore_Server.cpp41
-rw-r--r--examples/System_V_IPC/SV_Semaphores/Semaphore_Test.h11
-rw-r--r--examples/System_V_IPC/SV_Semaphores/Semaphores.cpp94
-rw-r--r--examples/System_V_IPC/SV_Shared_Memory/Makefile54
-rw-r--r--examples/System_V_IPC/SV_Shared_Memory/SV_Shared_Memory_Test.cpp60
-rw-r--r--examples/System_V_IPC/SV_Shared_Memory/SV_Shared_Memory_Test.h7
-rw-r--r--examples/Threads/Makefile1004
-rw-r--r--examples/Threads/test_auto_event.cpp106
-rw-r--r--examples/Threads/test_barrier1.cpp84
-rw-r--r--examples/Threads/test_barrier2.cpp272
-rw-r--r--examples/Threads/test_cancel.cpp72
-rw-r--r--examples/Threads/test_future1.cpp420
-rw-r--r--examples/Threads/test_future2.cpp524
-rw-r--r--examples/Threads/test_manual_event.cpp99
-rw-r--r--examples/Threads/test_process_mutex.cpp66
-rw-r--r--examples/Threads/test_process_semaphore.cpp56
-rw-r--r--examples/Threads/test_reader_writer.cpp187
-rw-r--r--examples/Threads/test_recursive_mutex.cpp110
-rw-r--r--examples/Threads/test_task.cpp104
-rw-r--r--examples/Threads/test_task_three.cpp229
-rw-r--r--examples/Threads/test_task_two.cpp156
-rw-r--r--examples/Threads/test_thread_manager.cpp105
-rw-r--r--examples/Threads/test_thread_pool.cpp214
-rw-r--r--examples/Threads/test_thread_specific.cpp208
-rw-r--r--examples/Threads/test_token.cpp76
-rw-r--r--examples/Threads/test_tss.cpp235
-rw-r--r--include/makeinclude/macros.GNU22
-rw-r--r--include/makeinclude/platform_aix.GNU30
-rw-r--r--include/makeinclude/platform_hpux.GNU21
-rw-r--r--include/makeinclude/platform_hpux_orbix.GNU23
-rw-r--r--include/makeinclude/platform_irix5.2.GNU11
-rw-r--r--include/makeinclude/platform_irix5.3_g++.GNU13
-rw-r--r--include/makeinclude/platform_irix5.3_sgic++.GNU19
-rw-r--r--include/makeinclude/platform_irix6.2_sgic++.GNU24
-rw-r--r--include/makeinclude/platform_linux.GNU18
-rw-r--r--include/makeinclude/platform_linux_pthread.GNU24
-rw-r--r--include/makeinclude/platform_m88k.GNU24
-rw-r--r--include/makeinclude/platform_osf1_3.2.GNU13
-rw-r--r--include/makeinclude/platform_osf1_4.0.GNU16
-rw-r--r--include/makeinclude/platform_sco-nothread.GNU20
-rw-r--r--include/makeinclude/platform_sunos4_g++.GNU22
-rw-r--r--include/makeinclude/platform_sunos4_lucid.GNU13
-rw-r--r--include/makeinclude/platform_sunos4_sunc++3.x.GNU17
-rw-r--r--include/makeinclude/platform_sunos4_sunc++4.x.GNU12
-rw-r--r--include/makeinclude/platform_sunos4_sunc++4.x_orbix.GNU14
-rw-r--r--include/makeinclude/platform_sunos5_centerline.GNU13
-rw-r--r--include/makeinclude/platform_sunos5_centerline_orbix.GNU14
-rw-r--r--include/makeinclude/platform_sunos5_g++.GNU22
-rw-r--r--include/makeinclude/platform_sunos5_sunc++.GNU14
-rw-r--r--include/makeinclude/platform_sunos5_sunc++_4.1.GNU14
-rw-r--r--include/makeinclude/platform_sunos5_sunc++_orbix.GNU15
-rw-r--r--include/makeinclude/platform_sunos5_x86_g++.GNU22
-rw-r--r--include/makeinclude/platform_unixware_g++.GNU21
-rw-r--r--include/makeinclude/rules.bin.GNU12
-rw-r--r--include/makeinclude/rules.common.GNU17
-rw-r--r--include/makeinclude/rules.lib.GNU113
-rw-r--r--include/makeinclude/rules.local.GNU151
-rw-r--r--include/makeinclude/rules.nested.GNU15
-rw-r--r--include/makeinclude/rules.nolocal.GNU8
-rw-r--r--include/makeinclude/rules.nonested.GNU8
-rw-r--r--include/makeinclude/wrapper_macros.GNU116
-rw-r--r--netsvcs/ACE-netsvcs.html895
-rw-r--r--netsvcs/Makefile27
-rw-r--r--netsvcs/README20
-rw-r--r--netsvcs/clients/Logger/Makefile77
-rw-r--r--netsvcs/clients/Logger/README18
-rw-r--r--netsvcs/clients/Logger/direct_logging.cpp42
-rw-r--r--netsvcs/clients/Logger/indirect_logging.cpp34
-rw-r--r--netsvcs/clients/Makefile24
-rw-r--r--netsvcs/clients/Naming/Client/Client_Test.cpp561
-rw-r--r--netsvcs/clients/Naming/Client/Client_Test.h9
-rw-r--r--netsvcs/clients/Naming/Client/Makefile175
-rw-r--r--netsvcs/clients/Naming/Client/main.cpp42
-rw-r--r--netsvcs/clients/Naming/Client/svc.conf6
-rw-r--r--netsvcs/clients/Naming/Client/svc2.conf9
-rw-r--r--netsvcs/clients/Naming/Dump_Restore/Dump_Restore.cpp388
-rw-r--r--netsvcs/clients/Naming/Dump_Restore/Dump_Restore.h74
-rw-r--r--netsvcs/clients/Naming/Dump_Restore/Makefile176
-rw-r--r--netsvcs/clients/Naming/Dump_Restore/README67
-rw-r--r--netsvcs/clients/Naming/Dump_Restore/createfile.cpp32
-rw-r--r--netsvcs/clients/Naming/Dump_Restore/main.cpp22
-rw-r--r--netsvcs/clients/Naming/Dump_Restore/nametest.cpp112
-rw-r--r--netsvcs/clients/Naming/Dump_Restore/nametest.h15
-rw-r--r--netsvcs/clients/Naming/Makefile25
-rw-r--r--netsvcs/clients/Naming/README124
-rw-r--r--netsvcs/clients/README8
-rw-r--r--netsvcs/clients/Tokens/Makefile26
-rw-r--r--netsvcs/clients/Tokens/README34
-rw-r--r--netsvcs/clients/Tokens/collection/Makefile108
-rw-r--r--netsvcs/clients/Tokens/collection/README25
-rw-r--r--netsvcs/clients/Tokens/collection/collection.cpp217
-rw-r--r--netsvcs/clients/Tokens/collection/rw_locks.cpp175
-rw-r--r--netsvcs/clients/Tokens/deadlock/Makefile87
-rw-r--r--netsvcs/clients/Tokens/deadlock/README98
-rw-r--r--netsvcs/clients/Tokens/deadlock/deadlock_detection_test.cpp342
-rw-r--r--netsvcs/clients/Tokens/invariant/Makefile72
-rw-r--r--netsvcs/clients/Tokens/invariant/README27
-rw-r--r--netsvcs/clients/Tokens/invariant/invariant.cpp199
-rw-r--r--netsvcs/clients/Tokens/manual/Makefile109
-rw-r--r--netsvcs/clients/Tokens/manual/README67
-rw-r--r--netsvcs/clients/Tokens/manual/manual.cpp347
-rw-r--r--netsvcs/clients/Tokens/mutex/Makefile85
-rw-r--r--netsvcs/clients/Tokens/mutex/README23
-rw-r--r--netsvcs/clients/Tokens/mutex/test_mutex.cpp144
-rw-r--r--netsvcs/clients/Tokens/rw_lock/Makefile86
-rw-r--r--netsvcs/clients/Tokens/rw_lock/README40
-rw-r--r--netsvcs/clients/Tokens/rw_lock/rw_locks.cpp255
-rw-r--r--netsvcs/lib/Client_Logging_Handler.cpp373
-rw-r--r--netsvcs/lib/Client_Logging_Handler.h25
-rw-r--r--netsvcs/lib/Client_Logging_Handler.i4
-rw-r--r--netsvcs/lib/Logging_Strategy.cpp145
-rw-r--r--netsvcs/lib/Logging_Strategy.h25
-rw-r--r--netsvcs/lib/Makefile465
-rw-r--r--netsvcs/lib/Name_Handler.cpp738
-rw-r--r--netsvcs/lib/Name_Handler.h24
-rw-r--r--netsvcs/lib/README270
-rw-r--r--netsvcs/lib/Server_Logging_Handler.cpp453
-rw-r--r--netsvcs/lib/Server_Logging_Handler.h26
-rw-r--r--netsvcs/lib/Server_Logging_Handler.i4
-rw-r--r--netsvcs/lib/TS_Clerk_Handler.cpp826
-rw-r--r--netsvcs/lib/TS_Clerk_Handler.h23
-rw-r--r--netsvcs/lib/TS_Server_Handler.cpp324
-rw-r--r--netsvcs/lib/TS_Server_Handler.h25
-rw-r--r--netsvcs/lib/Token_Handler.cpp882
-rw-r--r--netsvcs/lib/Token_Handler.h26
-rw-r--r--netsvcs/lib/netsvcs.mak1082
-rw-r--r--netsvcs/lib/netsvcs.mdpbin0 -> 47104 bytes
-rw-r--r--netsvcs/servers/Makefile51
-rw-r--r--netsvcs/servers/README29
-rw-r--r--netsvcs/servers/cli.conf11
-rw-r--r--netsvcs/servers/main.cpp77
-rw-r--r--netsvcs/servers/ntsvc.conf12
-rw-r--r--netsvcs/servers/servers.mak402
-rw-r--r--netsvcs/servers/servers.mdpbin0 -> 41984 bytes
-rw-r--r--netsvcs/servers/svc.conf15
-rw-r--r--performance-tests/Makefile30
-rw-r--r--performance-tests/Misc/Makefile146
-rw-r--r--performance-tests/Misc/test_mutex.cpp230
-rw-r--r--performance-tests/Misc/test_naming.cpp169
-rw-r--r--performance-tests/Misc/test_singleton.cpp183
-rw-r--r--performance-tests/Synch-Benchmarks/Benchmark.cpp95
-rw-r--r--performance-tests/Synch-Benchmarks/Benchmark.h73
-rw-r--r--performance-tests/Synch-Benchmarks/Makefile1192
-rw-r--r--performance-tests/Synch-Benchmarks/Makefile.driver41
-rw-r--r--performance-tests/Synch-Benchmarks/Makefile.synch_tests948
-rw-r--r--performance-tests/Synch-Benchmarks/Options.cpp391
-rw-r--r--performance-tests/Synch-Benchmarks/Options.h126
-rw-r--r--performance-tests/Synch-Benchmarks/Options.i264
-rw-r--r--performance-tests/Synch-Benchmarks/README29
-rw-r--r--performance-tests/Synch-Benchmarks/benchmarks19
-rw-r--r--performance-tests/Synch-Benchmarks/condb_test.cpp71
-rw-r--r--performance-tests/Synch-Benchmarks/conds_test.cpp74
-rw-r--r--performance-tests/Synch-Benchmarks/context.c72
-rw-r--r--performance-tests/Synch-Benchmarks/context.csh16
-rw-r--r--performance-tests/Synch-Benchmarks/context_test.cpp40
-rw-r--r--performance-tests/Synch-Benchmarks/memory_test.cpp42
-rw-r--r--performance-tests/Synch-Benchmarks/mutex_test.cpp46
-rw-r--r--performance-tests/Synch-Benchmarks/orig-results73
-rw-r--r--performance-tests/Synch-Benchmarks/pipe_proc_test.cpp85
-rw-r--r--performance-tests/Synch-Benchmarks/pipe_thr_test.cpp81
-rw-r--r--performance-tests/Synch-Benchmarks/recursive_lock_test.cpp45
-rw-r--r--performance-tests/Synch-Benchmarks/rwrd_test.cpp46
-rw-r--r--performance-tests/Synch-Benchmarks/rwwr_test.cpp46
-rw-r--r--performance-tests/Synch-Benchmarks/sema_test.cpp46
-rw-r--r--performance-tests/Synch-Benchmarks/svc.conf14
-rw-r--r--performance-tests/Synch-Benchmarks/synch_driver.cpp166
-rw-r--r--performance-tests/Synch-Benchmarks/sysvsema_test.cpp47
-rw-r--r--performance-tests/TTCP/ACE-C++/How_to_run_tests29
-rw-r--r--performance-tests/TTCP/ACE-C++/Makefile52
-rw-r--r--performance-tests/TTCP/ACE-C++/run_test35
-rw-r--r--performance-tests/TTCP/ACE-C++/wrapper-new-ttcp.cpp947
-rw-r--r--performance-tests/TTCP/C/How_to_run_tests30
-rw-r--r--performance-tests/TTCP/C/Makefile52
-rw-r--r--performance-tests/TTCP/C/README38
-rw-r--r--performance-tests/TTCP/C/new-ttcp.cpp981
-rw-r--r--performance-tests/TTCP/C/run_test35
-rw-r--r--performance-tests/TTCP/Makefile27
-rw-r--r--performance-tests/TTCP/ORBeline/How_to_run_tests57
-rw-r--r--performance-tests/TTCP/ORBeline/Makefile33
-rw-r--r--performance-tests/TTCP/ORBeline/run_test30
-rw-r--r--performance-tests/TTCP/ORBeline/ser4
-rw-r--r--performance-tests/TTCP/ORBeline/stdmk34
-rw-r--r--performance-tests/TTCP/ORBeline/tango_clt6
-rw-r--r--performance-tests/TTCP/ORBeline/ttcp.idl23
-rw-r--r--performance-tests/TTCP/ORBeline/ttcp_c.cc302
-rw-r--r--performance-tests/TTCP/ORBeline/ttcp_c.hh181
-rw-r--r--performance-tests/TTCP/ORBeline/ttcp_i.cpp1028
-rw-r--r--performance-tests/TTCP/ORBeline/ttcp_i.h45
-rw-r--r--performance-tests/TTCP/ORBeline/ttcp_s.cc168
-rw-r--r--performance-tests/TTCP/ORBeline/ttcp_s.hh89
-rw-r--r--performance-tests/TTCP/Orbix/How_to_run_tests59
-rw-r--r--performance-tests/TTCP/Orbix/Makefile30
-rw-r--r--performance-tests/TTCP/Orbix/README13
-rw-r--r--performance-tests/TTCP/Orbix/orbix_defaults.mk85
-rw-r--r--performance-tests/TTCP/Orbix/run_test30
-rw-r--r--performance-tests/TTCP/Orbix/ttcp.hh376
-rw-r--r--performance-tests/TTCP/Orbix/ttcp.idl22
-rw-r--r--performance-tests/TTCP/Orbix/ttcpC.cpp343
-rw-r--r--performance-tests/TTCP/Orbix/ttcpS.cpp159
-rw-r--r--performance-tests/TTCP/Orbix/ttcp_i.cpp1013
-rw-r--r--performance-tests/TTCP/Orbix/ttcp_i.h46
-rw-r--r--rpc++/.dependencies131
-rw-r--r--rpc++/COPYING481
-rw-r--r--rpc++/Makefile55
-rw-r--r--rpc++/Proj.make68
-rw-r--r--rpc++/README18
-rw-r--r--rpc++/README.ORIG9
-rw-r--r--rpc++/StdHdrs/Makefile13
-rw-r--r--rpc++/StdHdrs/README3
-rw-r--r--rpc++/StdHdrs/rpc/auth.h171
-rw-r--r--rpc++/StdHdrs/rpc/c_types.h79
-rw-r--r--rpc++/StdHdrs/rpc/clnt.h347
-rw-r--r--rpc++/StdHdrs/rpc/pmap_clnt.h82
-rw-r--r--rpc++/StdHdrs/rpc/svc.h286
-rw-r--r--rpc++/StdHdrs/rpc/xdr.h275
-rw-r--r--rpc++/callback.cc38
-rw-r--r--rpc++/example/Makefile40
-rw-r--r--rpc++/example/calcsvc.cc30
-rw-r--r--rpc++/example/calcsvc.h34
-rw-r--r--rpc++/example/client.cc64
-rw-r--r--rpc++/example/server.cc112
-rw-r--r--rpc++/gcc-2.2.fix252
-rw-r--r--rpc++/request.cc165
-rw-r--r--rpc++/rpc++.cp13
-rw-r--r--rpc++/rpc++.fn63
-rw-r--r--rpc++/rpc++.ky0
-rw-r--r--rpc++/rpc++.pg0
-rw-r--r--rpc++/rpc++.texi1519
-rw-r--r--rpc++/rpc++.toc23
-rw-r--r--rpc++/rpc++.tp7
-rw-r--r--rpc++/rpc++.vr13
-rw-r--r--rpc++/rpc++/callback.h533
-rw-r--r--rpc++/rpc++/request.h121
-rw-r--r--rpc++/rpc++/service.h132
-rw-r--r--rpc++/rpc++/stub.h145
-rw-r--r--rpc++/rpc++/xdr++.h98
-rw-r--r--rpc++/service.cc316
-rw-r--r--rpc++/stub.cc207
-rw-r--r--rpc++/version.h4
-rw-r--r--rpc++/xdr++.cc75
-rw-r--r--tests/Barrier_Test.cpp98
-rw-r--r--tests/Buffer_Stream_Test.cpp234
-rw-r--r--tests/CPP_Test.cpp263
-rw-r--r--tests/Future_Test.cpp427
-rw-r--r--tests/Handle_Set_Test.cpp78
-rw-r--r--tests/Makefile1105
-rw-r--r--tests/Mem_Map_Test.cpp157
-rw-r--r--tests/Mutex_Test.cpp48
-rw-r--r--tests/Naming_Test.cpp146
-rw-r--r--tests/Priority_Buffer_Test.cpp158
-rw-r--r--tests/README51
-rw-r--r--tests/Reactor_Timer_Test.cpp95
-rw-r--r--tests/Reactors_Test.cpp215
-rw-r--r--tests/Reader_Writer_Test.cpp216
-rw-r--r--tests/Recursive_Mutex_Test.cpp88
-rw-r--r--tests/SPIPE_Test.cpp146
-rw-r--r--tests/SString_Test.cpp45
-rw-r--r--tests/SV_Shared_Memory_Test.cpp86
-rw-r--r--tests/Shared_Memory_MM_Test.cpp132
-rw-r--r--tests/Shared_Memory_SV_Test.cpp81
-rw-r--r--tests/TSS_Test.cpp218
-rw-r--r--tests/Task_Test.cpp117
-rw-r--r--tests/Thread_Manager_Test.cpp123
-rw-r--r--tests/Thread_Pool_Test.cpp221
-rw-r--r--tests/Time_Service_Test.cpp77
-rw-r--r--tests/Time_Value_Test.cpp49
-rw-r--r--tests/Timer_Queue_Test.cpp65
-rw-r--r--tests/Tokens_Test.cpp251
-rw-r--r--tests/UNIXclerk.conf3
-rw-r--r--tests/UNIXserver.conf10
-rw-r--r--tests/UNIXtokens.conf6
-rw-r--r--tests/UPIPE_SAP_Test.cpp168
-rw-r--r--tests/Win32clerk.conf3
-rw-r--r--tests/Win32server.conf10
-rw-r--r--tests/Win32tokens.conf6
-rw-r--r--tests/run_tests.bat32
-rwxr-xr-xtests/run_tests.sh66
-rw-r--r--tests/test_config.h95
-rw-r--r--tests/tests.mak3941
-rw-r--r--tests/tests.mdpbin0 -> 120320 bytes
1181 files changed, 202920 insertions, 0 deletions
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 <asagar@spdmail.spd.dsccc.com>
+#
+# 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="<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> ..."
+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> ..."
+ 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> ..."
+ 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 <gmake> 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 <gmake> ..."
+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 <<EOF>> 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
+ <gokhale@cs.wustl.edu>.
+
+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 <stdio> for <unistd>. 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 <clahey@ix.netcom.com> 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: <sys/select.h>. 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 <clahey@ix.netcom.com> 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
+ <sys/utime.h>.
+
+ * 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 <alexm@teltrunk1.tait.co.nz> 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 <aurelio@irsipcs2-27-le0.irsip.na.cnr.it> 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
+ <stophph@diku.dk> 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
+ <stophph@diku.dk> 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 <stophph@diku.dk>
+ 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 <alexm@teltrunk1.tait.co.nz>
+ 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 <stophph@diku.dk> updates for Windows
+ NT.
+
+ * include/ace/Malloc.h: Added a forward declaration for
+ ACE_Malloc_Iterator right before ACE_Malloc. Thanks to Antonio
+ Tortorici <antonio@rh0011.roma.tlsoft.it> for reporting it.
+
+ * libsrc/Threads/Synch_T.h: Fixed a small typo in
+ ACE_Null_Condition. Thanks to Antonio Tortorici
+ <antonio@rh0011.roma.tlsoft.it> 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 <ip1@cec.wustl.edu> new
+ test program that exercises the new features of ACE_Malloc that
+ are described in the following bullet.
+
+ * libsrc/Shared_Malloc: Added Irfan Pyarali <ip1@cec.wustl.edu>
+ 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 <marklz@topaz.technion.ac.il> 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 <gokhale@cs.wustl.edu> 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
+ <alexm@teltrunk1.tait.co.nz> 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 <ip1@cec.wustl.edu> 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 <ip1@cec.wustl.edu> 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 <rael@anarchy.cybercom.net> 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
+ <rael@anarchy.cybercom.net> for finding this!
+
+ * Removed all traces of ACE_Condition<ACE_Mutex> 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
+ <bwalton@hughes.scg.hac.com>.
+
+ * 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
+ <rael@anarchy.cybercom.net> 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 <tmont@cerc.wvu.edu> 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
+ <tmont@cerc.wvu.edu> 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
+ <tmont@cerc.wvu.edu> 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 <quehl@erlh.siemens.de> 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 <service_name> == 0 then we don't try to do a
+ putit (previously, this check used <marker_name>, which is less
+ useful...).
+
+ * libsrc/CORBA/CORBA_Handler.C (activate_service): Removed the
+ <default_iterations> 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 <alexm@teltrunk1.tait.co.nz> 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 <length_> 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 <termios.h> 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 <jack@cibc.com> 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 <pjain@wuerl.wustl.edu> 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
+ <alexm@teltrunk1.tait.co.nz> 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 <tang@tekats.com> 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
+ <Karel.Zuiderveld@cv.ruu.nl> 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 SVC_HANDLER, class PEER_ACCEPTOR, class PEER_ADDR>
+ class ACE_Acceptor { /* ... */
+ virtual int open (const PEER_ADDR &);
+ };
+
+ that are currently used like this:
+
+ ACE_Acceptor <My_Svc_Handler, ACE_SOCK_Acceptor, ACE_INET_Addr> acc;
+
+ can be replaced with
+
+ template <class SVC_HANDLER, class PEER_ACCEPTOR>
+ class ACE_Acceptor { /* ... */
+ virtual int open (const PEER_ACCEPTOR::PEER_ADDR &);
+ };
+
+ that are used like this:
+
+ ACE_Acceptor <My_Svc_Handler, ACE_SOCK_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 <gokhale@cs.wustl.edu> 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
+ <jasons@ims.com> 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
+ <alexm@teltrunk1.tait.co.nz> 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 <jasons@ims.com> 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
+ <sys/syslog.h>.
+
+ 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 <jasons@ims.com> 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
+ <jasons@ims.com> 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
+ <jasons@ims.com> 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
+ <phil@yakko.envision.com> and Chris Cleeland
+ <chris@envision.com> 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 <phil_brooks@mentorg.com> for detecting this issue and
+ implementing a solution.
+
+ * include/ace/sysincludes.h: Added #ifdef support for HP/UX, which
+ fails to properly wrap <sys/mman.h> 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
+ <mseaborn@itthp1.comm.mot.com> for noticing this.
+
+ * libsrc/Connection: Changed all uses of ADDR to PEER_ADDR to
+ avoid a name clash in Linux... Thanks to James Morris
+ <jmorris@aurora.apana.org.au> 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<Log_Msg> 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<Mutex> 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<Mutex>. 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 <ace/Reactor.h>
+
+ 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 <bruce@betsy.gps.caltech.edu> 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 <douglas@gtcterminator>
+
+ * 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 <douglas@gtccipher>
+
+ * /libsrc/Connection/Acceptor.i: Fixed a potential memory leak in
+ handle_input().
+
+Thu Mar 9 11:59:54 1995 Doug Schmidt <douglas@gtccipher>
+
+ * 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 <douglas@gtccipher>
+
+ * 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
+ <sts@dad.stibo.dk> 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 <rossd@acm.org> 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
+ <johnlu@f1.telekurs.ch> 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 <sjw@aesthetic.com> 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<LOCK> m (lock_) to ACE_GUARD
+ (LOCK, lock_), which is a macro that is defined as follows:
+
+ ACE_Guard<MUTEX> 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 <olson@mcs.anl.gov> 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 <kellera@pop.eunet.ch> 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 <asagar@spdmail.spd.dsccc.com> 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 <gsalsber@simsun.atsc.allied.com> and
+ Eric Beser <beser@simsun.atsc.allied.com> for helping with this.
+
+ * ace: Added support for the m88k OS. Thanks to Gary Salsbery
+ <gsalsber@simsun.atsc.allied.com> and Eric Beser
+ <beser@simsun.atsc.allied.com> 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 <nbc@metsci.com> 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 <asagar@spdmail.spd.dsccc.com> for reporting this.
+
+ * ace/Makefile: Changed things back so that both static and
+ dynamic libs are built by default... Thanks to Brad Brown
+ <bbrown@rdxsunhost.aud.alcatel.com> 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
+ <sommerau@matisse.informatik.uni-stuttgart.de> 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
+ <sommerau@matisse.informatik.uni-stuttgart.de> 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
+ <asagar@spdmail.spd.dsccc.com> 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 <sjw@aesthetic.com>
+ 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 <Chris_Eich@optilink.optilink.dsccc.com> 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
+ <stuartp@in.ot.com.au> 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 <stuartp@in.ot.com.au> 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 <mommeja@vnet.ibm.com> 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 <mike@vocaltec.com> 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 <gvw@cs.toronto.edu> 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
+ <gvw@cs.toronto.edu> 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
+ <trl@icon-stl.net> 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 "<local host>", 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 <nigel@nt.com> 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 <rcn@nynexst.com>
+ 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 <sjw@aesthetic.com> 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 <antonio@rh0011.roma.tlsoft.it> for
+ suggesting this.
+
+ * examples/Threads/test_thread_manager.cpp (main): Changed argv[1]
+ to argv[2]. Thanks to Andres Kruse <kruse@cern.ch> 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 <ecn@clark.net> 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
+ <akg@na47sun05.cern.ch> for finding this.
+
+ * ace/Malloc.h: Added a very important #else... Thanks to Alex
+ Karev <akg@na47sun05.cern.ch> 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 <spweismu@rsoc.rockwell.com> 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 <akg@na47sun05.cern.ch> 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 <darrin@jeeves.net>
+ 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 <raj@itd.ssb.com> 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 <jwr@icm.edu.pl> 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
+ <gonzo@ing.puc.cl> 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 <perry@zso.dec.com> 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
+ <perry@zso.dec.com> 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 <singhai@delirius.cs.uiuc.edu> 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 <asagar@spdmail.spd.dsccc.com> 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
+ <jwr@icm.edu.pl> 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 <olson@mcs.anl.gov>. 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 <rryan@mseng.kla.com> 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 <rryan@mseng.kla.com> for
+ pointing this out.
+
+ * ace/Synch_T.cpp (ts_get): at line 270 (within
+ ACE_TSS<TYPE>::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<ACE_Mutex> 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 <bruce@betsy.gps.caltech.edu> 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
+ <rryan@mseng.kla.com> 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
+ <marklz@rotem.technion.ac.il> 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 <jwr@icm.edu.pl> 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<ACE_SYNCH_1>* (or <ACE_SYNCH_2>), 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
+ <rorr@costello.den.csci.csc.com> 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
+ <akg@na47sun05.cern.ch> 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 <nbc@metsci.com> 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 <rossd@krinfo.com> 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 <kirk.sinnard@lawson.com> for this fix.
+
+ * ace/OS.h: Added a couple of fixes for the SCO port. Thanks
+ again to Matt Newhook <matthew@neweast.ca>
+
+ * 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 <phil@envision.com> 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 <marklz@rotem.technion.ac.il>
+ for reporting this.
+
+ * ace/Reactor.cpp (advance): Fixed a bug that prevented the
+ iterator from advancing. Thanks to Mark Zusman
+ <marklz@rotem.technion.ac.il> 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
+ <matthew@thor.udc.neweast.ca> 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 <matthew@thor.udc.neweast.ca> 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 <wendland@hpp015.mch2.scn.de> 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
+ <bruce@seismo.gps.caltech.edu> 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 <butenhof@zko.dec.com> 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
+ <matthew@neweast.ca> for contributing this.
+
+Sat Mar 30 12:41:16 1996 Douglas C. Schmidt <schmidt@pride.cs.wustl.edu>
+
+ * 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 <Event_Handler> "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 <matthew@neweast.ca> 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 <kirk.sinnard@lawson.com> 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 <str> 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 <filename> 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
+ <pommier@volnay.stortek.com>.
+
+ * man: Included a shell script to automatically generate an
+ acewindex.html file. This file is useful just after running
+ man2html. Thanks to Vincent Pommier
+ <pommier@volnay.stortek.com> 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
+ <mike.flinn@smtpgate.aws.waii.com> 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
+ <mike.flinn@smtpgate.aws.waii.com> 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
+ <mike.flinn@smtpgate.aws.waii.com> 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
+ <hofner@pd.et-inf.uni-siegen.de> 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
+ <Chris_Eich@optilink.optilink.dsccc.com> and Alex V. Maclinovsky
+ <alexm@teltrunk1.tait.co.nz> 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<ACE_TPQ_Entry>::operator ACE_TPQ_Entry *();
+
+ with
+
+ return (ACE_TPQ_Entry *) (*((ACE_TSS<ACE_TPQ_Entry> *) 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 <hearn_j@sat.mot.com> for this recommendation.
+
+ * ace/Shared_Memory.h: The conditional compilation wrapper was out
+ of date, so I renamed it. Thanks to Alex V Maclinovsky
+ <alexm@teltrunk1.tait.co.nz> 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
+ <sandeepj@emailbox.att.com> 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 <Audun.Tornquist@iu.hioslo.no> 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 <windows.h>
+ #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
+ <bgrigg@opus.bcbnet.com> 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
+ <akg@na47sun05.cern.ch> 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
+ <akg@na47sun05.cern.ch> for reporting this.
+
+ * ace/Typed_SV_Message.i (length): Fixed a minor typo that caused
+ a bigger bug ;-). Thanks to Alexandre Karev
+ <akg@na47sun05.cern.ch> 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 <akg@na47sun05.cern.ch> 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
+ <akg@na47sun05.cern.ch> 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 <akg@na47sun05.cern.ch> 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 <marklz@rotem.technion.ac.il> 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
+ <aurelio@irsipcs2-27-le0.irsip.na.cnr.it> 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 <chris@envision.com> 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 <marklz@rotem.technion.ac.il> 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
+ <liran@bimacs.cs.biu.ac.il> 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 <akg@na47sun05.cern.ch> for noticing this.
+
+ * include/makeinclude: Added a new config file from Bryon G. Rigg
+ <bgrigg@opus.bcbnet.com>, 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 <akg@na47sun05.cern.ch> 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 <bryon_rigg@mail.telecorpsys.com> 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 <bryon_rigg@mail.telecorpsys.com> 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
+ <bryon_rigg@mail.telecorpsys.com> 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 <tmont@cerc.wvu.edu> 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 <class TYPE> TYPE *
+ ACE_TSS<TYPE>::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<ACE_SOCK_STREAM,
+ ACE_NULL_SYNCH>. 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 <akg@na47sun05.cern.ch>
+ 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 <akg@na47sun05.cern.ch> 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 <akg@na47sun05.cern.ch> 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 <bryon_rigg@mail.telecorpsys.com> 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 <agilbert@csci.csc.com> 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 <destroy> method to decide if we need to delete <this>...
+ 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
+ <akg@na47sun05.cern.ch> 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
+ <akg@na47sun05.cern.ch> 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
+ <marklz@topaz.technion.ac.il> 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
+ <marklz@topaz.technion.ac.il> 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 <pramod@saturn.miel.mot.com> 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
+ <akg@na47sun05.cern.ch> 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 <GBaker@p01.az15m.iac.honeywell.com> 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 <GBaker@p01.az15m.iac.honeywell.com> 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
+ <GBaker@p01.az15m.iac.honeywell.com> 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 <GBaker@p01.az15m.iac.honeywell.com> 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
+ <alexm@teltrunk1.tait.co.nz> 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
+ <marklz@topaz.technion.ac.il> 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
+ <marklz@topaz.technion.ac.il> for this.
+
+Fri Jan 12 00:47:57 1996 Douglas C. Schmidt (schmidt@tango.cs.wustl.edu)
+
+ * ace/Time_Value.h: #included <pthreads.h> 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 <clahey@ix.netcom.com>.
+ 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 <alexm@teltrunk1.tait.co.nz> 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 <alexm@teltrunk1.tait.co.nz> 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
+ <GBaker@p01.az15m.iac.honeywell.com> 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 <rodrigc@ecf.toronto.edu> 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 <index> 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 <sys/time.h>
+ 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 <akers@cebaf.gov> 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 <levine@cs.wustl.edu>
+
+ * 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 <schmidt@tango.cs.wustl.edu>
+
+ * 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 <axs2@osi.com> for providing these.
+
+ * ace/OS.h: Added many new ACE_LACKS* and ACE_HAS* macros to
+ support the MVS port. Thanks to Chuck Gehr
+ <gehr@sweng.stortek.com> for these.
+
+Tue Oct 15 11:56:59 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu>
+
+ * 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 <axs2@osi.com> for suggesting this.
+
+ * ace/Local_Tokens.h: Removed an unnecessary parameter name
+ that was unused. Thanks to Stuart Powell <stuartp@in.ot.com.au>
+ for reporting this.
+
+Tue Oct 15 17:03:37 1996 Tim H. Harrison <harrison@lambada.cs.wustl.edu>
+
+ * 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
+ <Ari_Erev@comverse.com> 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 <schmidt@tango.cs.wustl.edu>
+
+ * tests: Added a new version of run_tests.sh, which was
+ contributed by Michael Rueger <mike@SYSCOMP.DE>.
+
+ * 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
+ <christ@swl.fh-heilbronn.de> for suggesting this.
+
+Mon Oct 14 11:09:42 1996 Prashant Jain <pjain@merengue.cs.wustl.edu>
+
+ * 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 <schmidt@tango.cs.wustl.edu>
+
+ * 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 <christ@swl.fh-heilbronn.de> 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 <schmidt@tango.cs.wustl.edu>
+
+ * 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 <lucapri@mbox.vol.it> 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 <schmidt@tango.cs.wustl.edu>
+
+ * 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 <schmidt@tango.cs.wustl.edu>
+
+ * 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
+ <christ@swl.fh-heilbronn.de> 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 <afarahat@CCGATE.HAC.COM> for
+ contributing this.
+
+Wed Oct 9 14:34:19 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu>
+
+ * 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 <bytor@faxint.com> 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 <irfan@flamenco.cs.wustl.edu>
+
+ * 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 <schmidt@tango.cs.wustl.edu>
+
+ * ace/DEV.cpp (ACE_DEV): Removed a stray call to
+ ACE_IO_SAP::dump(). Thanks to Brad Flood <BFLOOD@tcs.lmco.com>
+ 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 <schmidt@tango.cs.wustl.edu>
+
+ * ace/OS.i: Added David Levine's new ACE_OS::mktemp() implementation.
+
+Wed Oct 2 13:26:20 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu>
+
+ * 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 <schmidt@tango.cs.wustl.edu>
+
+ * 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 <schmidt@polka.cs.wustl.edu>
+
+ * 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
+ <sommerau@informatik.uni-stuttgart.de> 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 <jay_denkberg@comverse.com> for
+ suggesting this.
+
+Mon Sep 30 22:59:38 1996 Douglas C. Schmidt <schmidt@polka.cs.wustl.edu>
+
+ * 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
+ <gehr@sweng.stortek.com> for this fix.
+
+ * ace/OS: Added a new macro called ACE_HAS_TIMEZONE_GETTIMEOFDAY
+ that handles problems on MVS. Thanks to Chuck Gehr
+ <gehr@sweng.stortek.com> for this fix.
+
+Mon Sep 30 13:45:10 1996 Tim H. Harrison <harrison@lambada.cs.wustl.edu>
+
+ * ace/Local_Tokens.h: Updated some documentation in all the Token
+ files.
+
+Mon Sep 30 18:01:12 1996 Prashant Jain <pjain@merengue.cs.wustl.edu>
+
+ * 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 <schmidt@tango.cs.wustl.edu>
+
+ * ace/OS.h: Added Chuck Gehr <gehr@sweng.stortek.com> fixes for
+ MVS to enable signals to work correctly.
+
+ * ace/Time_Value.h: Added an extern "C" { } block around #include
+ <pthreads.h> to solve a problem with Linux. Thanks to Padhu
+ Ramalingam <padhu@magicnet.net> 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
+ <gonzo@ing.puc.cl> 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 <gonzo@ing.puc.cl> 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 <gonzo@ing.puc.cl> for reporting
+ this.
+
+ * ace/Synch_T.h: #include'd "ace/Event_Handler.h". Thanks to
+ Gonzalo Diethelm <gonzo@ing.puc.cl> for reporting this.
+
+ * ace/Synch.h: The parameter name gives warnings when
+ instantiating templates. Thanks to Gonzalo Diethelm
+ <gonzo@ing.puc.cl> 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 <gonzo@ing.puc.cl> 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 <gonzo@ing.puc.cl> 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
+ <gonzo@ing.puc.cl> 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 <pjain@merengue.cs.wustl.edu>
+
+ * 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 <schmidt@tango.cs.wustl.edu>
+
+ * 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 <schmidt@polka.cs.wustl.edu>
+
+ * 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 <levine@cs.wustl.edu> for getting this rolling!
+
+Thu Sep 26 00:15:46 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu>
+
+ * 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 <dietrich.quehl@med-iss1.med.siemens.de>
+ 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 <schmidt@tango.cs.wustl.edu>
+
+ * 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 <msg.h> prototypes on that platform.
+
+Fri Sep 20 00:15:29 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu>
+
+ * 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
+ <gehr@sweng.stortek.com> 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
+ <trumble@steosf.nio.dec.com> 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 <schmidt@tango.cs.wustl.edu>
+
+ * 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 <trl@icon-stl.net> 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 <rpc/rpc.h> if the platform has RPC!
+ Thanks to Chuck Gehr <gehr@sweng.stortek.com> 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 <gehr@sweng.stortek.com> 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
+ <gehr@sweng.stortek.com> 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
+ <antonio@rh0011.roma.tlsoft.it> 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 <BFLOOD@tcs.lmco.com> for reporting this.
+
+Wed Sep 18 00:36:01 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu>
+
+ * 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
+ <lucapri@mbox.vol.it> 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 <gonzo@ing.puc.cl> 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 <schmidt@tango.cs.wustl.edu>
+
+ * 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 <amos_shapira@mail.icomverse.com> 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 <lucapri@mbox.vol.it> 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
+ <trumble@steosf.nio.dec.com> 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 <lucapri@mbox.vol.it> 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 <lucapri@mbox.vol.it> 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 <pjain@merengue.cs.wustl.edu>
+
+ * 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 <schmidt@tango.cs.wustl.edu>
+
+ * 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
+ <lucapri@mbox.vol.it> 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 <lucapri@mbox.vol.it> 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 <Axs2@osi.com> for
+ reporting this!
+
+ * ace/Log_Msg.cpp (open): Added a check for the OSTREAM flag in
+ the ACE logger. Thanks to Rick Orr
+ <rorr@costello.den.csci.csc.com> 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 <pjain@merengue.cs.wustl.edu>
+
+ * 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 <harrison@lambada.cs.wustl.edu>
+
+ * 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
+ <lucapri@mbox.vol.it> for suggesting this change.
+
+Sun Sep 15 00:55:59 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu>
+
+ * 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 <james@wgold.demon.co.uk> 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 <harrison@lambada.cs.wustl.edu>
+
+ * 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 <pjain@merengue.cs.wustl.edu>
+
+ * 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 <schmidt@tango.cs.wustl.edu>
+
+ * 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 <schmidt@tango.cs.wustl.edu>
+
+ * ace/OS.h: Changed the order of #includes so that <assert.h>
+ comes before <sys/stat.h>. This fixes some bugs with the
+ Siemens SVR4 C++. Thanks to Antonio Tortorici
+ <antonio@rh0011.roma.tlsoft.it> 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
+ <Avraham_Nash@praxisint.com> 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 <gehr@sweng.stortek.com> 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
+ <tmont@cerc.wvu.edu> and Steve Weismuller
+ <spweismu@rsoc.rockwell.com> 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 <harrison@lambada.cs.wustl.edu>
+
+ * 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 <schmidt@tango.cs.wustl.edu>
+
+ * ace/DEV_IO: Added methods get_local_addr() and get_remote_addr()
+ so that ACE_Connector will work correctly. Thanks to Brad Flood
+ <BFLOOD@tcs.lmco.com> 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" <lucapri@mbox.vol.it> for clarifying this.
+
+ * ace/Proactor.cpp (initiate): Fixed an incorrect set of return
+ values -- they were reversed. Thanks to Brad Flood
+ <BFLOOD@tcs.lmco.com> 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 <schoeckle@ike.uni-stuttgart.de> 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 <BFLOOD@tcs.lmco.com> 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 <BFLOOD@tcs.lmco.com> for
+ reporting this.
+
+ * ace/Thread_Manager.h: Implemented a non-synchronized version of
+ the lookup function for the <hthread_descriptor>. 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 <lucapri@mbox.vol.it> for
+ reporting this.
+
+ * examples/Reactor/ReactorEx/test_reactorEx.cpp
+ (register_thread_exit_hook): Changed hthread_t to ACE_hthread_t.
+ Thanks to Luca Priorelli <lucapri@mbox.vol.it> 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 <schmidt@tango.cs.wustl.edu>
+
+ * 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 <bytor@faxint.com> for suggesting this.
+
+ * ace/Pipe: Added a new constructor that makes it possible to
+ initialize the <ACE_Pipe> from the <read> and <write> 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" <lucapri@mbox.vol.it> for reporting this.
+
+ * ace/{ACE,Log_Msg}.cpp: Added fixes for hexdump(). Thanks to
+ Luca Priorelli" <lucapri@mbox.vol.it> 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 <shupes@mitre.org> 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 <momalley@caesun16.msd.ray.com> for the fixes.
+
+ * ace/OS.cpp (thr_create): Added yet another fix for the IRIX 6.2
+ pthreads implementation. Thanks to Gonzalo Diethelm
+ <gonzo@ing.puc.cl> 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
+ <gonzo@ing.puc.cl> 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
+ <james@wgold.demon.co.uk> for recommending this.
+
+Tue Sep 10 00:26:52 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu>
+
+ * 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 <james@wgold.demon.co.uk> 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 <lucapri@mbox.vol.it> for reporting
+ this.
+
+ * ace: Changed the ACE_NO_POSIX_PROTO #define to something more
+ meaningful: ACE_LACKS_POSIX_PROTO. Thanks to Jonathan Biggar
+ <jon@sems.com> for suggesting this.
+
+ * ace/config-sunos4-g++.h: Added the #define ACE_NEEDS_SYSTIME_H.
+ Thanks to Alexandre Karev <akg@na47sun05.cern.ch> 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
+ <trumble@steosf.nio.dec.com> 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 <trumble@steosf.nio.dec.com> for reporting this.
+
+ * ace/Local_Tokens.h: Fixed a broken use of "friend", which was
+ missing the keyword "class." Thanks to Dave Trumble
+ <trumble@steosf.nio.dec.com> for reporting this.
+
+ * ace/config-osf1-4.0.h: Included Dave Trumble's
+ <trumble@steosf.nio.dec.com> config file for OSF/1 4.0.
+
+ * include/makeinclude/platform_osf1_4.0.GNU: Included Dave
+ Trumble's <trumble@steosf.nio.dec.com> 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
+ <amos_shapira@mail.icomverse.com> 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 <schmidt@tango.cs.wustl.edu>
+
+ * 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 <jmorey@tbi.com> 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
+ <gonzo@ing.puc.cl> 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 <james@wgold.demon.co.uk> 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 <james@wgold.demon.co.uk> 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 <james@wgold.demon.co.uk> 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
+ <rocky@alter.it> 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
+ <amos_shapira@mail.icomverse.com> for reporting this.
+
+Sun Sep 8 14:11:08 1996 Tim H. Harrison <harrison@lambada.cs.wustl.edu>
+
+ * 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 <amos_shapira@mail.icomverse.com> 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
+ <james@wgold.demon.co.uk> 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 <cope@research.bell-labs.com>
+ 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 <Andres.Kruse@cern.ch> 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
+ <james@wgold.demon.co.uk> 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
+ <james@wgold.demon.co.uk> 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 <marius@funcom.no> 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 <schoeckle@ike.uni-stuttgart.de> 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
+ <schoeckle@ike.uni-stuttgart.de> 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 <schoeckle@ike.uni-stuttgart.de> 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 <gonzo@ing.puc.cl> 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 <gonzo@ing.puc.cl> 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
+ <X11/Intrinsic.h>. Thanks to Gonzalo Diethelm
+ <gonzo@ing.puc.cl> 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 <gonzo@ing.puc.cl> 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 <Axs2@osi.com> 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
+ <kruse@cern.ch> 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
+ <kruse@cern.ch> 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 <sys/time.h> for those platforms
+ that don't already do this in <time.h> (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 <asagar@spdmail.spd.dsccc.com> 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 <bytor@faxint.com> 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
+ <gerecke@rayva.org> 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 <t> to <s>, returning a pointer to the end of the copied
+ region (rather than the beginning, a la <strcpy>.
+
+Thu Aug 22 15:43:58 1996 <harrison@samba.cs.wustl.edu>
+
+ * 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 <rossd@krinfo.com>
+ 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 <johnston@tortilla.ds.boeing.com> 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
+ <lucapri@mbox.vol.it> 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 <lucapri@mbox.vol.it> for suggesting this.
+
+ * ace/config-win32-msvc4.0.h: Added
+
+ #define _WINSOCKAPI_
+
+ To avoid multiple inclusions. Thanks to Luca Priorelli
+ <lucapri@mbox.vol.it> 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 <lucapri@mbox.vol.it> 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 <lucapri@mbox.vol.it> 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 <gerecke@rayva.org> 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
+ <gonzo@ing.puc.cl> 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 <gonzo@ing.puc.cl> 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 <gonzo@ing.puc.cl> 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
+ <mark_patton@ftw.paging.mot.com> 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 <tottinge@csci.csc.com> 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 <axs2@osi.com> 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 <tottinge@csci.csc.com> 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
+ <gerecke@rayva.org> 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
+ <schoeckle@ike.uni-stuttgart.de> for sending these.
+
+ * ace/config-osf1-3.2.h: Updated this file with fixes for OSF/1 by
+ Martin Schoeckle <schoeckle@ike.uni-stuttgart.de>.
+
+ * 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
+ <antonio@rh0011.roma.tlsoft.it> for this fix and the explanation
+ above.
+
+ * ace/OS.h: Added support for Borland 5.0's uint64. Thanks to
+ Hani Yakan <hani@i-online.com> 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
+ <axs2@osi.com> 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
+ <gonzo@ing.puc.cl> for recommending this.
+
+ * examples/Misc/test_XtReactor1.cpp: Added a new test of the
+ XtReactor, courtesy of Eric Newton <ecn@clark.net>.
+
+ * ace/config-hpux-10.x.h: According to Eugene K. Plaude
+ <jec@r-style.msk.su>, 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 <schmidt@tango.cs.wustl.edu>
+
+ * After a long hiatus, released version 4.0.28 for testing.
+
+Thu Aug 15 21:04:35 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu>
+
+ * 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 <lucapri@mbox.vol.it> 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
+ <lucapri@mbox.vol.it> 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 <ecn@clark.net> 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
+ <gillies@noao.edu> 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
+ <gonzo@ing.puc.cl> 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 <bytor@faxint.com> 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 <jec@r-style.msk.su> for fixing this!
+
+ * ace/config-hpux-10.x.h: Added support for TLI since according to
+ Eugene K. Plaude <jec@r-style.msk.su> this should work. If not,
+ please let me know.
+
+Wed Aug 14 21:29:46 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu>
+
+ * 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 <ecn@clark.net> 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 <gonzo@ing.puc.cl> 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 <gonzo@ing.puc.cl> for
+ pointing this out.
+
+Wed Aug 14 01:25:47 1996 <harrison@samba.cs.wustl.edu>
+
+ * 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 <harrison@samba.cs.wustl.edu>
+
+ * 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 <thread> 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
+ <Chris_Eich@optilink.optilink.dsccc.com> 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
+ <Chris_Eich@optilink.optilink.dsccc.com> 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
+ <marius@funcom.no> 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
+ <marius@funcom.no> 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 <ecn@clark.net> test case for
+ his XtReactor integration.
+
+ * ace: Included Eric Newton's <ecn@clark.net> 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 <shuston@ultranet.com> 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 <marius@funcom.com> 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 <marius@funcom.com> 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 <BFLOOD@slc.unisysgsg.com> 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
+ <gconaty@outbackinc.com> 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
+ <tottinge@csci.csc.com> 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 <trl@icon-stl.net> 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 <exception.h>
+
+ 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
+ <istvan.buki@infoboard.be>, 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
+ <istvan.buki@infoboard.be> 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 <jack@cibc.com> for reporting this.
+
+ * examples/IPC_SAP/TLI_SAP/ftp-server.cpp: Fixed some typos that
+ were causing problems on AIX. Thanks to Greg Wilson
+ <gvwilson@vnet.ibm.com> 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
+ <gvwilson@vnet.ibm.com> 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
+ <gvwilson@vnet.ibm.com> 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 <gvwilson@vnet.ibm.com> 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
+ <singhai@delirius.cs.uiuc.edu> 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
+ <m_rueger@syscomp.de> 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 <mansionj@lonnds.ml.com> 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 <sys/signal.h>
+
+----------------------------------------
+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<Mutex> m( this->lock_ ));
+>
+> if( cond )
+> b();
+> }
+>
+> void b()
+> {
+> MT( Mutex_Block<Mutex> 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<Recursive_Lock <Mutex> > m( this->lock_ ));
+ b ();
+ }
+
+ void b()
+ {
+ MT( Guard<Recursive_Lock <Mutex> > 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<Mutex> m( this->lock_ ));
+ b_i ();
+ }
+
+ void b_i()
+ {
+ if( cond )
+ a_i();
+ }
+
+ void a_i()
+ {
+ if( cond )
+ b_i();
+ }
+
+ void a()
+ {
+ MT( Guard<Mutex> 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<Mutex> m( this->lock_ ));
+ m.release ();
+ a ();
+ m.acquire ();
+ }
+
+ void a()
+ {
+ MT( Guard<Mutex> 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
+<Mehdi.TABATABAI@ed.nce.sita.int>:
+
+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<int>;
+ template ostream& operator << (ostream&, const A<int>&);
+
+ 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<int>;
+
+ 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<FOO> *) 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<ACE_Log_Msg>. 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 IPC>
+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<ACE_TLI_Stream>;
+ else if (use_sockets)
+ this->my_ipc_ = new ACE_SAP_IPC<ACE_SOCK_Stream>;
+ 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<ACE_MMAP_Memory_Pool, ACE_Process_Mutex> 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<My_Memory_Pool, ACE_Process_Mutex> 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 <gokhale@cs.wustl.edu>
+Tim Harrison <harrison@cs.wustl.edu>
+Prashant Jain <pjain@cs.wustl.edu>
+Irfan Pyarali <ip1@cs.wustl.edu>
+David Levine <levine@cs.wustl.edu>
+
+I would also like to thank all the following people who have also
+contributed to ACE over the years:
+
+Paul Stephenson <pstephenson@objectspace.com>
+Olaf Kruger <okruger@cssc-melb.tansu.com.au>
+Ed Brown <eebrown@netcom.com>
+Lee Baker <baker@ctis.af.mil>
+Alex Ranous <ranous@nsa.hp.com>
+Mark Patton <mark_patton@tx72.mot.com>
+Steffen Winther Sorensen <sts@dad.stibo.dk> for
+Chris Cleeland <chris@milo.st-louis.mo.us>
+Tim Harrison <harrison@cs.wustl.edu>
+Troy Warner <tnw1@core01.osi.com>
+Stacy Mahlon <mcs@contour.mayo.edu>
+Charles Eads <eads@synoptics.com>
+Mark Frutig <mfrutig@fnbc.com>
+Todd Hoff <thm@ictv.com>
+George <george@truffula.fp.trw.com>
+Aniruddha Gokhale <gokhale@cs.wustl.edu>
+Irfan Pyarali <ip1@cs.wustl.edu>
+Prashant Jain <pjain@cs.wustl.edu>
+Brad Needham <bneedham@ix.netcom.com>
+Leslee Xu <lxu@ics.uci.edu>
+Alex V. Maclinovsky <alexm@teltrunk1.tait.co.nz>
+Detlef Becker <beckerd@erlh.siemens.de>
+Bruce Worden <bruce@betsy.gps.caltech.edu>
+Chris Tarr <ctarr@objectspace.co>
+Bill Sears <wsears@world.std.com>
+Greg Lavendar <g.lavender@isode.com>
+Steve Warwick <sjw@aesthetic.com>
+Mats Sundvall <sundvall@perrier.embnet.se>
+Andreas Ueltschi <Andreas.Ueltschi@ska.com>
+Nigel Hooke <n.hooke@trl.oz.au>
+Medhi Tabatabai <Mehdi.Tabatabai@ed.nce.sita.int>
+Stuart Powell <stuartp@ot.com.au>
+Bin Mu <mubin@wfg.com>
+Andrew McGowan <mcgowan@wg2.waii.com>
+Ken Konecki <kenk@wfg.com>
+John P. Hearn <jph@ccrl.nj.nec.com>
+Giang Hoang Nguyen <yang@titan.com>
+Carlos Garcia Braschi <cgarcia@caramba.tid.es>
+Jam Hamidi <jh1@osi.com>
+Eric Vaughan <evaughan@arinc.com>
+Karl-Heinz Dorn <kdorn@erlh.siemens.de>
+Steve Ritter <ritter@titan.com>
+Chandra Venkatapathy <cvenkat@develop.bsis.com>
+Matt Stevens <mstevens@kirk.softeng.infonautics.com>
+Bob Vistica <robertv@ims.com>
+David Trumble <trumble@cvg.enet.dec.com>
+John Morey <jmorey@crl.com>
+George Reynolds <george@dvcorp.com>
+Hans Rohnert <Hans.Rohnert@zfe.siemens.de>
+Alex V Maclinvosky <alexey@ace.elektra.ru>
+Todd Blanchard <tblancha@evolving.com>
+Rob Clairmont <rclairmo@bnr.ca>
+Christian Millour <chris@etca.fr>
+Neil Cohen <nbc@metsci.com>
+Dieter Quehl <quehl@csaserv.erlh.siemens.de>
+Reginald S. Perry <perry@zso.dec.com>
+James Morris <jmorris@aurora.apana.org.au>
+Mark Seaborn <mseaborn@itthp1.comm.mot.com>
+Phil Brooks <phil_brooks@mentorg.com>
+E. Jason Scheck <jasons@ims.com>
+Daniel Proulx <daproulx@qc.bell.ca>
+Bill Tang <tang@tekats.com>
+John Huchinson <hutchiso@epi.syr.ge.com>
+Jack Erickson <jack@cibc.com>
+Byron Walton <bwalton@hughes.scg.hac.com>
+Bill Lear <rael@anarchy.cybercom.net>
+Mark Zusman <marklz@topaz.technion.ac.il>
+Aurelio Nocerino <aurelio@irsipcs2-27-le0.irsip.na.cnr.it>
+Walt Akers <akers@cebaf.gov>
+Greg Baker <GBaker@p01.az15m.iac.honeywell.com>
+Alexandre Karev <karev@vxcern.cern.ch>
+Pramod Kumar Singh <pramod@saturn.miel.mot.com>
+Bryon Rigg <bryon_rigg@mail.telecorpsys.com>
+Brad Brown <bbrown@rdxsunhost.aud.alcatel.com>
+Patty Genualdi <genualdp@agcs.com>
+Eshel Liran <liran@bimacs.cs.biu.ac.il>
+Mick Adams <eeimas@eei.ericsson.se>
+Chris Eich <Chris_Eich@optilink.optilink.dsccc.com>
+Mike Flinn <mike.flinn@smtpgate.aws.waii.com>
+Audun Tornquist <Audun.Tornquist@iu.hioslo.no>
+Sandeep Joshi <sandeepj@emailbox.att.com>
+Kirk Sinnard <1764@mn.lawson.lawson.com>
+Bernd Hofner <hofner@pd.et-inf.uni-siegen.de>
+Craig Perras <CraigP@saros.com>
+Kirk Sinnard <kirk.sinnard@lawson.com>
+Matthew Newhook <matthew@neweast.ca>
+Gerolf Wendland <wendland@hpp015.mch2.scn.de>
+Phil Mesnier <phil@envision.com>
+Ross Dargahi <rossd@krinfo.com>
+Richard Orr <rorr@costello.den.csci.csc.com>
+Rich Ryan <rryan@mseng.kla.com>
+Jan Rychter <jwr@icm.edu.pl>
+Tom Marrs <0002104588@mcimail.com>
+Bob Olson <olson@mcs.anl.gov>
+Jean-Francois Ripouteau <Jean-Francois.Ripouteau@netsurf.org>
+Ajit Sagar <asagar@spdmail.spd.dsccc.com>
+Ashish Singhai <singhai@delirius.cs.uiuc.edu>
+David Sames <David.L.Sames.1@gsfc.nasa.gov>
+Gonzalo Diethelm <gonzo@ing.puc.cl>
+Raj <raj@itd.ssb.com>
+Darrin <darrin@jeeves.net>
+Steve Weismuller <spweismu@rsoc.rockwell.com>
+Eric C. Newton <ecn@clark.net>
+Andres Kruse <kruse@cern.ch>
+Ramesh Nagabushnam <rcn@nynexst.com>
+Antonio Tortorici <antonio@rh0011.roma.tlsoft.it>
+Nigel Lowe <nigel@nt.com>
+Tom Leith <trl@icon-stl.net>
+Greg Wilson <gvw@cs.toronto.edu>
+Michael Fortinsky <mike@vocaltec.com>
+Marco Sommerau <sommerau@matisse.informatik.uni-stuttgart.de>
+Gary Salsbery <gsalsber@simsun.atsc.allied.com>
+Eric Beser <beser@simsun.atsc.allied.com>
+Alfred Keller <kellera@pop.eunet.ch>
+John Lu <johnlu@f1.telekurs.ch>
+James Mansion <james@wgold.demon.co.uk>
+Jesper S. M|ller <Jesper.Moller@ameridata.dk>
+Chris Lahey <clahey@ix.netcom.com>
+Michael R"uger <m_rueger@syscomp.de>
+Istvan Buki <istvan.buki@infoboard.be>
+Greg Wilson <gvwilson@vnet.ibm.com>
+Jack Erickson <jack@cibc.com>
+Garrett Conaty <gconaty@outbackinc.com>
+Brad Flood <BFLOOD@slc.unisysgsg.com>
+Marius Kjeldahl <marius@funcom.com>
+Steve Huston <shuston@ultranet.com>
+Eugene K. Plaude <jec@r-style.msk.su>
+Joseph DeAngelis <bytor@faxint.com>
+Kim Gillies <gillies@noao.edu>
+Luca Priorelli <lucapri@mbox.vol.it>
+Alan Stewart <axs2@osi.com>
+Hani Yakan <hani@i-online.com>
+William L. Gerecke <gerecke@rayva.org>
+Craig Johnston <johnston@tortilla.ds.boeing.com>
+Pierre-Yves Duval <duval@cppm.in2p3.fr>
+Rochi Febo Dommarco <rocky@alter.it>
+Jonathan Biggar <jon@sems.com>
+Scott Shupe <shupes@mitre.org>
+Chuck Gehr <gehr@sweng.stortek.com>
+Avraham Nash <Avraham_Nash@praxisint.com>
+Padhu Ramalingam <padhu@magicnet.net>
+Jay Denkberg <jay_denkberg@comverse.com>
+Ayman Farahat <afarahat@CCGATE.HAC.COM>
+Tilo Christ <christ@swl.fh-heilbronn.de>
+Ari Erev <Ari_Erev@comverse.com>
+
+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
+<tmont@cerc.wvu.edu>, 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 <event_handler> must be a subclass of
+// <ACE_Event_Handler>. If the <get_handle> method of this event
+// handler returns <ACE_INVALID_HANDLE> 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 <len> bytes into <buf> from <handle> (uses the <read>
+ // system call on UNIX and the <ReadFile> 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 <len> bytes into <buf> from <handle> (uses the <write>
+// system call on UNIX and the <WriteFile> 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 <day_and_time>.
+
+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 <timeout> 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 <restart> 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 <len> bytes into <buf> from <handle> (uses the
+ // <recv> call).
+
+ static ssize_t recv (ACE_HANDLE handle,
+ void *buf,
+ size_t len);
+ // Receive up to <len> bytes into <buf> from <handle> (uses the
+ // <read> system call on UNIX and the <recv> call on Win32).
+
+ static ssize_t send (ACE_HANDLE handle,
+ const void *buf,
+ size_t len,
+ int flags);
+ // Send up to <len> bytes into <buf> from <handle> (uses the <send>
+ // call).
+
+ static ssize_t send (ACE_HANDLE handle,
+ const void *buf,
+ size_t len);
+ // Send up to <len> bytes into <buf> from <handle> (uses the <write>
+ // system call on UNIX and the <send> 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 <len> bytes into <buf> from <handle> (uses the <recv>
+ // call).
+
+ static ssize_t recv_n (ACE_HANDLE handle,
+ void *buf,
+ size_t len);
+ // Receive <len> bytes into <buf> from <handle> (uses the <read>
+ // system call on UNIX and the <recv> call on Win32).
+
+ static ssize_t send_n (ACE_HANDLE handle,
+ const void *buf,
+ size_t len,
+ int flags);
+ // Receive <len> bytes into <buf> from <handle> (uses the <send>
+ // system call).
+
+ static ssize_t send_n (ACE_HANDLE handle,
+ const void *buf,
+ size_t len);
+ // Receive <len> bytes into <buf> from <handle> (uses the <write>
+ // system call on UNIX and the <recv> 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 <len> bytes into <buf> from <handle> (uses the <read>
+ // system call on UNIX and the <ReadFile> call on Win32).
+
+ static ssize_t write_n (ACE_HANDLE handle,
+ const void *buf,
+ size_t len);
+ // Receive <len> bytes into <buf> from <handle> (uses the <write>
+ // system call on UNIX and the <WriteFile> 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 <handle>.
+
+ static int handle_timed_accept (ACE_HANDLE listener,
+ ACE_Time_Value *timeout,
+ int restart);
+ // Wait up to <timeout> amount of time to passively establish a
+ // connection. This method doesn't perform the <accept>, it just
+ // does the timed wait...
+
+ static ACE_HANDLE handle_timed_complete (ACE_HANDLE listener,
+ ACE_Time_Value *timeout);
+ // Wait up to <timeout> 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 <timeout> amount of time to actively open a device.
+ // This method doesn't perform the <connect>, it just does the timed
+ // wait...
+
+ static int set_flags (ACE_HANDLE handle,
+ int flags);
+ // Set flags associated with <handle>.
+
+ static int clr_flags (ACE_HANDLE handle,
+ int flags);
+ // Clear flags associated with <handle>.
+
+ static int set_handle_limit (int new_limit = -1);
+ // Reset the limit on the number of open handles. If <new_limit> ==
+ // -1 set the limit to the maximum allowable. Otherwise, set it to
+ // be the value of <new_limit>.
+
+ static int max_handles (void);
+ // Returns the maximum number of open handles currently permitted in
+ // this process. This maximum may be extended using
+ // <ACE::set_handle_limit>.
+
+ // = 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 <str>, substituting
+ // the environment variable if <str[0] == '$'>. Note that the
+ // pointer is allocated with <ACE_OS::malloc> and must be freed by
+ // <ACE_OS::free>
+
+ static char *strecpy (char *s, const char *t);
+ // Copies <t> to <s>, returning a pointer to the end of the copied
+ // region (rather than the beginning, a la <strcpy>.
+
+ static const char *execname (const char *pathname);
+ // On Win32 returns <pathname> if it already ends in ".exe,"
+ // otherwise returns a dynamically allocated buffer containing
+ // "<pathname>.exe". Always returns <pathname> on UNIX.
+
+ static const char *basename (const char *pathname, char delim);
+ // Returns the "basename" of a <pathname>.
+
+ 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 <day_and_time>.
+
+ 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 <filename> 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 <ldopen> to locate and open the appropriate <filename> and
+ // returns a pointer to the file, else it returns a NULL
+ // pointer. <type> specifies how the file should be open.
+
+ static u_long hash_pjw (const char *str);
+ // Computes the hash value of <str> 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 <event_handler> must be a
+ // subclass of <ACE_Event_Handler>. If the <get_handle> method of
+ // this event handler returns <ACE_INVALID_HANDLE> 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 <buf> into an <argv> style vector of
+ // strings or an <argv> style vector of string <buf>, performing
+ // environment variable substitutions if necessary.
+{
+public:
+ // = Initialization and termination.
+ ACE_ARGV (char buf[], int substitute_env_args = 1);
+ // Converts <buf> into an <argv>-style vector of strings. If
+ // <substitute_env_args> 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 <argv> into a linear string. If <substitute_env_args>
+ // 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 <index>th string in the ARGV array.
+
+ char **argv (void) const;
+ // Returns the <argv> array. Caller should not delete this memory
+ // since the <ARGV> destructor will delete it.
+
+ size_t argc (void) const;
+ // Returns <argc>.
+
+ char *buf (void) const;
+ // Returns the <buf>. Caller should not delete this memory since
+ // the <ARGV> 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 <argv> 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 <class SH, PR_AC_1> void
+ACE_Acceptor<SH, PR_AC_2>::dump (void) const
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::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 <class SH, PR_AC_1>
+ACE_Acceptor<SH, PR_AC_2>::operator ACE_PEER_ACCEPTOR & () const
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::operator ACE_PEER_ACCEPTOR &");
+ return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_;
+}
+
+template <class SH, PR_AC_1> ACE_Reactor *
+ACE_Acceptor<SH, PR_AC_2>::reactor (void) const
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::reactor");
+ return this->reactor_;
+}
+
+template <class SH, PR_AC_1> void
+ACE_Acceptor<SH, PR_AC_2>::reactor (ACE_Reactor *r)
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::reactor");
+ this->reactor_ = r;
+}
+
+template <class SH, PR_AC_1> ACE_PEER_ACCEPTOR &
+ACE_Acceptor<SH, PR_AC_2>::acceptor (void) const
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::acceptor");
+ return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_;
+}
+
+// Returns ACE_HANDLE of the underlying Acceptor_Strategy.
+
+template <class SH, PR_AC_1> ACE_HANDLE
+ACE_Acceptor<SH, PR_AC_2>::get_handle (void) const
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::get_handle");
+ return this->peer_acceptor_.get_handle ();
+}
+
+// Initialize the appropriate strategies for creation, passive
+// connection acceptance, and concurrency, and then register <this>
+// with the Reactor and listen for connection requests at the
+// designated <local_addr>.
+
+template <class SH, PR_AC_1> int
+ACE_Acceptor<SH, PR_AC_2>::open (const PR_AD &local_addr,
+ ACE_Reactor *reactor)
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::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 <class SH, PR_AC_1>
+ACE_Acceptor<SH, PR_AC_2>::ACE_Acceptor (ACE_Reactor *reactor)
+ : reactor_ (reactor)
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::ACE_Acceptor");
+}
+
+template <class SH, PR_AC_1>
+ACE_Acceptor<SH, PR_AC_2>::ACE_Acceptor (const PR_AD &addr,
+ ACE_Reactor *reactor)
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::ACE_Acceptor");
+ if (this->open (addr, reactor) == -1)
+ ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Acceptor::ACE_Acceptor"));
+}
+
+template <class SH, PR_AC_1>
+ACE_Acceptor<SH, PR_AC_2>::~ACE_Acceptor (void)
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::~ACE_Acceptor");
+ this->handle_close ();
+}
+
+template <class SH, PR_AC_1> int
+ACE_Acceptor<SH, PR_AC_2>::fini (void)
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::fini");
+ return ACE_Acceptor<SH, PR_AC_2>::handle_close ();
+}
+
+// Hook called by the explicit dynamic linking facility.
+
+template <class SH, PR_AC_1> int
+ACE_Acceptor<SH, PR_AC_2>::init (int, char *[])
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::init");
+ return -1;
+}
+
+template <class SH, PR_AC_1> int
+ACE_Acceptor<SH, PR_AC_2>::info (char **strp, size_t length) const
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::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 <class SH, PR_AC_1> int
+ACE_Acceptor<SH, PR_AC_2>::suspend (void)
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::suspend");
+ return this->reactor_->suspend_handler (this);
+}
+
+template <class SH, PR_AC_1> int
+ACE_Acceptor<SH, PR_AC_2>::resume (void)
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::resume");
+ return this->reactor_->resume_handler (this);
+}
+
+// Perform termination activities when <this> is removed from the
+// <reactor_>.
+
+template <class SH, PR_AC_1> int
+ACE_Acceptor<SH, PR_AC_2>::handle_close (ACE_HANDLE,
+ ACE_Reactor_Mask)
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::handle_close");
+ // Guard against multiple closes.
+ if (this->reactor_ != 0)
+ {
+ ACE_HANDLE handle = this->get_handle ();
+
+ // We must use the <handle> 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
+// <creation_strategy_>. 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 <class SH, PR_AC_1> SH *
+ACE_Acceptor<SH, PR_AC_2>::make_svc_handler (void)
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::make_svc_handler");
+ return new SH;
+}
+
+// Bridge method for accepting the new connection into the
+// <svc_handler>. The default behavior delegates to the
+// PEER_ACCEPTOR::accept() in the Acceptor_Strategy.
+
+template <class SH, PR_AC_1> int
+ACE_Acceptor<SH, PR_AC_2>::accept_svc_handler (SH *svc_handler)
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::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 <svc_handler> 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 <class SH, PR_AC_1> int
+ACE_Acceptor<SH, PR_AC_2>::activate_svc_handler (SH *svc_handler)
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::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 <class SH, PR_AC_1> int
+ACE_Acceptor<SH, PR_AC_2>::handle_input (ACE_HANDLE listener)
+{
+ ACE_TRACE ("ACE_Acceptor<SH, PR_AC_2>::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 <svc_handler> 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 <class SH, PR_AC_1> int
+ACE_Strategy_Acceptor<SH, PR_AC_2>::suspend (void)
+{
+ ACE_TRACE ("ACE_Strategy_Acceptor<SH, PR_AC_2>::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<SH, PR_AC_2>::suspend ();
+}
+
+template <class SH, PR_AC_1> int
+ACE_Strategy_Acceptor<SH, PR_AC_2>::resume (void)
+{
+ ACE_TRACE ("ACE_Strategy_Acceptor<SH, PR_AC_2>::resume");
+
+ // First resume ourselves.
+ if (ACE_Acceptor<SH, PR_AC_2>::suspend () == -1)
+ return -1;
+ else // Then resume the SVC_HANDLER's we've created.
+ return this->scheduling_strategy_->resume ();
+}
+
+template <class SH, PR_AC_1> void
+ACE_Strategy_Acceptor<SH, PR_AC_2>::dump (void) const
+{
+ ACE_TRACE ("ACE_Strategy_Acceptor<SH, PR_AC_2>::dump");
+
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+ ACE_Acceptor<SH, PR_AC_2>::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 <class SH, PR_AC_1> ACE_PEER_ACCEPTOR &
+ACE_Strategy_Acceptor<SH, PR_AC_2>::acceptor (void) const
+{
+ ACE_TRACE ("ACE_Strategy_Acceptor<SH, PR_AC_2>::acceptor");
+ return this->accept_strategy_->acceptor ();
+}
+
+template <class SH, PR_AC_1>
+ACE_Strategy_Acceptor<SH, PR_AC_2>::operator ACE_PEER_ACCEPTOR & () const
+{
+ ACE_TRACE ("ACE_Strategy_Acceptor<SH, PR_AC_2>::operator ACE_PEER_ACCEPTOR &");
+ return this->accept_strategy_->acceptor ();
+}
+
+// Returns ACE_HANDLE of the underlying Acceptor_Strategy.
+
+template <class SH, PR_AC_1> ACE_HANDLE
+ACE_Strategy_Acceptor<SH, PR_AC_2>::get_handle (void) const
+{
+ ACE_TRACE ("ACE_Strategy_Acceptor<SH, PR_AC_2>::get_handle");
+ return this->accept_strategy_->get_handle ();
+}
+
+// Initialize the appropriate strategies for creation, passive
+// connection acceptance, and concurrency, and then register <this>
+// with the Reactor and listen for connection requests at the
+// designated <local_addr>.
+
+template <class SH, PR_AC_1> int
+ACE_Strategy_Acceptor<SH, PR_AC_2>::open (const PR_AD &local_addr,
+ ACE_Reactor *reactor,
+ ACE_Creation_Strategy<SH> *cre_s,
+ ACE_Accept_Strategy<SH, PR_AC_2> *acc_s,
+ ACE_Concurrency_Strategy<SH> *con_s,
+ ACE_Scheduling_Strategy<SVC_HANDLER> *sch_s,
+ const char service_name[],
+ const char service_description[])
+{
+ ACE_TRACE ("ACE_Strategy_Acceptor<SH, PR_AC_2>::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 <class SH, PR_AC_1>
+ACE_Strategy_Acceptor<SH, PR_AC_2>::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<SH, PR_AC_2>::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 <class SH, PR_AC_1>
+ACE_Strategy_Acceptor<SH, PR_AC_2>::ACE_Strategy_Acceptor (const PR_AD &addr,
+ ACE_Reactor *reactor,
+ ACE_Creation_Strategy<SH> *cre_s,
+ ACE_Accept_Strategy<SH, PR_AC_2> *acc_s,
+ ACE_Concurrency_Strategy<SH> *con_s,
+ ACE_Scheduling_Strategy<SVC_HANDLER> *sch_s,
+ const char service_name[],
+ const char service_description[])
+{
+ ACE_TRACE ("ACE_Strategy_Acceptor<SH, PR_AC_2>::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 <this> is removed from the
+// <ACE_Reactor>.
+
+template <class SH, PR_AC_1> int
+ACE_Strategy_Acceptor<SH, PR_AC_2>::handle_close (ACE_HANDLE,
+ ACE_Reactor_Mask)
+{
+ ACE_TRACE ("ACE_Strategy_Acceptor<SH, PR_AC_2>::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 <handle> 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
+// <creation_strategy_>. 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 <class SH, PR_AC_1> SH *
+ACE_Strategy_Acceptor<SH, PR_AC_2>::make_svc_handler (void)
+{
+ ACE_TRACE ("ACE_Strategy_Acceptor<SH, PR_AC_2>::make_svc_handler");
+ return this->creation_strategy_->make_svc_handler ();
+}
+
+// Bridge method for accepting the new connection into the
+// <svc_handler>. The default behavior delegates to the
+// <Strategy_Acceptor::accept> in the Acceptor_Strategy.
+
+template <class SH, PR_AC_1> int
+ACE_Strategy_Acceptor<SH, PR_AC_2>::accept_svc_handler (SH *svc_handler)
+{
+ ACE_TRACE ("ACE_Strategy_Acceptor<SH, PR_AC_2>::accept_svc_handler");
+ return this->accept_strategy_->accept_svc_handler (svc_handler);
+}
+
+// Bridge method for activating a <svc_handler> 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 <class SH, PR_AC_1> int
+ACE_Strategy_Acceptor<SH, PR_AC_2>::activate_svc_handler (SH *svc_handler)
+{
+ ACE_TRACE ("ACE_Strategy_Acceptor<SH, PR_AC_2>::activate_svc_handler");
+ return this->concurrency_strategy_->activate_svc_handler
+ (svc_handler, (void *) this);
+}
+
+template <class SH, PR_AC_1>
+ACE_Strategy_Acceptor<SH, PR_AC_2>::~ACE_Strategy_Acceptor (void)
+{
+ ACE_TRACE ("ACE_Strategy_Acceptor<SH, PR_AC_2>::~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 <class SH, PR_AC_1> int
+ACE_Strategy_Acceptor<SH, PR_AC_2>::handle_signal (int, siginfo_t *, ucontext_t *)
+{
+ ACE_TRACE ("ACE_Strategy_Acceptor::handle_signal");
+ ACE_Service_Config::end_reactor_event_loop ();
+ return 0;
+}
+
+template <class SH, PR_AC_1> int
+ACE_Strategy_Acceptor<SH, PR_AC_2>::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 <class SH, PR_AC_1> int
+ACE_Strategy_Acceptor<SH, PR_AC_2>::fini (void)
+{
+ ACE_TRACE ("ACE_Strategy_Acceptor<SH, PR_AC_2>::fini");
+ return this->ACE_Strategy_Acceptor<SH, PR_AC_2>::handle_close ();
+}
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Oneshot_Acceptor)
+
+template <class SH, PR_AC_1> void
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::dump (void) const
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::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 <class SH, PR_AC_1> int
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::open (const PR_AD &addr,
+ ACE_Reactor *reactor,
+ ACE_Concurrency_Strategy<SH> *con_s)
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::open");
+ this->reactor (reactor);
+
+ // Initialize the concurrency strategy.
+
+ if (con_s == 0)
+ {
+ ACE_NEW_RETURN (con_s, ACE_Concurrency_Strategy<SH>, -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 <class SH, PR_AC_1>
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::ACE_Oneshot_Acceptor (void)
+ : delete_concurrency_strategy_ (0),
+ reactor_ (0)
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::ACE_Oneshot_Acceptor");
+}
+
+template <class SH, PR_AC_1>
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::ACE_Oneshot_Acceptor (const PR_AD &addr,
+ ACE_Reactor *reactor,
+ ACE_Concurrency_Strategy<SH> *cs)
+ : delete_concurrency_strategy_ (0)
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::ACE_Oneshot_Acceptor");
+ if (this->open (addr, reactor, cs) == -1)
+ ACE_ERROR ((LM_ERROR, "%p\n",
+ "ACE_Oneshot_Acceptor::ACE_Oneshot_Acceptor"));
+}
+
+template <class SH, PR_AC_1>
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::~ACE_Oneshot_Acceptor (void)
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::~ACE_Oneshot_Acceptor");
+ this->handle_close ();
+}
+
+template <class SH, PR_AC_1> int
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::handle_close (ACE_HANDLE,
+ ACE_Reactor_Mask)
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::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 <class SH, PR_AC_1> int
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::handle_timeout (const ACE_Time_Value &tv,
+ const void *arg)
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::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 <class SH, PR_AC_1> int
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::cancel (void)
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::cancel");
+ return this->reactor_ && this->reactor_->cancel_timer (this);
+}
+
+template <class SH, PR_AC_1> int
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::register_handler (SH *svc_handler,
+ const ACE_Synch_Options &synch_options,
+ int restart)
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::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 <svc_handler> 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 <class SH, PR_AC_1> int
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::activate_svc_handler (SH *svc_handler)
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::activate_svc_handler");
+ return this->concurrency_strategy_->activate_svc_handler
+ (svc_handler, (void *) this);
+}
+
+// Factors out the code shared between the <accept> and <handle_input>
+// methods.
+
+template <class SH, PR_AC_1> int
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::shared_accept (SH *svc_handler,
+ PR_AD *remote_addr,
+ ACE_Time_Value *timeout,
+ int restart)
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::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 <svc_handler> 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 <class SH, PR_AC_1> int
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::accept (SH *svc_handler,
+ PR_AD *remote_addr,
+ const ACE_Synch_Options &synch_options,
+ int restart)
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::accept");
+ // Note that if timeout == ACE_Time_Value (x, y) where (x > 0 || y >
+ // 0) then this->connector_.connect() will block synchronously. If
+ // <use_reactor> 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 <class SH, PR_AC_1> int
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::handle_input (ACE_HANDLE listener)
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::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 <class SH, PR_AC_1> int
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::init (int, char *[])
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::init");
+ return -1;
+}
+
+template <class SH, PR_AC_1> int
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::fini (void)
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::fini");
+ return this->handle_close ();
+}
+
+template <class SH, PR_AC_1> int
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::info (char **strp,
+ size_t length) const
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::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 <class SH, PR_AC_1> int
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::suspend (void)
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::suspend");
+ return this->reactor_ && this->reactor_->suspend_handler (this);
+}
+
+template <class SH, PR_AC_1> int
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::resume (void)
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::resume");
+ return this->reactor_ && this->reactor_->resume_handler (this);
+}
+
+// Returns ACE_HANDLE of the underlying peer_acceptor.
+
+template <class SH, PR_AC_1> ACE_HANDLE
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::get_handle (void) const
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::get_handle");
+ return this->peer_acceptor_.get_handle ();
+}
+
+template <class SH, PR_AC_1> ACE_PEER_ACCEPTOR &
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::acceptor (void) const
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::acceptor");
+ return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_;
+}
+
+template <class SH, PR_AC_1>
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::operator ACE_PEER_ACCEPTOR & () const
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::operator ACE_PEER_ACCEPTOR &");
+ return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_;
+}
+
+template <class SH, PR_AC_1> ACE_Reactor *
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::reactor (void) const
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::reactor");
+ return this->reactor_;
+}
+
+template <class SH, PR_AC_1> void
+ACE_Oneshot_Acceptor<SH, PR_AC_2>::reactor (ACE_Reactor *r)
+{
+ ACE_TRACE ("ACE_Oneshot_Acceptor<SH, PR_AC_2>::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 SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
+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 <this> with the Reactor and listen for
+ // connection requests at the designated <local_addr>.
+
+ int open (const ACE_PEER_ACCEPTOR_ADDR &,
+ ACE_Reactor * = ACE_Service_Config::reactor ());
+ // Initialize and register <this> with the Reactor and listen for
+ // connection requests at the designated <local_addr>.
+
+ 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 <ACE_HANDLE>.
+
+ 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
+ // <svc_handler>. The default behavior delegates to the
+ // PEER_ACCEPTOR::accept.
+
+ virtual int activate_svc_handler (SVC_HANDLER *svc_handler);
+ // Bridge method for activating a <svc_handler> 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 <this> is removed from the
+ // <reactor_>.
+
+ 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 <handle_close>.
+
+ virtual int info (char **buf, size_t) const;
+ // Default version returns address info in <buf>.
+
+ // = Service management hooks.
+ virtual int suspend (void);
+ // This method calls <Reactor::suspend>.
+
+ virtual int resume (void);
+ // This method calls <Reactor::resume>.
+
+private:
+ ACE_Reactor *reactor_;
+ // Event demultiplexer associated with this object.
+
+ ACE_PEER_ACCEPTOR peer_acceptor_;
+ // Concrete factory for accepting connections from clients...
+};
+
+template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
+class ACE_Strategy_Acceptor : public ACE_Acceptor <SVC_HANDLER, ACE_PEER_ACCEPTOR_2>
+ // = 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<SVC_HANDLER> * = 0,
+ ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2> * = 0,
+ ACE_Concurrency_Strategy<SVC_HANDLER> * = 0,
+ ACE_Scheduling_Strategy<SVC_HANDLER> * = 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 <this>
+ // with the Reactor and listen for connection requests at the
+ // designated <local_addr>.
+
+ int open (const ACE_PEER_ACCEPTOR_ADDR &,
+ ACE_Reactor * = ACE_Service_Config::reactor (),
+ ACE_Creation_Strategy<SVC_HANDLER> * = 0,
+ ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2> * = 0,
+ ACE_Concurrency_Strategy<SVC_HANDLER> * = 0,
+ ACE_Scheduling_Strategy<SVC_HANDLER> * = 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 <this>
+ // with the Reactor and listen for connection requests at the
+ // designated <local_addr>.
+
+ 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 <Scheduling_Strategy>'s <suspend>
+ // method.
+
+ virtual int resume (void);
+ // This method delegates to the <Scheduling_Strategy>'s <resume>
+ // method.
+
+ virtual int fini (void);
+ // Calls <handle_close> when dynamically unlinked.
+
+ virtual int info (char **buf, size_t) const;
+ // Default version returns address info in <buf>.
+
+ // = 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 strategy for
+ // creating a <SVC_HANDLER> are configured into the Acceptor via
+ // it's <creation_strategy_>. 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
+ // <SVC_HANDLER>. The default behavior delegates to the
+ // <PEER_ACCEPTOR::accept> in the <Acceptor_Strategy>.
+
+ virtual int activate_svc_handler (SVC_HANDLER *svc_handler);
+ // Bridge method for activating a <SVC_HANDLER> 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).
+
+ // = Demultiplexing hooks.
+ virtual ACE_HANDLE get_handle (void) const;
+ // Returns the listening acceptor's <ACE_HANDLE>.
+
+ virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE,
+ ACE_Reactor_Mask = ACE_Event_Handler::RWE_MASK);
+ // Perform termination activities when <this> is removed from the
+ // <Reactor>.
+
+ 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<SVC_HANDLER> CREATION_STRATEGY;
+ typedef ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2> ACCEPT_STRATEGY;
+ typedef ACE_Concurrency_Strategy<SVC_HANDLER> CONCURRENCY_STRATEGY;
+ typedef ACE_Scheduling_Strategy<SVC_HANDLER> SCHEDULING_STRATEGY;
+
+ // = Strategy objects.
+
+ CREATION_STRATEGY *creation_strategy_;
+ // Creation strategy for an Acceptor.
+
+ int delete_creation_strategy_;
+ // 1 if <Acceptor> created the creation strategy and thus should
+ // delete it, else 0.
+
+ ACCEPT_STRATEGY *accept_strategy_;
+ // Accept strategy for an <Acceptor>.
+
+ int delete_accept_strategy_;
+ // 1 if <Acceptor> created the accept strategy and thus should delete
+ // it, else 0.
+
+ 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.
+
+ SCHEDULING_STRATEGY *scheduling_strategy_;
+ // Scheduling strategy for an <Acceptor>.
+
+ int delete_scheduling_strategy_;
+ // 1 if <Acceptor> 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 <Strategy_Acceptor> uses to listen for
+ // connections.
+};
+
+template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
+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<SVC_HANDLER> * = 0);
+ // Initialize the appropriate strategies for concurrency and
+ // creation and then register <this> at the designated <local_addr>.
+
+ int open (const ACE_PEER_ACCEPTOR_ADDR &,
+ ACE_Reactor * = ACE_Service_Config::reactor (),
+ ACE_Concurrency_Strategy<SVC_HANDLER> * = 0);
+ // Initialize the appropriate strategies for concurrency and
+ // creation and then register <this> at the designated <local_addr>.
+
+ virtual ~ACE_Oneshot_Acceptor (void);
+ // Close down the <Oneshot_Acceptor>.
+
+ // = 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 <svc_handler> 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 <accept> and
+ // <handle_input> 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 <ACE_HANDLE>.
+
+ virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE,
+ ACE_Reactor_Mask = ACE_Event_Handler::RWE_MASK);
+ // Perform termination activities when <this> is removed from the
+ // <reactor_>.
+
+ 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 <buf>.
+
+ // = 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<SVC_HANDLER> *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<ACE_SYNCH> *new_queue)
+ : delete_queue_ (0)
+{
+ if (new_queue)
+ this->queue_ = new_queue;
+ else
+ {
+ ACE_NEW (this->queue_, ACE_Message_Queue<ACE_SYNCH>);
+ 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 <Andres.Kruse@cern.ch> and Douglas C. Schmidt
+// <schmidt@cs.wustl.edu>
+//
+// ============================================================================
+
+#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 <Method_Object> is inserted in the <Activation_Queue>, where
+ // it is subsequently removed by the <Scheduler> and invoked.
+{
+public:
+ // = Initialization and termination methods.
+ ACE_Activation_Queue (ACE_Message_Queue<ACE_SYNCH> *new_queue = 0);
+ ~ACE_Activation_Queue (void);
+
+ // = Queue operations.
+ ACE_Method_Object *dequeue (ACE_Time_Value *tv = 0);
+ // Dequeue the next available <Method_Object>.
+
+ int enqueue (ACE_Method_Object *new_method_object,
+ ACE_Time_Value *tv = 0);
+ // Enqueue the <Method_Object>.
+
+ void dump (void) const;
+ // Dump the state of an object.
+
+ ACE_ALLOC_HOOK_DECLARE;
+ // Declare the dynamic allocation hooks.
+
+private:
+ ACE_Message_Queue<ACE_SYNCH> *queue_;
+ // Stores the <Method_Objects>.
+
+ 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<class X> void
+auto_ptr<X>::dump (void) const
+{
+ ACE_TRACE ("auto_ptr<X>::dump");
+}
+
+template<class X> void
+auto_ptr<X>::remove (X *& x)
+{
+ ACE_TRACE ("auto_ptr<X>::remove");
+
+ X *tp = x;
+ x = 0;
+ delete tp;
+}
+
+ACE_ALLOC_HOOK_DEFINE(auto_array_ptr)
+
+template<class X> void
+auto_array_ptr<X>::dump (void) const
+{
+ ACE_TRACE ("auto_array_ptr<X>::dump");
+}
+
+template<class X> void
+auto_array_ptr<X>::remove (X *& x)
+{
+ ACE_TRACE ("auto_array_ptr<X>::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 X>
+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<X> &ap);
+ ~auto_ptr (void);
+ void operator= (auto_ptr<X> &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 X>
+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<X> &ap);
+ ~auto_array_ptr (void);
+ void operator= (auto_array_ptr<X> &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<class X> ACE_INLINE void
+auto_ptr<X>::operator= (auto_ptr<X> &rhs)
+{
+ ACE_TRACE ("auto_ptr<X>::operator=");
+ if (this != &rhs)
+ {
+ auto_ptr<X>::remove (p_);
+ p_ = rhs.release ();
+ }
+}
+
+template<class X> ACE_INLINE
+auto_ptr<X>::auto_ptr (X *p)
+ : p_ (p)
+{
+ ACE_TRACE ("auto_ptr<X>::auto_ptr");
+}
+
+template<class X> ACE_INLINE
+auto_ptr<X>::auto_ptr (auto_ptr<X> &ap)
+ : p_ (ap.release ())
+{
+ ACE_TRACE ("auto_ptr<X>::auto_ptr");
+}
+
+template<class X> ACE_INLINE
+auto_ptr<X>::~auto_ptr (void)
+{
+ ACE_TRACE ("auto_ptr<X>::~auto_ptr");
+ delete p_;
+}
+
+template<class X> ACE_INLINE X &
+auto_ptr<X>::operator *() const
+{
+ return *p_;
+}
+
+template<class X> ACE_INLINE X *
+auto_ptr<X>::operator-> () const
+{
+ ACE_TRACE ("auto_ptr<X>::operator->");
+ return p_;
+}
+
+template<class X> ACE_INLINE X *
+auto_ptr<X>::get (void) const
+{
+ ACE_TRACE ("auto_ptr<X>::get");
+ return p_;
+}
+
+template<class X> ACE_INLINE X *
+auto_ptr<X>::release (void)
+{
+ ACE_TRACE ("auto_ptr<X>::release");
+ return this->reset (0);
+}
+
+template<class X> ACE_INLINE X *
+auto_ptr<X>::reset (X *p)
+{
+ ACE_TRACE ("auto_ptr<X>::reset");
+ X *tp = p_;
+ p_ = p;
+ return tp;
+}
+
+template<class X> ACE_INLINE
+auto_array_ptr<X>::auto_array_ptr (X *p)
+ : p_ (p)
+{
+ ACE_TRACE ("auto_array_ptr<X>::auto_array_ptr");
+}
+
+template<class X> ACE_INLINE
+auto_array_ptr<X>::auto_array_ptr (auto_array_ptr<X> &ap)
+ : p_ (ap.release ())
+{
+ ACE_TRACE ("auto_array_ptr<X>::auto_array_ptr");
+}
+
+template<class X> ACE_INLINE
+auto_array_ptr<X>::~auto_array_ptr (void)
+{
+ ACE_TRACE ("auto_array_ptr<X>::~auto_array_ptr");
+ delete [] p_;
+}
+
+template<class X> ACE_INLINE X &
+auto_array_ptr<X>::operator*()
+{
+ return *p_;
+}
+
+template<class X> ACE_INLINE X *
+auto_array_ptr<X>::operator->()
+{
+ return p_;
+}
+
+template<class X> ACE_INLINE X &
+auto_array_ptr<X>::operator[](int i)
+{
+ return p_[i];
+}
+
+template<class X> ACE_INLINE X
+auto_array_ptr<X>::operator[](int i) const
+{
+ return p_[i];
+}
+
+template<class X> ACE_INLINE X *
+auto_array_ptr<X>::get (void) const
+{
+ ACE_TRACE ("auto_array_ptr<X>::get");
+ return p_;
+}
+
+template<class X> ACE_INLINE X *
+auto_array_ptr<X>::release (void)
+{
+ ACE_TRACE ("auto_array_ptr<X>::release");
+ return this->reset (0);
+}
+
+template<class X> ACE_INLINE X *
+auto_array_ptr<X>::reset (X *p)
+{
+ ACE_TRACE ("auto_array_ptr<X>::reset");
+ X *tp = p_;
+ p_ = p;
+ return tp;
+}
+
+template<class X> ACE_INLINE void
+auto_array_ptr<X>::operator= (auto_array_ptr<X> &rhs)
+{
+ ACE_TRACE ("auto_array_ptr<X>::operator=");
+ if (this != &rhs)
+ {
+ auto_array_ptr<X>::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 <ACE_ST_CORBA_Handler::iterations_> 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 <service_name> by doing a "putit" to register the
+// <service_name> using the <marker_name> at <service_location> 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 <service_name> by doing a "putit" to register
+// <service_name> using the <marker_name> 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 <service_name> with the Orbix daemon. If
+// <marker_name> and <service_location> 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 <CORBA.h>
+// #include <daemon.hh>
+#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 <service_name> with the Orbix daemon. If
+ // <marker_name> and <service_location> 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 <service_name> by doing a "putit" to register
+ // the <service_name> using the <marker_name> at <service_location>
+ // with orbixd.
+
+ virtual int remove_service (const char *service_name,
+ const char *marker_name = 0);
+ // Register <service_name> by doing a "putit" to register
+ // <service_name> using the <marker_name> 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 <thr_mgr ()>.
+
+ virtual int resume (void);
+ // Atomically resume all the threads associated with the <thr_mgr ()_>.
+
+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 <thr_mgr ()>.
+
+ virtual int resume (void);
+ // Atomically resume all the threads associated with the <thr_mgr ()>.
+
+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<class CORBA_REF>
+ACE_CORBA_Ref<CORBA_REF>::ACE_CORBA_Ref (void)
+ : ref_ (0)
+{
+ ACE_TRACE ("ACE_CORBA_Ref<CORBA_REF>::ACE_CORBA_Ref");
+}
+
+template<class CORBA_REF>
+ACE_CORBA_Ref<CORBA_REF>::ACE_CORBA_Ref (CORBA_REF *ref)
+{
+ ACE_TRACE ("ACE_CORBA_Ref<CORBA_REF>::ACE_CORBA_Ref");
+ if (ref != 0)
+ ref_ = ref->_duplicate ();
+ else
+ ref_ = 0;
+}
+
+template<class CORBA_REF> CORBA_REF *
+ACE_CORBA_Ref<CORBA_REF>::operator= (CORBA_REF *ref)
+{
+ ACE_TRACE ("ACE_CORBA_Ref<CORBA_REF>::operator=");
+ if (ref_ != 0)
+ ref_->_release ();
+ if (ref == 0)
+ {
+ ref_ = 0;
+ return 0;
+ }
+ else
+ return ref_ = ref->_duplicate ();
+}
+
+template<class CORBA_REF>
+ACE_CORBA_Ref<CORBA_REF>::operator CORBA_REF * (void) const
+{
+ ACE_TRACE ("ACE_CORBA_Ref<CORBA_REF>::operator CORBA_REF *");
+ ACE_ASSERT (ref_ != 0);
+ return ref_;
+}
+
+template<class CORBA_REF> CORBA_REF *
+ACE_CORBA_Ref<CORBA_REF>::operator-> (void) const
+{
+ ACE_TRACE ("ACE_CORBA_Ref<CORBA_REF>::operator->");
+ ACE_ASSERT (ref_ != 0);
+ return ref_;
+}
+
+template<class CORBA_REF> int
+ACE_CORBA_Ref<CORBA_REF>::operator== (CORBA_REF *rhs) const
+{
+ ACE_TRACE ("ACE_CORBA_Ref<CORBA_REF>::operator==");
+ // pointer comparison.
+ return ref_ == rhs;
+}
+
+template<class CORBA_REF> int
+ACE_CORBA_Ref<CORBA_REF>::operator!= (CORBA_REF *rhs) const
+{
+ ACE_TRACE ("ACE_CORBA_Ref<CORBA_REF>::operator!=");
+ // pointer comparison.
+ return ref_ != rhs;
+}
+
+template<class CORBA_REF>
+ACE_CORBA_Ref<CORBA_REF>::~ACE_CORBA_Ref ()
+{
+ ACE_TRACE ("ACE_CORBA_Ref<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 CORBA_REF>
+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 <class SH, PR_CO_1> ACE_Reactor *
+ACE_Connector<SH, PR_CO_2>::reactor (void) const
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::reactor");
+ return this->reactor_;
+}
+
+template <class SH, PR_CO_1> void
+ACE_Connector<SH, PR_CO_2>::reactor (ACE_Reactor *r)
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::reactor");
+ this->reactor_ = r;
+}
+
+template <class SH, PR_CO_1> void
+ACE_Connector<SH, PR_CO_2>::dump (void) const
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::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 <class SH, PR_CO_1> int
+ACE_Connector<SH, PR_CO_2>::activate_svc_handler (SVC_HANDLER *svc_handler)
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::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 <class SH, PR_CO_1> int
+ACE_Connector<SH, PR_CO_2>::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<SH, PR_CO_2>::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
+ // <use_reactor> 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 <class SH, PR_CO_1> PEER_CONNECTOR &
+ACE_Connector<SH, PR_CO_2>::connector (void) const
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::connector");
+ return (PEER_CONNECTOR &) this->connector_;
+}
+
+template <class SH, PR_CO_1> int
+ACE_Connector<SH, PR_CO_2>::open (ACE_Reactor *reactor)
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::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 <class SH, PR_CO_1> ACE_HANDLE
+ACE_Connector<SH, PR_CO_2>::get_handle (void) const
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::get_handle");
+ return this->connector_.get_handle ();
+}
+
+template <class SH>
+ACE_Svc_Tuple<SH>::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<SH>::ACE_Svc_Tuple");
+}
+
+template <class SH> SVC_HANDLER *
+ACE_Svc_Tuple<SH>::svc_handler (void)
+{
+ ACE_TRACE ("ACE_Svc_Tuple<SH>::svc_handler");
+ return this->svc_handler_;
+}
+
+template <class SH> const void *
+ACE_Svc_Tuple<SH>::arg (void)
+{
+ ACE_TRACE ("ACE_Svc_Tuple<SH>::arg");
+ return this->arg_;
+}
+
+template <class SH> void
+ACE_Svc_Tuple<SH>::arg (const void *v)
+{
+ ACE_TRACE ("ACE_Svc_Tuple<SH>::arg");
+ this->arg_ = v;
+}
+
+template <class SH> ACE_HANDLE
+ACE_Svc_Tuple<SH>::handle (void)
+{
+ ACE_TRACE ("ACE_Svc_Tuple<SH>::handle");
+ return this->handle_;
+}
+
+template <class SH> void
+ACE_Svc_Tuple<SH>::handle (ACE_HANDLE h)
+{
+ ACE_TRACE ("ACE_Svc_Tuple<SH>::handle");
+ this->handle_ = h;
+}
+
+template <class SH> int
+ACE_Svc_Tuple<SH>::cancellation_id (void)
+{
+ ACE_TRACE ("ACE_Svc_Tuple<SH>::cancellation_id");
+ return this->cancellation_id_;
+}
+
+template <class SH> void
+ACE_Svc_Tuple<SH>::cancellation_id (int id)
+{
+ ACE_TRACE ("ACE_Svc_Tuple<SH>::cancellation_id");
+ this->cancellation_id_ = id;
+}
+
+template <class SH> void
+ACE_Svc_Tuple<SH>::dump (void) const
+{
+ ACE_TRACE ("ACE_Svc_Tuple<SH>::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 <class SH, PR_CO_1>
+ACE_Connector<SH, PR_CO_2>::ACE_Connector (ACE_Reactor *reactor)
+ : reactor_ (reactor)
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::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 <class SH, PR_CO_1> int
+ACE_Connector<SH, PR_CO_2>::handle_timeout (const ACE_Time_Value &tv,
+ const void *arg)
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::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 <arg> that was passed in as a
+ // magic cookie during ACE_Connector::connect().
+ sh->handle_timeout (tv, ast->arg ());
+
+ delete ast;
+ return 0;
+ }
+}
+
+template <class SH, PR_CO_1> int
+ACE_Connector<SH, PR_CO_2>::cleanup_AST (ACE_HANDLE handle,
+ ACE_Svc_Tuple<SH> *&ast)
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::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 <class SH, PR_CO_1> int
+ACE_Connector<SH, PR_CO_2>::handle_input (ACE_HANDLE h)
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::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 <class SH, PR_CO_1> int
+ACE_Connector<SH, PR_CO_2>::handle_output (ACE_HANDLE handle)
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::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 <class SH, PR_CO_1> int
+ACE_Connector<SH, PR_CO_2>::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<SH, PR_CO_2>::connect");
+ // Delegate to connection strategy.
+ return this->connect_svc_handler (sh, remote_addr, synch_options,
+ local_addr, reuse_addr,
+ flags, perms);
+
+}
+
+// Cancel a <svc_handler> that was started asynchronously.
+template <class SH, PR_CO_1> int
+ACE_Connector<SH, PR_CO_2>::cancel (SH *sh)
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::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 <class SH, PR_CO_1> int
+ACE_Connector<SH, PR_CO_2>::create_AST (SH *sh,
+ const ACE_Synch_Options &synch_options)
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::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 <class SH, PR_CO_1> int
+ACE_Connector<SH, PR_CO_2>::handle_close (ACE_HANDLE, ACE_Reactor_Mask mask)
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::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 <class SH, PR_CO_1> int
+ACE_Connector<SH, PR_CO_2>::fini (void)
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::fini");
+ // Make sure we call our handle_close(), not a subclass's!
+ return ACE_Connector<SH, PR_CO_2>::handle_close ();
+}
+
+// Hook called by the explicit dynamic linking facility.
+
+template <class SH, PR_CO_1> int
+ACE_Connector<SH, PR_CO_2>::init (int, char *[])
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::init");
+ return -1;
+}
+
+template <class SH, PR_CO_1> int
+ACE_Connector<SH, PR_CO_2>::suspend (void)
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::suspend");
+ return -1;
+}
+
+template <class SH, PR_CO_1> int
+ACE_Connector<SH, PR_CO_2>::resume (void)
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::resume");
+ return -1;
+}
+
+template <class SH, PR_CO_1> int
+ACE_Connector<SH, PR_CO_2>::info (char **strp, size_t length) const
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::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 <class SH, PR_CO_1>
+ACE_Connector<SH, PR_CO_2>::~ACE_Connector (void)
+{
+ ACE_TRACE ("ACE_Connector<SH, PR_CO_2>::~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 SVC_HANDLER>
+class ACE_Svc_Tuple
+ // = TITLE
+ // Holds the ACE_Svc_Handler and its argument and
+ // <ACE_Timer_Handle> 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 <HANDLE> that we are trying to connect.
+
+ const void *arg_;
+ // Associated argument.
+
+ int cancellation_id_;
+ // Associated cancellation id.
+};
+
+template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1>
+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 <peer> at <remote_addr> using
+ // <synch_options>. If the caller wants to designate the selected
+ // <local_addr> they can (and can also insist that the <local_addr>
+ // be reused by passing a value <reuse_addr> == 1). <flags> and
+ // <perms> 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 <svc_handler> 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<SVC_HANDLER> AST;
+
+#if defined (ACE_MT_SAFE)
+ typedef ACE_Map_Manager<ACE_HANDLE, ACE_Svc_Tuple<SVC_HANDLER> *, ACE_RW_Mutex> MAP_MANAGER;
+ typedef ACE_Map_Iterator<ACE_HANDLE, ACE_Svc_Tuple<SVC_HANDLER> *, ACE_RW_Mutex> MAP_ITERATOR;
+ typedef ACE_Map_Entry<ACE_HANDLE, ACE_Svc_Tuple<SVC_HANDLER> *> MAP_ENTRY;
+// ACE_Thread_Mutex lock_;
+#else
+ typedef ACE_Map_Manager<ACE_HANDLE, ACE_Svc_Tuple<SVC_HANDLER> *, ACE_Null_Mutex> MAP_MANAGER;
+ typedef ACE_Map_Iterator<ACE_HANDLE, ACE_Svc_Tuple<SVC_HANDLER> *, ACE_Null_Mutex> MAP_ITERATOR;
+ typedef ACE_Map_Entry<ACE_HANDLE, ACE_Svc_Tuple<SVC_HANDLER> *> 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 <svc_handler> to the
+ // <remote_addr>. The default behavior delegates to the
+ // PEER_CONNECTOR::connect.
+
+ virtual int activate_svc_handler (SVC_HANDLER *svc_handler);
+ // Bridge method for activating a <svc_handler> 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 <handle_close> to shutdown the Connector gracefully.
+
+ virtual int info (char **, size_t) const;
+ // Default version returns address info in <buf>.
+
+ // = 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 <handler_map_>.
+ // so that we can continue accepting this connection asynchronously.
+
+ int cleanup_AST (ACE_HANDLE, AST *&);
+ // Cleanup the <handler_map_> 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
+ // <ACE_Connector> 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 <new_stream> if things go well.
+ // The <remote_sap> is the address that we are trying to connect
+ // with. The <timeout> 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 <errno == EWOULDBLOCK>. 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 <errno == ETIMEDOUT>.
+ // The <local_sap> is the value of local address to bind to. If
+ // it's the default value of <ACE_Addr::sap_any> then the user is
+ // letting the OS do the binding. If <reuse_addr> == 1 then the
+ // <local_addr> is reused, even if it hasn't been cleanedup yet.
+ // The <flags> and <perms> 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 <new_stream> if things go well.
+ // The <remote_sap> is the address that we are trying to connect
+ // with. The <timeout> 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 <errno == EWOULDBLOCK>. 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 <errno == ETIMEDOUT>.
+ // The <local_sap> is the value of local address to bind to. If
+ // it's the default value of <ACE_Addr::sap_any> then the user is
+ // letting the OS do the binding. If <reuse_addr> == 1 then the
+ // <local_addr> is reused, even if it hasn't been cleanedup yet.
+ // The <flags> and <perms> 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 <n> bytes in <buf>.
+
+ ssize_t recv (void *buf, size_t n) const;
+ // Recv upto <n> bytes in <buf>.
+
+ 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 <cntl> and <data> via STREAM pipes.
+
+ ssize_t send (const ACE_Str_Buf *cntl,
+ const ACE_Str_Buf *data,
+ int flags = 0) const;
+ // Send <cntl> and <data> 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 <n> bytes via Win32 WriteFile using overlapped I/O.
+
+ ssize_t recv (void *buf, size_t n, ACE_OVERLAPPED *overlapped) const;
+ // Recv <n> 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 <dumper>. 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 <dumper, this_> to the list of registered ACE objects.
+
+ void remove_object (const void *this_);
+ // Use <this_> to locate and remove the associated <dumper> 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 <object_table_>.
+
+#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<CLASS> (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 <class Concrete>
+ACE_Dumpable_Adapter<Concrete>::~ACE_Dumpable_Adapter (void)
+{
+ ACE_TRACE ("ACE_Dumpable_Adapter<Concrete>::~ACE_Dumpable_Adapter");
+}
+
+template <class Concrete>
+ACE_Dumpable_Adapter<Concrete>::ACE_Dumpable_Adapter (const Concrete *t)
+ : this_ (t), ACE_Dumpable ((const void *) t)
+{
+ ACE_TRACE ("ACE_Dumpable_Adapter<Concrete>::ACE_Dumpable_Adapter");
+}
+
+template <class Concrete> Concrete *
+ACE_Dumpable_Adapter<Concrete>::operator->() const
+{
+ return (Concrete *) this->this_;
+}
+
+template <class Concrete> void
+ACE_Dumpable_Adapter<Concrete>::dump (void) const
+{
+ ACE_TRACE ("ACE_Dumpable_Adapter<Concrete>::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 Concrete>
+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 <class Concrete>.
+ //
+ // = DESCRIPTION
+ // This design is similar to the Adapter and Decorator patterns
+ // from the ``Gang of Four'' book. Note that <class Concrete>
+ // 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 <dump> method of
+ // <class Concrete>).
+
+ Concrete *operator->() const;
+ // Delegate to methods in the Concrete class.
+
+private:
+ const Concrete *this_;
+ // Pointer to <this> of <class Concrete>.
+};
+
+#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 <instance_> 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 <class SERVICE> void
+ACE_Dynamic_Service<SERVICE>::dump (void) const
+{
+ ACE_TRACE ("ACE_Dynamic_Service<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 <name>.
+
+template <class SERVICE> SERVICE *
+ACE_Dynamic_Service<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 SERVICE>
+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 <name> 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
+ // <get_message> and <get_handle> 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 <handle_close> is called. If
+ // <bytes_transferred> >= 0, then the I/O operation completed
+ // successfully. If <bytes_transferred> == -1, then the I/O
+ // operation failed. Check <message> 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 <handle_close> is called. If
+ // <bytes_transferred> >= 0, then the I/O operation completed
+ // successfully. If <bytes_transferred> == -1, then the I/O
+ // operation failed. Check <message> for total bytes received and
+ // errno for reason.
+
+ virtual ACE_Message_Block *get_message (void);
+ // Factory that creates an <ACE_Message_Block> that is used by the
+ // Proactor to send or receive a message asynchronously. When the
+ // asynchronous call completes, this message is returned to the
+ // <IO_Handler> 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 <class T> void
+ACE_Event_Handler_T<T>::dump (void) const
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::dump");
+}
+
+template<class T>
+ACE_Event_Handler_T<T>::~ACE_Event_Handler_T (void)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::~ACE_Event_Handler_T");
+ if (this->delete_handler_)
+ delete this->op_handler_;
+}
+
+template <class T>
+ACE_Event_Handler_T<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<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 T>
+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 <op_handler_> object of type <T> 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 <op_handler>
+
+ // = Override all the ACE_Event_Handler methods and have them call
+ // through to the <T> 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<class T> void ACE_INLINE
+ACE_Event_Handler_T<T>::op_handler (T *op)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::op_handler");
+ this->op_handler_ = op;
+}
+
+template<class T> ACE_INLINE T *
+ACE_Event_Handler_T<T>::op_handler (void)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::op_handler");
+ return this->op_handler_;
+}
+
+template<class T> ACE_HANDLE ACE_INLINE
+ACE_Event_Handler_T<T>::get_handle (void) const
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::get_handle");
+ return this->get_handle_ == 0 ? -1 : (this->op_handler_->*get_handle_) ();
+}
+
+template<class T> void ACE_INLINE
+ACE_Event_Handler_T<T>::set_handle (ACE_HANDLE h)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::set_handle");
+ if (this->set_handle_ != 0)
+ (this->op_handler_->*set_handle_) (h);
+}
+
+template<class T> int ACE_INLINE
+ACE_Event_Handler_T<T>::handle_input (ACE_HANDLE fd)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::handle_input");
+ return this->input_handler_ == 0 ? 0 : (this->op_handler_->*input_handler_) (fd);
+}
+
+template<class T> int ACE_INLINE
+ACE_Event_Handler_T<T>::handle_output (ACE_HANDLE fd)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::handle_output");
+ return this->output_handler_ == 0 ? 0 : (this->op_handler_->*output_handler_) (fd);
+}
+
+template<class T> ACE_INLINE int
+ACE_Event_Handler_T<T>::handle_exception (ACE_HANDLE fd)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::handle_exception");
+ return this->except_handler_ == 0 ? 0 : (this->op_handler_->*except_handler_) (fd);
+}
+
+template<class T> ACE_INLINE int
+ACE_Event_Handler_T<T>::handle_timeout (const ACE_Time_Value &tv, const void *arg)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::handle_timeout");
+ return this->to_handler_ == 0 ? 0 : (this->op_handler_->*to_handler_) (tv, arg);
+}
+
+template<class T> ACE_INLINE int
+ACE_Event_Handler_T<T>::handle_close (ACE_HANDLE fd, ACE_Reactor_Mask close_mask)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::handle_close");
+ return this->cl_handler_ == 0 ? 0 : (this->op_handler_->*cl_handler_) (fd, close_mask);
+}
+
+template<class T> ACE_INLINE int
+ACE_Event_Handler_T<T>::handle_signal (ACE_HANDLE signum, siginfo_t *s, ucontext_t *u)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::handle_signal");
+ return this->sig_handler_ == 0 ? 0 : (this->op_handler_->*sig_handler_) (signum, s, u);
+}
+
+template<class T> ACE_INLINE ACE_Event_Handler_T<T>::GET_HANDLE
+ACE_Event_Handler_T<T>::handle_get (void)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::handle_get");
+ return this->get_handle_;
+}
+
+template<class T> ACE_INLINE void
+ACE_Event_Handler_T<T>::handle_get (ACE_Event_Handler_T<T>::GET_HANDLE h)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::handle_get");
+ this->get_handle_ = h;
+}
+
+template<class T> ACE_INLINE ACE_Event_Handler_T<T>::SET_HANDLE
+ACE_Event_Handler_T<T>::handle_set (void)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::handle_set");
+ return this->set_handle_;
+}
+
+template<class T> ACE_INLINE void
+ACE_Event_Handler_T<T>::handle_set (ACE_Event_Handler_T<T>::SET_HANDLE h)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::handle_set");
+ this->set_handle_ = h;
+}
+
+template<class T> ACE_INLINE ACE_Event_Handler_T<T>::IO_HANDLER
+ACE_Event_Handler_T<T>::input_handler (void)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::input_handler");
+ return this->input_handler_;
+}
+
+template<class T> ACE_INLINE void
+ACE_Event_Handler_T<T>::input_handler (ACE_Event_Handler_T<T>::IO_HANDLER h)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::input_handler");
+ this->input_handler_ = h;
+}
+
+template<class T> ACE_INLINE ACE_Event_Handler_T<T>::IO_HANDLER
+ACE_Event_Handler_T<T>::output_handler (void)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::output_handler");
+ return this->output_handler_;
+}
+
+template<class T> ACE_INLINE void
+ACE_Event_Handler_T<T>::output_handler (ACE_Event_Handler_T<T>::IO_HANDLER h)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::output_handler");
+ this->output_handler_ = h;
+}
+
+template<class T> ACE_INLINE ACE_Event_Handler_T<T>::IO_HANDLER
+ACE_Event_Handler_T<T>::except_handler (void)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::except_handler");
+ return this->except_handler_;
+}
+
+template<class T> ACE_INLINE void
+ACE_Event_Handler_T<T>::except_handler (ACE_Event_Handler_T<T>::IO_HANDLER h)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::except_handler");
+ this->except_handler_ = h;
+}
+
+template<class T> ACE_INLINE ACE_Event_Handler_T<T>::TO_HANDLER
+ACE_Event_Handler_T<T>::to_handler (void)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::to_handler");
+ return this->to_handler_;
+}
+
+template<class T> ACE_INLINE void
+ACE_Event_Handler_T<T>::to_handler (ACE_Event_Handler_T<T>::TO_HANDLER h)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::to_handler");
+ this->to_handler_ = h;
+}
+
+template<class T> ACE_INLINE ACE_Event_Handler_T<T>::CL_HANDLER
+ACE_Event_Handler_T<T>::cl_handler (void)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::cl_handler");
+ return this->cl_handler_;
+}
+
+template<class T> ACE_INLINE void
+ACE_Event_Handler_T<T>::cl_handler (ACE_Event_Handler_T<T>::CL_HANDLER h)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::cl_handler");
+ this->cl_handler_ = h;
+}
+
+template<class T> ACE_INLINE ACE_Event_Handler_T<T>::SIG_HANDLER
+ACE_Event_Handler_T<T>::sig_handler (void)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<T>::sig_handler");
+ return this->sig_handler_;
+}
+
+template<class T> ACE_INLINE void
+ACE_Event_Handler_T<T>::sig_handler (ACE_Event_Handler_T<T>::SIG_HANDLER h)
+{
+ ACE_TRACE ("ACE_Event_Handler_T<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 <rendezvous> 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 <rendezvous> 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 <buf> of up to <len> bytes.
+
+ ssize_t recv_n (void *buf, size_t len);
+ // Recv <buf> of exactly <len> 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 <msg> as an ACE_Str_Buf.
+
+ ssize_t recv (void *buf, size_t len);
+ // Recv <msg> as a buffer.
+
+#if defined (ACE_HAS_STREAM_PIPES)
+ ssize_t recv (ACE_Str_Buf *data,
+ ACE_Str_Buf *cntl,
+ int *flags);
+ // Recv <data> and <cntl> message via Stream pipes.
+
+ ssize_t recv (int *band,
+ ACE_Str_Buf *data,
+ ACE_Str_Buf *cntl,
+ int *flags);
+ // Recv <data> and <cntl> 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 <buf> of up to <len> bytes.
+
+ ssize_t send_n (const void *buf, size_t len);
+ // Send <buf> of exactly <len> 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 <buf> of up to <len> bytes.
+
+ ssize_t send (const void *buf, size_t len);
+ // Send <buf> of exactly <len> 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 <data> and <cntl> 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 <data> and <cntl> 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 <new_stream> if things go well.
+ // The <remote_sap> is the address that we are trying to connect
+ // with. The <timeout> 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 <errno == EWOULDBLOCK>. 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 <errno == ETIMEDOUT>.
+ // The <local_sap> is the value of local address to bind to. If
+ // it's the default value of <ACE_Addr::sap_any> then the user is
+ // letting the OS do the binding. If <reuse_addr> == 1 then the
+ // <local_addr> is reused, even if it hasn't been cleanedup yet.
+ // The <flags> and <perms> 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 <new_stream> if things go well.
+ // The <remote_sap> is the address that we are trying to connect
+ // with. The <timeout> 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 <errno == EWOULDBLOCK>. 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 <errno == ETIMEDOUT>.
+ // The <local_sap> is the value of local address to bind to. If
+ // it's the default value of <ACE_Addr::sap_any> then the user is
+ // letting the OS do the binding. If <reuse_addr> == 1 then the
+ // <local_addr> is reused, even if it hasn't been cleanedup yet.
+ // The <flags> and <perms> 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 <n> bytes in <buf>.
+
+ ssize_t recv (void *buf, size_t n) const;
+ // Recv upto <n> bytes in <buf>.
+
+ 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 <n> bytes via Win32 WriteFile using overlapped I/O.
+
+ ssize_t recv (void *buf, size_t n, ACE_OVERLAPPED *overlapped) const;
+ // Recv <n> 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 <class T> void
+ACE_Future_Rep<T>::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 <class T>
+ACE_Future_Rep<T>::ACE_Future_Rep (void)
+ : ref_count_ (0),
+ value_ (0),
+ value_ready_ (this->value_ready_mutex_)
+{
+}
+
+template <class T>
+ACE_Future_Rep<T>::~ACE_Future_Rep (void)
+{
+ delete this->value_;
+ this->value_ = 0;
+}
+
+template <class T> int
+ACE_Future_Rep<T>::ready (void)
+{
+ return this->value_ != 0;
+}
+
+template <class T> int
+ACE_Future_Rep<T>::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 <class T> int
+ACE_Future_Rep<T>::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 <class T>
+ACE_Future_Rep<T>::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 <class T>
+ACE_Future<T>::ACE_Future (void)
+ : future_rep_ (0)
+{
+}
+
+template <class T>
+ACE_Future<T>::ACE_Future (const ACE_Future<T> &r)
+{
+
+ // copy constructor:
+ //
+ // bind <this> to the same <ACE_Future_Rep> as <r>.
+
+ // @@ 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 <r>. We have to make sure
+ // that <r> 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 <class T>
+ACE_Future<T>::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 <class T>
+ACE_Future<T>::~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 <class T> int
+ACE_Future<T>::operator== (const ACE_Future<T> &r) const
+{
+ return r.future_rep_ == this->future_rep_;
+}
+
+template <class T> int
+ACE_Future<T>::operator!= (const ACE_Future<T> &r) const
+{
+ return r.future_rep_ != this->future_rep_;
+}
+
+template <class T> int
+ACE_Future<T>::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 <class T> int
+ACE_Future<T>::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 <ACE_Future_Rep> yet?
+ return 0;
+}
+
+template <class T> ACE_Future_Rep<T> *
+ACE_Future<T>::create_rep_i (void) const
+{
+ // Should only be called internally with locks held.
+ ACE_NEW_RETURN (((ACE_Future<T> *) this)->future_rep_, ACE_Future_Rep<T>, 0);
+ this->future_rep_->ref_count_ = 1;
+ return this->future_rep_;
+}
+
+template <class T> int
+ACE_Future<T>::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 <class T> int
+ACE_Future<T>::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 <class T>
+ACE_Future<T>::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<T> futT;
+ // T t;
+ // t = futT;
+
+ // perform type conversion on Future_Rep.
+ return *future_rep_;
+}
+
+template <class T> void
+ACE_Future<T>::operator = (const ACE_Future<T> &r)
+{
+ // assignment:
+ //
+ // bind <this> to the same <ACE_Future_Rep> as <r>.
+
+ ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->mutex_));
+
+ // if there is already a <ACE_Future_Rep> we have
+ // to disconnect from it...
+ if (this->future_rep_)
+ {
+ // Disconnect from the <ACE_Future_Rep>.
+ this->future_rep_->ref_count_--;
+
+ if (this->future_rep_->ref_count_ == 0)
+ delete this->future_rep_;
+ }
+
+ // Acquire the mutex on <r>. We have to make sure
+ // that <r> 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 <class T> void
+ACE_Future<T>::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 <class T> void *
+ACE_Future<T>::operator new (size_t nbytes)
+{
+ return 0;
+}
+
+template <class T> void
+ACE_Future<T>::operator delete (void *)
+{
+}
+
+template <class T> void
+ACE_Future<T>::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 <Andres.Kruse@cern.ch> and Douglas C. Schmidt
+// <schmidt@cs.wustl.edu>
+//
+// ============================================================================
+
+#if !defined (ACE_FUTURE_H)
+#define ACE_FUTURE_H
+
+#include "ace/Synch.h"
+
+#if defined (ACE_HAS_THREADS)
+
+// Forward decl.
+template <class T> class ACE_Future;
+
+template <class T> class ACE_Future_Rep
+// = TITLE
+//
+// ACE_Future_Rep<T>
+//
+// = DESCRIPTION
+// An ACE_Future_Rep<T> 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<T> object[s]
+// and only accessible through them.
+{
+ friend class ACE_Future<T>;
+
+private:
+
+ int set (const T &r);
+ // Set the result value.
+
+ int get (T &value, ACE_Time_Value *tv);
+ // Wait up to <tv> time to get the <value>.
+
+ 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<ACE_Thread_Mutex, int> ref_count_;
+ // Reference count.
+
+ // = Condition variable and mutex that protect the <value_>.
+ ACE_Condition_Thread_Mutex value_ready_;
+ ACE_Thread_Mutex value_ready_mutex_;
+};
+
+template <class T> 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<T> &r);
+ // Copy constructor binds <this> and <r> to the same
+ // <ACE_Future_Rep>. An <ACE_Future_Rep> is created if necessary.
+
+ ACE_Future (const T &r);
+ // Constructor that initialises an <ACE_Future> to point to the
+ // result <r> immediately.
+
+ ~ACE_Future (void);
+ // Destructor.
+
+ void operator = (const ACE_Future<T> &r);
+ // Assignment operator that binds <this> and <r> to the same
+ // <ACE_Future_Rep>. An <ACE_Future_Rep> is created if necessary.
+
+ int cancel (const T &r);
+ // Cancel an <ACE_Future> and assign the value <r>. It is used if a
+ // client does not want to wait for <T> to be produced.
+
+ int operator == (const ACE_Future<T> &r) const;
+ // Equality operator that returns 1 if both ACE_Future<T> objects
+ // point to the same ACE_Future_Rep<T> object. Attention: It also
+ // returns 1 if both objects have just been instantiated and not
+ // used yet.
+
+ int operator != (const ACE_Future<T> &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 <tv> time to get the <value>.
+
+ 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<T> *create_rep_i (void) const;
+ // Create the <ACE_Future_Rep> 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<T> *future_rep_;
+ // the ACE_Future_Rep
+
+ ACE_Thread_Mutex mutex_;
+ // Protect operations on the <Future>.
+
+};
+
+#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 + <skip_argv0>; 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 <FD_SET> 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 <Handle_Set> we are iterating through.
+
+ int num_;
+ // Number of the word we're iterating on.
+
+ size_t index_;
+ // Index of the current <num_> 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 <port_name> and the remote
+// <host_name>.
+
+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 <port_name> 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 <ACE_INET_Addr> from a sockaddr_in structure.
+
+ ACE_INET_Addr (u_short port_number, const char host_name[]);
+ // Creates an <ACE_INET_Addr> from a <port_number> and the remote
+ // <host_name>.
+
+ ACE_INET_Addr (const char address[]);
+ // Initializes an <ACE_INET_Addr> from the <address>, 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 <address> 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 <ACE_INET_Addr> from a <port_number> and an Internet
+ // <ip_addr>. This method assumes that <port_number> and <ip_addr>
+ // are in host byte order.
+
+ ACE_INET_Addr (const char port_name[], const char host_name[]);
+ // Uses <getservbyname> to create an <ACE_INET_Addr> from a
+ // <port_name> and the remote <host_name>.
+
+ ACE_INET_Addr (const char port_name[], ACE_UINT32 ip_addr);
+ // Uses <getservbyname> to create an <ACE_INET_Addr> from a
+ // <port_name> and an Internet <ip_addr>. This method assumes that
+ // <ip_addr> is in host byte order.
+
+ // = Direct initialization methods (useful after the object has been
+ // constructed).
+ int set (const ACE_INET_Addr &);
+ // Initializes from another <ACE_INET_Addr>.
+
+ int set (u_short port_number, const char host_name[],
+ int encode = 1);
+ // Initializes an <ACE_INET_Addr> from a <port_number> and the
+ // remote <host_name>. If <encode> is enabled then <port_number> 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 <ACE_INET_Addr> from a <port_number> and an
+ // Internet <ip_addr>. If <encode> is enabled then <port_number>
+ // and <ip_addr> 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 <getservbyname> to initialize an <ACE_INET_Addr> from a
+ // <port_name> and the remote <host_name>.
+
+ int set (const char port_name[], ACE_UINT32 ip_addr);
+ // Uses <getservbyname> to initialize an <ACE_INET_Addr> from a
+ // <port_name> and an Internet address. This assumes that <ip_addr>
+ // is already in network byte order.
+
+ int set (const char addr[]);
+ // Initializes an <ACE_INET_Addr> from the <addr>, 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 <address> it
+ // is assumed to be a port number, with the IP address being
+ // INADDR_ANY.
+
+ int set (const sockaddr_in *, int len);
+ // Creates an <ACE_INET_Addr> 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 <ACE_INET_Addr> 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 <ACE_INET_Addr> from the <address>, 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 <address> 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
+ // <encode> is enabled then <port_number> 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 <hostname> (which is assumed to be
+ // <hostnamelen> 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 SYNCH> 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 <signum>.
+ int disable (int signum) const;
+ // Disable signal <signum>.
+
+ 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 <signum>.
+
+ int disable (int signum) const;
+ // Disable signal <signum>.
+
+ 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 <this->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 <handle>
+
+ 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 <new_stream> if things go well.
+ // The <remote_sap> is the address that we are trying to connect
+ // with. The <timeout> 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 <errno == EWOULDBLOCK>. 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 <errno == ETIMEDOUT>.
+ // The <local_sap> is the value of local address to bind to. If
+ // it's the default value of <ACE_Addr::sap_any> then the user is
+ // letting the OS do the binding. If <reuse_addr> == 1 then the
+ // <local_addr> 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 <new_stream> if things go well.
+ // The <remote_sap> is the address that we are trying to connect
+ // with. The <timeout> 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 <errno == EWOULDBLOCK>. 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 <errno == ETIMEDOUT>.
+ // The <local_sap> is the value of local address to bind to. If
+ // it's the default value of <ACE_Addr::sap_any> then the user is
+ // letting the OS do the binding. If <reuse_addr> == 1 then the
+ // <local_addr> 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<ACE_Name_Binding>;
+template class ACE_Unbounded_Set_Iterator<ACE_Name_Binding>;
+template class ACE_Unbounded_Set<ACE_WString>;
+template class ACE_Unbounded_Set_Iterator<ACE_WString>;
+template class ACE_Set_Node<ACE_WString>;
+template class ACE_Set_Node<ACE_Name_Binding>;
+template class ACE_Guard<ACE_RW_Process_Mutex>;
+template class ACE_Read_Guard<ACE_RW_Process_Mutex>;
+template class ACE_Write_Guard<ACE_RW_Process_Mutex>;
+template class ACE_Malloc<ACE_MMAP_Memory_Pool, ACE_RW_Process_Mutex>;
+template class ACE_Map_Manager<ACE_NS_String, ACE_NS_Internal, ACE_Null_Mutex>;
+template class ACE_Map_Iterator<ACE_NS_String, ACE_NS_Internal, ACE_Null_Mutex>;
+template class ACE_Map_Entry <ACE_NS_String, ACE_NS_Internal>;
+#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 <class ALLOCATOR>
+ACE_Name_Space_Map<ALLOCATOR>::ACE_Name_Space_Map (ALLOCATOR *allocator)
+ : MAP_MANAGER (allocator)
+{
+ ACE_TRACE ("ACE_Name_Space_Map::ACE_Name_Space_Map");
+}
+
+#if defined (ACE_WIN32)
+template <class ALLOCATOR> int
+ACE_Name_Space_Map<ALLOCATOR>::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 <class ALLOCATOR> int
+ACE_Name_Space_Map<ALLOCATOR>::close (ALLOCATOR* allocator)
+{
+ ACE_TRACE ("ACE_Name_Space_Map::close");
+
+ this->allocator_ = allocator;
+ return this->close_i ();
+}
+
+template <class ALLOCATOR> int
+ACE_Name_Space_Map<ALLOCATOR>::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 <class ALLOCATOR> int
+ACE_Name_Space_Map<ALLOCATOR>::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 <class ALLOCATOR> int
+ACE_Name_Space_Map<ALLOCATOR>::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 <class ALLOCATOR> int
+ACE_Name_Space_Map<ALLOCATOR>::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 <class MEM_POOL, class LOCK> int
+ACE_Local_Name_Space<MEM_POOL, LOCK>::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
+ // <new_internal> 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
+ // <new_name> and <new_internal> 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 <class MEM_POOL, class LOCK> int
+ACE_Local_Name_Space<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK> int
+ACE_Local_Name_Space<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK> int
+ACE_Local_Name_Space<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK> int
+ACE_Local_Name_Space<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK> int
+ACE_Local_Name_Space<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK>
+ACE_Local_Name_Space<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK>
+ACE_Local_Name_Space<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK>
+ACE_Local_Name_Space<MEM_POOL, LOCK>::~ACE_Local_Name_Space (void)
+{
+ ACE_TRACE ("ACE_Local_Name_Space::~ACE_Local_Name_Space");
+
+ // Remove the map
+ delete this->allocator_;
+}
+
+template <class MEM_POOL, class LOCK> int
+ACE_Local_Name_Space<MEM_POOL, LOCK>::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 <ALLOCATOR> *) 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 <ALLOCATOR> (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 <map> 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 <ALLOCATOR> *) ns_map;
+ }
+ ACE_DEBUG ((LM_DEBUG, "name_space_map_ = %d, ns_map = %d\n",
+ this->name_space_map_, ns_map));
+ }
+
+ return 0;
+}
+
+template <class MEM_POOL, class LOCK> int
+ACE_Local_Name_Space<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK> int
+ACE_Local_Name_Space<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK> int
+ACE_Local_Name_Space<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK> int
+ACE_Local_Name_Space <MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK> int
+ACE_Local_Name_Space<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK> int
+ACE_Local_Name_Space<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK> void
+ACE_Local_Name_Space<MEM_POOL, LOCK>::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> ACE_WSTRING_SET;
+
+// Simplify later usage by defining typedefs.
+typedef ACE_Map_Manager<ACE_NS_String, ACE_NS_Internal, ACE_Null_Mutex> MAP_MANAGER;
+typedef ACE_Map_Iterator<ACE_NS_String, ACE_NS_Internal, ACE_Null_Mutex> MAP_ITERATOR;
+typedef ACE_Map_Entry <ACE_NS_String, ACE_NS_Internal> MAP_ENTRY;
+
+template <class ALLOCATOR>
+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 <ACE_Map_Manager>. 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 MEM_POOL, class LOCK>
+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 <type>!
+
+ 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 <ACE_Malloc <MEM_POOL, LOCK> > ALLOCATOR;
+
+ ALLOCATOR *allocator_;
+ // Pointer to the allocator
+
+ ACE_Name_Space_Map <ALLOCATOR>*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<ACE_TPQ_Entry>::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<ACE_TPQ_Entry> *) 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 <id> 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 <id> is the owner, return false.
+ if ((this->owner () == 0) || this->is_owner (id))
+ return 0;
+
+ // Step through each waiter looking for <id>.
+ 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 <id>.
+ 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 <id> 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 <id> is the owner, return false.
+ if ((this->owner () == 0) ||
+ this->is_owner (id))
+ return 0;
+
+ // Step through each waiter looking for <id>.
+ 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 <id>.
+ 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 <ACE_TPQ_Entry>;
+#endif /* ACE_NO_TSS_TOKENS */
+template class ACE_Unbounded_Stack <ACE_TPQ_Entry *>;
+#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 <id> == client id. Does not check for <id> == 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> 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 <next_item>. 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<ACE_TPQ_Entry *>
+ 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 <id> is non-zero, returns 1 if id is an owner.
+
+ virtual int is_waiting_for (const char *id) = 0;
+ // Returns 1 if <id> is waiting for this token. 0 otherwise.
+
+ virtual int is_owner (const char *id) = 0;
+ // Returns 1 if <id> 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 <requeue_position> ==
+ // -1 and there are other threads waiting to obtain the token we are
+ // queued at the end of the list of waiters. If <requeue_position>
+ // > -1 then it indicates how many entries to skip over before
+ // inserting our thread into the list of waiters (e.g.,
+ // <requeue_position> == 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 <id> is non-zero, returns 1 if id is an owner.
+
+ virtual int is_waiting_for (const char *id);
+ // Returns 1 if <id> is waiting for this token. 0 otherwise.
+
+ virtual int is_owner (const char *id);
+ // Returns 1 if <id> 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 <requeue_position> ==
+ // -1 and there are other threads waiting to obtain the token we are
+ // queued at the end of the list of waiters. If <requeue_position>
+ // > -1 then it indicates how many entries to skip over before
+ // inserting our thread into the list of waiters (e.g.,
+ // <requeue_position> == 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 <id> is non-zero, returns 1 if id is an owner.
+
+ virtual int is_waiting_for (const char *id);
+ // Returns 1 if <id> is waiting for this token. 0 otherwise.
+
+ virtual int is_owner (const char *id);
+ // Returns 1 if <id> 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);
+ // <name> is the string uniquely identifying the token.
+ // <ignore_deadlock> can be 1 to disable deadlock notifications.
+ // <debug> 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);
+ // <token_name> uniquely id's the token.
+ // <ignore_deadlock> will allow deadlock to occur (useful for
+ // testing). <debug> 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);
+ // <token_name> uniquely id's the token.
+ // <ignore_deadlock> will allow deadlock to occur (useful for
+ // testing). <debug> 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);
+ // <token_name> uniquely id's the token.
+ // <ignore_deadlock> will allow deadlock to occur (useful for
+ // testing). <debug> 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 <class TYPE>
+ACE_Token_Name<TYPE>::ACE_Token_Name (void)
+{
+ ACE_TRACE ("ACE_Token_Name::ACE_Token_Name");
+}
+
+template <class TYPE>
+ACE_Token_Name<TYPE>::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 <class TYPE>
+ACE_Token_Name<TYPE>::ACE_Token_Name (const ACE_Token_Name<TYPE> &rhs)
+{
+ ACE_TRACE ("ACE_Token_Name::ACE_Token_Name");
+ this->type (rhs.type ());
+ this->name (rhs.name ());
+}
+
+template <class TYPE>
+ACE_Token_Name<TYPE>::~ACE_Token_Name ()
+{
+ ACE_TRACE ("ACE_Token_Name::~ACE_Token_Name");
+}
+
+template <class TYPE> void
+ACE_Token_Name<TYPE>::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 TYPE>
+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<TYPE> &rhs);
+ // copy construction
+
+ ~ACE_Token_Name (void);
+ // death
+
+ void operator= (const ACE_Token_Name<TYPE> &rhs);
+ // copy
+
+ int operator== (const ACE_Token_Name<TYPE> &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 <class TYPE> ACE_INLINE void
+ACE_Token_Name<TYPE>::operator= (const ACE_Token_Name<TYPE> &rhs)
+{
+ ACE_TRACE ("ACE_Token_Name<TYPE>::operator=");
+ if (&rhs == this)
+ return;
+ else
+ {
+ this->type (rhs.type ());
+ this->name (rhs.name ());
+ }
+}
+
+template <class TYPE> ACE_INLINE int
+ACE_Token_Name<TYPE>::operator== (const ACE_Token_Name<TYPE> &rhs) const
+{
+ ACE_TRACE ("ACE_Token_Name<TYPE>::operator==");
+
+ // the name and type must be the same
+ return (ACE_OS::strcmp (this->token_name_, rhs.name ()) == 0
+ && rhs.type () == type_);
+}
+
+template <class TYPE> ACE_INLINE const char*
+ACE_Token_Name<TYPE>::name (void) const
+{
+ ACE_TRACE ("ACE_Token_Name<TYPE>::name");
+ return this->token_name_;
+}
+
+template <class TYPE> ACE_INLINE void
+ACE_Token_Name<TYPE>::name (const char *new_name)
+{
+ ACE_TRACE ("ACE_Token_Name<TYPE>::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 <class TYPE> ACE_INLINE TYPE
+ACE_Token_Name<TYPE>::type (void) const
+{
+ ACE_TRACE ("ACE_Token_Name<TYPE>::type");
+ return this->type_;
+}
+
+template <class TYPE> ACE_INLINE void
+ACE_Token_Name<TYPE>::type (TYPE type)
+{
+ ACE_TRACE ("ACE_Token_Name<TYPE>::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 <ACE_Log_Msg> 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 "<unknown>" 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 : "<unknown 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_ : "<unknown>");
+ 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: <unknown error> = %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, "<unknown signal> %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
+ // <priority_mask_> 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_ : "<unknown>"));
+ ACE_DEBUG ((LM_DEBUG, "\nlocal_host_ = %s\n", this->local_host_ ? this->local_host_ : "<unknown>"));
+ 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
+// <akg@na47sun05.cern.ch>.
+#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. <prog_name> is the
+ // name of the executable program. <flags> are a bitwise-or of
+ // options flags passed to the Logger (see the enum above for the valid
+ // values). If the <LOGGER> bit in <flags> is enabled then
+ // <logger_key> 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 <ACE_Log_Priority> mask.
+ u_long priority_mask (u_long);
+ // Set the <ACE_Log_Priority> 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 "<unknown>" 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
+ // <log> 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 <sys/errno.h>).
+
+ 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 <ACE_Thread_Manager> this
+ // will point to the <thr_state_> field in the
+ // <ACE_Thread_Descriptor>. 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 <ACE_Thread_Manager> this
+ // will point to the <thr_handle_> field in the
+ // <ACE_Thread_Descriptor>. Threads can use this to rapidly
+ // determine their real ACE_hthread_t.
+
+ u_long priority_mask_;
+ // Keeps track of all the <ACE_Log_Priority> 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 = "<local_host>";
+
+ 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 = "<local_host>";
+
+ 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 <Log_Record> 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
+ // <FILE>.
+
+ 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
+ // <ostream>.
+
+ // = Marshall/demarshall
+ void encode (void);
+ // Encode the <Log_Record> for transmission on the network.
+
+ void decode (void);
+ // Decode the <Log_Record> received from the network.
+
+ // = Set/get methods
+
+ long type (void) const;
+ // Get the type of the <Log_Record>.
+
+ void type (long);
+ // Set the type of the <Log_Record>.
+
+ long length (void) const;
+ // Get the length of the <Log_Record>.
+
+ void length (long);
+ // Set the length of the <Log_Record>.
+
+ long time_stamp (void) const;
+ // Get the time stamp of the <Log_Record>.
+
+ void time_stamp (long);
+ // Set the time stamp of the <Log_Record>.
+
+ long pid (void) const;
+ // Get the process id of the <Log_Record>.
+
+ void pid (long);
+ // Set the process id of the <Log_Record>.
+
+ char *msg_data (void);
+ // Get the message data of the <Log_Record>.
+
+ void msg_data (const char *data);
+ // Set the message data of the <Log_Record>.
+
+ void msg_data_len (size_t len);
+ // Set the size of the message data of the <Log_Record>.
+
+ 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 <nbytes>, but don't give them any initial value.
+
+ virtual void *calloc (size_t nbytes, char initial_value = '\0') = 0;
+ // Allocate <nbytes>, giving them <initial_value>.
+
+ virtual void free (void *ptr) = 0;
+ // Free <ptr> (must have been allocated by <ACE_Allocator::malloc>).
+
+ 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 <name> with <pointer>. If <duplicates> == 0 then do
+ // not allow duplicate <name>/<pointer> associations, else if
+ // <duplicates> != 0 then allow duplicate <name>/<pointer>
+ // assocations. Returns 0 if successfully binds (1) a previously
+ // unbound <name> or (2) <duplicates> != 0, returns 1 if trying to
+ // bind a previously bound <name> and <duplicates> == 0, else
+ // returns -1 if a resource failure occurs.
+
+ virtual int trybind (const char *name, void *&pointer) = 0;
+ // Associate <name> with <pointer>. Does not allow duplicate
+ // <name>/<pointer> associations. Returns 0 if successfully binds
+ // (1) a previously unbound <name>, 1 if trying to bind a previously
+ // bound <name>, or returns -1 if a resource failure occurs. When
+ // this call returns <pointer>'s value will always reference the
+ // void * that <name> is associated with. Thus, if the caller needs
+ // to use <pointer> (e.g., to free it) a copy must be maintained by
+ // the caller.
+
+ virtual int find (const char *name, void *&pointer) = 0;
+ // Locate <name> 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 <len> bytes of the memory region to the backing store
+ // starting at <this->base_addr_>. If <len> == -1 then sync the
+ // whole region.
+
+ virtual int sync (void *addr, size_t len, int flags = MS_SYNC) = 0;
+ // Sync <len> bytes of the memory region to the backing store
+ // starting at <addr_>.
+
+ virtual int protect (ssize_t len = -1, int prot = PROT_RDWR) = 0;
+ // Change the protection of the pages of the mapped region to <prot>
+ // starting at <this->base_addr_> up to <len> bytes. If <len> == -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 <prot>
+ // starting at <addr> up to <len> 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_PROCESS_MUTEX, int> 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 <class MALLOC>
+ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter (const char *pool_name,
+ const char *lock_name)
+ : allocator_ (pool_name, lock_name)
+{
+ ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter");
+}
+
+template <class MALLOC>
+ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter (const char *pool_name)
+ : allocator_ (pool_name)
+{
+ ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::ACE_Allocator_Adapter");
+}
+
+template <class MALLOC> void
+ACE_Allocator_Adapter<MALLOC>::dump (void) const
+{
+ ACE_TRACE ("ACE_Malloc<MALLOC>::dump");
+ this->allocator_.dump ();
+}
+
+template <class MEM_POOL, class LOCK> void
+ACE_Malloc<MEM_POOL, LOCK>::dump (void) const
+{
+ ACE_TRACE ("ACE_Malloc<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK> void
+ACE_Malloc<MEM_POOL, LOCK>::print_stats (void)
+{
+ ACE_TRACE ("ACE_Malloc<MEM_POOL, LOCK>::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<class MEM_POOL, class LOCK> void
+ACE_Malloc<MEM_POOL, LOCK>::free (void *ap)
+{
+ ACE_TRACE ("ACE_Malloc<MEM_POOL, LOCK>::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 <MEM_POOL> (i.e., shared
+// vs. local) subsequent calls from other processes will only
+// initialize the control block pointer.
+
+template <class MEM_POOL, class LOCK> int
+ACE_Malloc<MEM_POOL, LOCK>::open (void)
+{
+ ACE_TRACE ("ACE_Malloc<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK>
+ACE_Malloc<MEM_POOL, LOCK>::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<MEM_POOL, LOCK>::ACE_Malloc");
+
+ this->open ();
+}
+
+template <class MEM_POOL, class LOCK>
+ACE_Malloc<MEM_POOL, LOCK>::ACE_Malloc (const char *pool_name,
+ const char *lock_name)
+ : memory_pool_ (pool_name),
+ lock_ (lock_name)
+{
+ ACE_TRACE ("ACE_Malloc<MEM_POOL, LOCK>::ACE_Malloc");
+
+ this->open ();
+}
+
+// Clean up the resources allocated by ACE_Malloc.
+
+template <class MEM_POOL, class LOCK> int
+ACE_Malloc<MEM_POOL, LOCK>::remove (void)
+{
+ ACE_TRACE ("ACE_Malloc<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK> void *
+ACE_Malloc<MEM_POOL, LOCK>::shared_malloc (size_t nbytes)
+{
+ ACE_TRACE ("ACE_Malloc<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK> void *
+ACE_Malloc<MEM_POOL, LOCK>::malloc (size_t nbytes)
+{
+ ACE_TRACE ("ACE_Malloc<MEM_POOL, LOCK>::malloc");
+ ACE_GUARD_RETURN (LOCK, ace_mon, this->lock_, 0);
+
+ return this->shared_malloc (nbytes);
+}
+
+// General-purpose memory allocator.
+
+template <class MEM_POOL, class LOCK> void *
+ACE_Malloc<MEM_POOL, LOCK>::calloc (size_t nbytes,
+ char initial_value)
+{
+ ACE_TRACE ("ACE_Malloc<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK> void
+ACE_Malloc<MEM_POOL, LOCK>::shared_free (void *ap)
+{
+ ACE_TRACE ("ACE_Malloc<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK> ACE_Name_Node *
+ACE_Malloc<MEM_POOL, LOCK>::shared_find (const char *name)
+{
+ ACE_TRACE ("ACE_Malloc<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK> int
+ACE_Malloc<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK> int
+ACE_Malloc<MEM_POOL, LOCK>::trybind (const char *name,
+ void *&pointer)
+{
+ ACE_TRACE ("ACE_Malloc<MEM_POOL, LOCK>::trybind");
+ ACE_Write_Guard<LOCK> 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 <class MEM_POOL, class LOCK> int
+ACE_Malloc<MEM_POOL, LOCK>::bind (const char *name,
+ void *pointer,
+ int duplicates)
+{
+ ACE_TRACE ("ACE_Malloc<MEM_POOL, LOCK>::bind");
+ ACE_Write_Guard<LOCK> 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 <class MEM_POOL, class LOCK> int
+ACE_Malloc<MEM_POOL, LOCK>::find (const char *name, void *&pointer)
+{
+ ACE_TRACE ("ACE_Malloc<MEM_POOL, LOCK>::find");
+
+ ACE_Read_Guard<LOCK> mon (this->lock_);
+
+ ACE_Name_Node *node = this->shared_find (name);
+
+ if (node == 0)
+ return -1;
+ else
+ {
+ pointer = node->pointer_;
+ return 0;
+ }
+}
+
+template <class MEM_POOL, class LOCK> int
+ACE_Malloc<MEM_POOL, LOCK>::find (const char *name)
+{
+ ACE_TRACE ("ACE_Malloc<MEM_POOL, LOCK>::find");
+
+ ACE_Read_Guard<LOCK> mon (this->lock_);
+ return this->shared_find (name) == 0 ? -1 : 0;
+}
+
+template <class MEM_POOL, class LOCK> int
+ACE_Malloc<MEM_POOL, LOCK>::unbind (const char *name, void *&pointer)
+{
+ ACE_TRACE ("ACE_Malloc<MEM_POOL, LOCK>::unbind");
+
+ ACE_Write_Guard<LOCK> 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 <class MEM_POOL, class LOCK> int
+ACE_Malloc<MEM_POOL, LOCK>::unbind (const char *name)
+{
+ ACE_TRACE ("ACE_Malloc<MEM_POOL, LOCK>::unbind");
+ void *temp = 0;
+ return this->unbind (name, temp);
+}
+
+
+template <class MEM_POOL, class LOCK> void
+ACE_Malloc_Iterator<MEM_POOL, LOCK>::dump (void) const
+{
+ ACE_TRACE ("ACE_Malloc_Iterator<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK>
+ACE_Malloc_Iterator<MEM_POOL, LOCK>::ACE_Malloc_Iterator (ACE_Malloc<MEM_POOL, LOCK> &malloc,
+ const char *name)
+ : malloc_ (malloc),
+ guard_ (malloc_.lock_),
+ curr_ (0),
+ name_ (name != 0 ? ACE_OS::strdup (name) : 0)
+{
+ ACE_TRACE ("ACE_Malloc_Iterator<MEM_POOL, LOCK>::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 <class MEM_POOL, class LOCK>
+ACE_Malloc_Iterator<MEM_POOL, LOCK>::~ACE_Malloc_Iterator (void)
+{
+ ACE_OS::free ((void *) this->name_);
+}
+
+template <class MEM_POOL, class LOCK> int
+ACE_Malloc_Iterator<MEM_POOL, LOCK>::next (void *&next_entry,
+ char *&name)
+{
+ ACE_TRACE ("ACE_Malloc_Iterator<MEM_POOL, LOCK>::next");
+
+ if (curr_ != 0)
+ {
+ next_entry = curr_->pointer_;
+ name = curr_->name_;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+template <class MEM_POOL, class LOCK> int
+ACE_Malloc_Iterator<MEM_POOL, LOCK>::next (void *&next_entry)
+{
+ ACE_TRACE ("ACE_Malloc_Iterator<MEM_POOL, LOCK>::next");
+
+ if (curr_ != 0)
+ {
+ next_entry = curr_->pointer_;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+template <class MEM_POOL, class LOCK> int
+ACE_Malloc_Iterator<MEM_POOL, LOCK>::advance (void)
+{
+ ACE_TRACE ("ACE_Malloc_Iterator<MEM_POOL, LOCK>::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 MALLOC>
+class ACE_Allocator_Adapter : public ACE_Allocator
+ // = TITLE
+ // This class is an Adapter that allows the <ACE_Allocator> to
+ // use the <Malloc> 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 <nbytes>, but don't give them any initial value.
+
+ virtual void *calloc (size_t nbytes, char initial_value = '\0');
+ // Allocate <nbytes>, giving them all an <initial_value>.
+
+ virtual void free (void *ptr);
+ // Free <ptr> (must have been allocated by <ACE_Allocator::malloc>).
+
+ 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 <name> with <pointer>. If <duplicates> == 0 then do
+ // not allow duplicate <name>/<pointer> associations, else if
+ // <duplicates> != 0 then allow duplicate <name>/<pointer>
+ // assocations. Returns 0 if successfully binds (1) a previously
+ // unbound <name> or (2) <duplicates> != 0, returns 1 if trying to
+ // bind a previously bound <name> and <duplicates> == 0, else
+ // returns -1 if a resource failure occurs.
+
+ int trybind (const char *name, void *&pointer);
+ // Associate <name> with <pointer>. Does not allow duplicate
+ // <name>/<pointer> associations. Returns 0 if successfully binds
+ // (1) a previously unbound <name>, 1 if trying to bind a previously
+ // bound <name>, or returns -1 if a resource failure occurs. When
+ // this call returns <pointer>'s value will always reference the
+ // void * that <name> is associated with. Thus, if the caller needs
+ // to use <pointer> (e.g., to free it) a copy must be maintained by
+ // the caller.
+
+ int find (const char *name, void *&pointer);
+ // Locate <name> 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 <len> bytes of the memory region to the backing store
+ // starting at <this->base_addr_>. If <len> == -1 then sync the
+ // whole region.
+
+ int sync (void *addr, size_t len, int flags = MS_SYNC);
+ // Sync <len> bytes of the memory region to the backing store
+ // starting at <addr_>.
+
+ int protect (ssize_t len = -1, int prot = PROT_RDWR);
+ // Change the protection of the pages of the mapped region to <prot>
+ // starting at <this->base_addr_> up to <len> bytes. If <len> == -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 <prot>
+ // starting at <addr> up to <len> 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 MEM_POOL, class LOCK>
+class ACE_Malloc_Iterator;
+
+template <class MEM_POOL, class LOCK>
+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<MEM_POOL, LOCK>;
+public:
+ typedef MEM_POOL MEMORY_POOL;
+
+ // = Initialization and termination methods.
+ ACE_Malloc (const char *pool_name = 0);
+ // Initialize ACE_Malloc. This constructor passes <pool_name> to
+ // initialize the memory pool, and uses <ACE::basename> 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 <pool_name> to
+ // initialize the memory pool, and uses <lock_name> 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 <nbytes>, but don't give them any initial value.
+
+ void *calloc (size_t nbytes, char initial_value = '\0');
+ // Allocate <nbytes>, giving them <initial_value>.
+
+ void free (void *ptr);
+ // Deallocate memory pointed to by <ptr>, which must have been
+ // allocated previously by <this->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 <name> with <pointer>. If <duplicates> == 0 then do
+ // not allow duplicate <name>/<pointer> associations, else if
+ // <duplicates> != 0 then allow duplicate <name>/<pointer>
+ // assocations. Returns 0 if successfully binds (1) a previously
+ // unbound <name> or (2) <duplicates> != 0, returns 1 if trying to
+ // bind a previously bound <name> and <duplicates> == 0, else
+ // returns -1 if a resource failure occurs.
+
+ int trybind (const char *name, void *&pointer);
+ // Associate <name> with <pointer>. Does not allow duplicate
+ // <name>/<pointer> associations. Returns 0 if successfully binds
+ // (1) a previously unbound <name>, 1 if trying to bind a previously
+ // bound <name>, or returns -1 if a resource failure occurs. When
+ // this call returns <pointer>'s value will always reference the
+ // void * that <name> is associated with. Thus, if the caller needs
+ // to use <pointer> (e.g., to free it) a copy must be maintained by
+ // the caller.
+
+ int find (const char *name, void *&pointer);
+ // Locate <name> and pass out parameter via <pointer>. If found,
+ // return 0, returns -1 if failure occurs.
+
+ int find (const char *name);
+ // Returns 0 if <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. If you want to remove all occurrences of <name>
+ // you'll need to call this method multiple times until it fails...
+
+ int unbind (const char *name, void *&pointer);
+ // Unbind (remove) one association of <name> to <pointer>. Returns
+ // the value of pointer in case the caller needs to deallocate
+ // memory. If you want to remove all occurrences of <name> 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 <len> bytes of the memory region to the backing store
+ // starting at <this->base_addr_>. If <len> == -1 then sync the
+ // whole region.
+
+ int sync (void *addr, size_t len, int flags = MS_SYNC);
+ // Sync <len> bytes of the memory region to the backing store
+ // starting at <addr_>.
+
+ int protect (ssize_t len = -1, int prot = PROT_RDWR);
+ // Change the protection of the pages of the mapped region to <prot>
+ // starting at <this->base_addr_> up to <len> bytes. If <len> == -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 <prot>
+ // starting at <addr> up to <len> 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 <name> with <pointer>. Assumes that locks are held by
+ // callers.
+
+ ACE_Name_Node *shared_find (const char *name);
+ // Try to locate <name>. If found, return the associated
+ // <ACE_Name_Node>, else returns 0 if can't find the <name>.
+ // 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 MEM_POOL, class LOCK>
+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<MEM_POOL, LOCK> &malloc, const char *name = 0);
+ // if <name> = 0 it will iterate through everything else only
+ // through those entries whose <name> match
+
+ ~ACE_Malloc_Iterator (void);
+
+ // = Iteration methods.
+
+ int next (void *&next_entry);
+ // Pass back the next <entry> 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 <entry> (and the <name> 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<MEM_POOL, LOCK> &malloc_;
+ // Malloc we are iterating over.
+
+ ACE_Name_Node *curr_;
+ // Keeps track of how far we've advanced...
+
+ ACE_Read_Guard<LOCK> 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 <class MALLOC> ACE_INLINE void *
+ACE_Allocator_Adapter<MALLOC>::malloc (size_t nbytes)
+{
+ ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::malloc");
+ return this->allocator_.malloc (nbytes);
+}
+
+template <class MALLOC> ACE_INLINE void *
+ACE_Allocator_Adapter<MALLOC>::calloc (size_t nbytes,
+ char initial_value)
+{
+ ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::malloc");
+ return this->allocator_.calloc (nbytes, initial_value);
+}
+
+template <class MALLOC> ACE_INLINE MALLOC &
+ACE_Allocator_Adapter<MALLOC>::allocator (void)
+{
+ ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::allocator");
+ return this->allocator_;
+}
+
+template <class MALLOC> ACE_INLINE void
+ACE_Allocator_Adapter<MALLOC>::free (void *ptr)
+{
+ ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::free");
+ this->allocator_.free (ptr);
+}
+
+template <class MALLOC> ACE_INLINE int
+ACE_Allocator_Adapter<MALLOC>::remove (void)
+{
+ ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::remove");
+ return this->allocator_.remove ();
+}
+
+template <class MALLOC> ACE_INLINE int
+ACE_Allocator_Adapter<MALLOC>::trybind (const char *name,
+ void *&pointer)
+{
+ ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::trybind");
+ return this->allocator_.trybind (name, pointer);
+}
+
+template <class MALLOC> ACE_INLINE int
+ACE_Allocator_Adapter<MALLOC>::bind (const char *name,
+ void *pointer,
+ int duplicates)
+{
+ ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::bind");
+ return this->allocator_.bind (name, pointer, duplicates);
+}
+
+template <class MALLOC> ACE_INLINE int
+ACE_Allocator_Adapter<MALLOC>::find (const char *name,
+ void *&pointer)
+{
+ ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::find");
+ return this->allocator_.find (name, pointer);
+}
+
+template <class MALLOC> ACE_INLINE int
+ACE_Allocator_Adapter<MALLOC>::find (const char *name)
+{
+ ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::find");
+ return this->allocator_.find (name);
+}
+
+template <class MALLOC> ACE_INLINE int
+ACE_Allocator_Adapter<MALLOC>::unbind (const char *name, void *&pointer)
+{
+ ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::unbind");
+ return this->allocator_.unbind (name, pointer);
+}
+
+template <class MALLOC> ACE_INLINE int
+ACE_Allocator_Adapter<MALLOC>::unbind (const char *name)
+{
+ ACE_TRACE ("ACE_Allocator_Adapter<MALLOC>::unbind");
+ return this->allocator_.unbind (name);
+}
+
+template <class MALLOC> ACE_INLINE int
+ACE_Allocator_Adapter<MALLOC>::sync (ssize_t len, int flags)
+{
+ ACE_TRACE ("ACE_Malloc<MEMORY_POOL, LOCK>::sync");
+ return this->allocator_.sync (len, flags);
+}
+
+template <class MALLOC> ACE_INLINE int
+ACE_Allocator_Adapter<MALLOC>::sync (void *addr, size_t len, int flags)
+{
+ ACE_TRACE ("ACE_Malloc<MEMORY_POOL, LOCK>::sync");
+ return this->allocator_.sync (addr, len, flags);
+}
+
+template <class MALLOC> ACE_INLINE int
+ACE_Allocator_Adapter<MALLOC>::protect (ssize_t len, int flags)
+{
+ ACE_TRACE ("ACE_Malloc<MEMORY_POOL, LOCK>::protect");
+ return this->allocator_.protect (len, flags);
+}
+
+template <class MALLOC> ACE_INLINE int
+ACE_Allocator_Adapter<MALLOC>::protect (void *addr, size_t len, int flags)
+{
+ ACE_TRACE ("ACE_Malloc<MEMORY_POOL, LOCK>::protect");
+ return this->allocator_.protect (addr, len, flags);
+}
+
+template <class MEM_POOL, class LOCK> MEM_POOL &
+ACE_Malloc<MEM_POOL, LOCK>::memory_pool (void)
+{
+ ACE_TRACE ("ACE_Malloc<MEMORY_POOL, LOCK>::memory_pool");
+ return this->memory_pool_;
+}
+
+template <class MEM_POOL, class LOCK> int
+ACE_Malloc<MEM_POOL, LOCK>::sync (ssize_t len, int flags)
+{
+ ACE_TRACE ("ACE_Malloc<MEMORY_POOL, LOCK>::sync");
+ return this->memory_pool_.sync (len, flags);
+}
+
+template <class MEM_POOL, class LOCK> int
+ACE_Malloc<MEM_POOL, LOCK>::sync (void *addr, size_t len, int flags)
+{
+ ACE_TRACE ("ACE_Malloc<MEMORY_POOL, LOCK>::sync");
+ return this->memory_pool_.sync (addr, len, flags);
+}
+
+template <class MEM_POOL, class LOCK> int
+ACE_Malloc<MEM_POOL, LOCK>::protect (ssize_t len, int flags)
+{
+ ACE_TRACE ("ACE_Malloc<MEMORY_POOL, LOCK>::protect");
+ return this->memory_pool_.protect (len, flags);
+}
+
+template <class MEM_POOL, class LOCK> int
+ACE_Malloc<MEM_POOL, LOCK>::protect (void *addr, size_t len, int flags)
+{
+ ACE_TRACE ("ACE_Malloc<MEMORY_POOL, LOCK>::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 <class EXT_ID, class INT_ID> void
+ACE_Map_Entry<EXT_ID, INT_ID>::dump (void) const
+{
+ ACE_TRACE ("ACE_Map_Entry<EXT_ID, INT_ID>::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 <class EXT_ID, class INT_ID, class LOCK> void
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::dump (void) const
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::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 <class EXT_ID, class INT_ID, class LOCK>
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::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<EXT_ID, INT_ID, LOCK>::ACE_Map_Manager");
+
+ if (this->open (size, allocator) == -1)
+ ACE_ERROR ((LM_ERROR, "ACE_Map_Manager\n"));
+}
+
+template <class EXT_ID, class INT_ID, class LOCK>
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::ACE_Map_Manager (ACE_Allocator *allocator)
+ : allocator_ (0),
+ max_size_ (0),
+ cur_size_ (0),
+ search_structure_ (0)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::ACE_Map_Manager");
+ if (this->open (DEFAULT_SIZE, allocator) == -1)
+ ACE_ERROR ((LM_ERROR, "ACE_Map_Manager\n"));
+}
+
+template <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::close_i (void)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::close_i");
+
+ if (this->search_structure_ != 0)
+ {
+ this->allocator_->free (this->search_structure_);
+ this->search_structure_ = 0;
+ }
+ return 0;
+}
+
+template <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::close (void)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::close");
+ ACE_Write_Guard<LOCK> m (this->lock_);
+
+ return this->close_i ();
+}
+
+template <class EXT_ID, class INT_ID, class LOCK>
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::~ACE_Map_Manager (void)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::~ACE_Map_Manager");
+ this->close ();
+}
+
+// Create a new search_structure of size SIZE.
+
+template <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::open (size_t size,
+ ACE_Allocator *allocator)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::open");
+ ACE_Write_Guard<LOCK> 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 <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::resize_i (size_t size)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::resize_i");
+
+ // If we need to grow buffer, then remove the existing buffer.
+ void *ptr = this->allocator_->malloc (size * sizeof (ACE_Map_Entry<EXT_ID, INT_ID>));
+
+ if (ptr == 0)
+ {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ size_t i;
+
+ ACE_Map_Entry<EXT_ID, INT_ID> *temp = (ACE_Map_Entry<EXT_ID, INT_ID> *) ptr;
+ ACE_Map_Entry<EXT_ID, INT_ID> *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<EXT_ID, INT_ID>;
+ temp[i].is_free_ = 1;
+ }
+
+ this->allocator_->free (this->search_structure_);
+
+ this->search_structure_ = temp;
+ return 0;
+}
+
+template <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::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<EXT_ID, INT_ID> &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 <int_id> corresponding to the <ext_id>.
+
+template <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::shared_find (const EXT_ID &ext_id)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::shared_find");
+
+ for (size_t i = 0; i < this->cur_size_; i++)
+ {
+ const ACE_Map_Entry<EXT_ID, INT_ID> &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 <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::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<EXT_ID, INT_ID> &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<EXT_ID, INT_ID> &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 <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::trybind_i (const EXT_ID &ext_id,
+ INT_ID &int_id)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::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 <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::trybind (const EXT_ID &ext_id,
+ INT_ID &int_id)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::trybind");
+ ACE_Write_Guard<LOCK> m (this->lock_);
+
+ return this->trybind_i (ext_id, int_id);
+}
+
+template <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::find_i (const EXT_ID &ext_id)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::find_i");
+ return this->shared_find (ext_id);
+}
+
+// Find the INT_ID corresponding to the EXT_ID.
+
+template <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::find (const EXT_ID &ext_id)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::find");
+ ACE_Read_Guard<LOCK> 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 <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::unbind_i (const EXT_ID &ext_id,
+ INT_ID &int_id)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::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 <ext_id> with <int_id>. If <ext_id> is already in the
+// map then the <Map_Entry> 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 <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::bind_i (const EXT_ID &ext_id,
+ const INT_ID &int_id)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::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 <ext_id> with <int_id>. If <ext_id> is not in the
+// map then behaves just like <bind>. Otherwise, store the old
+// values of <ext_id> and <int_id> into the "out" parameters and
+// rebind the new parameters. This is very useful if you need to
+// have an atomic way of updating <Map_Entries> 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 <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::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<EXT_ID, INT_ID, LOCK>::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<EXT_ID, INT_ID> &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 <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::find_i (const EXT_ID &ext_id,
+ INT_ID &int_id)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::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 <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::shared_unbind (const EXT_ID &ext_id)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::shared_unbind");
+ for (size_t i = 0; i < this->cur_size_; i++)
+ {
+ ACE_Map_Entry<EXT_ID, INT_ID> &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 <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::unbind (const EXT_ID &ext_id,
+ INT_ID &int_id)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::unbind");
+ ACE_Write_Guard<LOCK> m (this->lock_);
+
+ return this->unbind_i (ext_id, int_id);
+}
+
+template <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::bind (const EXT_ID &ext_id,
+ const INT_ID &int_id)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::bind");
+ ACE_Write_Guard<LOCK> m (this->lock_);
+
+ return this->bind_i (ext_id, int_id);
+}
+
+template <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::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<EXT_ID, INT_ID, LOCK>::rebind");
+ ACE_Write_Guard<LOCK> m (this->lock_);
+
+ return this->rebind_i (ext_id, int_id, old_ext_id, old_int_id);
+}
+
+template <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::find (const EXT_ID &ext_id,
+ INT_ID &int_id)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::find");
+ ACE_Read_Guard<LOCK> 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 <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::unbind_i (const EXT_ID &ext_id)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::unbind_i");
+ return this->shared_unbind (ext_id) == -1 ? -1 : 0;
+}
+
+template <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::unbind (const EXT_ID &ext_id)
+{
+ ACE_TRACE ("ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::unbind");
+ ACE_Write_Guard<LOCK> m (this->lock_);
+ return this->unbind_i (ext_id) == -1 ? -1 : 0;
+}
+
+template <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::current_size (void)
+{
+ ACE_TRACE ("ACE_Map_Manager::current_size");
+ ACE_Write_Guard<LOCK> m (this->lock_);
+ return this->cur_size_;
+}
+
+template <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Manager<EXT_ID, INT_ID, LOCK>::total_size (void)
+{
+ ACE_TRACE ("ACE_Map_Manager::total_size");
+ ACE_Write_Guard<LOCK> m (this->lock_);
+ return this->max_size_;
+}
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Map_Iterator)
+
+template <class EXT_ID, class INT_ID, class LOCK> void
+ACE_Map_Iterator<EXT_ID, INT_ID, LOCK>::dump (void) const
+{
+ ACE_TRACE ("ACE_Map_Iterator<EXT_ID, INT_ID, LOCK>::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 <class EXT_ID, class INT_ID, class LOCK>
+ACE_Map_Iterator<EXT_ID, INT_ID, LOCK>::ACE_Map_Iterator (ACE_Map_Manager<EXT_ID, INT_ID, LOCK> &mm)
+ : map_man_ (mm),
+ next_ (-1)
+{
+ ACE_TRACE ("ACE_Map_Iterator<EXT_ID, INT_ID, LOCK>::ACE_Map_Iterator");
+ this->advance ();
+}
+
+template <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Iterator<EXT_ID, INT_ID, LOCK>::next (ACE_Map_Entry<EXT_ID, INT_ID> *&mm)
+{
+ ACE_TRACE ("ACE_Map_Iterator<EXT_ID, INT_ID, LOCK>::next");
+ ACE_Read_Guard<LOCK> 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 <class EXT_ID, class INT_ID, class LOCK> int
+ACE_Map_Iterator<EXT_ID, INT_ID, LOCK>::advance (void)
+{
+ ACE_TRACE ("ACE_Map_Iterator<EXT_ID, INT_ID, LOCK>::advance");
+ ACE_Read_Guard<LOCK> 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 <class EXT_ID, class INT_ID>
+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 EXT_ID, class INT_ID, class LOCK>
+class ACE_Map_Iterator;
+
+template <class EXT_ID, class INT_ID, class LOCK>
+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<EXT_ID, INT_ID, LOCK>;
+public:
+ enum {DEFAULT_SIZE = ACE_DEFAULT_MAP_SIZE};
+
+ // = Initialization and termination methods.
+ ACE_Map_Manager (ACE_Allocator *allocator = 0);
+ // Initialize a <Map_Manager> with the <DEFAULT_SIZE>.
+
+ ACE_Map_Manager (size_t size, ACE_Allocator *allocator = 0);
+ // Initialize a <Map_Manager> with <size> entries.
+
+ int open (size_t length = DEFAULT_SIZE,
+ ACE_Allocator *allocator = 0);
+ // Initialize a <Map_Manager> with size <length>.
+
+ int close (void);
+ // Close down a <Map_Manager> and release dynamically allocated
+ // resources.
+
+ ~ACE_Map_Manager (void);
+ // Close down a <Map_Manager> and release dynamically allocated
+ // resources.
+
+ int trybind (const EXT_ID &ext_id, INT_ID &int_id);
+ // Associate <ext_id> with <int_id> if and only if <ext_id> is not
+ // in the map. If <ext_id> is already in the map then the <int_id>
+ // 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 <ext_id> with <int_id>. If <ext_id> is already in the
+ // map then the <Map_Entry> 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 <ext_id> with <int_id>. If <ext_id> is not in the
+ // map then behaves just like <bind>. Otherwise, store the old
+ // values of <ext_id> and <int_id> into the "out" parameters and
+ // rebind the new parameters. This is very useful if you need to
+ // have an atomic way of updating <Map_Entries> 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 <ext_id> and pass out parameter via <int_id>. If found,
+ // return 0, returns -1 if failure occurs.
+
+ int find (const EXT_ID &ext_id);
+ // Returns 0 if the <ext_id> is in the mapping, otherwise -1.
+
+ int unbind (const EXT_ID &ext_id, INT_ID &int_id);
+ // Break any association of <ext_id>. Returns the value of <int_id> in
+ // case the caller needs to deallocate memory.
+
+ int unbind (const EXT_ID &ext_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_id>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<EXT_ID, INT_ID> *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 <ext_id> to <int_id>. 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 <ext_it> to <int_id>. Must be called
+ // with locks held.
+
+ int find_i (const EXT_ID &ext_id, INT_ID &int_id);
+ // Performs a find of <int_id> using <ext_id> as the key. Must be
+ // called with locks held.
+
+ int find_i (const EXT_ID &ext_id);
+ // Performs a find using <ext_id> 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 <int_id> using <ext_id> as the key. Must
+ // be called with locks held.
+
+ int unbind_i (const EXT_ID &ext_id);
+ // Performs an unbind using <ext_id> 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 <int_id> using <ext_id> 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 <Map_Manager>. 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 <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. 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 EXT_ID, class INT_ID, class LOCK>
+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 <EXT_ID, INT_ID, LOCK> &mm);
+
+ // = Iteration methods.
+
+ int next (ACE_Map_Entry<EXT_ID, INT_ID> *&next_entry);
+ // Pass back the <entry> 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 <EXT_ID, INT_ID, LOCK> &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 <file_len> 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 <handle>. 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 <file_name>.
+
+ 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 <handle>. 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 <handle_>.
+
+ 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 <filename>.
+
+ ~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 <handle_> 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 <base_addr_>.
+
+ int unmap (void *addr, int len);
+ // Unmap the region starting at <addr_>.
+
+ int sync (ssize_t len = -1, int flags = MS_SYNC);
+ // Sync <len> bytes of the memory region to the backing store
+ // starting at <base_addr_>. If <len> == -1 then sync the whole
+ // region.
+
+ int sync (void *addr, size_t len, int flags = MS_SYNC);
+ // Sync <len> bytes of the memory region to the backing store
+ // starting at <addr_>.
+
+ int protect (ssize_t len = -1, int prot = PROT_RDWR);
+ // Change the protection of the pages of the mapped region to <prot>
+ // starting at <base_addr_> up to <len> bytes. If <len> == -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 <prot>
+ // starting at <addr> up to <len> 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 <handle_>.
+
+ 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 <this->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 <this->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 <addr_>.
+
+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 <len> bytes of the memory region to the backing store starting
+// at <this->base_addr_>. If <len> == -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 <len> bytes of the memory region to the backing store starting
+// at <addr_>.
+
+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 <prot>
+// starting at <this->base_addr_> up to <len> bytes. If <len> == -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 <prot>
+// starting at <addr> up to <len> 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 <len> bytes of the memory region to the backing store starting
+// at <addr_>.
+
+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 <prot>
+// starting at <this->base_addr_> up to <len> bytes. If <len> == -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 <prot>
+// starting at <addr> up to <len> 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 <file_offset> 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 <sbrk(2)>.
+{
+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 <len> bytes of the memory region to the backing store
+ // starting at <this->base_addr_>. If <len> == -1 then sync the
+ // whole region.
+
+ virtual int sync (void *addr, size_t len, int flags = MS_SYNC);
+ // Sync <len> bytes of the memory region to the backing store
+ // starting at <addr_>.
+
+ virtual int protect (ssize_t len = -1, int prot = PROT_RDWR);
+ // Change the protection of the pages of the mapped region to <prot>
+ // starting at <this->base_addr_> up to <len> bytes. If <len> == -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 <prot>
+ // starting at <addr> up to <len> 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
+ // <this->base_addr_>.
+
+ virtual int sync (void *addr, size_t len, int flags = MS_SYNC);
+ // Sync the memory region to the backing store starting at <addr_>.
+
+ virtual int protect (ssize_t len = -1, int prot = PROT_RDWR);
+ // Change the protection of the pages of the mapped region to <prot>
+ // starting at <this->base_addr_> up to <len> bytes. If <len> == -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 <prot>
+ // starting at <addr> up to <len> 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. <offset> 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 <len> bytes of the memory region to the backing store
+ // starting at <this->base_addr_>. If <len> == -1 then sync the
+ // whole region.
+
+ virtual int sync (void *addr, size_t len, int flags = MS_SYNC);
+ // Sync <len> bytes of the memory region to the backing store
+ // starting at <addr_>.
+
+ virtual int protect (ssize_t len = -1, int prot = PROT_RDWR);
+ // Change the protection of the pages of the mapped region to <prot>
+ // starting at <this->base_addr_> up to <len> bytes. If <len> == -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 <prot>
+ // starting at <addr> up to <len> 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 <mmap(2)>. 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 <nbytes> from the memory pool. <rounded_bytes>
+ // is the actual number of bytes allocated. Also acquires an
+ // internal semaphore that ensures proper serialization of
+ // <ACE_MMAP_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
+ // <this->base_addr_>.
+
+ virtual int sync (void *addr, size_t len, int flags = MS_SYNC);
+ // Sync the memory region to the backing store starting at <addr_>.
+
+ virtual int protect (ssize_t len = -1, int prot = PROT_RDWR);
+ // Change the protection of the pages of the mapped region to <prot>
+ // starting at <this->base_addr_> up to <len> bytes. If <len> == -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 <prot>
+ // starting at <addr> up to <len> bytes.
+
+ virtual int remap (void *addr);
+ // Try to extend the virtual address space so that <addr> 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 <file_offset> 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 <ACE_OS::mmap>.
+
+ 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 <ACE_Mem_Map>.
+ //
+ // = DESCRIPTION
+ // This implementation allows memory to be shared between
+ // processes. However, unlike the <ACE_MMAP_Memory_Pool>
+ // 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 <data> 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 <type> containing <size>
+ // bytes. The <cont> argument initializes the continuation field in
+ // the <Message_Block>. If <data> == 0 then we create and own the
+ // <data>, using <allocator> to get the data if it's non-0. If
+ // <data> != 0 we assume ownership of the <data> (and don't delete
+ // it).
+
+ int init (const char *data,
+ size_t size = 0);
+ // Create a Message Block that assumes ownership of <data> (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 <type> containing <size>
+ // bytes. The <cont> argument initializes the continuation field in
+ // the <Message_Block>. If <data> == 0 then we create and own the
+ // <data>, using <allocator> to get the data if it's non-0. If
+ // <data> != 0 we assume ownership of the <data> (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,
+ // <normal> messages and <high-priority> 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 <n> bytes from <buf> 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 <ptr>.
+ void rd_ptr (size_t n);
+ // Set the read pointer ahead <n> bytes.
+
+ char *wr_ptr (void);
+ // Get the write pointer.
+ void wr_ptr (char *ptr);
+ // Set the write pointer to <ptr>.
+ void wr_ptr (size_t n);
+ // Set the write pointer ahead <n> 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 <next_> pointer points to the <Message_Block> 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 <prev_> pointer points to the <Message_Block> 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 <clone> 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 <ACE_SYNCH_1> void
+ACE_Message_Queue<ACE_SYNCH_2>::dump (void) const
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::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_SYNCH_1>
+ACE_Message_Queue<ACE_SYNCH_2>::ACE_Message_Queue (size_t hwm,
+ size_t lwm)
+ : notfull_cond_ (this->lock_),
+ notempty_cond_ (this->lock_)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::ACE_Message_Queue");
+ if (this->open (hwm, lwm) == -1)
+ ACE_ERROR ((LM_ERROR, "open"));
+}
+
+template <ACE_SYNCH_1>
+ACE_Message_Queue<ACE_SYNCH_2>::~ACE_Message_Queue (void)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::~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 <ACE_SYNCH_1> int
+ACE_Message_Queue<ACE_SYNCH_2>::open (size_t hwm, size_t lwm)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Message_Queue<ACE_SYNCH_2>::deactivate_i (void)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Message_Queue<ACE_SYNCH_2>::activate_i (void)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Message_Queue<ACE_SYNCH_2>::close (void)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Message_Queue<ACE_SYNCH_2>::enqueue_tail_i (ACE_Message_Block *new_item)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Message_Queue<ACE_SYNCH_2>::enqueue_head_i (ACE_Message_Block *new_item)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Message_Queue<ACE_SYNCH_2>::enqueue_i (ACE_Message_Block *new_item)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::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 <new_item> 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 <new_item>.
+ break;
+ }
+
+ if (temp == 0)
+ // Check for simple case of inserting at the head of the queue,
+ // where all we need to do is insert <new_item> 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 <new_item> 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 <ACE_SYNCH_1> int
+ACE_Message_Queue<ACE_SYNCH_2>::dequeue_head_i (ACE_Message_Block *&first_item)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Message_Queue<ACE_SYNCH_2>::peek_dequeue_head (ACE_Message_Block *&first_item,
+ ACE_Time_Value *tv)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Message_Queue<ACE_SYNCH_2>::enqueue_head (ACE_Message_Block *new_item,
+ ACE_Time_Value *tv)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::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 <ACE_Message_Block *> into the <Message_Queue> in
+// accordance with its <msg_priority> (0 is lowest priority). Returns
+// -1 on failure, else the number of items still on the queue.
+
+template <ACE_SYNCH_1> int
+ACE_Message_Queue<ACE_SYNCH_2>::enqueue (ACE_Message_Block *new_item,
+ ACE_Time_Value *tv)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Message_Queue<ACE_SYNCH_2>::enqueue_tail (ACE_Message_Block *new_item,
+ ACE_Time_Value *tv)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Message_Queue<ACE_SYNCH_2>::dequeue_head (ACE_Message_Block *&first_item,
+ ACE_Time_Value *tv)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::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 <ACE_SYNCH_1>
+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 <ACE_SYNCH_1> is
+ // ACE_MT_SYNCH then all operations are thread-safe. Otherwise,
+ // if it's <ACE_NULL_SYNCH> 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 <ACE_Message_Block *> into the <Message_Queue> in
+ // accordance with its <msg_priority> (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 <ACE_Message_Block *> 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 <ACE_Message_Block *> 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 <ACE_Message_Block *> 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 <errno> ==
+ // 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 <ACE_Message_Block *> in accordance with its priority.
+
+ int enqueue_tail_i (ACE_Message_Block *new_item);
+ // Enqueue an <ACE_Message_Block *> at the end of the queue.
+
+ int enqueue_head_i (ACE_Message_Block *new_item);
+ // Enqueue an <ACE_Message_Block *> at the head of the queue.
+
+ int dequeue_head_i (ACE_Message_Block *&first_item);
+ // Dequeue and return the <ACE_Message_Block *> 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_SYNCH_1> ACE_INLINE int
+ACE_Message_Queue<ACE_SYNCH_2>::is_empty_i (void)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::is_empty_i");
+ return this->cur_bytes_ <= 0 && this->cur_count_ <= 0;
+}
+
+// Check if queue is full (does not hold locks).
+
+template <ACE_SYNCH_1> ACE_INLINE int
+ACE_Message_Queue<ACE_SYNCH_2>::is_full_i (void)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::is_full_i");
+ return this->cur_bytes_ > this->high_water_mark_;
+}
+
+// Check if queue is empty (holds locks).
+
+template <ACE_SYNCH_1> ACE_INLINE int
+ACE_Message_Queue<ACE_SYNCH_2>::is_empty (void)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::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_SYNCH_1> ACE_INLINE int
+ACE_Message_Queue<ACE_SYNCH_2>::is_full (void)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::is_full");
+ ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1);
+
+ return this->is_full_i ();
+}
+
+template <ACE_SYNCH_1> ACE_INLINE size_t
+ACE_Message_Queue<ACE_SYNCH_2>::high_water_mark (void)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::high_water_mark");
+ ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0);
+
+ return this->high_water_mark_;
+}
+
+template <ACE_SYNCH_1> ACE_INLINE void
+ACE_Message_Queue<ACE_SYNCH_2>::high_water_mark (size_t hwm)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::high_water_mark");
+ ACE_GUARD (ACE_SYNCH_MUTEX, ace_mon, this->lock_);
+
+ this->high_water_mark_ = hwm;
+}
+
+template <ACE_SYNCH_1> ACE_INLINE size_t
+ACE_Message_Queue<ACE_SYNCH_2>::low_water_mark (void)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::low_water_mark");
+ ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0);
+
+ return this->low_water_mark_;
+}
+
+template <ACE_SYNCH_1> ACE_INLINE void
+ACE_Message_Queue<ACE_SYNCH_2>::low_water_mark (size_t lwm)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::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_SYNCH_1> ACE_INLINE size_t
+ACE_Message_Queue<ACE_SYNCH_2>::message_bytes (void)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::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_SYNCH_1> ACE_INLINE size_t
+ACE_Message_Queue<ACE_SYNCH_2>::message_count (void)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::message_count");
+ ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0);
+
+ return this->cur_count_;
+}
+
+template <ACE_SYNCH_1> int
+ACE_Message_Queue<ACE_SYNCH_2>::activate (void)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::activate");
+ ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1);
+
+ return this->activate_i ();
+}
+
+template <ACE_SYNCH_1> int
+ACE_Message_Queue<ACE_SYNCH_2>::deactivate (void)
+{
+ ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_2>::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 <Andres.Kruse@cern.ch> and Douglas C. Schmidt
+// <schmidt@cs.wustl.edu>
+//
+// ============================================================================
+
+#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 <Method_Object> is inserted in the <Activation_Queue>, where
+ // it is subsequently removed by the <Scheduler> 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 <Method_Object> 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 <ACE_SYNCH_1> void
+ACE_Module<ACE_SYNCH_2>::dump (void) const
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::dump");
+}
+
+template <ACE_SYNCH_1> void
+ACE_Module<ACE_SYNCH_2>::writer (ACE_Task<ACE_SYNCH_2> *q)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::writer");
+ this->q_pair_[1] = q;
+ if (q != 0)
+ ACE_CLR_BITS (q->flags_, ACE_Task_Flags::ACE_READER);
+}
+
+template <ACE_SYNCH_1> void
+ACE_Module<ACE_SYNCH_2>::reader (ACE_Task<ACE_SYNCH_2> *q)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::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 <ACE_SYNCH_1> void
+ACE_Module<ACE_SYNCH_2>::link (ACE_Module<ACE_SYNCH_2> *m)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::link");
+ this->next (m);
+ this->writer ()->next (m->writer ());
+ m->reader ()->next (this->reader ());
+}
+
+template <ACE_SYNCH_1> int
+ACE_Module<ACE_SYNCH_2>::open (char *mod_name,
+ ACE_Task<ACE_SYNCH_2> *writer_q,
+ ACE_Task<ACE_SYNCH_2> *reader_q,
+ void *arg)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::open");
+ this->name (mod_name);
+ this->arg_ = arg;
+
+ if (writer_q == 0)
+ writer_q = new ACE_Thru_Task<ACE_SYNCH_2>;
+ if (reader_q == 0)
+ reader_q = new ACE_Thru_Task<ACE_SYNCH_2>;
+
+ // 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_SYNCH_1> ACE_Task<ACE_SYNCH_2> *
+ACE_Module<ACE_SYNCH_2>::sibling (ACE_Task<ACE_SYNCH_2> *orig)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::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_SYNCH_1> ACE_INLINE
+ACE_Module<ACE_SYNCH_2>::ACE_Module (void)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::ACE_Module");
+ this->name ("<unknown>");
+ // Do nothing...
+}
+
+// Should never be called...
+template <ACE_SYNCH_1> ACE_INLINE
+ACE_Module<ACE_SYNCH_2>::~ACE_Module (void)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::~ACE_Module");
+ ACE_ERROR ((LM_ERROR, "destructor for %s should never be called!\n",
+ this->name ()));
+}
+
+template <ACE_SYNCH_1> ACE_INLINE
+ACE_Module<ACE_SYNCH_2>::ACE_Module (char *mod_name,
+ ACE_Task<ACE_SYNCH_2> *writer_q,
+ ACE_Task<ACE_SYNCH_2> *reader_q,
+ void *flags)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::ACE_Module");
+ if (this->open (mod_name, writer_q, reader_q, flags) == -1)
+ ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Module"));
+}
+
+template <ACE_SYNCH_1> int
+ACE_Module<ACE_SYNCH_2>::close (u_long flags)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::close");
+ ACE_Task<ACE_SYNCH_2> *reader_q = this->reader ();
+ ACE_Task<ACE_SYNCH_2> *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<ACE_SYNCH_2>::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 <ACE_SYNCH_1> class ACE_Task;
+
+template <ACE_SYNCH_1>
+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<ACE_SYNCH_2> *writer = 0,
+ ACE_Task<ACE_SYNCH_2> *reader = 0, void *a = 0);
+ // Create an initialized module with <module_name> as its identity
+ // and <reader> and <writer> as its tasks.
+
+ int open (char *module_name,
+ ACE_Task<ACE_SYNCH_2> *writer = 0,
+ ACE_Task<ACE_SYNCH_2> *reader = 0, void *a = 0);
+ // Create an initialized module with <module_name> as its identity
+ // and <reader> and <writer> as its tasks.
+
+ int close (u_long flags = M_DELETE);
+ // Close down the Module and its Tasks. If the <M_DELETE> argument
+ // is given then delete all the memory too.
+
+ // = ACE_Task manipulation routines
+ ACE_Task<ACE_SYNCH_2> *writer (void);
+ // Get the writer task.
+ void writer (ACE_Task<ACE_SYNCH_2> *q);
+ // Set the writer task.
+
+ ACE_Task<ACE_SYNCH_2> *reader (void);
+ // Get the reader task.
+ void reader (ACE_Task<ACE_SYNCH_2> *q);
+ // Set the reader task.
+
+ ACE_Task<ACE_SYNCH_2> *sibling (ACE_Task<ACE_SYNCH_2> *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<ACE_SYNCH_2> *m);
+ // Link to other modules in the ustream stack
+
+ ACE_Module<ACE_SYNCH_2> *next (void);
+ // Get the next pointer to the module above in the stream.
+
+ void next (ACE_Module<ACE_SYNCH_2> *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<ACE_SYNCH_2> *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<ACE_SYNCH_2> *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_SYNCH_1> ACE_INLINE void *
+ACE_Module<ACE_SYNCH_2>::arg (void) const
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::arg");
+ return this->arg_;
+}
+
+template <ACE_SYNCH_1> ACE_INLINE void
+ACE_Module<ACE_SYNCH_2>::arg (void *a)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::arg");
+ this->arg_ = a;
+}
+
+template <ACE_SYNCH_1> ACE_INLINE const char *
+ACE_Module<ACE_SYNCH_2>::name (void) const
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::name");
+ return this->name_;
+}
+
+template <ACE_SYNCH_1> ACE_INLINE void
+ACE_Module<ACE_SYNCH_2>::name (char *n)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::name");
+ ACE_OS::strncpy (this->name_, n, MAXNAMLEN);
+}
+
+template <ACE_SYNCH_1> ACE_INLINE ACE_Task<ACE_SYNCH_2> *
+ACE_Module<ACE_SYNCH_2>::writer (void)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::writer");
+ return this->q_pair_[1];
+}
+
+template <ACE_SYNCH_1> ACE_INLINE ACE_Task<ACE_SYNCH_2> *
+ACE_Module<ACE_SYNCH_2>::reader (void)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::reader");
+ return this->q_pair_[0];
+}
+
+template <ACE_SYNCH_1> ACE_INLINE ACE_Module<ACE_SYNCH_2> *
+ACE_Module<ACE_SYNCH_2>::next (void)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::next");
+ return this->next_;
+}
+
+template <ACE_SYNCH_1> ACE_INLINE void
+ACE_Module<ACE_SYNCH_2>::next (ACE_Module<ACE_SYNCH_2> *m)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::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, "<unknown type> = %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, "<unknown type> = %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 <ACE_Name_Request> 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 <Transfer> 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., <BIND>, <REBIND>, <RESOLVE>, and <UNBIND>).
+
+ ACE_UINT32 block_forever_;
+ // Indicates if we should block forever. If 0, then <secTimeout_>
+ // and <usecTimeout_> 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 <name_>
+ // followed by the <value_>
+ // followed by the <type_>.
+ };
+
+ 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 <ACE_Name_Reply> 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 <Transfer> struct are transmitted to the server.
+
+ struct Transfer
+ {
+ ACE_UINT32 length_;
+ // Length of entire reply.
+
+ ACE_UINT32 type_;
+ // Type of the reply (i.e., <SUCCESS> or <FAILURE>).
+
+ ACE_UINT32 errno_;
+ // Indicates why error occurred if <this->type_> == <FAILURE>.
+ // Typical reasons include:
+ // <ETIME> (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> 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_Name_Binding> ACE_BINDING_SET;
+typedef ACE_Unbounded_Set_Iterator<ACE_Name_Binding> ACE_BINDING_ITERATOR;
+
+typedef ACE_Unbounded_Set<ACE_WString> ACE_PWSTRING_SET;
+typedef ACE_Unbounded_Set_Iterator<ACE_WString> 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 <value_out> and <type_out>!
+
+ 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 <ACE_MMAP_Memory_Pool, ACE_RW_Process_Mutex> LOCAL_NAME_SPACE;
+typedef ACE_Local_Name_Space <ACE_Lite_MMAP_Memory_Pool, ACE_RW_Process_Mutex> 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 <ACE_MMAP_Memory_Pool, ACE_RW_Process_Mutex>;
+template class ACE_Local_Name_Space <ACE_Lite_MMAP_Memory_Pool, ACE_RW_Process_Mutex>;
+template class ACE_Allocator_Adapter<ACE_Malloc<ACE_MMAP_Memory_Pool, ACE_RW_Process_Mutex> >;
+template class ACE_Allocator_Adapter<ACE_Malloc<ACE_Lite_MMAP_Memory_Pool, ACE_RW_Process_Mutex> >;
+ACE_Name_Space_Map <ACE_Allocator_Adapter <ACE_Malloc <ACE_MMAP_Memory_Pool, ACE_RW_Process_Mutex> > >;
+ACE_Name_Space_Map <ACE_Allocator_Adapter <ACE_Malloc <ACE_Lite_MMAP_Memory_Pool, ACE_RW_Process_Mutex> > >;
+#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 <light>
+ // 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 <light>
+ // 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 <value_out> and <type_out>!
+
+ 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 <value_out> and
+ // <type_out>!
+
+ 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 <value_out> and <type_out>!
+
+ 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> ACE_TSS_REF_TABLE;
+typedef ACE_Unbounded_Set_Iterator<ACE_TSS_Ref> 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<xxx> 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 <ACE_TSS_Info> objects that will reside
+// within thread-specific storage.
+typedef ACE_Unbounded_Set<ACE_TSS_Info> ACE_TSS_TABLE;
+typedef ACE_Unbounded_Set_Iterator<ACE_TSS_Info> 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 <status>.
+
+ int insert (ACE_thread_key_t key, void (*destructor)(void *), void *inst);
+ // Insert a <key, destructor> tuple into the table.
+
+ int remove (ACE_thread_key_t key);
+ // Remove a <key, destructor> 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 <ACE_TSS_Info>'s.
+
+ // = Static data.
+ static ACE_TSS_Cleanup *instance_;
+ // Pointer to the singleton instance.
+
+public:
+ static ACE_Recursive_Thread_Mutex lock_;
+ // Serialize initialization of <key_>.
+};
+
+// = Static object initialization.
+
+// Pointer to the singleton instance.
+ACE_TSS_Cleanup *ACE_TSS_Cleanup::instance_ = 0;
+
+// Serialize initialization of <key_>.
+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 <thr_create>).
+
+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 <send_n> 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 <send_n> 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 <schmidt@cs.wustl.edu>, Jesper S. M|ller
+// <stophph@diku.dk>, 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 <sys/procfs.h>
+#endif /* ACE_HAS_PROC_FD */
+
+#if defined (ACE_HAS_UNICODE)
+#include <wchar.h>
+#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
+// <Thread_Manager> 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<MUTEX> OBJ (LOCK); \
+ if (OBJ.locked () == 0) return RETURN;
+#define ACE_WRITE_GUARD_RETURN(MUTEX,OBJ,LOCK,RETURN) \
+ ACE_Write_Guard<MUTEX> OBJ (LOCK); \
+ if (OBJ.locked () == 0) return RETURN;
+#define ACE_READ_GUARD_RETURN(MUTEX,OBJ,LOCK,RETURN) \
+ ACE_Read_Guard<MUTEX> OBJ (LOCK); \
+ if (OBJ.locked () == 0) return RETURN;
+#define ACE_GUARD(MUTEX,OBJ,LOCK) \
+ ACE_Guard<MUTEX> OBJ (LOCK); \
+ if (OBJ.locked () == 0) return;
+
+#if defined (ACE_HAS_POSIX_SEM)
+#include <semaphore.h>
+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 <synch.h>
+#include <thread.h>
+#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 <semLib.h> // for mutex implementation using mutual-exclusion
+ // semaphores (which can be taken recursively)
+#include <taskLib.h>
+
+// 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 <sys/types.h>
+#include <assert.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <stdio.h>
+#include <new.h>
+#include <ctype.h>
+#include <signal.h>
+#include <string.h>
+#include <iostream.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+
+// 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 <utime.h>
+#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 <sys/timeb.h>
+
+// 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
+// <windows.h> directly.
+#if !defined (__AFX_H__)
+#include <windows.h>
+#endif /* __AFX_H__ */
+
+#include <winsock.h>
+
+#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 <time.h>
+#include <direct.h>
+#include <process.h>
+#include <io.h>
+
+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 <sys/socket.h>
+extern "C" {
+#if !defined (VXWORKS)
+#include <netdb.h>
+#endif /* VXWORKS */
+#include <net/if.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+}
+#if defined (VXWORKS)
+#include <sys/times.h>
+#else
+#include <sys/param.h>
+#include <sys/uio.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/sem.h>
+#include <sys/file.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+#include <pwd.h>
+#endif /* VXWORKS */
+#include <sys/ioctl.h>
+#include <dirent.h>
+#include <sys/utsname.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#if !defined (ACE_LACKS_PARAM_H)
+#include <sys/param.h>
+#endif /* ACE_LACKS_PARAM_H */
+
+#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) && !defined (VXWORKS)
+#include <sys/un.h>
+#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */
+
+#if defined (ACE_HAS_SIGINFO_T)
+#if !defined (ACE_LACKS_SIGINFO_H)
+#include <siginfo.h>
+#endif /* ACE_LACKS_SIGINFO_H */
+#if !defined (ACE_LACKS_UCONTEXT_H)
+#include <ucontext.h>
+#endif /* ACE_LACKS_UCONTEXT_H */
+#endif /* ACE_HAS_SIGINFO_T */
+
+#if defined (ACE_HAS_POLL)
+#include <poll.h>
+#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 <stropts.h>
+#undef _XOPEN_EXTENDED_SOURCE
+#else
+#include <stropts.h>
+#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 <sys/select.h>
+#endif /* ACE_HAS_SELECT_H */
+
+#if defined (ACE_HAS_ALLOCA_H)
+#include <alloca.h>
+#endif /* ACE_HAS_ALLOCA_H */
+
+#if defined (ACE_HAS_TIUSER_H)
+#include <tiuser.h>
+#endif /* ACE_HAS_TIUSER_H */
+
+#if defined (ACE_HAS_SVR4_DYNAMIC_LINKING)
+#include <dlfcn.h>
+#endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */
+
+#if defined (ACE_HAS_SOCKIO_H)
+#include <sys/sockio.h>
+#endif /* ACE_HAS_SOCKIO_ */
+
+#if defined (ACE_HAS_TIMOD_H)
+#include <sys/timod.h>
+#elif defined (ACE_HAS_OSF_TIMOD_H)
+#include <tli/timod.h>
+#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 <bstring.h>
+#endif /* ACE_HAS_BSTRING */
+
+// AIX defines bzero() in this odd file...
+#if defined (ACE_HAS_STRINGS)
+#include <strings.h>
+#endif /* ACE_HAS_STRINGS */
+
+#if defined (ACE_HAS_TERM_IOCTLS)
+#include <sys/termios.h>
+#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 <sys/mman.h>
+}
+#elif !defined (ACE_LACKS_MMAP)
+#include <sys/mman.h>
+#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 <sys/msg.h>
+#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 <vxWorks.h>
+
+#if defined (ACE_HAS_GREENHILLS_SOCKETS)
+#include <hostLib.h>
+#include <ioLib.h>
+#include <selectLib.h>
+#include <sigLib.h>
+#include <sockLib.h>
+
+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 <xti.h>
+#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 <xliuser.h>
+#endif /* ACE_HAS_XLI */
+
+#if !defined (ACE_HAS_CPLUSPLUS_HEADERS)
+#include <libc.h>
+#include <osfcn.h>
+#endif /* ACE_HAS_CPLUSPLUS_HEADERS */
+
+#if defined (ACE_HAS_SYSENT_H)
+#include <sysent.h>
+#endif /* ACE_HAS_SYSENT_H_*/
+
+#if defined (ACE_HAS_SYS_FILIO_H)
+#include <sys/filio.h>
+#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 <malloc.h>
+#endif /* ACE_LACKS_MALLOC_H */
+
+#if !defined (ACE_WIN32)
+
+#if !defined (ACE_LACKS_RPC_H)
+#include <rpc/rpc.h>
+#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 <string.h>
+#else
+#include <memory.h>
+#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 <regexpr.h>
+#endif /* ACE_HAS_REGEX */
+
+#if defined (ACE_HAS_SYSINFO)
+#include <sys/systeminfo.h>
+#endif /* ACE_HAS_SYS_INFO */
+
+#if defined (ACE_HAS_SYSCALL_H)
+#include <sys/syscall.h>
+#endif /* ACE_HAS_SYSCALL_H */
+
+#if defined (UNIXWARE) // See strcasecmp, below
+#include <ctype.h>
+#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 <external_mutex> 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 <external_mutex>
+ // 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 <relative_time> 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 <external_mutex>
+ // 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 <relative_time> 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 <relative_time> 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 <count> and
+ // its maximum value initialized to <max>.
+ *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 <function_name> 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<ACE_Thread_Mutex, ACE_Condition_Thread_Mutex>;
+// template class ACE_Task<ACE_Thread_Mutex, ACE_Condition_Thread_Mutex>;
+// template class ACE_Task_Exit<ACE_Thread_Mutex, ACE_Condition_Thread_Mutex>;
+// template class ACE_TSS<ACE_Task_Exit<ACE_Thread_Mutex, ACE_Condition_Thread_Mutex> >;
+#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 <ACE_Pipe> from the <read> and <write> 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 <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 -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 <handler>. If <msg> == 0, the Proactor
+ // will call handler::get_message to obtain an ACE_Message_Block
+ // to send/recv according to <mask>. If <mask> ==
+ // ACE_Event_Handler::WRITE_MASK, the Proactor calls WriteFile using
+ // the <msg> and Event_Handler::get_handle. Returns 1 if the operation
+ // succeeded immediately, 0 if the operation is pending (in which
+ // case the <handler> will be called back), and -1 if an error
+ // occurred. <file> 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. <file> is ignored for network I/O or if
+ // <file> == 0. If <file> != 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 <Event_Handler> that will expire after <delay> amount
+ // of time. If it expires then <arg> is passed in as the value to
+ // the <Event_Handler>'s <handle_timeout> callback method. If
+ // <interval> is != to <ACE_Time_Value::zero> then it is used to
+ // reschedule the <Event_Handler> automatically. This method
+ // returns a timer handle that uniquely identifies the
+ // <Event_Handler> 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 *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 <ACE_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.
+
+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 <handler> 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
+ // <invoke> 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
+ // <ACE_Proactor> with the <ACE_Dispatcher>).
+};
+
+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 <file>.
+
+ 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 <file_name> according to <mode> and <perms>. This method
+ // is equivalent to CreateFile. Returns 0 on success, -1 on failure
+ // with errno == reason.
+
+ int open (ACE_HANDLE handle);
+ // Uses the given <handle>. Returns 0 on success, -1 on failure.
+ // This will only return -1 when <handle> == 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 <whence> == SEEK_SET, then the file pointer is set to
+ // <offset>. If <whence> == SEEK_CUR, then the file pointer is set
+ // to its current location plus <offset>. If <whence> == SEEK_END,
+ // the file pointer is set to the size of the file plus <offset>.
+
+ 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 <handle_>.
+};
+
+#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 <harrison@cs.wustl.edu>
+//
+// ============================================================================
+
+#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 <t_id>. 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 <func>.
+
+ // 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 <func>.
+
+ // 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 <timeout>
+ // 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 <p_id>. Returns
+ // -1 if <p_id> is not in the table doesn't contain <p_id>.
+
+ 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 <func> to all members of the table that match the <grp_id>.
+
+ int apply_all (PROC_FUNC, int = 0);
+ // Apply <func> to all members of the table.
+
+ int resume_proc (int i);
+ // Resume the process at index <i>.
+
+ int suspend_proc (int i);
+ // Suspend the process at index <i>.
+
+ int kill_proc (int i, int signum);
+ // Send signal <signum> to the process at index <i>.
+
+ 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 <start>.
+
+ 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 <alloca.h>
+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 <msg.h> 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 <sys/timers.h>
+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 <bstring.h> (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 <poll.h>
+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 <sys/procfs.h>
+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 <sys/syscall.h> file.
+ACE_HAS_SYSENT_H Platform provides <sysent.h> 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 <sys/filio.h> 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 <sys/param.h> (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 <time.h> doesn't automatically #include <sys/time.h>
+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 <sys/procfs.h>
+ 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 <stropts.h>
+
+ 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 <dlfcn.h>
+ 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 <poll.h>
+ #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 <sys/filio.h>.
+ 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:
+ <sys/ioctl.h> defines FIOASYNC and some other ones,
+ <sgtty.h> 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 <sys/timod.h>
+
+ 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 <tiuser.h>
+
+ 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 <size>.
+
+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 <ACE_Event_Handler *> associated with <ACE_HANDLE>.
+
+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 <ACE_Event_Handler *> to the <ACE_HANDLE>.
+
+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 <ACE_HANDLE>.
+
+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 <next_item> 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 <how_long> 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 <size>.
+
+ int close (ACE_Reactor *);
+ // Destroy the handler and cleanup the Reactor.
+
+ // = Search structure operations.
+
+ ACE_Event_Handler *find (ACE_HANDLE);
+ // Return the <ACE_Event_Handler *> associated with <ACE_HANDLE>.
+
+ int bind (ACE_HANDLE, ACE_Event_Handler *);
+ // Bind the <ACE_Event_Handler *> to the <ACE_HANDLE>.
+
+ int unbind (ACE_HANDLE, ACE_Handle_Set &rd_mask,
+ ACE_Handle_Set &wr_mask, ACE_Handle_Set &ex_mask);
+ // Remove the binding of <ACE_HANDLE>.
+
+ // 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 <HANDLES> to <Event_Handlers>.
+ 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 <ACE_NT_EH_Record *>. 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 <ACE_Event_Handler *> 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 <next_item> 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 <size>.
+
+ virtual int open (size_t size = DEFAULT_SIZE,
+ int restart = 0,
+ ACE_Sig_Handler * = 0);
+ // Initialize the new ACE_Reactor of size <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 <event_handler> that will expire after <delay> amount
+ // of time. If it expires then <arg> is passed in as the value to
+ // the <event_handler>'s <handle_timeout> callback method. If
+ // <interval> is != to <ACE_Time_Value::zero> then it is used to
+ // reschedule the <event_handler> automatically. This method
+ // returns a timer handle that uniquely identifies the
+ // <event_handler> 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 <ACE_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.
+
+ // = Event loop drivers.
+ virtual int handle_events (ACE_Time_Value *how_long = 0);
+ // 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.
+
+ 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).
+
+ // = Register and remove Handlers.
+ virtual int register_handler (ACE_Event_Handler *eh,
+ ACE_Reactor_Mask mask);
+ // Register an Event_Handler <eh> with a particular <mask>. 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 <eh> with a particular <mask>. Note
+ // that since the <handle> 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 <eh> with all the <handles> in the <Handle_Set>.
+
+ 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 <new_sh> to handle the signal <signum> using the
+ // <new_disp>. Returns the <old_sh> that was previously registered
+ // (if any), along with the <old_disp> 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 <new_sh> to handle a set of signals <sigset> using the
+ // <new_disp>.
+
+ virtual int remove_handler (ACE_Event_Handler *eh,
+ ACE_Reactor_Mask mask);
+ // Removes the <mask> binding of <eh> from the Reactor. If there
+ // are no more bindings for this <eh> 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 <mask> bind of <Event_Handler> whose handle is
+ // <handle> from the Reactor. If there are no more bindings for
+ // this <eh> then it is removed from the Reactor.
+
+ virtual int remove_handler (const ACE_Handle_Set &handle_set,
+ ACE_Reactor_Mask);
+ // Removes all the <mask> bindings for handles in the <handle_set>
+ // bind of <Event_Handler>. 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 <signum>.
+ // <sigkey> 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 <signum> is invalid.
+
+ virtual int remove_handler (const ACE_Sig_Set &sigset);
+ // Calls <remove_handler> for every signal in <sigset>.
+
+ // = Suspend and resume Handlers.
+
+ virtual int suspend_handler (ACE_Event_Handler *eh);
+ // Temporarily suspend the <Event_Handler> associated with <eh>.
+
+ virtual int suspend_handler (ACE_HANDLE handle);
+ // Temporarily suspend the <Event_Handler> associated with <handle>.
+
+ virtual int resume_handler (ACE_Event_Handler *eh);
+ // Resume a temporarily suspend <Event_Handler> associated with
+ // <eh>.
+
+ virtual int resume_handler (ACE_HANDLE handle);
+ // Resume a temporarily suspended <Event_Handler> associated with
+ // <handle>.
+
+ virtual int suspend_handlers (void);
+ // Suspend all the <Event_Handlers> in the Reactor.
+
+ virtual int resume_handlers (void);
+ // Resume all the <Event_Handlers> 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 <handle> is associated with a valid Event_Handler
+ // bound to <mask>. Return the <eh> associated with this <handler>
+ // if <eh> != 0.
+
+ virtual int handler (int signum,
+ ACE_Event_Handler ** = 0);
+ // Check to see if <signum> is associated with a valid Event_Handler
+ // bound to a signal. Return the <eh> associated with this
+ // <handler> if <eh> != 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 <eh> and the <mask>.
+
+ virtual int schedule_wakeup (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask);
+ // ADD the dispatch MASK "bit" bound with the <handle> and the <mask>.
+
+ virtual int cancel_wakeup (ACE_Event_Handler *eh,
+ ACE_Reactor_Mask mask);
+ // CLR the dispatch MASK "bit" bound with the <eh> and the <mask>.
+
+ virtual int cancel_wakeup (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask);
+ // CLR the dispatch MASK "bit" bound with the <handle> and the <mask>.
+
+ // = 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 <eh> and
+ // <mask>.
+
+ virtual int mask_ops (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask,
+ int ops);
+ // GET/SET/ADD/CLR the dispatch MASK "bit" bound with the <handle>
+ // and <mask>.
+
+ // = 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 <eh> and <mask>.
+
+ virtual int ready_ops (ACE_HANDLE handle,
+ ACE_Reactor_Mask,
+ int ops);
+ // GET/SET/ADD/CLR the ready "bit" bound with the <handle> and <mask>.
+
+ 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 <handle> and <eh> with the
+ // <mask>.
+
+ virtual int detach (ACE_HANDLE handle,
+ ACE_Reactor_Mask);
+ // Do the work of actually unbinding the <handle> and <eh> with the
+ // <mask>.
+
+ virtual int suspend (ACE_HANDLE handle);
+ // Suspend the <Event_Handler> associated with <handle>
+ virtual int resume (ACE_HANDLE handle);
+ // Resume the <Event_Handler> associated with <handle>
+
+ virtual int remove_handlers (const ACE_Handle_Set &handles,
+ ACE_Reactor_Mask);
+ // Remove a set of <handles>.
+
+ virtual int register_handlers (const ACE_Handle_Set &handles,
+ ACE_Event_Handler *handler,
+ ACE_Reactor_Mask mask);
+ // Register a set of <handles>.
+
+ virtual int handler_i (ACE_HANDLE handle,
+ ACE_Reactor_Mask,
+ ACE_Event_Handler ** = 0);
+ // Implement the public <handler> method.
+
+ virtual int handler_i (int signum, ACE_Event_Handler ** = 0);
+ // Implement the public <handler> 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 <callback> in the context of the <eh>
+ // associated with <handle> 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 <ACE_Event_Handler *>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 <Handle_Sets> 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 <requeue_position_>.
+
+ 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 <terminator>. If
+ // <search> is >= 0 then all occurrences of the <search> value are
+ // substituted with the <replace> 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 <read>.
+
+ size_t size (void) const;
+ // Returns the size of the allocated buffer obtained during a <read>.
+
+ 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> 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 <value_out> and <type_out>!
+
+ 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_TSS_Connection, ACE_TSS_CONNECTION_MUTEX>
+ 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<ACE_SOCK_Stream>::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<ACE_SOCK_Stream>::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 <ACE_SOCK_Stream>;
+template class ACE_Singleton <ACE_TSS_Connection, ACE_TSS_CONNECTION_MUTEX>;
+#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. <name> is the string uniquely identifying
+ // the token. <ignore_deadlock> can be 1 to disable deadlock
+ // notifications. <debug> 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 <errno> == 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 <this->release()> followed by
+ // <this->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 <errno> ==
+ // 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<ACE_SOCK_Stream>
+ // = 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 <timeout> of 0 means
+ // block forever, a <timeout> of {0, 0} means poll. <restart> == 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>.
+ 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>.
+ 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 <new_stream> if things go well.
+ // The <remote_sap> is the address that we are trying to connect
+ // with. The <timeout> 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 <errno == EWOULDBLOCK>. 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 <errno == ETIMEDOUT>.
+ // The <local_sap> is the value of local address to bind to. If
+ // it's the default value of <ACE_Addr::sap_any> then the user is
+ // letting the OS do the binding. If <reuse_addr> == 1 then the
+ // <local_addr> 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 <new_stream> if things go well.
+ // The <remote_sap> is the address that we are trying to connect
+ // with. The <timeout> 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 <errno == EWOULDBLOCK>. 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 <errno == ETIMEDOUT>.
+ // The <local_sap> is the value of local address to bind to. If
+ // it's the default value of <ACE_Addr::sap_any> then the user is
+ // letting the OS do the binding. If <reuse_addr> == 1 then the
+ // <local_addr> 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 <new_stream> contains
+ // the connected ACE_SOCK_Stream. If <remote_sap> 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 <n> byte <buf> to the datagram socket (uses sendto(3)).
+
+ ssize_t recv (void *buf,
+ size_t n,
+ ACE_Addr &addr,
+ int flags = 0) const;
+ // Receive an <n> byte <buf> 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 <iovec> of size <n> to the datagram socket (uses
+ // sendmsg(3)).
+
+ ssize_t recv (iovec iov[],
+ size_t n,
+ ACE_Addr &addr,
+ int flags = 0) const;
+ // Recv an <iovec> of size <n> 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 <LSOCK_Dgram>.
+
+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 <iovec> 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 <iovec> of size <n> to <addr> 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 <n> bytes in <buf>.
+
+ ssize_t send (const iovec iov[], size_t n, int flags = 0) const;
+ // Send <n> <iovecs>.
+
+ // = 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 <n> bytes via Win32 WriteFile using overlapped I/O.
+
+ ssize_t recv (void *buf, size_t n, ACE_OVERLAPPED *overlapped) const;
+ // Recv <n> 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 <ACE_SOCK_Stream> abstraction.
+ //
+ // = DESCRIPTION
+ // This adds additional wrapper methods atop the <ACE_SOCK_IO> 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 <buf>. 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 <buf> to <handle>. 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 <timeout> of 0 means
+ // block forever, a <timeout> of {0, 0} means poll. <restart> == 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 <new_stream> if things go well.
+ // The <remote_sap> is the address that we are trying to connect
+ // with. The <timeout> 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 <errno == EWOULDBLOCK>. 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 <errno == ETIMEDOUT>.
+ // The <local_sap> is the value of local address to bind to. If
+ // it's the default value of <ACE_Addr::sap_any> then the user is
+ // letting the OS do the binding. If <reuse_addr> == 1 then the
+ // <local_addr> is reused, even if it hasn't been cleanedup yet.
+ // The <flags> and <perms> 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 <new_stream> if things go well.
+ // The <remote_sap> is the address that we are trying to connect
+ // with. The <timeout> 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 <errno == EWOULDBLOCK>. 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 <errno == ETIMEDOUT>.
+ // The <local_sap> is the value of local address to bind to. If
+ // it's the default value of <ACE_Addr::sap_any> then the user is
+ // letting the OS do the binding. If <reuse_addr> == 1 then the
+ // <local_addr> is reused, even if it hasn't been cleanedup yet.
+ // The <flags> and <perms> 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 <cntl> and <data> via STREAM pipes.
+
+ ssize_t recv (ACE_Str_Buf *cntl,
+ ACE_Str_Buf *data,
+ int *flags) const;
+ // Recv <cntl> and <data> 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 <n> bytes via Win32 WriteFile using overlapped I/O.
+
+ ssize_t recv (void *buf, size_t n, ACE_OVERLAPPED *overlapped) const;
+ // Recv <n> 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 <s> 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 <len> chars of <s> 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 <index'th> 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 <s> into dynamically allocated memory.
+
+ ACE_SString (const char *s, size_t len, ACE_Allocator *allocator = 0);
+ // Constructor that copies <len> chars of <s> 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 <index'th> 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 <s> into dynamically allocated memory.
+
+ ACE_WString (const ACE_USHORT16 *s, ACE_Allocator *allocator = 0);
+ // Constructor that copies <s> into dynamically allocated memory.
+
+ ACE_WString (const ACE_USHORT16 *s, size_t len, ACE_Allocator *allocator = 0);
+ // Constructor that copies <len> ACE_USHORT16's of <s> 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 <index'th> 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 <index'th> 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 <index'th> 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 <index'th> 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 <external_id>.
+
+ ~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 <external_id>.
+
+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 <remove> 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 <acquire>.
+
+ 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 <shmctl>.
+
+ // = 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_Local_Memory_Pool, ACE_Null_Mutex>
+ 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 <ACE_DEFAULT_MALLOC>,
+ 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 <svc_name> 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
+// <service_config_file>.
+
+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<ACE_Obstack> 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 <ACE_Reactor::handle_events>
+// method returns -1 or the <end_reactor_event_loop> 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 <ACE_Reactor::handle_events>
+// method returns -1, the <end_reactor_event_loop> method
+// is invoked, or the <ACE_Time_Value> 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<ACE_Static_Svc_Descriptor *>;
+template class ACE_Unbounded_Set<ACE_Static_Svc_Descriptor *>;
+template class ACE_Unbounded_Set_Iterator<ACE_Static_Svc_Descriptor *>;
+template class ACE_Malloc<ACE_Local_Memory_Pool, ACE_Null_Mutex>;
+template class ACE_Allocator_Adapter<ACE_Malloc<ACE_Local_Memory_Pool, ACE_Null_Mutex> >;
+template class auto_ptr<ACE_Obstack>;
+#if !defined (ACE_HAS_THREADS)
+template class ACE_Guard<ACE_Null_Mutex>;
+template class ACE_Read_Guard<ACE_Null_Mutex>;
+template class ACE_Write_Guard<ACE_Null_Mutex>;
+#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_Svc_Descriptor *> ACE_STATIC_SVCS;
+typedef ACE_Unbounded_Set_Iterator<ACE_Static_Svc_Descriptor *> 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 <ACE_Event_Handler> 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 <close_svcs> and <close_singletons>.
+
+ static int close_svcs (void);
+ // Perform user-specified close hooks on all of the configured
+ // services in the <Service_Repository>, then delete the
+ // <Service_Repository> itself.
+
+ static int close_singletons (void);
+ // Delete the dynamically allocated Singletons (i.e., the <Reactor>,
+ // <Proactor>, <ReactorEx>, <Thread_Manager>, and <Allocator>).
+
+ // = Reactor event loop management methods.
+ static int run_reactor_event_loop (void);
+ // Run the event loop until the <ACE_Reactor::handle_events> method
+ // returns -1 or the <end_reactor_event_loop> method is invoked.
+
+ static int run_reactor_event_loop (ACE_Time_Value &tv);
+ // Run the event loop until the <ACE_Reactor::handle_events> method
+ // returns -1, the <end_reactor_event_loop> method is invoked, or the
+ // <ACE_Time_Value> expires.
+
+ static int end_reactor_event_loop (void);
+ // Instruct the <ACE_Service_Config> to terminate its event loop and
+ // notifies the <ACE_Service_Config::reactor> 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 <ACE_Proactor::handle_events>
+ // method returns -1 or the <end_proactor_event_loop> method
+ // is invoked.
+
+ static int run_proactor_event_loop (ACE_Time_Value &tv);
+ // Run the event loop until the <ACE_Proactor::handle_events>
+ // method returns -1, the <end_proactor_event_loop> method
+ // is invoked, or the <ACE_Time_Value> expires.
+
+ static int end_proactor_event_loop (void);
+ // Instruct the <ACE_Service_Config> 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 <ACE_ReactorEx::handle_events>
+ // method returns -1 or the <end_reactorEx_event_loop> method
+ // is invoked.
+
+ static int run_reactorEx_event_loop (ACE_Time_Value &tv);
+ // Run the event loop until the <ACE_ReactorEx::handle_events>
+ // method returns -1, the <end_reactorEx_event_loop> method
+ // is invoked, or the <ACE_Time_Value> expires.
+
+ static int end_reactorEx_event_loop (void);
+ // Instruct the <ACE_Service_Config> 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 <ACE_Reactor>.
+
+ static ACE_Reactor *reactor (ACE_Reactor *);
+ // Set pointer to a process-wide <ACE_Reactor> and return existing
+ // pointer.
+
+ static ACE_Proactor *proactor (size_t threads = 0);
+ // Get pointer to a process-wide <ACE_Proactor>. <threads> 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 <ACE_Proactor> and return existing
+ // pointer.
+
+ static ACE_ReactorEx *reactorEx (void);
+ // Get pointer to a process-wide <ACE_ReactorEx>.
+
+ static ACE_ReactorEx *reactorEx (ACE_ReactorEx *);
+ // Set pointer to a process-wide <ACE_ReactorEx> and return existing
+ // pointer.
+
+ static ACE_Service_Repository *svc_rep (void);
+ // Get pointer to a process-wide <ACE_Service_Repository>.
+
+ static ACE_Service_Repository *svc_rep (ACE_Service_Repository *);
+ // Set pointer to a process-wide <ACE_Service_Repository> and return
+ // existing pointer.
+
+ static ACE_Thread_Manager *thr_mgr (void);
+ // Get pointer to a process-wide <ACE_Thread_Manager>.
+
+ static ACE_Thread_Manager *thr_mgr (ACE_Thread_Manager *);
+ // Set pointer to a process-wide <ACE_Thread_Manager> and return
+ // existing pointer.
+
+ static ACE_Allocator *allocator (void);
+ // Get pointer to a default <ACE_Allocator>.
+
+ static ACE_Allocator *allocator (ACE_Allocator *);
+ // Set pointer to a process-wide <ACE_Allocator> 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 <svc_name> service.
+
+ static int resume (const char svc_name[]);
+ // Resume a <svc_name> that was previously suspended or has not yet
+ // been resumed (e.g., a static service).
+
+ static int suspend (const char 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...
+
+ static int remove (const char svc_name[]);
+ // Totally remove <svc_name> 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 <service_config_file>.
+
+ static void parse_args (int, char *[]);
+ // Handle the command-line options intended for the <ACE_Service_Config>.
+
+ 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 <ACE_Service_Repository>.
+
+ 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 <ACE_Service_Repository>.
+
+ static int delete_svc_rep_;
+ // Must delete the <svc_rep_> if non-0.
+
+ static ACE_Thread_Manager *thr_mgr_;
+ // Pointer to a process-wide <ACE_Thread_Manager>.
+
+ static int delete_thr_mgr_;
+ // Must delete the <thr_mgr_> if non-0.
+
+ static ACE_Allocator *allocator_;
+ // Pointer to a process-wide <ACE_Allocator> instance.
+
+ static int delete_allocator_;
+ // Must delete the <allocator_> if non-0.
+
+ static ACE_Proactor *proactor_;
+ // Pointer to a process-wide <ACE_Reactor>.
+
+ static int delete_proactor_;
+ // Must delete the <proactor_> if non-0.
+
+ static ACE_ReactorEx *reactorEx_;
+ // Pointer to a process-wide <ACE_Reactor>.
+
+ static int delete_reactorEx_;
+ // Must delete the <proactor_> if non-0.
+
+ static ACE_Reactor *reactor_;
+ // Pointer to a process-wide <ACE_Reactor>.
+
+ static int delete_reactor_;
+ // Must delete the <reactor_> 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<ACE_SYNCH>;
+template class ACE_Stream<ACE_SYNCH>;
+template class ACE_Task<ACE_SYNCH>;
+template class ACE_Message_Queue<ACE_SYNCH>;
+template class ACE_Task_Exit<ACE_SYNCH>;
+template class ACE_TSS<ACE_Task_Exit<ACE_SYNCH> >;
+template class ACE_Thru_Task<ACE_SYNCH>;
+template class ACE_Stream_Head<ACE_SYNCH>;
+template class ACE_Stream_Tail<ACE_SYNCH>;
+#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<ACE_SYNCH> MT_Stream;
+typedef ACE_Module<ACE_SYNCH> MT_Module;
+typedef ACE_Task<ACE_SYNCH> MT_Task;
+
+class ACE_Export ACE_Service_Object_Type : public ACE_Service_Type
+ // = TITLE
+ // Define the methods for handling <ACE_Service_Objects>.
+{
+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 <ACE_Modules>.
+{
+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 <ACE_Streams>.
+{
+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
+ // <ACE_Service_Types>.
+{
+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 <name> 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 <service_count> 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 <service_name>. 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 <class T, size_t SIZE> void
+ACE_Fixed_Set<T, SIZE>::dump (void) const
+{
+ ACE_TRACE ("ACE_Fixed_Set<T, SIZE>::dump");
+}
+
+template <class T, size_t SIZE>
+ACE_Fixed_Set<T, SIZE>::~ACE_Fixed_Set (void)
+{
+ ACE_TRACE ("ACE_Fixed_Set<T, SIZE>::~ACE_Fixed_Set");
+ this->cur_size_ = 0;
+}
+
+template <class T, size_t SIZE>
+ACE_Fixed_Set<T, SIZE>::ACE_Fixed_Set (void)
+ : cur_size_ (0),
+ max_size_ (SIZE)
+{
+ ACE_TRACE ("ACE_Fixed_Set<T, SIZE>::ACE_Fixed_Set");
+ for (size_t i = 0; i < this->max_size_; i++)
+ this->search_structure_[i].is_free_ = 1;
+}
+
+template <class T, size_t SIZE> int
+ACE_Fixed_Set<T, SIZE>::find (const T &item) const
+{
+ ACE_TRACE ("ACE_Fixed_Set<T, SIZE>::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 <class T, size_t SIZE> int
+ACE_Fixed_Set<T, SIZE>::insert (const T &item)
+
+{
+ ACE_TRACE ("ACE_Fixed_Set<T, SIZE>::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 <class T, size_t SIZE> int
+ACE_Fixed_Set<T, SIZE>::remove (const T &item)
+{
+ ACE_TRACE ("ACE_Fixed_Set<T, SIZE>::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 <class T, size_t SIZE> void
+ACE_Fixed_Set_Iterator<T, SIZE>::dump (void) const
+{
+ ACE_TRACE ("ACE_Fixed_Set_Iterator<T, SIZE>::dump");
+}
+
+template <class T, size_t SIZE>
+ACE_Fixed_Set_Iterator<T, SIZE>::ACE_Fixed_Set_Iterator (ACE_Fixed_Set<T, SIZE> &s)
+ : s_ (s),
+ next_ (-1)
+{
+ ACE_TRACE ("ACE_Fixed_Set_Iterator<T, SIZE>::ACE_Fixed_Set_Iterator");
+ this->advance ();
+}
+
+template <class T, size_t SIZE> int
+ACE_Fixed_Set_Iterator<T, SIZE>::advance (void)
+{
+ ACE_TRACE ("ACE_Fixed_Set_Iterator<T, SIZE>::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 <class T, size_t SIZE> int
+ACE_Fixed_Set_Iterator<T, SIZE>::next (T *&item)
+{
+ ACE_TRACE ("ACE_Fixed_Set_Iterator<T, SIZE>::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 <class T> void
+ACE_Bounded_Set<T>::dump (void) const
+{
+ ACE_TRACE ("ACE_Bounded_Set<T>::dump");
+}
+
+template <class T>
+ACE_Bounded_Set<T>::~ACE_Bounded_Set (void)
+{
+ ACE_TRACE ("ACE_Bounded_Set<T>::~ACE_Bounded_Set");
+ delete [] this->search_structure_;
+}
+
+template <class T>
+ACE_Bounded_Set<T>::ACE_Bounded_Set (void)
+ : cur_size_ (0),
+ max_size_ (size_t (ACE_Bounded_Set<T>::DEFAULT_SIZE))
+{
+ ACE_TRACE ("ACE_Bounded_Set<T>::ACE_Bounded_Set");
+
+ ACE_NEW (this->search_structure_, ACE_Bounded_Set<T>::Search_Structure[this->max_size_]);
+
+ for (size_t i = 0; i < this->max_size_; i++)
+ this->search_structure_[i].is_free_ = 1;
+}
+
+template <class T>
+ACE_Bounded_Set<T>::ACE_Bounded_Set (size_t size)
+ : cur_size_ (0),
+ max_size_ (size)
+{
+ ACE_TRACE ("ACE_Bounded_Set<T>::ACE_Bounded_Set");
+ ACE_NEW (this->search_structure_, ACE_Bounded_Set<T>::Search_Structure[size]);
+
+ for (size_t i = 0; i < this->max_size_; i++)
+ this->search_structure_[i].is_free_ = 1;
+}
+
+template <class T> int
+ACE_Bounded_Set<T>::find (const T &item) const
+{
+ ACE_TRACE ("ACE_Bounded_Set<T>::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 <class T> int
+ACE_Bounded_Set<T>::insert (const T &item)
+{
+ ACE_TRACE ("ACE_Bounded_Set<T>::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 <class T> int
+ACE_Bounded_Set<T>::remove (const T &item)
+{
+ ACE_TRACE ("ACE_Bounded_Set<T>::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 <class T> void
+ACE_Bounded_Set_Iterator<T>::dump (void) const
+{
+ ACE_TRACE ("ACE_Bounded_Set_Iterator<T>::dump");
+}
+
+template <class T>
+ACE_Bounded_Set_Iterator<T>::ACE_Bounded_Set_Iterator (ACE_Bounded_Set<T> &s)
+ : s_ (s),
+ next_ (-1)
+{
+ ACE_TRACE ("ACE_Bounded_Set_Iterator<T>::ACE_Bounded_Set_Iterator");
+ this->advance ();
+}
+
+template <class T> int
+ACE_Bounded_Set_Iterator<T>::advance (void)
+{
+ ACE_TRACE ("ACE_Bounded_Set_Iterator<T>::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 <class T> int
+ACE_Bounded_Set_Iterator<T>::next (T *&item)
+{
+ ACE_TRACE ("ACE_Bounded_Set_Iterator<T>::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 T>
+class ACE_Set_Node
+{
+friend class ACE_Unbounded_Set<T>;
+friend class ACE_Unbounded_Set_Iterator<T>;
+public:
+ // = Initialization methods
+ ACE_Set_Node (const T &i, ACE_Set_Node<T> *n);
+ ACE_Set_Node (ACE_Set_Node<T> *n = 0);
+ ACE_Set_Node (const ACE_Set_Node<T> &n);
+
+private:
+ ACE_Set_Node<T> *next_;
+ // Pointer to next element in the list of ACE_Set_Nodes.
+
+ T item_;
+ // Current value of the item in this node.
+};
+
+template <class T>
+ACE_Set_Node<T>::ACE_Set_Node (const T &i, ACE_Set_Node<T> *n)
+ : next_ (n),
+ item_ (i)
+{
+// ACE_TRACE ("ACE_Set_Node<T>::ACE_Set_Node");
+}
+
+template <class T>
+ACE_Set_Node<T>::ACE_Set_Node (ACE_Set_Node<T> *n)
+ : next_ (n)
+{
+// ACE_TRACE ("ACE_Set_Node<T>::ACE_Set_Node");
+}
+
+template <class T>
+ACE_Set_Node<T>::ACE_Set_Node (const ACE_Set_Node<T> &s)
+ : next_ (s.next_),
+ item_ (s.item_)
+{
+// ACE_TRACE ("ACE_Set_Node<T>::ACE_Set_Node");
+}
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Unbounded_Set)
+
+template <class T> void
+ACE_Unbounded_Set<T>::dump (void) const
+{
+// ACE_TRACE ("ACE_Unbounded_Set<T>::dump");
+}
+
+template <class T>
+ACE_Unbounded_Set<T>::~ACE_Unbounded_Set (void)
+{
+// ACE_TRACE ("ACE_Unbounded_Set<T>::~ACE_Unbounded_Set");
+ while (this->head_ != 0)
+ {
+ ACE_Set_Node<T> *temp = this->head_;
+ this->head_ = this->head_->next_;
+ this->cur_size_--;
+ delete temp;
+ }
+}
+
+template <class T> int
+ACE_Unbounded_Set<T>::find (const T &item) const
+{
+// ACE_TRACE ("ACE_Unbounded_Set<T>::find");
+ for (ACE_Set_Node<T> *temp = this->head_;
+ temp != 0;
+ temp = temp->next_)
+ if (temp->item_ == item)
+ return 1;
+
+ return 0;
+}
+
+template <class T>
+ACE_Unbounded_Set<T>::ACE_Unbounded_Set (void)
+ : head_ (0),
+ cur_size_ (0)
+{
+// ACE_TRACE ("ACE_Unbounded_Set<T>::ACE_Unbounded_Set");
+}
+
+template <class T> int
+ACE_Unbounded_Set<T>::insert (const T &item)
+{
+// ACE_TRACE ("ACE_Unbounded_Set<T>::insert");
+ if (this->find (item) == 0)
+ {
+ ACE_NEW_RETURN (this->head_, ACE_Set_Node<T> (item, this->head_), -1);
+ this->cur_size_++;
+ return 0;
+ }
+ else
+ return 1;
+}
+
+template <class T> int
+ACE_Unbounded_Set<T>::remove (const T &item)
+{
+// ACE_TRACE ("ACE_Unbounded_Set<T>::remove");
+ ACE_Set_Node<T> *prev = 0;
+ ACE_Set_Node<T> *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 <class T> void
+ACE_Unbounded_Set_Iterator<T>::dump (void) const
+{
+// ACE_TRACE ("ACE_Unbounded_Set_Iterator<T>::dump");
+}
+
+template <class T>
+ACE_Unbounded_Set_Iterator<T>::ACE_Unbounded_Set_Iterator (ACE_Unbounded_Set<T> &s)
+ : current_ (s.head_)
+{
+// ACE_TRACE ("ACE_Unbounded_Set_Iterator<T>::ACE_Unbounded_Set_Iterator");
+}
+
+template <class T> int
+ACE_Unbounded_Set_Iterator<T>::advance (void)
+{
+// ACE_TRACE ("ACE_Unbounded_Set_Iterator<T>::advance");
+ this->current_ = this->current_->next_;
+ return 1;
+}
+
+template <class T> int
+ACE_Unbounded_Set_Iterator<T>::next (T *&item)
+{
+// ACE_TRACE ("ACE_Unbounded_Set_Iterator<T>::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 T> class ACE_Unbounded_Set;
+
+// "Cheshire cat"
+template <class T> class ACE_Set_Node;
+
+template <class T>
+class ACE_Unbounded_Set_Iterator
+ // = TITLE
+ // Implement an iterator over an unbounded set.
+{
+public:
+ // = Initialization method.
+ ACE_Unbounded_Set_Iterator (ACE_Unbounded_Set<T> &s);
+
+ // = Iteration methods.
+
+ int next (T *&next_item);
+ // Pass back the <next_item> 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<T> *current_;
+};
+
+// Forward declaration (use the "Cheshire Cat" approach to information
+// hiding).
+template <class T>
+class ACE_Set_Node;
+
+template <class T>
+class ACE_Unbounded_Set
+ // = TITLE
+ // Implement a simple unordered set of <T> 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<T>;
+public:
+ // = Initialization and termination methods.
+ ACE_Unbounded_Set (void);
+ ~ACE_Unbounded_Set (void);
+
+ // = Classic unordered set operations.
+ int insert (const T &new_item);
+ // Insert <new_item> 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 <item> 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 <item> 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<T> *head_;
+ // Head of the linked list of Nodes.
+
+ size_t cur_size_;
+ // Current size of the set.
+};
+
+// Forward declaration.
+template <class T, size_t SIZE>
+class ACE_Fixed_Set;
+
+template <class T, size_t SIZE>
+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<T, SIZE> &s);
+
+ // = Iteration methods.
+
+ int next (T *&next_item);
+ // Pass back the <next_item> 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<T, SIZE> &s_;
+ // Set we are iterating over.
+
+ ssize_t next_;
+ // How far we've advanced over the set.
+};
+
+template <class T, size_t SIZE>
+class ACE_Fixed_Set
+ // = TITLE
+ // Implement a simple unordered set of <T> with maximum <SIZE>.
+ //
+ // = DESCRIPTION
+ // This implementation of an unordered set uses a fixed array.
+ // This implementation does not allow duplicates...
+{
+friend class ACE_Fixed_Set_Iterator<T, SIZE>;
+public:
+ // = Initialization and termination methods.
+ ACE_Fixed_Set (void);
+ ~ACE_Fixed_Set (void);
+
+ // = Classic unordered set operations.
+ int insert (const T &new_item);
+ // Insert <new_item> 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 <item> 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 <item> 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 T>
+class ACE_Bounded_Set;
+
+template <class T>
+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<T> &s);
+
+ // = Iteration methods.
+
+ int next (T *&next_item);
+ // Pass back the <next_item> 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<T> &s_;
+ // Set we are iterating over.
+
+ ssize_t next_;
+ // How far we've advanced over the set.
+};
+
+template <class T>
+class ACE_Bounded_Set
+ // = TITLE
+ // Implement a simple unordered set of <T> 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<T>;
+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 <new_item> 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 <item> 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 <item> 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 <class T, size_t SIZE> ACE_INLINE size_t
+ACE_Fixed_Set<T, SIZE>::size (void) const
+{
+ return this->cur_size_;
+}
+
+template <class T> ACE_INLINE size_t
+ACE_Bounded_Set<T>::size (void) const
+{
+ ACE_TRACE ("ACE_Bounded_Set<T>::size");
+ return this->cur_size_;
+}
+
+template <class T> ACE_INLINE size_t
+ACE_Unbounded_Set<T>::size (void) const
+{
+// ACE_TRACE ("ACE_Unbounded_Set<T>::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 <ACE_Malloc> 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 <size> bytes.
+
+ virtual int free (void *p);
+ // Free a chuck of memory allocated by <ACE_Shared_Memory_MM::malloc>.
+
+ 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 <size> bytes.
+
+ virtual int free (void *p);
+ // Free a chuck of memory allocated by <ACE_Shared_Memory_SV::malloc>.
+
+ 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<ACE_Recursive_Thread_Mutex> 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<ACE_Recursive_Thread_Mutex> 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<ACE_Recursive_Thread_Mutex> 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<ACE_Recursive_Thread_Mutex> 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<ACE_Recursive_Thread_Mutex> 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<ACE_Recursive_Thread_Mutex> 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<ACE_Recursive_Thread_Mutex> 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
+// <remove_handler> 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_Event_Handler *, ACE_MAX_SIGNAL_HANDLERS>
+ ACE_SIG_HANDLERS_SET;
+typedef ACE_Fixed_Set_Iterator <ACE_Event_Handler *, ACE_MAX_SIGNAL_HANDLERS>
+ 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<ACE_Recursive_Thread_Mutex> 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 <signum>.
+// Install the new disposition (if given) and return the previous
+// disposition (if desired by the caller). Returns 0 on success and
+// -1 if <signum> 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<ACE_Recursive_Thread_Mutex> 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., <sigkey> == -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<ACE_Recursive_Thread_Mutex> 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<ACE_Event_Handler *, ACE_MAX_SIGNAL_HANDLERS>;
+template class ACE_Fixed_Set_Iterator<ACE_Event_Handler *, ACE_MAX_SIGNAL_HANDLERS>;
+#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 <signo> to the set.
+
+ int sig_del (int signo);
+ // Deletes the individual signal specified by <signo> from the set.
+
+ int is_member (int signo) const;
+ // Checks whether the signal specified by <signo> 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 <this> as the current disposition and store old
+ // disposition into <oaction> if it is non-NULL.
+
+ int restore_action (int signum, ACE_Sig_Action &oaction);
+ // Assign the value of <oaction> to <this> and make it become the
+ // new signal disposition.
+
+ int retrieve_action (int signum);
+ // Retrieve the current disposition into <this>.
+
+ // = 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 <ACE_Event_Handler>
+ // with the <ACE_Sig_Handler> in order to handle a designated
+ // <signum>. When a signal occurs that corresponds to this
+ // <signum>, the <handle_signal> method of the registered
+ // <ACE_Event_Handler> 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 <ACE_Event_Handler> and a new sigaction associated with
+ // <signum>. 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 <ACE_Event_Handler> currently associated with
+ // <signum>. <sigkey> 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 <signum>
+ // 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 <sig_pending_> 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 <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>.
+ // 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 <ACE_Reactor>.
+
+{
+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
+ // <ACE_Reactor>'s internal table.
+
+ virtual int handle_signal (int, siginfo_t *, ucontext_t *);
+ // Called by the <Reactor> 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
+ // <ACE_Sig_Action> 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 <signum>. When a signal occurs that
+ // corresponds to this <signum>, the <handle_signal> 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
+ // <signum>. Passes back the existing ACE_Event_Handler and its
+ // sigaction if pointers are non-zero. Returns -1 on failure and
+ // a <sigkey> 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 <signum>.
+ // Install the new disposition (if given) and return the previous
+ // disposition (if desired by the caller). Returns 0 on success and
+ // -1 if <signum> 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 <signum>
+
+ 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
+ // <remove_handler> 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 <class TYPE, class LOCK> void
+ACE_Singleton<TYPE, LOCK>::dump (void) const
+{
+ ACE_TRACE ("ACE_Singleton<TYPE, LOCK>::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 <class TYPE, class LOCK> TYPE *
+ACE_Singleton<TYPE, LOCK>::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<TYPE, LOCK>::instance_ == 0)
+ {
+ ACE_GUARD_RETURN (LOCK, ace_mon, (ACE_Singleton<TYPE, LOCK>::ace_singleton_lock_), 0);
+
+ if (ACE_Singleton<TYPE, LOCK>::instance_ == 0)
+ ACE_NEW_RETURN ((ACE_Singleton<TYPE, LOCK>::instance_), TYPE, 0);
+ }
+
+ return ACE_Singleton<TYPE, LOCK>::instance_;
+
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+
+}
+
+#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+// Pointer to the Singleton instance.
+template <class TYPE, class LOCK> TYPE *
+ACE_Singleton<TYPE, LOCK>::instance_ = 0;
+
+// Lock the creation of the singleton.
+template <class TYPE, class LOCK> LOCK
+ACE_Singleton<TYPE, LOCK>::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 TYPE, class LOCK>
+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 <class T> void
+ACE_Bounded_Stack<T>::dump (void) const
+{
+ ACE_TRACE ("ACE_Bounded_Stack<T>::dump");
+}
+
+template<class T>
+ACE_Bounded_Stack<T>::ACE_Bounded_Stack (size_t size)
+ : top_ (0),
+ size_ (size)
+{
+ ACE_NEW (this->stack_, T[size]);
+
+ ACE_TRACE ("ACE_Bounded_Stack<T>::ACE_Bounded_Stack");
+}
+
+template<class T>
+ACE_Bounded_Stack<T>::ACE_Bounded_Stack (const ACE_Bounded_Stack<T> &s)
+ : top_ (s.top_),
+ size_ (s.size_)
+{
+ ACE_NEW (this->stack_, T[s.size_]);
+
+ ACE_TRACE ("ACE_Bounded_Stack<T>::ACE_Bounded_Stack");
+
+ for (size_t i = 0; i < this->top_; i++)
+ this->stack_[i] = s.stack_[i];
+}
+
+template<class T> void
+ACE_Bounded_Stack<T>::operator= (const ACE_Bounded_Stack<T> &s)
+{
+ ACE_TRACE ("ACE_Bounded_Stack<T>::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<class T>
+ACE_Bounded_Stack<T>::~ACE_Bounded_Stack (void)
+{
+ ACE_TRACE ("ACE_Bounded_Stack<T>::~ACE_Bounded_Stack");
+ delete [] this->stack_;
+}
+
+// ----------------------------------------
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Fixed_Stack)
+
+template <class T, size_t SIZE> void
+ACE_Fixed_Stack<T, SIZE>::dump (void) const
+{
+ ACE_TRACE ("ACE_Fixed_Stack<T, SIZE>::dump");
+}
+
+template<class T, size_t SIZE>
+ACE_Fixed_Stack<T, SIZE>::ACE_Fixed_Stack (void)
+ : top_ (0),
+ size_ (SIZE)
+{
+ ACE_TRACE ("ACE_Fixed_Stack<T, SIZE>::ACE_Fixed_Stack");
+}
+
+template<class T, size_t SIZE>
+ACE_Fixed_Stack<T, SIZE>::ACE_Fixed_Stack (const ACE_Fixed_Stack<T, SIZE> &s)
+ : top_ (s.top_),
+ size_ (s.size_)
+{
+ ACE_TRACE ("ACE_Fixed_Stack<T, SIZE>::ACE_Fixed_Stack");
+ for (size_t i = 0; i < this->top_; i++)
+ this->stack_[i] = s.stack_[i];
+}
+
+template<class T, size_t SIZE> void
+ACE_Fixed_Stack<T, SIZE>::operator= (const ACE_Fixed_Stack<T, SIZE> &s)
+{
+ ACE_TRACE ("ACE_Fixed_Stack<T, SIZE>::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<class T, size_t SIZE>
+ACE_Fixed_Stack<T, SIZE>::~ACE_Fixed_Stack (void)
+{
+ ACE_TRACE ("ACE_Fixed_Stack<T, SIZE>::~ACE_Fixed_Stack");
+ delete [] this->stack_;
+}
+
+//----------------------------------------
+
+template<class T>
+class ACE_Stack_Node
+{
+friend class ACE_Unbounded_Stack<T>;
+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<T> *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<T> *n);
+ ACE_Stack_Node (void);
+
+ ACE_Stack_Node<T> *next_;
+ T item_;
+};
+
+#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+/* static */
+template<class T> ACE_Stack_Node<T> *
+ACE_Stack_Node<T>::free_list_ = 0;
+
+template<class T> void *
+ACE_Stack_Node<T>::operator new (size_t bytes)
+{
+ ACE_TRACE ("ACE_Stack_Node<T>::operator new");
+ ACE_Stack_Node<T> *temp = ACE_Stack_Node<T>::free_list_;
+
+ if (temp)
+ ACE_Stack_Node<T>::free_list_ = ACE_Stack_Node<T>::free_list_->next_;
+ else
+ temp = (ACE_Stack_Node<T> *) new char[bytes];
+
+ return temp;
+}
+
+template<class T> void
+ACE_Stack_Node<T>::operator delete (void *ptr)
+{
+ ACE_TRACE ("ACE_Stack_Node<T>::operator delete");
+ ((ACE_Stack_Node<T> *) ptr)->next_ = ACE_Stack_Node<T>::free_list_;
+ ACE_Stack_Node<T>::free_list_ = (ACE_Stack_Node<T> *) ptr;
+}
+
+template<class T> void
+ACE_Stack_Node<T>::free_all_nodes (void)
+{
+ ACE_TRACE ("ACE_Stack_Node<T>::free_all_nodes");
+
+ while (ACE_Stack_Node<T>::free_list_)
+ {
+ ACE_Stack_Node<T> *temp = ACE_Stack_Node<T>::free_list_;
+ ACE_Stack_Node<T>::free_list_ = ACE_Stack_Node<T>::free_list_->next_;
+ ::delete temp;
+ }
+}
+
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+
+template<class T>
+ACE_Stack_Node<T>::ACE_Stack_Node (T i, ACE_Stack_Node<T> *n)
+ : next_ (n),
+ item_ (i)
+{
+ ACE_TRACE ("ACE_Stack_Node<T>::ACE_Stack_Node");
+}
+
+template<class T>
+ACE_Stack_Node<T>::ACE_Stack_Node (void)
+ : next_ (0)
+{
+ ACE_TRACE ("ACE_Stack_Node<T>::ACE_Stack_Node");
+}
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Unbounded_Stack)
+
+template <class T> void
+ACE_Unbounded_Stack<T>::dump (void) const
+{
+ ACE_TRACE ("ACE_Unbounded_Stack<T>::dump");
+}
+
+template<class T>
+ACE_Unbounded_Stack<T>::ACE_Unbounded_Stack (void)
+ : head_ (0)
+{
+ ACE_NEW (this->last_resort_, ACE_Stack_Node<T>);
+ ACE_TRACE ("ACE_Unbounded_Stack<T>::ACE_Unbounded_Stack");
+}
+
+template<class T> void
+ACE_Unbounded_Stack<T>::delete_all_nodes (void)
+{
+ ACE_TRACE ("ACE_Unbounded_Stack<T>::delete_all_nodes");
+ while (this->head_ != 0)
+ {
+ ACE_Stack_Node<T> *temp = this->head_;
+ this->head_ = this->head_->next_;
+ delete temp;
+ }
+
+ delete this->last_resort_;
+ this->last_resort_ = 0;
+}
+
+template<class T> void
+ACE_Unbounded_Stack<T>::copy_all_nodes (const ACE_Unbounded_Stack<T> &s)
+{
+ ACE_TRACE ("ACE_Unbounded_Stack<T>::copy_all_nodes");
+ // Push all of <s>'s nodes onto our stack (this puts them in the
+ // reverse order).
+ ACE_Stack_Node<T> *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<T> *prev = 0;
+
+ for (temp = this->head_; temp != 0; )
+ {
+ ACE_Stack_Node<T> *next = temp->next_;
+
+ temp->next_ = prev;
+ prev = temp;
+ temp = next;
+ }
+
+ this->head_ = prev;
+}
+
+template<class T>
+ACE_Unbounded_Stack<T>::ACE_Unbounded_Stack (const ACE_Unbounded_Stack<T> &s)
+ : head_ (0)
+{
+ ACE_NEW (this->last_resort_, ACE_Stack_Node<T>);
+
+ ACE_TRACE ("ACE_Unbounded_Stack<T>::ACE_Unbounded_Stack");
+ this->copy_all_nodes (s);
+}
+
+template<class T> void
+ACE_Unbounded_Stack<T>::operator= (const ACE_Unbounded_Stack<T> &s)
+{
+ ACE_TRACE ("ACE_Unbounded_Stack<T>::operator=");
+ if (this == &s)
+ return;
+
+ this->delete_all_nodes ();
+ this->copy_all_nodes (s);
+}
+
+template<class T>
+ACE_Unbounded_Stack<T>::~ACE_Unbounded_Stack (void)
+{
+ ACE_TRACE ("ACE_Unbounded_Stack<T>::~ACE_Unbounded_Stack");
+ this->delete_all_nodes ();
+}
+
+template<class T> void
+ACE_Unbounded_Stack<T>::push (const T &new_item)
+{
+ ACE_TRACE ("ACE_Unbounded_Stack<T>::push");
+
+ ACE_Stack_Node<T> *temp = new ACE_Stack_Node<T> (new_item, this->head_);
+
+ if (temp == 0)
+ {
+ temp = this->last_resort_;
+ this->last_resort_ = 0;
+ }
+
+ this->head_ = temp;
+}
+
+template<class T> void
+ACE_Unbounded_Stack<T>::pop (T &item)
+{
+ ACE_TRACE ("ACE_Unbounded_Stack<T>::pop");
+ item = this->head_->item_;
+ ACE_Stack_Node<T> *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<class T> void
+ACE_Unbounded_Stack<T>::delete_free_list (void)
+{
+ ACE_TRACE ("ACE_Unbounded_Stack<T>::delete_free_list");
+#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES)
+ ACE_Stack_Node<T>::free_all_nodes ();
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+}
+
+template<class T>
+class ACE_Queue_Node
+{
+friend class ACE_Unbounded_Queue<T>;
+ ACE_Queue_Node (T i, ACE_Queue_Node<T> *n);
+
+ ACE_Queue_Node<T> *next_;
+ T item_;
+};
+
+template<class T>
+ACE_Queue_Node<T>::ACE_Queue_Node (T i, ACE_Queue_Node<T> *n)
+ : next_ (n),
+ item_ (i)
+{
+ ACE_TRACE ("ACE_Queue_Node<T>::ACE_Queue_Node");
+}
+
+template <class TYPE>
+ACE_Unbounded_Queue<TYPE>::ACE_Unbounded_Queue (void)
+ : head_ (0),
+ tail_ (0),
+ cur_size_ (0)
+{
+ ACE_TRACE ("ACE_Unbounded_Queue<TYPE>::ACE_Unbounded_Queue (void)");
+}
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Unbounded_Queue)
+
+template <class TYPE> void
+ACE_Unbounded_Queue<TYPE>::dump (void) const
+{
+ ACE_TRACE ("ACE_Unbounded_Queue<TYPE>::dump");
+}
+
+template <class TYPE>
+ACE_Unbounded_Queue<TYPE>::~ACE_Unbounded_Queue (void)
+{
+ ACE_TRACE ("ACE_Unbounded_Queue<TYPE>::~ACE_Unbounded_Queue (void)");
+ ACE_Queue_Node<TYPE> *temp = head_;
+ while (temp != 0)
+ {
+ head_ = head_->next_;
+ delete temp;
+ temp = head_;
+ this->cur_size_--;
+ }
+}
+
+template <class TYPE> int
+ACE_Unbounded_Queue<TYPE>::enqueue (const TYPE &new_item)
+{
+ ACE_TRACE ("ACE_Unbounded_Queue<TYPE>::enqueue (const TYPE& new_item)");
+
+ ACE_Queue_Node<TYPE> *temp = new ACE_Queue_Node<TYPE> (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 <class TYPE> int
+ACE_Unbounded_Queue<TYPE>::dequeue (TYPE &item)
+{
+ ACE_TRACE ("ACE_Unbounded_Queue<TYPE>::dequeue (TYPE *&item)");
+
+ if (head_ == 0)
+ return -1;
+
+ item = head_->item_;
+ ACE_Queue_Node<TYPE> *temp = head_;
+ head_ = head_->next_;
+ delete temp;
+ --this->cur_size_;
+ return 0;
+}
+
+template <class TYPE> int
+ACE_Unbounded_Queue<TYPE>::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 T>
+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<T> &s);
+ // The copy constructor (performs initialization).
+
+ void operator= (const ACE_Bounded_Stack<T> &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 T, size_t SIZE>
+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<T, SIZE> &s);
+ // The copy constructor (performs initialization).
+
+ void operator= (const ACE_Fixed_Stack<T, SIZE> &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 T>
+class ACE_Stack_Node;
+
+template <class T>
+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<T> &s);
+ // The copy constructor (performs initialization).
+
+ void operator= (const ACE_Unbounded_Stack<T> &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<T> &s);
+ // Copy all nodes from <s> to <this>.
+
+ ACE_Stack_Node<T> *head_;
+ // Head of the linked list of Nodes.
+
+ ACE_Stack_Node<T> *last_resort_;
+ // Use this node when all memory is exhausted...
+};
+
+// Forward declaration (use the "Cheshire Cat" approach to information
+// hiding).
+template <class T>
+class ACE_Queue_Node;
+
+template <class TYPE>
+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<TYPE> *head_;
+ // Head of the Queue.
+
+ ACE_Queue_Node<TYPE> *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 <class T> ACE_INLINE void
+ACE_Bounded_Stack<T>::push (const T &new_item)
+{
+ ACE_TRACE ("ACE_Bounded_Stack<T>::push");
+ this->stack_[this->top_++] = new_item;
+}
+
+template <class T> ACE_INLINE void
+ACE_Bounded_Stack<T>::pop (T &item)
+{
+ ACE_TRACE ("ACE_Bounded_Stack<T>::pop");
+ item = this->stack_[--this->top_];
+}
+
+template <class T> ACE_INLINE void
+ACE_Bounded_Stack<T>::top (T &item) const
+{
+ ACE_TRACE ("ACE_Bounded_Stack<T>::top");
+ item = this->stack_[this->top_ - 1];
+}
+
+template <class T> ACE_INLINE int
+ACE_Bounded_Stack<T>::is_empty (void) const
+{
+ ACE_TRACE ("ACE_Bounded_Stack<T>::is_empty");
+ return this->top_ == 0;
+}
+
+template <class T> ACE_INLINE int
+ACE_Bounded_Stack<T>::is_full (void) const
+{
+ ACE_TRACE ("ACE_Bounded_Stack<T>::is_full");
+ return this->top_ >= this->size_;
+}
+
+//----------------------------------------
+
+template <class T, size_t SIZE> ACE_INLINE void
+ACE_Fixed_Stack<T, SIZE>::push (const T &new_item)
+{
+ ACE_TRACE ("ACE_Fixed_Stack<T, SIZE>::push");
+ this->stack_[this->top_++] = new_item;
+}
+
+template <class T, size_t SIZE> ACE_INLINE void
+ACE_Fixed_Stack<T, SIZE>::pop (T &item)
+{
+ ACE_TRACE ("ACE_Fixed_Stack<T, SIZE>::pop");
+ item = this->stack_[--this->top_];
+}
+
+template <class T, size_t SIZE> ACE_INLINE void
+ACE_Fixed_Stack<T, SIZE>::top (T &item) const
+{
+ ACE_TRACE ("ACE_Fixed_Stack<T, SIZE>::top");
+ item = this->stack_[this->top_ - 1];
+}
+
+template <class T, size_t SIZE> ACE_INLINE int
+ACE_Fixed_Stack<T, SIZE>::is_empty (void) const
+{
+ ACE_TRACE ("ACE_Fixed_Stack<T, SIZE>::is_empty");
+ return this->top_ == 0;
+}
+
+template <class T, size_t SIZE> ACE_INLINE int
+ACE_Fixed_Stack<T, SIZE>::is_full (void) const
+{
+ ACE_TRACE ("ACE_Fixed_Stack<T, SIZE>::is_full");
+ return this->top_ >= this->size_;
+}
+
+//----------------------------------------
+
+template <class T> ACE_INLINE void
+ACE_Unbounded_Stack<T>::top (T &item) const
+{
+ ACE_TRACE ("ACE_Unbounded_Stack<T>::top");
+ item = this->head_->item_;
+}
+
+template <class T> ACE_INLINE int
+ACE_Unbounded_Stack<T>::is_empty (void) const
+{
+ ACE_TRACE ("ACE_Unbounded_Stack<T>::is_empty");
+ return this->head_ == 0;
+}
+
+template <class T> ACE_INLINE int
+ACE_Unbounded_Stack<T>::is_full (void) const
+{
+ ACE_TRACE ("ACE_Unbounded_Stack<T>::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 <class SH> void
+ACE_Singleton_Strategy<SH>::dump (void) const
+{
+ ACE_TRACE ("ACE_Singleton_Strategy<SH>::dump");
+}
+
+template <class SH> int
+ACE_Singleton_Strategy<SH>::open (SVC_HANDLER *sh,
+ ACE_Thread_Manager *)
+{
+ ACE_TRACE ("ACE_Singleton_Strategy<SH>::open");
+ if (this->svc_handler_ != 0)
+ delete this->svc_handler_;
+
+ this->svc_handler_ = sh;
+ return 0;
+}
+
+template <class SH>
+ACE_Singleton_Strategy<SH>::ACE_Singleton_Strategy (SVC_HANDLER *sh,
+ ACE_Thread_Manager *tm)
+ : svc_handler_ (0)
+{
+ ACE_TRACE ("ACE_Singleton_Strategy<SH>::ACE_Singleton_Strategy");
+ this->open (sh, tm);
+}
+
+template <class SH>
+ACE_Singleton_Strategy<SH>::~ACE_Singleton_Strategy (void)
+{
+ ACE_TRACE ("ACE_Singleton_Strategy<SH>::~ACE_Singleton_Strategy");
+ delete this->svc_handler_;
+}
+
+// Create a Singleton SVC_HANDLER by always returning the same
+// SVC_HANDLER.
+
+template <class SH> SVC_HANDLER *
+ACE_Singleton_Strategy<SH>::make_svc_handler (void)
+{
+ ACE_TRACE ("ACE_Singleton_Strategy<SH>::make_svc_handler");
+ return this->svc_handler_;
+}
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Creation_Strategy)
+
+template <class SH> void
+ACE_Creation_Strategy<SH>::dump (void) const
+{
+ ACE_TRACE ("ACE_Creation_Strategy<SH>::dump");
+}
+
+template <class SH> int
+ACE_Creation_Strategy<SH>::open (ACE_Thread_Manager *thr_mgr)
+{
+ ACE_TRACE ("ACE_Creation_Strategy<SH>::open");
+ this->thr_mgr_ = thr_mgr;
+ return 0;
+}
+
+
+template <class SH>
+ACE_Creation_Strategy<SH>::ACE_Creation_Strategy (ACE_Thread_Manager *thr_mgr)
+{
+ ACE_TRACE ("ACE_Creation_Strategy<SH>::ACE_Creation_Strategy");
+ this->open (thr_mgr);
+}
+
+// Default behavior is to make a new SVC_HANDLER, passing in the
+// Thread_Manager (if any).
+
+template <class SH> SH *
+ACE_Creation_Strategy<SH>::make_svc_handler (void)
+{
+ ACE_TRACE ("ACE_Creation_Strategy<SH>::make_svc_handler");
+ return new SH (this->thr_mgr_);
+}
+
+template <class SH>
+ACE_Creation_Strategy<SH>::~ACE_Creation_Strategy (void)
+{
+ ACE_TRACE ("ACE_Creation_Strategy<SH>::~ACE_Creation_Strategy");
+}
+
+ACE_ALLOC_HOOK_DEFINE(ACE_DLL_Strategy)
+
+template <class SH> void
+ACE_DLL_Strategy<SH>::dump (void) const
+{
+ ACE_TRACE ("ACE_DLL_Strategy<SH>::dump");
+}
+
+template <class SH> int
+ACE_DLL_Strategy<SH>::open (const char svc_dll_info[],
+ ACE_Service_Config *svc_config,
+ ACE_Thread_Manager *thr_mgr)
+{
+ ACE_TRACE ("ACE_DLL_Strategy<SH>::open");
+ this->inherited::open (thr_mgr);
+ this->svc_config_ = svc_config;
+ return 0;
+}
+
+template <class SH>
+ACE_DLL_Strategy<SH>::ACE_DLL_Strategy (const char svc_dll_info[],
+ ACE_Service_Config *sc,
+ ACE_Thread_Manager *thr_mgr)
+{
+ ACE_TRACE ("ACE_DLL_Strategy<SH>::ACE_DLL_Strategy");
+ if (this->open (svc_dll_info, sc, thr_mgr) == -1)
+ ACE_ERROR ((LM_ERROR, "%p\n", "open"));
+}
+
+template <class SH>
+ACE_DLL_Strategy<SH>::ACE_DLL_Strategy (void)
+{
+ ACE_TRACE ("ACE_DLL_Strategy<SH>::ACE_DLL_Strategy");
+}
+
+// Create a SVC_HANDLER by dynamically linking it from a DLL.
+
+template <class SH> SH *
+ACE_DLL_Strategy<SH>::make_svc_handler (void)
+{
+ ACE_TRACE ("ACE_DLL_Strategy<SH>::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 <class SH> void
+ACE_Concurrency_Strategy<SH>::dump (void) const
+{
+ ACE_TRACE ("ACE_Concurrency_Strategy<SH>::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 <class SH> int
+ACE_Concurrency_Strategy<SH>::activate_svc_handler (SH *svc_handler,
+ void *arg)
+{
+ ACE_TRACE ("ACE_Concurrency_Strategy<SH>::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 <class SH>
+ACE_Concurrency_Strategy<SH>::~ACE_Concurrency_Strategy (void)
+{
+ ACE_TRACE ("ACE_Concurrency_Strategy<SH>::~ACE_Concurrency_Strategy");
+}
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Strategy)
+
+template <class SH> void
+ACE_Thread_Strategy<SH>::dump (void) const
+{
+ ACE_TRACE ("ACE_Thread_Strategy<SH>::dump");
+}
+
+template <class SH> int
+ACE_Thread_Strategy<SH>::open (ACE_Thread_Manager *thr_mgr,
+ long thr_flags,
+ int n_threads)
+{
+ ACE_TRACE ("ACE_Thread_Strategy<SH>::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 <class SH>
+ACE_Thread_Strategy<SH>::ACE_Thread_Strategy (ACE_Thread_Manager *thr_mgr,
+ long thr_flags,
+ int n_threads)
+{
+ ACE_TRACE ("ACE_Thread_Strategy<SH>::ACE_Thread_Strategy");
+ this->open (thr_mgr, thr_flags, n_threads);
+}
+
+template <class SH>
+ACE_Thread_Strategy<SH>::ACE_Thread_Strategy (void)
+{
+ ACE_TRACE ("ACE_Thread_Strategy<SH>::ACE_Thread_Strategy");
+}
+
+template <class SH>
+ACE_Thread_Strategy<SH>::~ACE_Thread_Strategy (void)
+{
+ ACE_TRACE ("ACE_Thread_Strategy<SH>::~ACE_Thread_Strategy");
+}
+
+template <class SH> int
+ACE_Thread_Strategy<SH>::activate_svc_handler (SH *svc_handler,
+ void *arg)
+{
+ ACE_TRACE ("ACE_Thread_Strategy<SH>::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 <svc_handler> 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 <class SH, PR_AC_1> void
+ACE_Accept_Strategy<SH, PR_AC_2>::dump (void) const
+{
+ ACE_TRACE ("ACE_Accept_Strategy<SH, PR_AC_2>::dump");
+}
+
+template <class SH, PR_AC_1> int
+ACE_Accept_Strategy<SH, PR_AC_2>::open (const PR_AD &local_addr,
+ int restart)
+{
+ ACE_TRACE ("ACE_Accept_Strategy<SH, PR_AC_2>::open");
+ return this->peer_acceptor_.open (local_addr, restart);
+}
+
+template <class SH, PR_AC_1>
+ACE_Accept_Strategy<SH, PR_AC_2>::ACE_Accept_Strategy (const PR_AD &local_addr,
+ int restart)
+{
+ ACE_TRACE ("ACE_Accept_Strategy<SH, PR_AC_2>::ACE_Accept_Strategy");
+ if (this->open (local_addr, restart) == -1)
+ ACE_ERROR ((LM_ERROR, "%p\n", "open"));
+}
+
+template <class SH, PR_AC_1>
+ACE_Accept_Strategy<SH, PR_AC_2>::ACE_Accept_Strategy (void)
+{
+ ACE_TRACE ("ACE_Accept_Strategy<SH, PR_AC_2>::ACE_Accept_Strategy");
+}
+
+template <class SH, PR_AC_1> int
+ACE_Accept_Strategy<SH, PR_AC_2>::accept_svc_handler (SH *svc_handler)
+{
+ ACE_TRACE ("ACE_Accept_Strategy<SH, PR_AC_2>::accept_svc_handler");
+ if (this->peer_acceptor_.accept (*svc_handler) == -1)
+ {
+ svc_handler->close (0);
+ return -1;
+ }
+ else
+ return 0;
+}
+
+template <class SH, PR_AC_1> ACE_HANDLE
+ACE_Accept_Strategy<SH, PR_AC_2>::get_handle (void) const
+{
+ ACE_TRACE ("ACE_Accept_Strategy<SH, PR_AC_2>::get_handle");
+ return this->peer_acceptor_.get_handle ();
+}
+
+template <class SH, PR_AC_1> ACE_PEER_ACCEPTOR &
+ACE_Accept_Strategy<SH, PR_AC_2>::acceptor (void) const
+{
+ ACE_TRACE ("ACE_Accept_Strategy<SH, PR_AC_2>::acceptor");
+ return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_;
+}
+
+template <class SH, PR_AC_1>
+ACE_Accept_Strategy<SH, PR_AC_2>::~ACE_Accept_Strategy (void)
+{
+ ACE_TRACE ("ACE_Accept_Strategy<SH, PR_AC_2>::~ACE_Accept_Strategy");
+ if (this->peer_acceptor_.close () == -1)
+ ACE_ERROR ((LM_ERROR, "%p\n", "close"));
+}
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Process_Strategy)
+
+template <class SH> void
+ACE_Process_Strategy<SH>::dump (void) const
+{
+ ACE_TRACE ("ACE_Process_Strategy<SH>::dump");
+}
+
+template <class SH> int
+ACE_Process_Strategy<SH>::open (int n_processes)
+{
+ ACE_TRACE ("ACE_Process_Strategy<SH>::open");
+ this->n_processes_ = n_processes;
+
+ return 0;
+}
+
+template <class SH>
+ACE_Process_Strategy<SH>::ACE_Process_Strategy (int n_processes)
+{
+ ACE_TRACE ("ACE_Process_Strategy<SH>::ACE_Process_Strategy");
+ this->open (thr_mgr, thr_flags, n_threads);
+}
+
+template <class SH>
+ACE_Process_Strategy<SH>::ACE_Process_Strategy (void)
+{
+ ACE_TRACE ("ACE_Process_Strategy<SH>::ACE_Process_Strategy");
+}
+
+template <class SH>
+ACE_Process_Strategy<SH>::~ACE_Process_Strategy (void)
+{
+ ACE_TRACE ("ACE_Process_Strategy<SH>::~ACE_Process_Strategy");
+}
+
+template <class SH> int
+ACE_Process_Strategy<SH>::activate_svc_handler (SH *svc_handler,
+ void *arg)
+{
+ ACE_TRACE ("ACE_Process_Strategy<SH>::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 <class SH>
+ACE_Scheduling_Strategy<SH>::ACE_Scheduling_Strategy (SH *scheduler)
+ : scheduler_ (scheduler),
+ delete_scheduler_ (0)
+{
+ ACE_TRACE ("ACE_Scheduling_Strategy<SH>::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 <class SH>
+ACE_Scheduling_Strategy<SH>::~ACE_Scheduling_Strategy (void)
+{
+ ACE_TRACE ("ACE_Scheduling_Strategy<SH>::~ACE_Scheduling_Strategy");
+
+ if (this->delete_scheduler_)
+ this->scheduler_->destroy ();
+}
+
+template <class SH> void
+ACE_Scheduling_Strategy<SH>::dump (void) const
+{
+ ACE_TRACE ("ACE_Scheduling_Strategy<SH>::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 <class SH> int
+ACE_Scheduling_Strategy<SH>::suspend (void)
+{
+ ACE_TRACE ("ACE_Scheduling_Strategy<SH>::suspend");
+ return -1;
+}
+
+template <class SH> int
+ACE_Scheduling_Strategy<SH>::resume (void)
+{
+ ACE_TRACE ("ACE_Scheduling_Strategy<SH>::resume");
+ return -1;
+}
+
+template <class SH>
+ACE_Schedule_All_Reactive_Strategy<SH>::ACE_Schedule_All_Reactive_Strategy (SH *scheduler)
+ : ACE_Scheduling_Strategy<SH> (scheduler)
+{
+ ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy<SH>::ACE_Schedule_All_Reactive_Strategy");
+}
+
+template <class SH> int
+ACE_Schedule_All_Reactive_Strategy<SH>::suspend (void)
+{
+ ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy<SH>::suspend");
+ return this->scheduler_->reactor ()->suspend_handlers ();
+}
+
+template <class SH> void
+ACE_Schedule_All_Reactive_Strategy<SH>::dump (void) const
+{
+ ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy<SH>::dump");
+
+ ACE_Scheduling_Strategy<SH>::dump ();
+}
+
+template <class SVC_HANDLER> int
+ACE_Schedule_All_Reactive_Strategy<SH>::resume (void)
+{
+ ACE_TRACE ("ACE_Schedule_All_Reactive_Strategy<SH>::resume");
+ return this->scheduler_->reactor ()->resume_handlers ();
+}
+
+template <class SH>
+ACE_Schedule_All_Threaded_Strategy<SH>::ACE_Schedule_All_Threaded_Strategy (SH *scheduler)
+ : ACE_Scheduling_Strategy<SH> (scheduler)
+{
+ ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy<SH>::ACE_Schedule_All_Threaded_Strategy");
+}
+
+template <class SH> int
+ACE_Schedule_All_Threaded_Strategy<SH>::suspend (void)
+{
+ ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy<SH>::suspend");
+ return this->scheduler_->thr_mgr ()->suspend_all ();
+}
+
+template <class SVC_HANDLER> int
+ACE_Schedule_All_Threaded_Strategy<SH>::resume (void)
+{
+ ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy<SH>::resume");
+ return this->scheduler_->thr_mgr ()->resume_all ();
+}
+
+template <class SH> void
+ACE_Schedule_All_Threaded_Strategy<SH>::dump (void) const
+{
+ ACE_TRACE ("ACE_Schedule_All_Threaded_Strategy<SH>::dump");
+
+ ACE_Scheduling_Strategy<SH>::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 SVC_HANDLER>
+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 <Thread_Manager> 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 SVC_HANDLER>
+class ACE_Singleton_Strategy : public ACE_Creation_Strategy<SVC_HANDLER>
+ // = TITLE
+ // Defines the interface for specifying a creation strategy for
+ // a <SVC_HANDLER> that always returns the same <SVC_HANDLER> (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 SVC_HANDLER>
+class ACE_DLL_Strategy : public ACE_Creation_Strategy<SVC_HANDLER>
+ // = 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 <svc_dll_info> 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 <svc_dll_info> 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<SVC_HANDLER> 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 SVC_HANDLER>
+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 <svc_handler> 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 SVC_HANDLER>
+class ACE_Thread_Strategy : public ACE_Concurrency_Strategy<SVC_HANDLER>
+ // = TITLE
+ // Defines the interface for specifying a concurrency strategy
+ // for a <SVC_HANDLER> 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
+ // <SVC_HANDLER>.
+{
+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 <svc_handler> 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<SVC_HANDLER> 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 SVC_HANDLER>
+class ACE_Process_Strategy : public ACE_Concurrency_Strategy<SVC_HANDLER>
+ // = TITLE
+ // Defines the interface for specifying a concurrency strategy
+ // for a <SVC_HANDLER> 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
+ // <SVC_HANDLER>.
+{
+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 <svc_handler> 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<SVC_HANDLER> inherited;
+
+ int n_processes_;
+ // Number of processes to spawn.
+};
+
+template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
+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 <peer_acceptor_> with <local_addr>.
+
+ virtual int open (const ACE_PEER_ACCEPTOR_ADDR &local_addr,
+ int restart = 0);
+ // Initialize the <peer_acceptor_> with <local_addr>.
+
+ virtual ACE_HANDLE get_handle (void) const;
+ // Return the underlying ACE_HANDLE of the <peer_acceptor_>.
+
+ virtual ACE_PEER_ACCEPTOR &acceptor (void) const;
+ // Return a reference to the <peer_acceptor_>.
+
+ ~ACE_Accept_Strategy (void);
+
+ // = Factory method.
+ virtual int accept_svc_handler (SVC_HANDLER *);
+ // The default behavior delegates to the <accept> 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 SVC_HANDLER>
+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 SVC_HANDLER>
+class ACE_Schedule_All_Reactive_Strategy : public ACE_Scheduling_Strategy<SVC_HANDLER>
+ // = 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 SVC_HANDLER>
+class ACE_Schedule_All_Threaded_Strategy : public ACE_Scheduling_Strategy<SVC_HANDLER>
+ // = 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 <ACE_SYNCH_1> void
+ACE_Stream<ACE_SYNCH_2>::dump (void) const
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::dump");
+ ACE_DEBUG ((LM_DEBUG, "-------- module links --------\n"));
+
+ for (ACE_Module<ACE_SYNCH_2> *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<ACE_SYNCH_2> *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 <ACE_SYNCH_1> int
+ACE_Stream<ACE_SYNCH_2>::push (ACE_Module<ACE_SYNCH_2> *new_top)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::push");
+ if (this->push_module (new_top,
+ this->stream_head_->next (),
+ this->stream_head_) == -1)
+ return -1;
+ else
+ return 0;
+}
+
+template <ACE_SYNCH_1> int
+ACE_Stream_Iterator<ACE_SYNCH_2>::advance (void)
+{
+ ACE_TRACE ("ACE_Stream_Iterator<ACE_SYNCH_2>::advance");
+ this->next_ = this->next_->next ();
+ return 0;
+}
+
+template <ACE_SYNCH_1> int
+ACE_Stream<ACE_SYNCH_2>::put (ACE_Message_Block *mb, ACE_Time_Value *tv)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::put");
+ return this->stream_head_->writer ()->put (mb, tv);
+}
+
+template <ACE_SYNCH_1> int
+ACE_Stream<ACE_SYNCH_2>::get (ACE_Message_Block *&mb, ACE_Time_Value *tv)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::get");
+ return this->stream_head_->reader ()->getq (mb, tv);
+}
+
+// Return the "top" ACE_Module in a ACE_Stream, skipping over the
+// stream_head.
+
+template <ACE_SYNCH_1> int
+ACE_Stream<ACE_SYNCH_2>::top (ACE_Module<ACE_SYNCH_2> *&m)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Stream<ACE_SYNCH_2>::pop (u_long flags)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::pop");
+ if (this->stream_head_->next () == this->stream_tail_)
+ return -1;
+ else
+ {
+ // Skip over the ACE_Stream head.
+ ACE_Module<ACE_SYNCH_2> *top = this->stream_head_->next ();
+ ACE_Module<ACE_SYNCH_2> *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 <ACE_SYNCH_1> int
+ACE_Stream<ACE_SYNCH_2>::remove (const char *name, u_long flags)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::remove");
+ ACE_Module<ACE_SYNCH_2> *prev = 0;
+
+ for (ACE_Module<ACE_SYNCH_2> *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_SYNCH_1> ACE_Module<ACE_SYNCH_2> *
+ACE_Stream<ACE_SYNCH_2>::find (const char *name)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::find");
+ for (ACE_Module<ACE_SYNCH_2> *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 <ACE_SYNCH_1> int
+ACE_Stream<ACE_SYNCH_2>::push_module (ACE_Module<ACE_SYNCH_2> *new_top,
+ ACE_Module<ACE_SYNCH_2> *current_top,
+ ACE_Module<ACE_SYNCH_2> *head)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::push_module");
+ ACE_Task<ACE_SYNCH_2> *nt_reader = new_top->reader ();
+ ACE_Task<ACE_SYNCH_2> *nt_writer = new_top->writer ();
+ ACE_Task<ACE_SYNCH_2> *ct_reader = 0;
+ ACE_Task<ACE_SYNCH_2> *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<ACE_SYNCH_2>::open (void *a,
+ ACE_Multiplexor &muxer,
+ ACE_Module<ACE_SYNCH_2> *head)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::open");
+ this->stream_head_ = head == 0
+ ? new ACE_Module<ACE_SYNCH_2> ("ACE_Stream_Head",
+ new ACE_Stream_Head<ACE_SYNCH_2>,
+ new ACE_Stream_Head<ACE_SYNCH_2>, a) : head;
+ this->stream_tail_ = 0;
+ return muxer.link_from_below (this->stream_head_);
+}
+#endif
+
+template <ACE_SYNCH_1> int
+ACE_Stream<ACE_SYNCH_2>::open (void *a,
+ ACE_Module<ACE_SYNCH_2> *head,
+ ACE_Module<ACE_SYNCH_2> *tail)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::open");
+ ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1);
+ ACE_Task<ACE_SYNCH_2> *h1, *h2;
+ ACE_Task<ACE_SYNCH_2> *t1, *t2;
+
+ if (head == 0)
+ {
+ h1 = new ACE_Stream_Head<ACE_SYNCH_2>;
+ h2 = new ACE_Stream_Head<ACE_SYNCH_2>;
+ head = new ACE_Module<ACE_SYNCH_2> ("ACE_Stream_Head", h1, h2, a);
+ }
+
+ if (tail == 0)
+ {
+ t1 = new ACE_Stream_Tail<ACE_SYNCH_2>;
+ t2 = new ACE_Stream_Tail<ACE_SYNCH_2>;
+ tail = new ACE_Module<ACE_SYNCH_2> ("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 <ACE_SYNCH_1> int
+ACE_Stream<ACE_SYNCH_2>::close (u_long flags)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Stream<ACE_SYNCH_2>::control (ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds cmd,
+ void *a)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Stream<ACE_SYNCH_2>::link_i (ACE_Stream<ACE_SYNCH_2> &us)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::link_i");
+ this->linked_us_ = &us;
+ // Make sure the other side is also linked to us!
+ us.linked_us_ = this;
+
+ ACE_Module<ACE_SYNCH_2> *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<ACE_SYNCH_2> *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 <ACE_SYNCH_1> int
+ACE_Stream<ACE_SYNCH_2>::link (ACE_Stream<ACE_SYNCH_2> &us)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::link");
+
+ ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1);
+
+ return this->link_i (us);
+}
+
+// Must be called with locks held...
+
+template <ACE_SYNCH_1> int
+ACE_Stream<ACE_SYNCH_2>::unlink_i (void)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::unlink_i");
+
+ // Only try to unlink if we are in fact still linked!
+
+ if (this->linked_us_ != 0)
+ {
+ ACE_Module<ACE_SYNCH_2> *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<ACE_SYNCH_2> *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 <ACE_SYNCH_1> int
+ACE_Stream<ACE_SYNCH_2>::unlink (void)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::unlink");
+ ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1);
+ return this->unlink_i ();
+}
+
+template <ACE_SYNCH_1> ACE_INLINE
+ACE_Stream<ACE_SYNCH_2>::ACE_Stream (void * a,
+ ACE_Module<ACE_SYNCH_2> *head,
+ ACE_Module<ACE_SYNCH_2> *tail)
+ : final_close_ (this->lock_),
+ linked_us_ (0)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::ACE_Stream");
+ if (this->open (a, head, tail) == -1)
+ ACE_ERROR ((LM_ERROR, "ACE_Stream<ACE_SYNCH_2>::open (%s, %s)\n",
+ head->name (), tail->name ()));
+}
+
+#if 0
+ACE_INLINE
+ACE_Stream<ACE_SYNCH_2>::ACE_Stream (void *a,
+ ACE_Multiplexor &muxer,
+ ACE_Module<ACE_SYNCH_2> *head)
+ : final_close_ (this->lock_),
+ linked_us_ (0)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::ACE_Stream");
+ if (this->open (a, muxer, head) == -1)
+ ACE_ERROR ((LM_ERROR, "ACE_Stream<ACE_SYNCH_2>::open (%s, %s)\n",
+ head->name ()));
+}
+#endif
+
+template <ACE_SYNCH_1> ACE_INLINE
+ACE_Stream<ACE_SYNCH_2>::~ACE_Stream (void)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::~ACE_Stream");
+ if (this->stream_head_ != 0)
+ this->close ();
+}
+
+template <ACE_SYNCH_1> ACE_INLINE
+ACE_Stream_Iterator<ACE_SYNCH_2>::ACE_Stream_Iterator (const ACE_Stream<ACE_SYNCH_2> &sr)
+ : next_ (sr.stream_head_)
+{
+ ACE_TRACE ("ACE_Stream_Iterator<ACE_SYNCH_2>::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<ACE_SYNCH_1> class ACE_Stream_Iterator;
+//template<ACE_SYNCH_1> class ACE_Module;
+
+template <ACE_SYNCH_1>
+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 <ACE_Modules>, each of which
+ // contains two <ACE_Tasks>.
+{
+friend class ACE_Stream_Iterator<ACE_SYNCH_2>;
+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<ACE_SYNCH_2> *head = 0,
+ ACE_Module<ACE_SYNCH_2> *tail = 0);
+ // Create a Stream consisting of <head> and <tail> as the Stream
+ // head and Stream tail, respectively. If these are 0 then the
+ // <ACE_Stream_Head> and <ACE_Stream_Tail> are used, respectively.
+ // <arg> is the value past in to the open() methods of the tasks.
+
+ int open (void *arg,
+ ACE_Module<ACE_SYNCH_2> *head = 0,
+ ACE_Module<ACE_SYNCH_2> *tail = 0);
+ // Create a Stream consisting of <head> and <tail> as the Stream
+ // head and Stream tail, respectively. If these are 0 then the
+ // <ACE_Stream_Head> and <ACE_Stream_Tail> are used, respectively.
+ // <arg> 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<ACE_SYNCH_2> *mod);
+ // Add a new module <mod> right below the Stream head.
+
+ int pop (u_long flags = M_DELETE);
+ // Remove the <mod> right below the Stream head and close it down.
+
+ int top (ACE_Module<ACE_SYNCH_2> *&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 <mod> from the stream. This bypasses the
+ // strict LIFO ordering of push() and pop().
+
+ ACE_Module<ACE_SYNCH_2> *head (void);
+ // Return current stream head.
+
+ ACE_Module<ACE_SYNCH_2> *tail (void);
+ // Return current stream tail.
+
+ ACE_Module<ACE_SYNCH_2> *find (const char *mod);
+ // Find a particular ACE_Module.
+
+ int link (ACE_Stream<ACE_SYNCH_2> &);
+ // 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 <mb> down the stream, starting at the Module
+ // below the Stream head. Wait for upto <timeout> amount of time
+ // for the operation to complete (or block forever if <timeout> ==
+ // 0).
+
+ int get (ACE_Message_Block *&mb, ACE_Time_Value *timeout);
+ // Read the message <mb> that is stored in the the stream head.
+ // Wait for upto <timeout> amount of time for the operation to
+ // complete (or block forever if <timeout> == 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<ACE_SYNCH_2> &);
+ // Actually perform the linking of two Streams (must be called with
+ // locks held).
+
+ int push_module (ACE_Module<ACE_SYNCH_2> *,
+ ACE_Module<ACE_SYNCH_2> * = 0,
+ ACE_Module<ACE_SYNCH_2> * = 0);
+ // Must a new module onto the Stream.
+
+ ACE_Module<ACE_SYNCH_2> *stream_head_;
+ // Pointer to the head of the stream.
+
+ ACE_Module<ACE_SYNCH_2> *stream_tail_;
+ // Pointer to the tail of the stream.
+
+ ACE_Stream<ACE_SYNCH_2> *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 <ACE_SYNCH_1>
+class ACE_Stream_Iterator
+{
+public:
+ ACE_Stream_Iterator (const ACE_Stream<ACE_SYNCH_2> &sr);
+ int next (const ACE_Module<ACE_SYNCH_2> *&mo);
+ int advance (void);
+
+private:
+ ACE_Module<ACE_SYNCH_2> *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_SYNCH_1> ACE_INLINE ACE_Module<ACE_SYNCH_2> *
+ACE_Stream<ACE_SYNCH_2>::head (void)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::head");
+ return this->stream_head_;
+}
+
+template <ACE_SYNCH_1> ACE_INLINE ACE_Module<ACE_SYNCH_2> *
+ACE_Stream<ACE_SYNCH_2>::tail (void)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::tail");
+ return this->stream_tail_;
+}
+
+template <ACE_SYNCH_1> ACE_INLINE int
+ACE_Stream<ACE_SYNCH_2>::wait (void)
+{
+ ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::wait");
+ return this->final_close_.wait ();
+}
+
+template <ACE_SYNCH_1> ACE_INLINE int
+ACE_Stream_Iterator<ACE_SYNCH_2>::next (const ACE_Module<ACE_SYNCH_2> *&mod)
+{
+ ACE_TRACE ("ACE_Stream_Iterator<ACE_SYNCH_2>::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 <ACE_SYNCH_1> void
+ACE_Stream_Head<ACE_SYNCH_2>::dump (void) const
+{
+ ACE_TRACE ("ACE_Stream_Head<ACE_SYNCH_2>::dump");
+}
+
+/* ACE_Module that act as the head and tail of a Stream. */
+
+template <ACE_SYNCH_1> int
+ACE_Stream_Head<ACE_SYNCH_2>::open (void *)
+{
+ ACE_TRACE ("ACE_Stream_Head<ACE_SYNCH_2>::open");
+ return 0;
+}
+
+template <ACE_SYNCH_1> int
+ACE_Stream_Head<ACE_SYNCH_2>::close (u_long)
+{
+ ACE_TRACE ("ACE_Stream_Head<ACE_SYNCH_2>::close");
+ return 0;
+}
+
+template <ACE_SYNCH_1> int
+ACE_Stream_Head<ACE_SYNCH_2>::svc (void)
+{
+ ACE_TRACE ("ACE_Stream_Head<ACE_SYNCH_2>::svc");
+ return -1;
+}
+
+template <ACE_SYNCH_1> int
+ACE_Stream_Head<ACE_SYNCH_2>::control (ACE_Message_Block *mb)
+{
+ ACE_TRACE ("ACE_Stream_Head<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Stream_Head<ACE_SYNCH_2>::canonical_flush (ACE_Message_Block *mb)
+{
+ ACE_TRACE ("ACE_Stream_Head<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Stream_Head<ACE_SYNCH_2>::put (ACE_Message_Block *mb, ACE_Time_Value *tv)
+{
+ ACE_TRACE ("ACE_Stream_Head<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Stream_Head<ACE_SYNCH_2>::init (int, char *[])
+{
+ ACE_TRACE ("ACE_Stream_Head<ACE_SYNCH_2>::init");
+ return 0;
+}
+
+template <ACE_SYNCH_1> int
+ACE_Stream_Head<ACE_SYNCH_2>::info (char **strp, size_t length) const
+{
+ ACE_TRACE ("ACE_Stream_Head<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Stream_Head<ACE_SYNCH_2>::fini (void)
+{
+ ACE_TRACE ("ACE_Stream_Head<ACE_SYNCH_2>::fini");
+ return 0;
+}
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Stream_Tail)
+
+template <ACE_SYNCH_1> void
+ACE_Stream_Tail<ACE_SYNCH_2>::dump (void) const
+{
+ ACE_TRACE ("ACE_Stream_Tail<ACE_SYNCH_2>::dump");
+}
+
+template <ACE_SYNCH_1> int
+ACE_Stream_Tail<ACE_SYNCH_2>::open (void *)
+{
+ ACE_TRACE ("ACE_Stream_Tail<ACE_SYNCH_2>::open");
+ return 0;
+}
+
+template <ACE_SYNCH_1> int
+ACE_Stream_Tail<ACE_SYNCH_2>::close (u_long)
+{
+ ACE_TRACE ("ACE_Stream_Tail<ACE_SYNCH_2>::close");
+ return 0;
+}
+
+template <ACE_SYNCH_1> int
+ACE_Stream_Tail<ACE_SYNCH_2>::svc (void)
+{
+ ACE_TRACE ("ACE_Stream_Tail<ACE_SYNCH_2>::svc");
+ return -1;
+}
+
+template <ACE_SYNCH_1> int
+ACE_Stream_Tail<ACE_SYNCH_2>::control (ACE_Message_Block *mb)
+{
+ ACE_TRACE ("ACE_Stream_Tail<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Stream_Tail<ACE_SYNCH_2>::canonical_flush (ACE_Message_Block *mb)
+{
+ ACE_TRACE ("ACE_Stream_Tail<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Stream_Tail<ACE_SYNCH_2>::put (ACE_Message_Block *mb, ACE_Time_Value *
+
+)
+{
+ ACE_TRACE ("ACE_Stream_Tail<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Stream_Tail<ACE_SYNCH_2>::init (int, char *[])
+{
+ ACE_TRACE ("ACE_Stream_Tail<ACE_SYNCH_2>::init");
+ return 0;
+}
+
+template <ACE_SYNCH_1> int
+ACE_Stream_Tail<ACE_SYNCH_2>::info (char **strp, size_t length) const
+{
+ ACE_TRACE ("ACE_Stream_Tail<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Stream_Tail<ACE_SYNCH_2>::fini (void)
+{
+ ACE_TRACE ("ACE_Stream_Tail<ACE_SYNCH_2>::fini");
+ return 0;
+}
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Thru_Task)
+
+template <ACE_SYNCH_1> void
+ACE_Thru_Task<ACE_SYNCH_2>::dump (void) const
+{
+ ACE_TRACE ("ACE_Thru_Task<ACE_SYNCH_2>::dump");
+}
+
+template <ACE_SYNCH_1> int
+ACE_Thru_Task<ACE_SYNCH_2>::open (void *)
+{
+ ACE_TRACE ("ACE_Thru_Task<ACE_SYNCH_2>::open");
+ return 0;
+}
+
+template <ACE_SYNCH_1> int
+ACE_Thru_Task<ACE_SYNCH_2>::close (u_long)
+{
+ ACE_TRACE ("ACE_Thru_Task<ACE_SYNCH_2>::close");
+ return 0;
+}
+
+template <ACE_SYNCH_1> int
+ACE_Thru_Task<ACE_SYNCH_2>::svc (void)
+{
+ ACE_TRACE ("ACE_Thru_Task<ACE_SYNCH_2>::svc");
+ return -1;
+}
+
+template <ACE_SYNCH_1> int
+ACE_Thru_Task<ACE_SYNCH_2>::put (ACE_Message_Block *msg,
+ ACE_Time_Value *tv)
+{
+ ACE_TRACE ("ACE_Thru_Task<ACE_SYNCH_2>::put");
+ return this->put_next (msg, tv);
+}
+
+template <ACE_SYNCH_1> int
+ACE_Thru_Task<ACE_SYNCH_2>::init (int, char *[])
+{
+ ACE_TRACE ("ACE_Thru_Task<ACE_SYNCH_2>::init");
+ return 0;
+}
+
+template <ACE_SYNCH_1> int
+ACE_Thru_Task<ACE_SYNCH_2>::info (char **strp,
+ size_t length) const
+{
+ ACE_TRACE ("ACE_Thru_Task<ACE_SYNCH_2>::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 <ACE_SYNCH_1> int
+ACE_Thru_Task<ACE_SYNCH_2>::fini (void)
+{
+ ACE_TRACE ("ACE_Thru_Task<ACE_SYNCH_2>::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 <ACE_SYNCH_1>
+class ACE_Stream_Head : public ACE_Task<ACE_SYNCH_2>
+ // = 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 <ACE_SYNCH_1>
+class ACE_Stream_Tail : public ACE_Task<ACE_SYNCH_2>
+ // = 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 <ACE_SYNCH_1>
+class ACE_Thru_Task : public ACE_Task<ACE_SYNCH_2>
+ // = 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)); }
+<<EOF>> { 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 <ident_> ACE_IDENT ACE_STRING ACE_PATHNAME parameters_opt
+%type <type_> type status
+%type <parse_node_> dynamic static suspend resume remove module_list stream
+%type <parse_node_> stream_modules module svc_config_entry
+%type <ACE_Static_Node_> stream_ops
+%type <svc_record_> svc_location
+%type <location_node_> 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 { $<ACE_Static_Node_>$ = new ACE_Static_Node ($2); } stream_modules
+ {
+ $$ = new ACE_Dummy_Node ($<ACE_Static_Node_>3, $4);
+ }
+ ;
+
+stream_ops
+ : dynamic
+ {
+ }
+ | static
+ {
+ }
+ ;
+
+stream_modules
+ : ACE_LBRACE
+ {
+ // Initialize left context...
+ $<ACE_Static_Node_>$ = $<ACE_Static_Node_>0;
+ }
+ module_list ACE_RBRACE
+ {
+ $$ = $3;
+ }
+ | /* EMPTY */ { $$ = 0; }
+ ;
+
+module_list
+ : module_list module { $2->link ($1); $$ = $2; }
+ | /* EMPTY */ { $$ = 0; }
+ ;
+
+module
+ : dynamic
+ {
+ ACE_ARGV args ($<ACE_Static_Node_>1->parameters ());
+ ACE_Module_Type *mt = get_module ($<ACE_Static_Node_>-1, $<ACE_Static_Node_>1);
+
+ if (::strcmp ($<ACE_Static_Node_>1->name (),
+ ((MT_Module *) mt->object ())->name ()) != 0)
+ ACE_ERROR ((LM_ERROR, "warning, service name %s is different from Module name %s\n",
+ $<ACE_Static_Node_>1->name (), ((MT_Module *) mt->object ())->name ()));
+
+ if (mt->init (args.argc (), args.argv ()) == -1
+ || ((ACE_Stream_Type *) ($<ACE_Static_Node_>-1)->record ()->type ())->push (mt) == -1)
+ {
+ ACE_ERROR ((LM_ERROR, "dynamic initialization failed for Module %s\n",
+ $<ACE_Static_Node_>1->name ()));
+ yyerrno++;
+ }
+ }
+ | static
+ {
+ ACE_Module_Type *mt = get_module ($<ACE_Static_Node_>-1, $<ACE_Static_Node_>1->name ());
+ if (::strcmp ($<ACE_Static_Node_>1->name (),
+ ((MT_Module *) mt->object ())->name ()) != 0)
+ ACE_ERROR ((LM_ERROR, "warning, service name %s is different from Module name %s\n",
+ $<ACE_Static_Node_>1->name (), ((MT_Module *) mt->object ())->name ()));
+ if (((ACE_Stream_Type *) ($<ACE_Static_Node_>-1)->record ()->type ())->push (mt) == -1)
+ yyerrno++;
+ }
+ | suspend
+ {
+ ACE_Module_Type *mt = get_module ($<ACE_Static_Node_>-1, $<ACE_Static_Node_>1->name ());
+ if (mt != 0)
+ mt->suspend ();
+ }
+ | resume
+ {
+ ACE_Module_Type *mt = get_module ($<ACE_Static_Node_>-1, $<ACE_Static_Node_>1->name ());
+ if (mt != 0)
+ mt->resume ();
+ }
+ | remove
+ {
+ ACE_Module_Type *mt = get_module ($<ACE_Static_Node_>-1, $<ACE_Static_Node_>1->name ());
+ if (mt != 0
+ && ((ACE_Stream_Type *) ($<ACE_Static_Node_>-1)->record ()->type ())->remove (mt) == -1)
+ {
+ ACE_ERROR ((LM_ERROR, "cannot remove Module_Type %s from STREAM_Type %s\n",
+ $<ACE_Static_Node_>1->name (), ($<ACE_Static_Node_>-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 <stdio.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/* 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 <stdlib.h>
+#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 <PR_ST_1, ACE_SYNCH_1>
+ACE_Thread_Mutex ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::ace_svc_handler_lock_;
+#endif /* defined (ACE_MT_SAFE) && !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */
+
+template <PR_ST_1, ACE_SYNCH_1> ACE_Dynamic *
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::instance (void)
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::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 <PR_ST_1, ACE_SYNCH_1> void *
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::operator new (size_t n)
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::operator new");
+ // Allocate the memory and store it (usually in thread-specific
+ // storage, depending on config flags).
+ return ACE_Svc_Handler<ACE_PEER_STREAM_2, ACE_SYNCH_2>::instance ()->set (::new char[n]);
+}
+
+template <PR_ST_1, ACE_SYNCH_1> void
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::destroy (void)
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::destroy");
+
+ // Only delete ourselves if we've been allocated dynamically.
+ if (this->dynamic_)
+ // Will call the destructor, which automatically calls <shutdown>.
+ // Note that if we are *not* allocated dynamically then the
+ // destructor will call <shutdown> automatically when it gets run
+ // during cleanup.
+ delete this;
+}
+
+template <PR_ST_1, ACE_SYNCH_1> void
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::operator delete (void *obj)
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::delete");
+ ::delete obj;
+}
+
+/* Default constructor */
+
+template <PR_ST_1, ACE_SYNCH_1>
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::ACE_Svc_Handler (ACE_Thread_Manager *tm,
+ ACE_Message_Queue<ACE_SYNCH_2> *mq,
+ ACE_Reactor *reactor)
+ : ACE_Task<ACE_SYNCH_2> (tm, mq),
+ reactor_ (reactor)
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::ACE_Svc_Handler");
+
+ // This clever idiom transparently checks if we were allocated
+ // dynamically. This information is used by the <destroy> method to
+ // decide if we need to delete <this>... 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<ACE_PEER_STREAM_2, ACE_SYNCH_2>::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 <PR_ST_1, ACE_SYNCH_1> int
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::open (void *)
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::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 <PR_ST_1, ACE_SYNCH_1> void
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::shutdown (void)
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::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 <PR_ST_1, ACE_SYNCH_1> ACE_Reactor *
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::reactor (void) const
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::reactor");
+ return this->reactor_;
+}
+
+template <PR_ST_1, ACE_SYNCH_1> void
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::reactor (ACE_Reactor *r)
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::reactor");
+ this->reactor_ = r;
+}
+
+template <PR_ST_1, ACE_SYNCH_1> void
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::dump (void) const
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::dump");
+}
+
+template <PR_ST_1, ACE_SYNCH_1> ACE_INLINE ACE_PEER_STREAM &
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::peer (void) const
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::peer");
+ return (PEER_STREAM &) this->peer_;
+}
+
+// Extract the underlying PEER_STREAM (e.g., used by ACE_Connector and
+// ACE_Acceptor).
+
+template <PR_ST_1, ACE_SYNCH_1>
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::operator ACE_PEER_STREAM &()
+{
+ return this->peer_;
+}
+
+/* Extract the underlying I/O descriptor. */
+
+template <PR_ST_1, ACE_SYNCH_1> ACE_HANDLE
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::get_handle (void) const
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::get_handle");
+ return this->peer_.get_handle ();
+}
+
+/* Set the underlying I/O descriptor. */
+
+template <PR_ST_1, ACE_SYNCH_1> void
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::set_handle (ACE_HANDLE h)
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::set_handle");
+ this->peer_.set_handle (h);
+}
+
+template <PR_ST_1, ACE_SYNCH_1>
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::~ACE_Svc_Handler (void)
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::~ACE_Svc_Handler");
+ this->shutdown ();
+}
+
+template <PR_ST_1, ACE_SYNCH_1> int
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::handle_close (ACE_HANDLE, ACE_Reactor_Mask)
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::handle_close");
+
+ this->destroy ();
+ return 0;
+}
+
+template <PR_ST_1, ACE_SYNCH_1> int
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::handle_timeout (const ACE_Time_Value &,
+ const void *)
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::handle_timeout");
+ return this->handle_close ();
+}
+
+template <PR_ST_1, ACE_SYNCH_1> int
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::close (unsigned long)
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::close");
+ return this->handle_close ();
+}
+
+template <PR_ST_1, ACE_SYNCH_1> int
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::svc (void)
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::svc");
+ return -1;
+}
+
+template <PR_ST_1, ACE_SYNCH_1> int
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::put (ACE_Message_Block *,
+ ACE_Time_Value *)
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::put");
+ return -1;
+}
+
+template <PR_ST_1, ACE_SYNCH_1> int
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::init (int, char *[])
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::init");
+ return -1;
+}
+
+template <PR_ST_1, ACE_SYNCH_1> int
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::fini (void)
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::fini");
+ return -1;
+}
+
+template <PR_ST_1, ACE_SYNCH_1> int
+ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::info (char **, size_t) const
+{
+ ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_2>::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 <ACE_PEER_STREAM_1, ACE_SYNCH_1>
+class ACE_Svc_Handler : public ACE_Task<ACE_SYNCH_2>
+ // = 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<ACE_SYNCH_2> * = 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 <peer_> (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
+ // <Svc_Handler> by calling <handle_close>.
+
+ virtual ACE_HANDLE get_handle (void) const;
+ // Get the underlying handle associated with the <peer_>.
+
+ virtual void set_handle (ACE_HANDLE);
+ // Set the underlying handle associated with the <peer_>.
+
+ 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 <delete> to free up dynamically allocated
+ // <Svc_Handler>. 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 <abstime> == 0
+// then we do a regular <cond_wait>, else we do a timed wait for up to
+// <abstime> using the <cond_timedwait> 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<MUTEX>::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_COND_MUTEX> 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 <handle_> of the File_Lock to <handle>. Note that this
+ // constructor assumes ownership of the <handle> and will close it
+ // down in <remove>. If you want the <handle> stays open when
+ // <remove> is called make sure to call <dup> on the <handle> before
+ // closing it.
+
+ ACE_File_Lock (const char *filename, int flags, mode_t mode = 0);
+ // Open the <filename> with <flags> and <mode> and set the result to
+ // <handle_>.
+
+ ~ACE_File_Lock (void);
+ // Remove a File lock by releasing it and closing down the <handle_>.
+
+ int remove (void);
+ // Remove a File lock by releasing it and closing down the <handle_>.
+
+ int acquire (short whence = 0, off_t start = 0, off_t len = 1);
+ // Note, for interface uniformity with other synchronization
+ // wrappers we include the <acquire> 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 <tryacquire> 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 <ACE_HANDLE>.
+
+ void set_handle (ACE_HANDLE);
+ // Set underlying <ACE_HANDLE>. Note that this method assumes
+ // ownership of the <handle> and will close it down in <remove>. If
+ // you want the <handle> stays open when <remove> is called make
+ // sure to call <dup> on the <handle> 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
+ // <abstime> 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 <CRITICAL_SECTION>s on NT
+ // and <ACE_mutex_t> with <type> set to <USYNC_THREAD> 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" <wait> semantics. Else, if <abstime>
+ // != 0 and the call times out before the condition is signaled
+ // <wait> 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 <mutex>
+ // passed as a parameter (this is useful if you need to store the
+ // <Condition> in shared memory). Else, if <abstime> != 0 and the
+ // call times out before the condition is signaled <wait> 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
+ // <ACE_Thread_Mutex> 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<class ACE_COND_MUTEX>;
+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 <acquire> 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 <tryacquire> 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 <count> and a
+ // maximum value of <max>.
+
+ 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 <count> and a
+ // maximum value of <max>.
+
+ ~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 <count> 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 <count> threads.
+
+ int wait (void);
+ // Block the caller until all <count> threads have called <wait> 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 <sub_barriers>, 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 <name>.
+
+ 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 <name>.
+
+ 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 <name>.
+
+ ~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 <count> threads.
+
+ int wait (void) { return 0; }
+ // Block the caller until all <count> threads have called <wait> 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 <ACE_Mutex>, 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 <ACE_Condition> 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 <Time_Value>. This value only makes
+ // sense if (*this)[USE_TIMEOUT] is true.
+
+ void timeout (ACE_Time_Value &tv);
+ // Set the <Time_Value>.
+
+ const ACE_Time_Value *time_value (void) const;
+ // Returns the address of the timeout <Time_Value> 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
+ // <schedule_timer> 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 <class LOCK, class TYPE>
+ACE_Test_and_Set<LOCK, TYPE>::ACE_Test_and_Set (TYPE initial_value)
+ : is_set_ (initial_value)
+{
+}
+
+// Returns true if we are done, else false.
+template <class LOCK, class TYPE> TYPE
+ACE_Test_and_Set<LOCK, TYPE>::is_set (void) const
+{
+ ACE_GUARD_RETURN (LOCK, ace_mon, (LOCK &) this->lock_, this->is_set_);
+ return this->is_set_;
+}
+
+// Sets the <is_set_> status.
+template <class LOCK, class TYPE> TYPE
+ACE_Test_and_Set<LOCK, TYPE>::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 <class LOCK, class TYPE> int
+ACE_Test_and_Set<LOCK, TYPE>::handle_signal (int signum, siginfo_t *, ucontext_t *)
+{
+ this->set (1);
+ return 0;
+}
+
+template <class LOCK, class TYPE> void
+ACE_Atomic_Op<LOCK, TYPE>::dump (void) const
+{
+// ACE_TRACE ("ACE_Atomic_Op<LOCK, TYPE>::dump");
+
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+ this->lock_.dump ();
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+}
+
+template <class LOCK, class TYPE>
+ACE_Atomic_Op<LOCK, TYPE>::ACE_Atomic_Op (void)
+ : value_ (0)
+{
+// ACE_TRACE ("ACE_Atomic_Op<LOCK, TYPE>::ACE_Atomic_Op");
+}
+
+template <class LOCK, class TYPE>
+ACE_Atomic_Op<LOCK, TYPE>::ACE_Atomic_Op (TYPE c)
+{
+// ACE_TRACE ("ACE_Atomic_Op<LOCK, TYPE>::ACE_Atomic_Op");
+ this->value_ = c;
+}
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Guard)
+
+template <class LOCK> void
+ACE_Guard<LOCK>::dump (void) const
+{
+// ACE_TRACE ("ACE_Guard<LOCK>::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 <class LOCK> void
+ACE_Write_Guard<LOCK>::dump (void) const
+{
+// ACE_TRACE ("ACE_Write_Guard<LOCK>::dump");
+ ACE_Guard<LOCK>::dump ();
+}
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Read_Guard)
+
+template <class LOCK> void
+ACE_Read_Guard<LOCK>::dump (void) const
+{
+// ACE_TRACE ("ACE_Read_Guard<LOCK>::dump");
+ ACE_Guard<LOCK>::dump ();
+}
+
+#if defined (ACE_HAS_THREADS)
+
+#if defined (__osf__) && ! defined (__GNUG__)
+#pragma define_template ACE_Condition<ACE_Mutex>
+#endif
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Condition)
+
+template <class MUTEX> void
+ACE_Condition<MUTEX>::dump (void) const
+{
+// ACE_TRACE ("ACE_Condition<MUTEX>::dump");
+
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+ ACE_DEBUG ((LM_DEBUG, "\n"));
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+}
+
+template <class MUTEX>
+ACE_Thread_Condition<MUTEX>::ACE_Thread_Condition (MUTEX &m,
+ LPCTSTR name,
+ void *arg)
+ : ACE_Condition<MUTEX> (m, USYNC_THREAD, name, arg)
+{
+// ACE_TRACE ("ACE_Thread_Condition<MUTEX>::ACE_Thread_Condition");
+}
+
+template <class MUTEX> void
+ACE_Thread_Condition<MUTEX>::dump (void) const
+{
+// ACE_TRACE ("ACE_Thread_Condition<MUTEX>::dump");
+
+ ACE_Condition<MUTEX>::dump ();
+}
+
+template <class MUTEX> void
+ACE_Process_Condition<MUTEX>::dump (void) const
+{
+// ACE_TRACE ("ACE_Process_Condition<MUTEX>::dump");
+
+ ACE_Condition<MUTEX>::dump ();
+}
+
+template <class MUTEX>
+ACE_Process_Condition<MUTEX>::ACE_Process_Condition (MUTEX &m,
+ LPCTSTR name,
+ void *arg)
+ : ACE_Condition<MUTEX> (m, USYNC_PROCESS, name, arg)
+{
+// ACE_TRACE ("ACE_Process_Condition<MUTEX>::ACE_Process_Condition");
+}
+
+template <class MUTEX>
+ACE_Condition<MUTEX>::ACE_Condition (MUTEX &m,
+ int type,
+ LPCTSTR name,
+ void *arg)
+ : mutex_ (m)
+{
+// ACE_TRACE ("ACE_Condition<MUTEX>::ACE_Condition");
+ if (ACE_OS::cond_init (&this->cond_, type, name, arg) != 0)
+ ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Condition::ACE_Condition"));
+}
+
+template <class MUTEX>
+ACE_Condition<MUTEX>::~ACE_Condition (void)
+{
+// ACE_TRACE ("ACE_Condition<MUTEX>::~ACE_Condition");
+ if (this->remove () == -1)
+ ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Condition::~ACE_Condition"));
+}
+
+template <class MUTEX> int
+ACE_Condition<MUTEX>::wait (void)
+{
+// ACE_TRACE ("ACE_Condition<MUTEX>::wait");
+ return ACE_OS::cond_wait (&this->cond_, this->mutex_.lock_);
+}
+
+template <class MUTEX> int
+ACE_Condition<MUTEX>::wait (MUTEX &mutex,
+ const ACE_Time_Value *abstime)
+{
+// ACE_TRACE ("ACE_Condition<MUTEX>::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 <class MUTEX> int
+ACE_Condition<MUTEX>::wait (const ACE_Time_Value *abstime)
+{
+// ACE_TRACE ("ACE_Condition<MUTEX>::wait");
+ return this->wait (this->mutex_, abstime);
+}
+#endif /* ACE_HAS_THREADS */
+
+ACE_ALLOC_HOOK_DEFINE(ACE_TSS)
+
+template <class TYPE>
+ACE_TSS<TYPE>::~ACE_TSS (void)
+{
+ ACE_OS::thr_key_detach (this);
+}
+
+template <class TYPE> TYPE *
+ACE_TSS<TYPE>::operator-> () const
+{
+ return this->ts_get ();
+}
+
+template <class TYPE>
+ACE_TSS<TYPE>::operator TYPE *(void) const
+{
+ return this->ts_get ();
+}
+
+template <class TYPE> TYPE *
+ACE_TSS<TYPE>::make_TSS_TYPE (void) const
+{
+ return new TYPE;
+}
+
+template <class TYPE> void
+ACE_TSS<TYPE>::dump (void) const
+{
+// ACE_TRACE ("ACE_TSS<TYPE>::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 <class TYPE> ACE_INLINE
+ACE_TSS<TYPE>::ACE_TSS (TYPE *)
+{
+}
+
+template <class TYPE> ACE_INLINE TYPE *
+ACE_TSS<TYPE>::ts_object (void) const
+{
+ return (TYPE *) &this->type_;
+}
+
+template <class TYPE> ACE_INLINE TYPE *
+ACE_TSS<TYPE>::ts_object (TYPE *)
+{
+ return &this->type_;
+}
+
+template <class TYPE> ACE_INLINE TYPE *
+ACE_TSS<TYPE>::ts_get (void) const
+{
+ return (TYPE *) &this->type_;
+}
+#else
+template <class TYPE>
+ACE_TSS<TYPE>::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<TYPE>::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 <class TYPE> TYPE *
+ACE_TSS<TYPE>::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<TYPE>::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 <class TYPE> TYPE *
+ACE_TSS<TYPE>::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 <class TYPE> TYPE *
+ACE_TSS<TYPE>::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 <class TYPE> void
+ACE_TSS<TYPE>::cleanup (void *ptr)
+{
+ // This cast is necessary to invoke the destructor (if necessary).
+ delete (TYPE *) ptr;
+}
+
+ACE_ALLOC_HOOK_DEFINE(ACE_TSS_Guard)
+
+template <class LOCK> void
+ACE_TSS_Guard<LOCK>::dump (void) const
+{
+// ACE_TRACE ("ACE_TSS_Guard<LOCK>::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 <class LOCK> void
+ACE_TSS_Guard<LOCK>::init_key (void)
+{
+// ACE_TRACE ("ACE_TSS_Guard<LOCK>::init_key");
+
+ this->key_ = 0;
+ ACE_Thread::keycreate (&this->key_,
+ &ACE_TSS_Guard<LOCK>::cleanup,
+ (void *) this);
+}
+
+template <class LOCK>
+ACE_TSS_Guard<LOCK>::ACE_TSS_Guard (void)
+{
+// ACE_TRACE ("ACE_TSS_Guard<LOCK>::ACE_TSS_Guard");
+ this->init_key ();
+}
+
+template <class LOCK> int
+ACE_TSS_Guard<LOCK>::release (void)
+{
+// ACE_TRACE ("ACE_TSS_Guard<LOCK>::release");
+
+ ACE_Guard<LOCK> *guard = 0;
+ ACE_Thread::getspecific (this->key_, (void **) &guard);
+ return guard->release ();
+}
+
+template <class LOCK> int
+ACE_TSS_Guard<LOCK>::remove (void)
+{
+// ACE_TRACE ("ACE_TSS_Guard<LOCK>::remove");
+
+ ACE_Guard<LOCK> *guard = 0;
+ ACE_Thread::getspecific (this->key_, (void **) &guard);
+ return guard->remove ();
+}
+
+template <class LOCK>
+ACE_TSS_Guard<LOCK>::~ACE_TSS_Guard (void)
+{
+// ACE_TRACE ("ACE_TSS_Guard<LOCK>::~ACE_TSS_Guard");
+
+ ACE_Guard<LOCK> *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 <class LOCK> void
+ACE_TSS_Guard<LOCK>::cleanup (void *ptr)
+{
+// ACE_TRACE ("ACE_TSS_Guard<LOCK>::dump");
+
+ // Destructor releases lock.
+ delete (ACE_Guard<LOCK> *) ptr;
+}
+
+template <class LOCK>
+ACE_TSS_Guard<LOCK>::ACE_TSS_Guard (LOCK &lock, int block)
+{
+// ACE_TRACE ("ACE_TSS_Guard<LOCK>::ACE_TSS_Guard");
+
+ this->init_key ();
+ ACE_Guard<LOCK> *guard;
+ ACE_NEW (guard, ACE_Guard<LOCK> (lock, block));
+ ACE_Thread::setspecific (this->key_, (void *) guard);
+}
+
+template <class LOCK> int
+ACE_TSS_Guard<LOCK>::acquire (void)
+{
+// ACE_TRACE ("ACE_TSS_Guard<LOCK>::acquire");
+
+ ACE_Guard<LOCK> *guard = 0;
+ ACE_Thread::getspecific (this->key_, (void **) &guard);
+ return guard->acquire ();
+}
+
+template <class LOCK> int
+ACE_TSS_Guard<LOCK>::tryacquire (void)
+{
+// ACE_TRACE ("ACE_TSS_Guard<LOCK>::tryacquire");
+
+ ACE_Guard<LOCK> *guard = 0;
+ ACE_Thread::getspecific (this->key_, (void **) &guard);
+ return guard->tryacquire ();
+}
+
+template <class LOCK>
+ACE_TSS_Write_Guard<LOCK>::ACE_TSS_Write_Guard (LOCK &lock, int block)
+{
+// ACE_TRACE ("ACE_TSS_Write_Guard<LOCK>::ACE_TSS_Write_Guard");
+
+ this->init_key ();
+ ACE_Guard<LOCK> *guard;
+ ACE_NEW (guard, ACE_Write_Guard<LOCK> (lock, block));
+ ACE_Thread::setspecific (this->key_, (void *) guard);
+}
+
+template <class LOCK> int
+ACE_TSS_Write_Guard<LOCK>::acquire (void)
+{
+// ACE_TRACE ("ACE_TSS_Write_Guard<LOCK>::acquire");
+
+ ACE_Write_Guard<LOCK> *guard = 0;
+ ACE_Thread::getspecific (this->key_, (void **) &guard);
+ return guard->acquire_write ();
+}
+
+template <class LOCK> int
+ACE_TSS_Write_Guard<LOCK>::tryacquire (void)
+{
+// ACE_TRACE ("ACE_TSS_Write_Guard<LOCK>::tryacquire");
+
+ ACE_Write_Guard<LOCK> *guard = 0;
+ ACE_Thread::getspecific (this->key_, (void **) &guard);
+ return guard->tryacquire_write ();
+}
+
+template <class LOCK> int
+ACE_TSS_Write_Guard<LOCK>::acquire_write (void)
+{
+// ACE_TRACE ("ACE_TSS_Write_Guard<LOCK>::acquire_write");
+
+ return this->acquire ();
+}
+
+template <class LOCK> int
+ACE_TSS_Write_Guard<LOCK>::tryacquire_write (void)
+{
+// ACE_TRACE ("ACE_TSS_Write_Guard<LOCK>::tryacquire_write");
+
+ return this->tryacquire ();
+}
+
+template <class LOCK> void
+ACE_TSS_Write_Guard<LOCK>::dump (void) const
+{
+// ACE_TRACE ("ACE_TSS_Write_Guard<LOCK>::dump");
+ ACE_TSS_Guard<LOCK>::dump ();
+}
+
+template <class LOCK>
+ACE_TSS_Read_Guard<LOCK>::ACE_TSS_Read_Guard (LOCK &lock, int block)
+{
+// ACE_TRACE ("ACE_TSS_Read_Guard<LOCK>::ACE_TSS_Read_Guard");
+
+ this->init_key ();
+ ACE_Guard<LOCK> *guard;
+ ACE_NEW (guard, ACE_Read_Guard<LOCK> (lock, block));
+ ACE_Thread::setspecific (this->key_, (void *) guard);
+}
+
+template <class LOCK> int
+ACE_TSS_Read_Guard<LOCK>::acquire (void)
+{
+// ACE_TRACE ("ACE_TSS_Read_Guard<LOCK>::acquire");
+
+ ACE_Read_Guard<LOCK> *guard = 0;
+ ACE_Thread::getspecific (this->key_, (void **) &guard);
+ return guard->acquire_read ();
+}
+
+template <class LOCK> int
+ACE_TSS_Read_Guard<LOCK>::tryacquire (void)
+{
+// ACE_TRACE ("ACE_TSS_Read_Guard<LOCK>::tryacquire");
+
+ ACE_Read_Guard<LOCK> *guard = 0;
+ ACE_Thread::getspecific (this->key_, (void **) &guard);
+ return guard->tryacquire_read ();
+}
+
+template <class LOCK> int
+ACE_TSS_Read_Guard<LOCK>::acquire_read (void)
+{
+// ACE_TRACE ("ACE_TSS_Read_Guard<LOCK>::acquire_read");
+
+ return this->acquire ();
+}
+
+template <class LOCK> int
+ACE_TSS_Read_Guard<LOCK>::tryacquire_read (void)
+{
+// ACE_TRACE ("ACE_TSS_Read_Guard<LOCK>::tryacquire_read");
+
+ return this->tryacquire ();
+}
+
+template <class LOCK> void
+ACE_TSS_Read_Guard<LOCK>::dump (void) const
+{
+// ACE_TRACE ("ACE_TSS_Read_Guard<LOCK>::dump");
+ ACE_TSS_Guard<LOCK>::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 LOCK, class TYPE>
+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 <is_set_>, 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 <set_> 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 LOCK, class TYPE>
+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 <count_> to 0.
+
+ ACE_Atomic_Op (TYPE c);
+ // Initialize <count_> to c.
+
+ TYPE operator++ (void);
+ // Atomically pre-increment <count_>.
+
+ TYPE operator++ (int);
+ // Atomically post-increment <count_>.
+
+ TYPE operator+= (const TYPE i);
+ // Atomically increment <count_> by inc.
+
+ TYPE operator-- (void);
+ // Atomically pre-decrement <count_>.
+
+ TYPE operator-- (int);
+ // Atomically post-decrement <count_>.
+
+ TYPE operator-= (const TYPE i);
+ // Atomically decrement <count_> by dec.
+
+ TYPE operator== (const TYPE i) const;
+ // Atomically compare <count_> with rhs.
+
+ TYPE operator>= (const TYPE i) const;
+ // Atomically check if <count_> greater than or equal to rhs.
+
+ TYPE operator> (const TYPE rhs) const;
+ // Atomically check if <count_> greater than rhs.
+
+ TYPE operator<= (const TYPE rhs) const;
+ // Atomically check if <count_> less than or equal to rhs.
+
+ TYPE operator< (const TYPE rhs) const;
+ // Atomically check if <count_> less than rhs.
+
+ void operator= (const TYPE i);
+ // Atomically assign rhs to <count_>.
+
+ void operator= (const ACE_Atomic_Op<LOCK, TYPE> &rhs);
+ // Atomically assign <rhs> to <count_>.
+
+ operator TYPE () const;
+ // Atomically return <count_>.
+
+ 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<LOCK, TYPE> &);
+ // Manage copying...
+
+private:
+ LOCK lock_;
+ // Type of synchronization mechanism.
+
+ TYPE value_;
+ // Current object decorated by the atomic op.
+};
+
+template <class TYPE>
+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 <key_>.
+
+ 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<TYPE> &) {}
+ ACE_TSS (const ACE_TSS<TYPE> &) {}
+};
+
+#if defined (ACE_HAS_TEMPLATE_TYPEDEFS)
+class ACE_NULL_SYNCH
+ // = TITLE
+ // Implement a do nothing Synchronization wrapper that
+ // typedefs the <ACE_Condition> and <ACE_Mutex> 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 LOCK>
+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 <LOCK>.
+ //
+ // = DESCRIPTION
+ // The <LOCK> class given as an actual parameter must provide at
+ // the very least the <acquire>, <tryacquire>, <release>, and
+ // <remove> 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<LOCK> &) {}
+ ACE_Guard (const ACE_Guard<LOCK> &) {}
+};
+
+template <class LOCK>
+class ACE_Write_Guard : public ACE_Guard<LOCK>
+ // = TITLE
+ // This class is similar to class <ACE_Guard>, though it
+ // acquires/releases a write lock automatically (naturally, the
+ // <LOCK> it is instantiated with must support the appropriate
+ // API).
+{
+public:
+ ACE_Write_Guard (LOCK &m, int block = 1): ACE_Guard<LOCK> (&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 LOCK>
+class ACE_Read_Guard : public ACE_Guard<LOCK>
+ // = TITLE
+ // This class is similar to class <ACE_Guard>, though it
+ // acquires/releases a read lock automatically (naturally, the
+ // <LOCK> it is instantiated with must support the appropriate
+ // API).
+{
+public:
+ ACE_Read_Guard (LOCK &m, int block = 1): ACE_Guard<LOCK> (&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 LOCK>
+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<LOCK> &) {}
+ ACE_TSS_Guard (const ACE_TSS_Guard<LOCK> &) {}
+};
+
+template <class LOCK>
+class ACE_TSS_Write_Guard : public ACE_TSS_Guard<LOCK>
+ // = 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 LOCK>
+class ACE_TSS_Read_Guard : public ACE_TSS_Guard<LOCK>
+ // = TITLE
+ // This class is similar to class <ACE_TSS_Guard>, though it
+ // acquires/releases a read lock automatically (naturally, the
+ // <LOCK> 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 MUTEX>
+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" <wait> semantics. Else, if <abstime>
+ // != 0 and the call times out before the condition is signaled
+ // <wait> 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 <mutex>
+ // passed as a parameter (this is useful if you need to store the
+ // <Condition> in shared memory). Else, if <abstime> != 0 and the
+ // call times out before the condition is signaled <wait> 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<MUTEX> &) {}
+ ACE_Condition (const ACE_Condition<MUTEX> &c): mutex_ (c.mutex_) {}
+};
+
+template <class MUTEX>
+class ACE_Process_Condition : public ACE_Condition<MUTEX>
+ // = 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 MUTEX>
+class ACE_Thread_Condition : public ACE_Condition<MUTEX>
+ // = 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 <ACE_Condition> and <ACE_Mutex> to the
+ // <ACE_Condition> and <ACE_Mutex> 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 <ACE_Mutex>
+#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 <class LOCK, class TYPE> ACE_INLINE
+ACE_Atomic_Op<LOCK, TYPE>::ACE_Atomic_Op (const ACE_Atomic_Op<LOCK, TYPE> &rhs)
+{
+// ACE_TRACE ("ACE_Atomic_Op<LOCK, TYPE>::ACE_Atomic_Op");
+ *this = rhs; // Invoke the assignment operator.
+}
+
+template <class LOCK, class TYPE> ACE_INLINE TYPE
+ACE_Atomic_Op<LOCK, TYPE>::operator++ (void)
+{
+// ACE_TRACE ("ACE_Atomic_Op<LOCK, TYPE>::operator++");
+ ACE_Guard<LOCK> m (this->lock_);
+ return ++this->value_;
+}
+
+template <class LOCK, class TYPE> ACE_INLINE TYPE
+ACE_Atomic_Op<LOCK, TYPE>::operator++ (int)
+{
+// ACE_TRACE ("ACE_Atomic_Op<LOCK, TYPE>::operator++");
+ ACE_Guard<LOCK> m (this->lock_);
+ return this->value_++;
+}
+
+template <class LOCK, class TYPE> ACE_INLINE TYPE
+ACE_Atomic_Op<LOCK, TYPE>::operator+= (const TYPE i)
+{
+// ACE_TRACE ("ACE_Atomic_Op<LOCK, TYPE>::operator+=");
+ ACE_Guard<LOCK> m (this->lock_);
+ return this->value_ += i;
+}
+
+template <class LOCK, class TYPE> ACE_INLINE TYPE
+ACE_Atomic_Op<LOCK, TYPE>::operator-- (void)
+{
+// ACE_TRACE ("ACE_Atomic_Op<LOCK, TYPE>::operator--");
+ ACE_Guard<LOCK> m (this->lock_);
+ return --this->value_;
+}
+
+template <class LOCK, class TYPE> ACE_INLINE TYPE
+ACE_Atomic_Op<LOCK, TYPE>::operator-- (int)
+{
+// ACE_TRACE ("ACE_Atomic_Op<LOCK, TYPE>::operator--");
+ ACE_Guard<LOCK> m (this->lock_);
+ return this->value_--;
+}
+
+template <class LOCK, class TYPE> ACE_INLINE TYPE
+ACE_Atomic_Op<LOCK, TYPE>::operator-= (const TYPE i)
+{
+// ACE_TRACE ("ACE_Atomic_Op<LOCK, TYPE>::operator-=");
+ ACE_Guard<LOCK> m (this->lock_);
+ return this->value_ -= i;
+}
+
+template <class LOCK, class TYPE> ACE_INLINE TYPE
+ACE_Atomic_Op<LOCK, TYPE>::operator== (const TYPE i) const
+{
+// ACE_TRACE ("ACE_Atomic_Op<LOCK, TYPE>::operator==");
+ ACE_Guard<LOCK> m ((LOCK &) this->lock_);
+ return this->value_ == i;
+}
+
+template <class LOCK, class TYPE> ACE_INLINE TYPE
+ACE_Atomic_Op<LOCK, TYPE>::operator>= (const TYPE i) const
+{
+// ACE_TRACE ("ACE_Atomic_Op<LOCK, TYPE>::operator>=");
+ ACE_Guard<LOCK> m ((LOCK &) this->lock_);
+ return this->value_ >= i;
+}
+
+template <class LOCK, class TYPE> ACE_INLINE TYPE
+ACE_Atomic_Op<LOCK, TYPE>::operator> (const TYPE rhs) const
+{
+// ACE_TRACE ("ACE_Atomic_Op<LOCK, TYPE>::operator>");
+ ACE_Guard<LOCK> m ((LOCK &) this->lock_);
+ return this->value_ > rhs;
+}
+
+template <class LOCK, class TYPE> ACE_INLINE TYPE
+ACE_Atomic_Op<LOCK, TYPE>::operator<= (const TYPE rhs) const
+{
+// ACE_TRACE ("ACE_Atomic_Op<LOCK, TYPE>::operator<=");
+ ACE_Guard<LOCK> m ((LOCK &) this->lock_);
+ return this->value_ <= rhs;
+}
+
+template <class LOCK, class TYPE> ACE_INLINE TYPE
+ACE_Atomic_Op<LOCK, TYPE>::operator< (const TYPE rhs) const
+{
+// ACE_TRACE ("ACE_Atomic_Op<LOCK, TYPE>::operator<");
+ ACE_Guard<LOCK> m ((LOCK &) this->lock_);
+ return this->value_ < rhs;
+}
+
+template <class LOCK, class TYPE> void
+ACE_Atomic_Op<LOCK, TYPE>::operator= (const ACE_Atomic_Op<LOCK, TYPE> &rhs)
+{
+// ACE_TRACE ("ACE_Atomic_Op<LOCK, TYPE>::operator=");
+ if (&rhs == this)
+ return; // Avoid deadlock...
+ ACE_Guard<LOCK> m (this->lock_);
+ // This will call ACE_Atomic_Op::TYPE(), which will ensure the value
+ // of <rhs> is acquired atomically.
+ this->value_ = rhs;
+}
+
+template <class LOCK, class TYPE> ACE_INLINE
+ACE_Atomic_Op<LOCK, TYPE>::operator TYPE () const
+{
+// ACE_TRACE ("ACE_Atomic_Op<LOCK, TYPE>::operator TYPE");
+ ACE_Guard<LOCK> m ((LOCK &) this->lock_);
+ return this->value_;
+}
+
+template <class LOCK, class TYPE> ACE_INLINE void
+ACE_Atomic_Op<LOCK, TYPE>::operator= (const TYPE i)
+{
+// ACE_TRACE ("ACE_Atomic_Op<LOCK, TYPE>::operator=");
+ ACE_Guard<LOCK> m (this->lock_);
+ this->value_ = i;
+}
+#if defined (ACE_HAS_THREADS)
+
+template<class MUTEX> ACE_INLINE int
+ACE_Condition<MUTEX>::remove (void)
+{
+// ACE_TRACE ("ACE_Condition<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;
+}
+
+template<class MUTEX> ACE_INLINE MUTEX &
+ACE_Condition<MUTEX>::mutex (void)
+{
+// ACE_TRACE ("ACE_Condition<MUTEX>::mutex");
+ return this->mutex_;
+}
+
+template <class MUTEX> ACE_INLINE int
+ACE_Condition<MUTEX>::signal (void)
+{
+// ACE_TRACE ("ACE_Condition<MUTEX>::signal");
+ return ACE_OS::cond_signal (&this->cond_);
+}
+
+template <class MUTEX> ACE_INLINE int
+ACE_Condition<MUTEX>::broadcast (void)
+{
+// ACE_TRACE ("ACE_Condition<MUTEX>::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<ACE_MMAP_Memory_Pool, ACE_Null_Mutex>;
+template class ACE_Allocator_Adapter<ACE_Malloc<ACE_MMAP_Memory_Pool, ACE_Null_Mutex> >;
+#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 <ACE_MMAP_Memory_Pool, ACE_Null_Mutex> MALLOC;
+ typedef ACE_Allocator_Adapter<MALLOC> 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 <sys/socket.h> 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 <sys/socket.h> 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 <timeout> of 0 means
+ // block forever, a <timeout> of {0, 0} means poll. <restart> == 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 <new_stream> to the <remote_sap>, waiting up to
+// <timeout> 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>.
+ 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>.
+ 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 <new_stream> if things go well.
+ // The <remote_sap> is the address that we are trying to connect
+ // with. The <timeout> 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 <errno == EWOULDBLOCK>. 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 <errno == ETIMEDOUT>.
+ // The <local_sap> is the value of local address to bind to. If
+ // it's the default value of <ACE_Addr::sap_any> then the user is
+ // letting the OS do the binding. If <reuse_addr> == 1 then the
+ // <local_addr> 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 <new_stream> if things go well.
+ // The <remote_sap> is the address that we are trying to connect
+ // with. The <timeout> 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 <errno == EWOULDBLOCK>. 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 <errno == ETIMEDOUT>.
+ // The <local_sap> is the value of local address to bind to. If
+ // it's the default value of <ACE_Addr::sap_any> then the user is
+ // letting the OS do the binding. If <reuse_addr> == 1 then the
+ // <local_addr> 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 <new_stream> contains
+ // the connected ACE_SOCK_Stream. If <remote_sap> 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_SYNCH_1>
+ACE_Thread_Mutex ACE_Task_Exit<ACE_SYNCH_2>::ace_task_lock_;
+#endif /* defined (ACE_MT_SAFE) && !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) */
+
+template<ACE_SYNCH_1> ACE_Task_Exit<ACE_SYNCH_2> *
+ACE_Task_Exit<ACE_SYNCH_2>::instance (void)
+{
+ ACE_TRACE ("ACE_Task_Exit<ACE_SYNCH_2>::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<ACE_SYNCH_2>) *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<ACE_SYNCH_2>), 0);
+ }
+
+ return ACE_TSS_GET (instance_, ACE_Task_Exit<ACE_SYNCH_2>);
+
+}
+
+// Grab hold of the Task * so that we can close() it in the
+// destructor.
+
+template<ACE_SYNCH_1>
+ACE_Task_Exit<ACE_SYNCH_2>::ACE_Task_Exit (void)
+ : t_ (0),
+ status_ ((void *) -1)
+{
+ ACE_TRACE ("ACE_Task_Exit<ACE_SYNCH_2>::ACE_Task_Exit");
+}
+
+// Set the this pointer...
+
+template<ACE_SYNCH_1> void
+ACE_Task_Exit<ACE_SYNCH_2>::set_this (ACE_Task<ACE_SYNCH_2> *t)
+{
+ ACE_TRACE ("ACE_Task_Exit<ACE_SYNCH_2>::set_this");
+ this->t_ = t;
+
+ if (t != 0)
+ this->tc_.insert (t->thr_mgr ());
+}
+
+// Set the thread exit status value.
+
+template<ACE_SYNCH_1> void *
+ACE_Task_Exit<ACE_SYNCH_2>::status (void *s)
+{
+ ACE_TRACE ("ACE_Task_Exit<ACE_SYNCH_2>::status");
+ return this->status_ = s;
+}
+
+template<ACE_SYNCH_1> void *
+ACE_Task_Exit<ACE_SYNCH_2>::status (void)
+{
+ ACE_TRACE ("ACE_Task_Exit<ACE_SYNCH_2>::status");
+ return this->status_;
+}
+
+// When this object is destroyed the Task is automatically closed
+// down!
+
+template<ACE_SYNCH_1>
+ACE_Task_Exit<ACE_SYNCH_2>::~ACE_Task_Exit (void)
+{
+ ACE_TRACE ("ACE_Task_Exit<ACE_SYNCH_2>::~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_SYNCH_1> ACE_INLINE void
+ACE_Task<ACE_SYNCH_2>::dump (void) const
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::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_SYNCH_1>
+ACE_Task<ACE_SYNCH_2>::ACE_Task (ACE_Thread_Manager *thr_man,
+ ACE_Message_Queue<ACE_SYNCH_2> *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_SYNCH_2>::ACE_Task");
+
+ if (mq == 0)
+ {
+ ACE_NEW (mq, ACE_Message_Queue<ACE_SYNCH_2>);
+ this->delete_msg_queue_ = 1;
+ }
+
+ this->msg_queue_ = mq;
+}
+
+template<ACE_SYNCH_1>
+ACE_Task<ACE_SYNCH_2>::~ACE_Task (void)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::~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<ACE_SYNCH_1> void *
+ACE_Task<ACE_SYNCH_2>::svc_run (ACE_Task<ACE_SYNCH_2> *t)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::svc_run");
+
+ // Obtain our thread-specific exit hook and make sure that it knows
+ // how to clean us up!
+ ACE_Task_Exit<ACE_SYNCH_2> *exit_hook =
+ ACE_Task_Exit<ACE_SYNCH_2>::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_SYNCH_1> ACE_Task<ACE_SYNCH_2> *
+ACE_Task<ACE_SYNCH_2>::sibling (void)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::sibling");
+ if (this->mod_ == 0)
+ return 0;
+ else
+ return this->mod_->sibling (this);
+}
+
+template<ACE_SYNCH_1> const char *
+ACE_Task<ACE_SYNCH_2>::name (void) const
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::name");
+ if (this->mod_ == 0)
+ return 0;
+ else
+ return this->mod_->name ();
+}
+
+template<ACE_SYNCH_1> ACE_Module<ACE_SYNCH_2> *
+ACE_Task<ACE_SYNCH_2>::module (void) const
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::module");
+ return this->mod_;
+}
+
+// Get the current group id.
+template <ACE_SYNCH_1> ACE_INLINE int
+ACE_Task<ACE_SYNCH_2>::grp_id (void)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::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_SYNCH_1> ACE_INLINE void
+ACE_Task<ACE_SYNCH_2>::grp_id (int id)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::grp_id");
+ ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->lock_));
+ this->grp_id_ = id;
+}
+
+// Suspend a task.
+template<ACE_SYNCH_1> int
+ACE_Task<ACE_SYNCH_2>::suspend (void)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::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<ACE_SYNCH_1> int
+ACE_Task<ACE_SYNCH_2>::resume (void)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::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<ACE_SYNCH_1> int
+ACE_Task<ACE_SYNCH_2>::activate (long flags,
+ int n_threads,
+ int force_active,
+ u_int priority,
+ int grp_id)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::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<ACE_SYNCH_2>::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 <ACE_SYNCH_1> class ACE_Module;
+template <ACE_SYNCH_1> 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 <ACE_SYNCH_1>
+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<ACE_SYNCH_2>;
+friend class ACE_Module_Type;
+friend class ACE_Task_Exit<ACE_SYNCH_2>;
+public:
+ // = Initialization/termination methods.
+ ACE_Task (ACE_Thread_Manager *thr_mgr = 0,
+ ACE_Message_Queue<ACE_SYNCH_2> *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. <args> can be used to pass arbitrary
+ // information into <open>.
+
+ 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 <n_threads> of
+ // control, all running at the <priority> level with the same
+ // <grp_id>, all of which invoke <Task::svc>. Returns -1 if failure
+ // occurs, returns 1 if Task is already an active object and
+ // <force_active> 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 <force_active> 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<ACE_SYNCH_2> *msg_queue (void);
+ // Gets the message queue associated with this task.
+
+ void msg_queue (ACE_Message_Queue<ACE_SYNCH_2> *);
+ // 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<ACE_SYNCH_2> *);
+ // 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<ACE_SYNCH_2> *sibling (void);
+ // Return the Task's sibling if there's one associated with the
+ // Task's Module, else returns 0.
+
+ ACE_Module<ACE_SYNCH_2> *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<ACE_SYNCH_2> *next (void);
+ // Get next Task pointer.
+ void next (ACE_Task<ACE_SYNCH_2> *);
+ // 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 <ACE_Task_Exit> 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
+ // <thr_count_> 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<ACE_SYNCH_2> *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<ACE_SYNCH_2> *mod_;
+ // Back-pointer to the enclosing module.
+
+ ACE_Task<ACE_SYNCH_2> *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<ACE_SYNCH_1>
+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<ACE_SYNCH_2> *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 <close> method of the captured Task on exit.
+
+ static ACE_Task_Exit<ACE_SYNCH_2> *instance (void);
+ // Singleton access point.
+
+private:
+ ACE_Task<ACE_SYNCH_2> *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_SYNCH_1> ACE_INLINE size_t
+ACE_Task<ACE_SYNCH_2>::thr_count (void)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::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_SYNCH_1> ACE_INLINE void
+ACE_Task<ACE_SYNCH_2>::thr_count_dec (void)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::thr_count_dec");
+ ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->lock_));
+
+ this->thr_count_--;
+}
+
+template <ACE_SYNCH_1> ACE_INLINE void
+ACE_Task<ACE_SYNCH_2>::water_marks (ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds cmd,
+ size_t size)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::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_SYNCH_1> ACE_INLINE int
+ACE_Task<ACE_SYNCH_2>::getq (ACE_Message_Block *&mb, ACE_Time_Value *tv)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::getq");
+ return this->msg_queue_->dequeue_head (mb, tv);
+}
+
+template <ACE_SYNCH_1> ACE_INLINE int
+ACE_Task<ACE_SYNCH_2>::can_put (ACE_Message_Block *)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::can_put");
+ assert (!"not implemented");
+ return -1;
+}
+
+template <ACE_SYNCH_1> ACE_INLINE int
+ACE_Task<ACE_SYNCH_2>::putq (ACE_Message_Block *mb, ACE_Time_Value *tv)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::putq");
+ return this->msg_queue_->enqueue_tail (mb, tv);
+}
+
+template <ACE_SYNCH_1> ACE_INLINE int
+ACE_Task<ACE_SYNCH_2>::ungetq (ACE_Message_Block *mb, ACE_Time_Value *tv)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::ungetq");
+ return this->msg_queue_->enqueue_head (mb, tv);
+}
+
+template <ACE_SYNCH_1> ACE_INLINE int
+ACE_Task<ACE_SYNCH_2>::is_reader (void)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::is_reader");
+ return (ACE_BIT_ENABLED (this->flags_, ACE_Task_Flags::ACE_READER));
+}
+
+template <ACE_SYNCH_1> ACE_INLINE int
+ACE_Task<ACE_SYNCH_2>::is_writer (void)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::is_writer");
+ return (ACE_BIT_DISABLED (this->flags_, ACE_Task_Flags::ACE_READER));
+}
+
+template <ACE_SYNCH_1> ACE_INLINE int
+ACE_Task<ACE_SYNCH_2>::flush (u_long flag)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::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_SYNCH_1> ACE_INLINE int
+ACE_Task<ACE_SYNCH_2>::svc (void)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::svc");
+ return 0;
+}
+
+template <ACE_SYNCH_1> ACE_INLINE ACE_Task<ACE_SYNCH_2> *
+ACE_Task<ACE_SYNCH_2>::next (void)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::next");
+ return this->next_;
+}
+
+template <ACE_SYNCH_1> ACE_INLINE void
+ACE_Task<ACE_SYNCH_2>::next (ACE_Task<ACE_SYNCH_2> *q)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::next");
+ this->next_ = q;
+}
+
+template <ACE_SYNCH_1> ACE_INLINE ACE_Thread_Manager *
+ACE_Task<ACE_SYNCH_2>::thr_mgr (void)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::thr_mgr");
+ return this->thr_mgr_;
+}
+
+template <ACE_SYNCH_1> ACE_INLINE void
+ACE_Task<ACE_SYNCH_2>::thr_mgr (ACE_Thread_Manager *thr_mgr)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::thr_mgr");
+ this->thr_mgr_ = thr_mgr;
+}
+
+template <ACE_SYNCH_1> ACE_INLINE void
+ACE_Task<ACE_SYNCH_2>::msg_queue (ACE_Message_Queue<ACE_SYNCH_2> *mq)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::msg_queue");
+ this->msg_queue_ = mq;
+}
+
+template <ACE_SYNCH_1> ACE_Message_Queue<ACE_SYNCH_2> *
+ACE_Task<ACE_SYNCH_2>::msg_queue (void)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::msg_queue");
+ return this->msg_queue_;
+}
+
+// Transfer msg to the next ACE_Task.
+
+template <ACE_SYNCH_1> ACE_INLINE int
+ACE_Task<ACE_SYNCH_2>::put_next (ACE_Message_Block *msg, ACE_Time_Value *tv)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::put_next");
+ return this->next_ == 0 ? -1 : this->next_->put (msg, tv);
+}
+
+template <ACE_SYNCH_1> ACE_INLINE int
+ACE_Task<ACE_SYNCH_2>::reply (ACE_Message_Block *mb, ACE_Time_Value *tv)
+{
+ ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::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 <func> with argument <arg>.
+ // 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 <stack>s
+ // are. Returns the number of threads actually spawned (if this
+ // doesn't equal the number requested then something has gone wrong
+ // and <errno> 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 <func> with argument <arg>.
+ // The thread_ids of successfully spawned threads will be placed
+ // into the <thread_ids> buffer, which must be the same size as <n>.
+ // 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 <stack>s
+ // are. Returns the number of threads actually spawned (if this
+ // doesn't equal the number requested then something has gone wrong
+ // and <errno> 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 <keyp> 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, <key>, for the calling
+ // thread.
+
+ static int getspecific (ACE_thread_key_t key,
+ void **valuep);
+ // Stores the current value bound to <key> for the calling thread
+ // into the location pointed to by <valuep>.
+
+ 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 <keyp> 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, <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 <key> for the calling thread
+// into the location pointed to by <valuep>.
+
+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 <t_id>. 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 <Thread_Manager>.
+{
+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 <func>.
+
+ // 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 <func>.
+
+ // 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 <do_thread_exit> is
+ // non-0 then <ACE_Thread::exit> is called to exit the thread, in
+ // which case <status> 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
+ // <Thread_Manager> or <timeout> expires. Returns 0 on success and
+ // -1 on failure.
+
+ // = Accessors for <ACE_Thread_Descriptors>.
+ 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 <t_id> 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 <t_id> 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 <t_id> 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 <t_id>. Returns
+ // -1 if <t_id> is not in the table doesn't contain <t_id>.
+
+ 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 <thread_descriptor>. 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 <hthread_descriptor>.
+ // 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 <thread> is in a particular <state>.
+ // This call updates the TSS cache if possible to speed up
+ // subsequent searches.
+
+ int apply_grp (int grp_id, THR_FUNC, int = 0);
+ // Apply <func> to all members of the table that match the <grp_id>.
+
+ int apply_all (THR_FUNC, int = 0);
+ // Apply <func> to all members of the table.
+
+ int resume_thr (int i);
+ // Resume the thread at index <i>.
+
+ int suspend_thr (int i);
+ // Suspend the thread at index <i>.
+
+ int kill_thr (int i, int signum);
+ // Send signal <signum> to the thread at index <i>.
+
+ int cancel_thr (int i);
+ // Set the cancellation flag for the thread at index <i>.
+
+ 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 <insert> != 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 <Thread_Manager>.
+
+ int insert (ACE_Thread_Manager *tm);
+ // Store the <Thread_Manager> and use it to register ourselves for
+ // correct shutdown.
+
+ ACE_Thread_Manager *thr_mgr (void);
+ // Returns the current <Thread_Manager>.
+
+ ACE_Thread_Manager *thr_mgr (ACE_Thread_Manager *);
+ // Atomically set a new <Thread_Manager> and return the old
+ // <Thread_Manager>.
+
+ 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 <Thread_Manager>.
+
+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 <Thread_Manager> and return the old
+// <Thread_Manager>.
+
+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, "<unknown type> = %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 <ACE_Time_Request> 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 <Transfer> 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., <TIME_UPDATE>)
+
+ ACE_UINT32 block_forever_;
+ // Indicates if we should block forever. If 0, then <secTimeout_>
+ // and <usecTimeout_> 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 <time_>
+ };
+
+ 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 <pthread.h>
+}
+#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 <time.h>
+#if defined (ACE_NEEDS_SYSTIME_H)
+// Some platforms may need to include this, but I suspect that most
+// will get it from <time.h>
+#if defined (VXWORKS)
+#include <sys/times.h>
+#else
+#include <sys/time.h>
+#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 <sys/timers.h> - Tom Marrs
+#include <sys/timers.h>
+#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 <tv> to this.
+
+ void operator -= (const ACE_Time_Value &tv);
+ // Subtract <tv> 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 <ACE_Event_Handler> with a value of
+// <timer_id> 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 <handler> 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 <handle_timeout> method for all Timers whose values are <=
+// <cur_time>.
+
+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 <handle_timeout> on when a timeout occurs.
+
+ const void *arg_;
+ // Argument to pass to <handle_timeout>.
+
+ 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 <event_handler> that will expire after <delay> amount
+ // of time. If it expires then <arg> is passed in as the value to
+ // the <event_handler>'s <handle_timeout> callback method. If
+ // <interval> is != to <ACE_Time_Value::zero> then it is used to
+ // reschedule the <event_handler> automatically. This method
+ // returns a timer handle that uniquely identifies the
+ // <event_handler> 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 (ACE_Event_Handler *event_handler);
+ // Cancel all <event_handlers> that match the address of
+ // <event_handler>.
+
+ virtual int cancel (int timer_id, const void **arg = 0);
+ // Cancel the single <ACE_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.
+
+ virtual int expire (const ACE_Time_Value &current_time);
+ // Run the <handle_timeout> method for all Timers whose values are
+ // <= <cur_time>.
+
+ virtual ACE_Time_Value *calculate_timeout (ACE_Time_Value *max);
+ // Determine the next event to timeout. Returns <max> 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 <cancel (int)>
+ // 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 <sleep_hook> 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
+// <timeout> 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
+ // <timeout> expires. If some other thread currently holds the
+ // token then <sleep_hook> is called before our thread goes to
+ // sleep. This <sleep_hook> 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 <sleep_hook>
+ // 1 if <sleep_hook> is called.
+ // -1 if failure or timeout occurs (if timeout occurs errno == ETIME)
+ // If <timeout> == <&ACE_Time_Value::zero> then acquire has polling
+ // semantics (and does *not* call <sleep_hook>).
+
+ int acquire (ACE_Time_Value *timeout = 0);
+ // This behaves just like the previous <acquire> method, except
+ // that it invokes the virtual function called <sleep_hook>
+ // 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 <acquire> 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 <requeue_position> ==
+ // -1 and there are other threads waiting to obtain the token we are
+ // queued at the end of the list of waiters. If <requeue_position>
+ // > -1 then it indicates how many entries to skip over before
+ // inserting our thread into the list of waiters (e.g.,
+ // <requeue_position> == 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 <acquire>).
+
+ 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 <acquire> and <tryacquire> 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., <owner_>) 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<ACE_Token_Name, ACE_Token_Proxy *, ACE_Null_Mutex>;
+template class ACE_Map_Iterator<ACE_Token_Name, ACE_Token_Proxy *, ACE_Null_Mutex>;
+template class ACE_Map_Entry<ACE_Token_Name, ACE_Token_Proxy *>;
+#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);
+ // <debug> print out verbose debugging messages. <name> 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 <errno> == problem. If a token
+ // proxy already exists in the collection with the same name, the
+ // insertion will fail. Also, <token> 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 <errno> ==
+ // 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 <token_name>. The other
+ // parameters are passed to <token>::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 <token_name>.
+
+ 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 <errno> ==
+ // 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 <token_name>. The other
+ // parameters are passed to <token>::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 <errno> ==
+ // problem.
+
+
+ virtual int release (const char *token_name,
+ ACE_Synch_Options &options =
+ ACE_Synch_Options::defaults);
+ // Release the token corresponding to <token_name>. The other
+ // parameters are passed to <token>::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<TOKEN_NAME, ACE_Token_Proxy *, ACE_Null_Mutex>
+ COLLECTION;
+ // COLLECTION maintains a mapping from token names to ACE_Tokens*
+
+ typedef ACE_Map_Iterator<TOKEN_NAME, ACE_Token_Proxy *, ACE_Null_Mutex>
+ COLLECTION_ITERATOR;
+ // Allows iterations through collection_
+
+ typedef ACE_Map_Entry<TOKEN_NAME, ACE_Token_Proxy *>
+ 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 <ACE_TPQ_Entry>;
+#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<TOKEN_NAME, ACE_Mutex_Invariants *, ACE_Null_Mutex>
+ MUTEX_COLLECTION;
+ // COLLECTION maintains a mapping from token names to mutexes.
+
+ typedef ACE_Map_Iterator<TOKEN_NAME, ACE_Mutex_Invariants *, ACE_Null_Mutex>
+ MUTEX_COLLECTION_ITERATOR;
+ // Allows iterations through collection.
+
+ typedef ACE_Map_Entry<TOKEN_NAME, ACE_Mutex_Invariants *>
+ 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<TOKEN_NAME, ACE_RWLock_Invariants *, ACE_Null_Mutex>
+ RWLOCK_COLLECTION;
+ // COLLECTION maintains a mapping from token names to mutexes.
+
+ typedef ACE_Map_Iterator<TOKEN_NAME, ACE_RWLock_Invariants *, ACE_Null_Mutex>
+ RWLOCK_COLLECTION_ITERATOR;
+ // Allows iterations through collection.
+
+ typedef ACE_Map_Entry<TOKEN_NAME, ACE_RWLock_Invariants *>
+ 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 <ACE_Token_Name, ACE_Tokens *, ACE_Null_Mutex>;
+template class ACE_Map_Iterator<ACE_Token_Name, ACE_Tokens *, ACE_Null_Mutex>;
+template class ACE_Map_Entry <ACE_Token_Name, ACE_Tokens *>;
+#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_. <token_name> 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<TOKEN_NAME, ACE_Tokens *, ACE_Null_Mutex>
+ COLLECTION;
+ // COLLECTION maintains a mapping from token names to ACE_Tokens*
+
+ typedef ACE_Map_Iterator<TOKEN_NAME, ACE_Tokens *, ACE_Null_Mutex>
+ COLLECTION_ITERATOR;
+ // Allows iterations through collection_
+
+ typedef ACE_Map_Entry<TOKEN_NAME, ACE_Tokens *>
+ 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, "<unknown operation type> = %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 <Transfer> 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., <ACQUIRE>, <RELEASE>, <RENEW>, and <REMOVE>).
+
+ 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 <secTimeout_>
+ // and <usecTimeout_> 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 <tokenName_> followed by a ':'
+ // followed by the <clientId_>.
+ } 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 <Transfer> struct are transmitted to the server.
+
+ struct Transfer
+ {
+ ACE_UINT32 length_;
+ // Length of entire reply.
+
+ ACE_UINT32 errno_;
+ // Indicates why error occurred if <this->type_> == <FAILURE>.
+ // Typical reasons include:
+ // <EWOULDBLOCK> (if client requested a non-blocking check for the token).
+ // <ETIME> (if the client timed out after waiting for the token).
+ // <ENOLCK> (if the token lock was removed out from underneath a waiter).
+ // <EACCES> (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 <class T> void
+ACE_Typed_SV_Message<T>::dump (void) const
+{
+ ACE_TRACE ("ACE_Typed_SV_Message<T>::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 T>
+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 <class T> ACE_INLINE
+ACE_Typed_SV_Message<T>::ACE_Typed_SV_Message (long t,
+ int l,
+ int m)
+ : type_ (t)
+{
+ ACE_TRACE ("ACE_Typed_SV_Message<T>::ACE_Typed_SV_Message");
+ this->length (l);
+ this->max_size (m);
+}
+
+template <class T> ACE_INLINE
+ACE_Typed_SV_Message<T>::ACE_Typed_SV_Message (const T &d,
+ long t,
+ int l,
+ int m)
+ : data_ (d),
+ type_ (t)
+{
+ ACE_TRACE ("ACE_Typed_SV_Message<T>::ACE_Typed_SV_Message");
+ this->length (l);
+ this->max_size (m);
+}
+
+template <class T> ACE_INLINE
+ACE_Typed_SV_Message<T>::~ACE_Typed_SV_Message (void)
+{
+ ACE_TRACE ("ACE_Typed_SV_Message<T>::~ACE_Typed_SV_Message");
+}
+
+template <class T> ACE_INLINE long
+ACE_Typed_SV_Message<T>::type (void) const
+{
+ ACE_TRACE ("ACE_Typed_SV_Message<T>::type");
+ return this->type_;
+}
+
+template <class T> ACE_INLINE void
+ACE_Typed_SV_Message<T>::type (long t)
+{
+ ACE_TRACE ("ACE_Typed_SV_Message<T>::type");
+ this->type_ = t;
+}
+
+template <class T> ACE_INLINE int
+ACE_Typed_SV_Message<T>::length (void) const
+{
+ ACE_TRACE ("ACE_Typed_SV_Message<T>::length");
+ return this->length_;
+}
+
+template <class T> ACE_INLINE void
+ACE_Typed_SV_Message<T>::length (int len)
+{
+ ACE_TRACE ("ACE_Typed_SV_Message<T>::length");
+ this->length_ = len + (sizeof *this - (sizeof this->type_ + sizeof this->data_));
+}
+
+template <class T> ACE_INLINE int
+ACE_Typed_SV_Message<T>::max_size (void) const
+{
+ ACE_TRACE ("ACE_Typed_SV_Message<T>::max_size");
+ return this->max_;
+}
+
+template <class T> ACE_INLINE void
+ACE_Typed_SV_Message<T>::max_size (int m)
+{
+ ACE_TRACE ("ACE_Typed_SV_Message<T>::max_size");
+ this->max_ = m + (sizeof *this - (sizeof this->type_ + sizeof this->data_));
+}
+
+template <class T> T &
+ACE_Typed_SV_Message<T>::data (void)
+{
+ ACE_TRACE ("ACE_Typed_SV_Message<T>::data");
+ return this->data_;
+}
+
+template <class T> void
+ACE_Typed_SV_Message<T>::data (const T &d)
+{
+ ACE_TRACE ("ACE_Typed_SV_Message<T>::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 <class T> void
+ACE_Typed_SV_Message_Queue<T>::dump (void) const
+{
+ ACE_TRACE ("ACE_Typed_SV_Message_Queue<T>::dump");
+}
+
+template <class T>
+ACE_Typed_SV_Message_Queue<T>::ACE_Typed_SV_Message_Queue (void)
+{
+ ACE_TRACE ("ACE_Typed_SV_Message_Queue<T>::ACE_Typed_SV_Message_Queue");
+}
+
+template <class T>
+ACE_Typed_SV_Message_Queue<T>::ACE_Typed_SV_Message_Queue (key_t external_id,
+ int create,
+ int perms)
+{
+ ACE_TRACE ("ACE_Typed_SV_Message_Queue<T>::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 <class T>
+ACE_Typed_SV_Message_Queue<T>::~ACE_Typed_SV_Message_Queue (void)
+{
+ ACE_TRACE ("ACE_Typed_SV_Message_Queue<T>::~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 T>
+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<T> &mb, int mflags = 0);
+ int recv (ACE_Typed_SV_Message<T> &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 <class T> ACE_INLINE int
+ACE_Typed_SV_Message_Queue<T>::open (key_t external_id,
+ int create,
+ int perms)
+{
+ ACE_TRACE ("ACE_Typed_SV_Message_Queue<T>::open");
+ return this->message_queue_.open (external_id, create, perms);
+}
+
+/* What does it mean to close a message queue?! */
+
+template <class T> ACE_INLINE int
+ACE_Typed_SV_Message_Queue<T>::close (void)
+{
+ ACE_TRACE ("ACE_Typed_SV_Message_Queue<T>::close");
+ return 1;
+}
+
+template <class T> ACE_INLINE int
+ACE_Typed_SV_Message_Queue<T>::recv (ACE_Typed_SV_Message<T> &mb,
+ int mflags)
+{
+ ACE_TRACE ("ACE_Typed_SV_Message_Queue<T>::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 <class T> ACE_INLINE int
+ACE_Typed_SV_Message_Queue<T>::send (const ACE_Typed_SV_Message<T> &mb,
+ int mflags)
+{
+ ACE_TRACE ("ACE_Typed_SV_Message_Queue<T>::send");
+ return this->message_queue_.send ((ACE_SV_Message &) mb,
+ mb.length (), mflags);
+}
+
+template <class T> ACE_INLINE int
+ACE_Typed_SV_Message_Queue<T>::remove (void)
+{
+ ACE_TRACE ("ACE_Typed_SV_Message_Queue<T>::remove");
+ return this->message_queue_.remove ();
+}
+
+template <class T> ACE_INLINE int
+ACE_Typed_SV_Message_Queue<T>::control (int option,
+ void *arg)
+{
+ ACE_TRACE ("ACE_Typed_SV_Message_Queue<T>::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 <Message_Queue>.
+ 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 <timeout> of 0 means
+ // block forever, a <timeout> of {0, 0} means poll. <restart> == 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
+ // <ACE_UPIPE_STREAM> 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 <new_stream> if things go well.
+ // The <remote_sap> is the address that we are trying to connect
+ // with. The <timeout> 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 <errno == EWOULDBLOCK>. 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 <errno == ETIMEDOUT>.
+ // The <local_sap> is the value of local address to bind to. If
+ // it's the default value of <ACE_Addr::sap_any> then the user is
+ // letting the OS do the binding. If <reuse_addr> == 1 then the
+ // <local_addr> is reused, even if it hasn't been cleanedup yet.
+ // The <flags> and <perms> 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 <new_stream> if things go well.
+ // The <remote_sap> is the address that we are trying to connect
+ // with. The <timeout> 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 <errno == EWOULDBLOCK>. 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 <errno == ETIMEDOUT>.
+ // The <local_sap> is the value of local address to bind to. If
+ // it's the default value of <ACE_Addr::sap_any> then the user is
+ // letting the OS do the binding. If <reuse_addr> == 1 then the
+ // <local_addr> is reused, even if it hasn't been cleanedup yet.
+ // The <flags> and <perms> 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<ACE_MT_SYNCH> 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 <n> 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 <n> 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 <n> 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 <n> 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 <UPIPE_Acceptor> and
+ // <UPIPE_Connector> 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 <ecn@clark.net> and Douglas C. Schmidt <schmidt@cs.wustl.edu>
+//
+// ============================================================================
+
+#if !defined (ACE_XTREACTOR_H)
+#define ACE_XTREACTOR_H
+
+#include "ace/Reactor.h"
+
+#if defined (ACE_HAS_XT)
+
+#define String XtString
+#include <X11/Intrinsic.h>
+#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
--- /dev/null
+++ b/ace/ace.mdp
Binary files 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 <olson@mcs.anl.gov> 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 <sys/syscall.h> 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 <sys/stdsyms.h>
+#include <sched.h> // 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 <sys/syscall.h> 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 <sys/syscall.h> 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 <sys/syscall.h> 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 <sys/syscall.h> file.
+#define ACE_HAS_SYSCALL_H
+
+// Platform supports recvmsg and sendmsg.
+#define ACE_HAS_MSG
+
+#define IRIX5
+#define ACE_HAS_ALLOCA
+// Compiler/platform has <alloca.h>
+#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 <sys/syscall.h> file.
+#define ACE_HAS_SYSCALL_H
+
+// Compiler/platform supports alloca()
+#define ACE_HAS_ALLOCA
+
+// Compiler/platform has <alloca.h>
+#define ACE_HAS_ALLOCA_H
+
+// IRIX5 needs to define bzero() in this odd file <bstring.h>
+#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 <poll.h>.
+#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 <sys/filio.h> 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 <sys/syscall.h> file.
+#define ACE_HAS_SYSCALL_H
+
+// Compiler/platform supports alloca()
+#define ACE_HAS_ALLOCA
+
+// Compiler/platform has <alloca.h>
+#define ACE_HAS_ALLOCA_H
+
+// IRIX5 needs to define bzero() in this odd file <bstring.h>
+#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 <poll.h>.
+#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 <sys/filio.h> 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 <sched.h>
+#include <task.h>
+#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 <sys/syscall.h> file.
+#define ACE_HAS_SYSCALL_H
+
+// Compiler/platform supports alloca()
+#define ACE_HAS_ALLOCA
+
+// Compiler/platform has <alloca.h>
+#define ACE_HAS_ALLOCA_H
+
+// Irix needs to define bzero() in this odd file <bstring.h>
+#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 <poll.h>.
+#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 <sys/filio.h> 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 <sys/syscall.h> 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 <alloca.h>
+#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 <pthread/mit/pthread.h>
+
+#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 <sys/syscall.h> 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 <alloca.h>
+#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 <sys/syscall.h> 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 <alloca.h>
+#define ACE_HAS_ALLOCA_H
+#endif // m88k
+
+// Sockets may be called in multi-threaded programs.
+#define ACE_HAS_MT_SAFE_SOCKETS
+
+// Platform contains <poll.h>.
+#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 <sys/filio.h> 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 <sys/procfs.h>
+#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 <sys/syscall.h> 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 <poll.h>.
+#define ACE_HAS_POLL
+
+// Platform supports POSIX timers via timestruc_t.
+#define ACE_HAS_POSIX_TIME
+
+// Platform defines struct timespec in <sys/timers.h>
+#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 <sys/procfs.h>
+//#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 <sys/syscall.h> 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 <poll.h>.
+#define ACE_HAS_POLL
+
+// Platform supports POSIX timers via timestruc_t.
+#define ACE_HAS_POSIX_TIME
+
+// Platform defines struct timespec in <sys/timers.h>
+// #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 <sys/syscall.h> 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 <sys/syscall.h> 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 <sys/filio.h> 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 <alloca.h>
+#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 <sys/syscall.h> file.
+#define ACE_HAS_SYSCALL_H
+
+// Compiler/platform supports alloca()
+#define ACE_HAS_ALLOCA
+
+// Compiler/platform has <alloca.h>
+#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 <sysent.h> header.
+#define ACE_HAS_SYSENT_H
+
+// Platform provides <sys/filio.h> 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 <sys/syscall.h> 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 <sys/filio.h> 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 <sys/syscall.h> 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 <sys/filio.h> 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 <sys/syscall.h> 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 <sys/filio.h> 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 <sys/syscall.h> 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 <sys/filio.h> 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 <sys/syscall.h> 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 <poll.h>.
+#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 <sys/filio.h> 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 <sys/syscall.h> 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 <alloca.h>
+#define ACE_HAS_ALLOCA_H
+
+// Sockets may be called in multi-threaded programs.
+#define ACE_HAS_MT_SAFE_SOCKETS
+
+// Platform contains <poll.h>.
+#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 <sys/filio.h> 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 <cstring>
+
+#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 <sys/syscall.h> 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 <alloca.h>
+#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 <poll.h>.
+#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 <sys/filio.h> 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 <sys/syscall.h> 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 <alloca.h>
+#define ACE_HAS_ALLOCA_H
+
+// Sockets may be called in multi-threaded programs.
+#define ACE_HAS_MT_SAFE_SOCKETS
+
+// Platform contains <poll.h>.
+#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 <sys/filio.h> 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 <sys/syscall.h> 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 <alloca.h>
+#define ACE_HAS_ALLOCA_H
+
+// Sockets may be called in multi-threaded programs.
+#define ACE_HAS_MT_SAFE_SOCKETS
+
+// Platform contains <poll.h>.
+#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 <sys/filio.h> 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 <cstring>
+
+#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 <sys/syscall.h> 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 <alloca.h>
+#define ACE_HAS_ALLOCA_H
+
+// Sockets may be called in multi-threaded programs.
+#define ACE_HAS_MT_SAFE_SOCKETS
+
+// Platform contains <poll.h>.
+#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 <sys/filio.h> 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 <sys/syscall.h> 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 <alloca.h>
+#define ACE_HAS_ALLOCA_H
+
+// Sockets may be called in multi-threaded programs.
+#define ACE_HAS_MT_SAFE_SOCKETS
+
+// Platform contains <poll.h>.
+#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 <sys/filio.h> 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 <sys/syscall.h> 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 <alloca.h>
+#define ACE_HAS_ALLOCA_H
+
+// Sockets may be called in multi-threaded programs.
+#define ACE_HAS_MT_SAFE_SOCKETS
+
+// Platform contains <poll.h>.
+#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 <sys/filio.h> 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 get<blah>by... 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 <winsock.h>
+
+#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 <poll.h>.
+//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 <sys/filio.h> 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 <winsock.h>
+
+#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
+
+// <windows.h> and MFC's <afxwin.h> are mutually
+// incompatible. <windows.h> 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) <winsock.h>,
+// 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. <afxwin.h> 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 <afxwin.h> // He is doing MFC
+#endif
+#ifdef _WINDLL // May be defined by MSVC++ IDE
+#include <afxwin.h> // He is doing MFC
+#endif
+
+#ifndef __AFX_H__ // set in afxwin.h
+#include <windows.h> // 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 <poll.h>.
+//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 <sys/filio.h> 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<CHANNEL_PEER_STREAM, SYNCH> (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<CHANNEL_PEER_STREAM, SYNCH>::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<Peer_Addr, Routing_Entry *, MUTEX>;
+template class ACE_Map_Iterator<Peer_Addr, Routing_Entry *, MUTEX>;
+template class ACE_Map_Entry<Peer_Addr, Routing_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<Peer_Addr, Routing_Entry, MUTEX>
+ ROUTING_TABLE;
+
+// Forward declaration.
+class Channel_Connector;
+
+class Channel : public ACE_Svc_Handler<CHANNEL_PEER_STREAM, SYNCH>
+ // = 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 <bytes>.
+
+ 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<Channel, CHANNEL_PEER_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<Channel, CHANNEL_PEER_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<CC_Config_File_Entry>;
+template class File_Parser<RT_Config_File_Entry>;
+#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<CC_Config_File_Entry>
+ // = 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<RT_Config_File_Entry>
+ // = 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 <class ENTRY> int
+File_Parser<ENTRY>::open (const char filename[])
+{
+ return (this->infile_ = ACE_OS::fopen (filename, "r")) == 0 ? -1 : 0;
+}
+
+template <class ENTRY> int
+File_Parser<ENTRY>::close (void)
+{
+ return ACE_OS::fclose (this->infile_);
+}
+
+template <class ENTRY> FP_RETURN_TYPE
+File_Parser<ENTRY>::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 <class ENTRY> FP_RETURN_TYPE
+File_Parser<ENTRY>::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 <class ENTRY> FP_RETURN_TYPE
+File_Parser<ENTRY>::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 <class ENTRY> int
+File_Parser<ENTRY>::delimiter (char ch)
+{
+ return ch == ' ' || ch == ',' || ch == '\t';
+}
+
+template <class ENTRY> int
+File_Parser<ENTRY>::comments (char ch)
+{
+ return ch == '#';
+}
+
+template <class ENTRY> int
+File_Parser<ENTRY>::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 ENTRY>
+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 INPUT_CHANNEL, class OUTPUT_CHANNEL>
+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<CONN_ID, Channel *, MUTEX> CONFIG_TABLE;
+ typedef ACE_Map_Iterator<CONN_ID, Channel *, MUTEX> 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 <class IC, class OC> int
+Gateway<IC, OC>::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 <class IC, class OC> int
+Gateway<IC, OC>::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 <class IC, class OC> int
+Gateway<IC, OC>::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 <CONN_ID, Channel *> *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 <class IC, class OC>
+Gateway<IC, OC>::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 <class IC, class OC> int
+Gateway<IC, OC>::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 <class IC, class OC> int
+Gateway<IC, OC>::initiate_connections (void)
+{
+ CONFIG_ITERATOR cti (this->config_table_);
+
+ // Iterate through the routing table connecting all the channels.
+
+ for (ACE_Map_Entry <CONN_ID, Channel *> *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 <class IC, class OC> int
+Gateway<IC, OC>::fini (void)
+{
+ // Question: do we need to do anything special about the Routing_Table?
+
+ CONFIG_ITERATOR cti (this->config_table_);
+
+ for (ACE_Map_Entry <CONN_ID, Channel *> *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 <class IC, class OC> int
+Gateway<IC, OC>::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 <class IC, class OC> int
+Gateway<IC, OC>::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 <class IC, class OC> int
+Gateway<IC, OC>::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 <class IC, class OC> int
+Gateway<IC, OC>::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<INPUT_CHANNEL, OUTPUT_CHANNEL> 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<Channel *> ENTRY_SET;
+ typedef ACE_Unbounded_Set_Iterator<Channel *> 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 <class EXT_ID, class INT_ID, class LOCK> ACE_INLINE int
+Routing_Table<EXT_ID, INT_ID, LOCK>::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 <class EXT_ID, class INT_ID, class LOCK> ACE_INLINE int
+Routing_Table<EXT_ID, INT_ID, LOCK>::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 <class EXT_ID, class INT_ID, class LOCK> ACE_INLINE int
+Routing_Table<EXT_ID, INT_ID, LOCK>::unbind (EXT_ID ext_id)
+{
+ return this->map_.unbind (ext_id);
+}
+
+template <class EXT_ID, class INT_ID, class LOCK> ACE_INLINE
+Routing_Iterator<EXT_ID, INT_ID, LOCK>::Routing_Iterator (Routing_Table<EXT_ID,
+ INT_ID, LOCK> &rt,
+ int ignore_inactive)
+ : map_iter_ (rt.map_),
+ ignore_inactive_ (ignore_inactive)
+{
+}
+
+template <class EXT_ID, class INT_ID, class LOCK> ACE_INLINE int
+Routing_Iterator<EXT_ID, INT_ID, LOCK>::next (INT_ID *&ss)
+{
+ // Loop in order to skip over inactive entries if necessary.
+
+ for (ACE_Map_Entry<EXT_ID, INT_ID *> *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 <class EXT_ID, class INT_ID, class LOCK> ACE_INLINE int
+Routing_Iterator<EXT_ID, INT_ID, LOCK>::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 EXT_ID, class INT_ID, class LOCK>
+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<EXT_ID, INT_ID *, LOCK> map_;
+ // Map external IDs to internal IDs.
+};
+
+template <class EXT_ID, class INT_ID, class LOCK>
+class Routing_Iterator
+{
+ // = TITLE
+ // Define an iterator for the Routing Table.
+public:
+ Routing_Iterator (Routing_Table<EXT_ID, INT_ID, LOCK> &mm,
+ int ignore_inactive = 1);
+ int next (INT_ID *&);
+ int advance (void);
+
+private:
+ ACE_Map_Iterator<EXT_ID, INT_ID *, LOCK> 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
+// <dequeue_head> 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<SYNCH>::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<SYNCH>::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 <ACE_HANDLE, Gateway_Handler *, ACE_Null_Mutex> HANDLER_MAP;
+typedef ACE_Map_Iterator<ACE_HANDLE, Gateway_Handler *, ACE_Null_Mutex> HANDLER_ITERATOR;
+typedef ACE_Map_Entry <ACE_HANDLE, Gateway_Handler *> MAP_ENTRY;
+
+// Handle Peer messages arriving as events.
+
+class Gateway_Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
+{
+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<ACE_SOCK_STREAM, ACE_NULL_SYNCH> 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<Gateway_Handler, ACE_SOCK_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<Gateway_Handler, ACE_SOCK_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 <Notification_Receiver_Handler> that
+ // receives notifications from the <Event_Comm::Notifier>.
+
+ 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 <Notification_Receiver> proxy object.
+
+ Event_Comm::Notifier *notifier_;
+ // Pointer to an IDL <Notifier> 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 <pathname>/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 <pathname>/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 <Consumers>.
+
+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 <Notification> to all <Notification_Receivers>.
+ 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 <Consumers>.
+
+ 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 <Notifier_Handler> 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 <Event_Comm::Notifier> 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 <CORBA.h>
+
+#include <string.h>
+
+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 <Notification_Receiver>
+//
+// = 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 <Notification_Receivers>.
+ //
+ // = DESCRIPTION
+{
+public:
+ Notification_Receiver_i (void);
+ ~Notification_Receiver_i (void);
+
+ virtual void receive_notification (const Event_Comm::Notification &notification,
+ CORBA::Environment &IT_env);
+ // Pass the <Notification> to the <Notification_Receiver>.
+
+ virtual void disconnect (const char *reason,
+ CORBA::Environment &IT_env);
+ // Disconnect the <Notification_Receiver> from the <Notifier>,
+ // giving it the <reason>.
+};
+
+#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 <Notifier>
+//
+// = 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 <Notifiers>.
+ //
+ // = 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 <reason>.
+
+ void send_notification (const Event_Comm::Notification &notification,
+ CORBA::Environment &IT_env);
+ // Send the <Notification> 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 <Notification_Receiver> to receive events that
+ // match <filtering_criteria> applied by the <Notifier>.
+
+ void unsubscribe (Event_Comm::Notification_Receiver *notification_receiver,
+ const char *filtering_criteria,
+ CORBA::Environment &IT_env);
+ // Unsubscribe the <Notification_Receiver>.
+
+private:
+ // The following implementation should be replaced
+ // by a standard container class from STL...
+
+ typedef ACE_Map_Manager <ACE_SString, Notification_Receiver_Entry *, ACE_Null_Mutex> MAP_MANAGER;
+ typedef ACE_Map_Iterator <ACE_SString, Notification_Receiver_Entry *, ACE_Null_Mutex> MAP_ITERATOR;
+ typedef ACE_Map_Entry <ACE_SString, Notification_Receiver_Entry *> MAP_ENTRY;
+
+ MAP_MANAGER map_;
+ // Table that maps a <Event_Comm::Notification_Receiver *> to a <Notification_Receiver_Entry *>.
+};
+
+#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 <CORBA.h>
+
+#include <string.h>
+
+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 <Notification>.
+ //
+ // = This is the type passed by the Notifier to the Notification_Receiver.
+ // Since it contains an <any>, 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 <Notification_Receiver> of events.
+ // Note that all operations are <oneway> to avoid blocking.
+ //
+ // = DESCRIPTION
+ {
+ oneway void receive_notification (in Notification notification);
+ // Inform the <Notification_Receiver> that <event> has occurred.
+
+ oneway void disconnect (in string reason);
+ // Disconnect the <Notification_Receiver> from the <Notifier>,
+ // giving it the <reason>.
+ };
+
+ interface Notifier
+ // = TITLE
+ // Defines the interface for a <Notifier> of events.
+ //
+ // = DESCRIPTION
+ {
+ oneway void send_disconnect (in string reason);
+ // Disconnect all the receivers, giving them the <reason>.
+
+ oneway void send_notification (in Notification notification);
+ // Send the <Notification> 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 <Notification_Receiver> to receive events that
+ // match the regular expresssion <filtering_criteria> applied by
+ // the <Notifier>. If <filtering_criteria> is "" then all events
+ // are matched.
+
+ oneway void unsubscribe (in Notification_Receiver notification_receiver,
+ in string filtering_criteria);
+ // Unsubscribe the <Notification_Receiver> that matches the
+ // filtering criteria. If <filtering_criteria> is "" then
+ // all <Notification_Receivers> 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 <Notification>.
+//
+// = AUTHOR
+// Douglas C. Schmidt (schmidt@cs.wustl.edu)
+//
+// ============================================================================
+
+#ifndef _NOTIFICATION_IDL
+#define _NOTIFICATION_IDL
+
+struct Notification
+ // = TITLE
+ // Defines the interface for an event <Notification>.
+ //
+ // = This is the type passed by the Notifier to the Notification_Receiver.
+ // Since it contains an <any>, 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
+// <Notification_Receiver> 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 <Notification_Receiver> of events.
+ // Note that all operations are <oneway> to avoid blocking.
+ //
+ // = DESCRIPTION
+{
+ oneway void receive_notification (in Notification notification);
+ // Inform the <Notification_Receiver> that <event> has occurred.
+
+ oneway void disconnect (in string reason);
+ // Disconnect the <Notification_Receiver> from the <Notifier>,
+ // giving it the <reason>.
+};
+
+#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 <Event_Comm::Notification_Receiver> that <event> has occurred.
+
+void
+Notification_Receiver_i::receive_notification
+ (const Event_Comm::Notification &notification,
+ CORBA::Environment &IT_env)
+{
+ const char *tmpstr = notification.tag_;
+
+ ACE_DEBUG ((LM_DEBUG, "**** got notification = %s\n", tmpstr));
+}
+
+// Disconnect the <Event_Comm::Notification_Receiver> from the <Event_Comm::Notifier>.
+
+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 <Notification_Receiver>
+//
+// = 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 <Notification_Receivers>.
+ //
+ // = DESCRIPTION
+{
+public:
+ Notification_Receiver_i (void);
+ ~Notification_Receiver_i (void);
+
+ virtual void receive_notification (const Event_Comm::Notification &notification,
+ CORBA::Environment &IT_env);
+ // Pass the <Notification> to the <Notification_Receiver>.
+
+ virtual void disconnect (const char *reason,
+ CORBA::Environment &IT_env);
+ // Disconnect the <Notification_Receiver> from the <Notifier>,
+ // giving it the <reason>.
+};
+
+#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 <Notifier>.
+//
+// = 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 <Notifier> of events.
+ //
+ // = DESCRIPTION
+{
+ oneway void send_disconnect (in string reason);
+ // Disconnect all the receivers, giving them the <reason>.
+
+ oneway void send_notification (in Notification notification);
+ // Send the <Notification> 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 <Notification_Receiver> to receive events that
+ // match <filtering_criteria> applied by the <Notifier>.
+
+ oneway void unsubscribe (in Notification_Receiver notification_receiver);
+ // Unsubscribe the <Notification_Receiver>.
+};
+
+#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 <Event_Comm::Notification_Receiver> 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 <Notification_Receiver_Entry> 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 <Notification_Receiver_Entry> 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 <reason>.
+
+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 &notification,
+ 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 <Notifier>
+//
+// = 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 <Notifiers>.
+ //
+ // = 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 <reason>.
+
+ void send_notification (const Event_Comm::Notification &notification,
+ CORBA::Environment &IT_env);
+ // Send the <Notification> 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 <Notification_Receiver> to receive events that
+ // match <filtering_criteria> applied by the <Notifier>.
+
+ void unsubscribe (Event_Comm::Notification_Receiver *notification_receiver,
+ const char *filtering_criteria,
+ CORBA::Environment &IT_env);
+ // Unsubscribe the <Notification_Receiver>.
+
+private:
+ // The following implementation should be replaced
+ // by a standard container class from STL...
+
+ typedef ACE_Map_Manager <ACE_SString, Notification_Receiver_Entry *, ACE_Null_Mutex> MAP_MANAGER;
+ typedef ACE_Map_Iterator <ACE_SString, Notification_Receiver_Entry *, ACE_Null_Mutex> MAP_ITERATOR;
+ typedef ACE_Map_Entry <ACE_SString, Notification_Receiver_Entry *> MAP_ENTRY;
+
+ MAP_MANAGER map_;
+ // Table that maps a <Event_Comm::Notification_Receiver *> to a <Notification_Receiver_Entry *>.
+};
+
+#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 <iostream.h>
+// @(#)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 <msg> of length <len> with priority <prio>.
+
+ 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<char> 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 <CORBA.h>
+
+#include <string.h>
+
+
+#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<char> 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 <iostream.h>
+#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 <iostream.h>
+#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.
+
+ <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., 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.
+
+ <signature of Ty Coon>, 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 <mrs@cygnus.com>
+
+ * src/new.cc: Since malloc/delete are not paired, we cannot call
+ free.
+
+Wed Jan 4 12:40:14 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * src/Makefile.in ($(TARGETPROG)): Link with $(LDFLAGS).
+ Patch from John Interrante <interran@uluru.stanford.edu>.
+
+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 <bothner@kalessin.cygnus.com>
+
+ * 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 <wbader@CSEE.Lehigh.Edu>.
+
+Fri Jul 15 09:38:11 1994 Per Bothner (bothner@cygnus.com)
+
+ * src/std-err.cc: #include <errno.h>, 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 <stddef.h> 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 <assert.h>
+ /* 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 <assert.h>
+/* 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]gGhH<hashname>i<init>Ijk<keys>K<keyname>lL<language>nN<function name>oOprs<size>S<switches>tTvZ<class name>].\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 <stdio.h>
+
+/* 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]gGhH<hashname>i<init>jk<keys>K<keyname>lL<language>nN<function name>oprs<size>S<switches>tTvZ<class name>].
+(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 <stdio.h>
+
+#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 @@
+<HTML>
+
+<HEAD>
+<TITLE>ACE OSE Tools</TITLE>
+
+<BODY text = "#000000"
+link="#000fff"
+vlink="#ff0f0f"
+bgcolor="#ffffff">
+
+<HR>
+<H3>Modified Version of the OSE Documentation Tools</H3>
+
+This <A HREF="http://www.cs.wustl.edu/~schmidt/ACE-bin/">directory</A>
+contains versions of the freely available <A
+HREF="http://www.telstra.com.au/docs/ose/doc/ose-home.html">OSE</A>
+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 <A
+HREF="ACE-obtain.html">ACE</A> release.<P>
+
+The primary goal of the modifications was to create a <EM>class</EM>.hxx and
+<EM>class</EM>.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. <P>
+
+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). <P>
+
+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. <P>
+
+The following changes were made to the original OSE tools:
+
+<UL>
+
+<LI> The vendor headers can be suppressed within the hiding.fmt file,
+so it is possible to generate <EM>class</EM>.cxx and
+<EM>class</EM>.hxx files consisting only of pure class description
+(hxx) and pure prototypes (cxx). Look at the vendor.fmt file and
+change the field <EM>vendor</EM> in replacing it with your company
+identifying line. <P>
+
+<LI> Added a new script class2hxxcxx for making a <EM>class</EM>.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. <P>
+
+<LI> Added new script info2headsrc for creating a <EM>class</EM>.hxx file for each
+ class, struct, union included in an ACE *.h file as well as a <EM>class</EM>.cxx
+ file that includes the correct prototypes for that class. <P>
+
+<LI> added a new script class2hxxcxxsingle for the feature listed above. <P>
+
+<LI> 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. <P>
+
+<LI> 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 <EM>class</EM>.hxx and <EM>class</EM>.cxx files. The information for these headers
+ is collected from the headers and comments of the according ACE *.h files. <P>
+
+<LI> changed info2doc and info2src for the features listed above. <P>
+
+<LI> added the ability for handling multiline ENUMs properly (class2info,info2doc). <P>
+
+<LI> added the ability for handling operator functions properly (info2src). <P>
+
+<LI> added the ability for handling template functions properly (info2src). <P>
+
+<LI> added the ability for handling nested classes, structs, unions properly
+ by introducing nawk-function recursion within info2doc (class2info,
+ info2doc, info2src). <P>
+
+<LI> added the ability for handling default values properly (info2src). <P>
+
+</UL>
+
+<HR><P>
+<H3>Known Bugs</H3>
+
+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! <P>
+
+INCORRECT: <P>
+
+<pre><code>
+ class x :
+ public y
+ {
+ }
+</pre></code>
+
+CORRECT: <P>
+
+<pre><code>
+ class x : public y
+ {
+ }
+</pre></code>
+
+- do not write multiline templates!<P>
+
+INCORRECT: <P>
+
+<pre><code>
+ template &ltclass t,
+ class&gt
+ class x
+ {
+ }
+</pre></code>
+
+CORRECT: <P>
+
+<pre><code>
+ template &ltclass t, class u&gt
+ class x
+ {
+ }
+</pre></code>
+
+<P><HR><P>
+Back to the <A HREF="ACE.html">ACE</A> home page.
+
+</BODY>
+</HTML>
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<num; i++ )
+ {
+ if ( lines[i] !~ "^[\t ]*=.*" )
+ {
+ if ( match( lines[i], "^ *[^ ]" ) != 0 )
+ {
+ if ( indent == -1 )
+ indent = RLENGTH-1
+ else
+ {
+ if ( RLENGTH-1 < indent )
+ indent = RLENGTH-1
+ }
+ }
+ }
+ }
+ blank = 0
+ for ( i=0; i<num; i++ )
+ {
+ if ( lines[i] ~ "^[\t ]*$" )
+ blank++
+ else
+ {
+ for ( j=0; j<blank; j++ )
+ printf( "//\n" )
+ blank = 0
+ if ( lines[i] !~ "^[\t ]*=( <.+>)?[\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<CODE>) 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<CODE>) show
+12 f0 0 185.2 moveto
+(The commands in this example are, `BEGIN<CODE>'and `END<CODE>'. 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<COMMAND>) show
+10 f4 0 127 moveto
+( // ....) show
+10 f4 0 106 moveto
+( // = END<COMMAND>) 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> 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
+(`<text>' 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 <OTCLIB_ASSERT\(\)> 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
+( // <NDEBUG> 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
+( <operator\\<\(\)>) 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<class T>) show
+10 f4 0 535.1 moveto
+( class OTC_List : public OTC_Collection<T>) 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
+( // <theString>, 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 <<EOF
+ <!-- This is an automatically generated file. Do Not Edit!
+ Use windex2html to generate it -->
+ <center><h1>ACE Wrappers Man Pages Index</h1></center>
+ <p>
+ This file has been generated from the <i>windex</i> file from the ACE package
+ and it contains a list of pointers to the man2html'ed man pages.
+ <p>
+ <HR>
+ <UL>
+EOF
+
+cat $WINDEX | \
+ sed -e 's/ / /g' \
+ -e 's%\(3\).*-%3\)</a>%g' \
+ -e 's/^[a-zA-Z_]*/&\.html">/g' \
+ -e 's/\.PP/<BR>/g' \
+ -e 's%^%<li><a HREF="html/%g' \
+ -e 's%\\f(CO[a-zA-Z_]*%<CODE>&</B></I></CODE>%g' \
+ -e 's%\\f(CO%%g'
+
+echo "</UL>"
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( "<MML>" )
+ print( "<Comment *** This file is automatically generated by class2mml.>" )
+ print( "<!DefineTag Body>" )
+ print( "<!DefineTag Heading1>" )
+ print( "<!DefineTag Heading2>" )
+ 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( "<Heading1>" )
+ print( class )
+ if ( found == 1 )
+ {
+ print( "<Body>" )
+ 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( "<Heading2>")
+ print( "SYNOPSIS" )
+ printf( "<Body>" )
+ printf( "<Plain>" )
+ printf( "<LeftIndent 0.1in>" )
+ printf( "<FirstIndent 0.1in>" )
+ printf( "<Alignment l>" )
+ }
+
+ #
+ # 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( "<Family Courier>#include \\<" library "/" filename "\\>" )
+ print( "<HardReturn>" )
+ }
+
+ 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( "<Heading2>" )
+ print( "COPYRIGHT" )
+ printf( "<Body>" )
+ printf( "<Plain>" )
+ printf( "<LeftIndent 0in>" )
+ printf( "<FirstIndent 0in>" )
+ printf( "<SpaceAfter 8pt>" )
+ }
+ 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( "<HardReturn>" )
+ }
+ 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( "<Heading2>" )
+ print( upper[line[3]] " MEMBERS" )
+ printf( "<Body>" )
+ printf( "<Plain>" )
+ printf( "<LeftIndent 0in>" )
+ printf( "<FirstIndent 0in>" )
+ printf( "<SpaceAfter 8pt>" )
+ }
+ }
+ if ( device == "text" )
+ {
+ print( "\n" )
+ }
+ else if ( device == "troff" )
+ {
+ print( ".nf" )
+ }
+ else if ( device == "mml" )
+ {
+ printf( "<Alignment l>" )
+ }
+ outputPrototype( line[4] )
+ if ( device == "text" )
+ {
+ }
+ else if ( device == "troff" )
+ {
+ print( ".fi" )
+ print( ".RS 0.25i" )
+ }
+ else if ( device == "mml" )
+ {
+ printf( "<Alignment lr>" )
+ printf( "<LeftIndent 0.1in>" )
+ printf( "<FirstIndent 0.1in>" )
+ }
+ 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( "<LeftIndent 0in>" )
+ printf( "<FirstIndent 0in>" )
+ }
+ }
+ }
+}
+
+#
+# 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( "<Heading2>" )
+ print( contract )
+ printf( "<Body>" )
+ printf( "<Plain>" )
+ printf( "<LeftIndent 0in>" )
+ printf( "<FirstIndent 0in>" )
+ printf( "<SpaceAfter 8pt>" )
+ }
+
+ 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( "<Alignment l>" )
+ }
+ outputPrototype( line[4] )
+ if ( device == "text" )
+ {
+ }
+ else if ( device == "troff" )
+ {
+ print( ".fi" )
+ print( ".RS 0.25i" )
+ }
+ else if ( device == "mml" )
+ {
+ printf( "<Alignment lr>" )
+ printf( "<LeftIndent 0.1in>" )
+ printf( "<FirstIndent 0.1in>" )
+ }
+ 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( "<LeftIndent 0in>" )
+ printf( "<FirstIndent 0in>" )
+ }
+ }
+ 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( "<Heading2>" )
+ print( section )
+ if ( line[start] != "" )
+ {
+ printf( "<Body>" )
+ printf( "<Plain>" )
+ printf( "<LeftIndent 0in>" )
+ printf( "<FirstIndent 0in>" )
+ printf( "<Alignment lr>" )
+ printf( "<SpaceAfter 8pt>" )
+ printf( "<Family Times>" )
+ }
+ }
+
+ 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<CODE>" )
+ {
+ 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( "<Plain>" )
+ printf( "<LeftIndent 0.2in>" )
+ printf( "<FirstIndent 0.2in>" )
+ printf( "<Alignment l>" )
+ printf( "<Family Courier>" )
+ }
+ }
+ else if ( line ~ "^= END<CODE>" )
+ {
+ inCode = -1
+ if ( device == "text" )
+ {
+ print( "\n" )
+ }
+ else if ( device == "troff" )
+ {
+ print( "\\fP\n.fi" )
+ print( ".RE" )
+ }
+ else if ( device == "mml" )
+ {
+ printf( "<LeftIndent 0in>" )
+ printf( "<FirstIndent 0in>" )
+ printf( "<Alignment lr>" )
+ printf( "<Family Times>")
+ }
+ }
+ else if ( line ~ "^= BEGIN<COMMENT>" )
+ inComment = 1
+ else if ( line ~ "^= BEGIN<INDENT>" )
+ {
+ if ( device == "text" )
+ {
+ }
+ else if ( device == "troff" )
+ print( ".RS 0.25i" )
+ else if ( device == "mml" )
+ {
+ printf( "<LeftIndent 0.2in>" )
+ printf( "<FirstIndent 0.2in>" )
+ }
+ }
+ else if ( line ~ "^= END<INDENT>" )
+ {
+ if ( device == "text" )
+ {
+ }
+ else if ( device == "troff" )
+ print( ".RE" )
+ else if ( device == "mml" )
+ {
+ printf( "<LeftIndent 0in>" )
+ printf( "<FirstIndent 0in>" )
+ }
+ }
+ else if ( line ~ "^= BEGIN<NOFILL>" )
+ {
+ inNoFill = 1
+ if ( device == "text" )
+ {
+ }
+ else if ( device == "troff" )
+ print( ".nf" )
+ else if ( device == "mml" )
+ printf( "<Alignment l>" )
+ }
+ else if ( line ~ "^= END<NOFILL>" )
+ {
+ inNoFill = 0
+ if ( device == "text" )
+ {
+ }
+ else if ( device == "troff" )
+ print( ".fi" )
+ else if ( device == "mml" )
+ printf( "<Alignment lr>" )
+ }
+ else
+ {
+ if ( inCode > 0 )
+ {
+ if ( device == "mml" )
+ {
+ gsub( " ", "\\ ", line )
+ gsub( "<", "\\<", line )
+ gsub( ">", "\\>", line )
+ if ( inCode > 1 )
+ line = "<HardReturn>" 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", "<Family Times><Plain>", line )
+ gsub( "\\\\fB", "<Bold>", line )
+ gsub( "\\\\fI", "<Italic>", line )
+ gsub( "\\\\f\\(CO", "<Family Courier>", line )
+
+ if ( inNoFill > 0 )
+ {
+ if ( inNoFill > 1 )
+ line = "<HardReturn>" 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<COMMENT>" )
+ 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( "<Family Courier>%s(\n<HardReturn>", 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<HardReturn>" )
+ }
+ else
+ {
+ # print after each argument of a line
+
+ if ( device == "text" )
+ print( "," )
+ else if ( device == "troff" )
+ print( "," )
+ else if ( device == "mml" )
+ printf( ",\n<HardReturn>" )
+ }
+ }
+ # 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 "<Family Times>" )
+
+ }
+ 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( "<Family Courier>" prototype "<Family Times>" )
+ }
+ }
+}
+
+#=============================================================
+# 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<nesting_level; z++)
+ outspace = outspace " "
+ printf( "%s",outspace)
+
+ if ( type == "template" )
+ {
+ #
+ # ADT == template
+ #
+ for ( i=0; i<=num; i++ )
+ {
+ split( lines[i], line, "\n" )
+
+# if ( line[1] == "TEMPLATE" && line[3] == class )
+ if ( line[1] == "TEMPLATE" && (line[3] == class || line[3] == baseandsubclass) )
+ break
+ }
+ if ( device == "text" )
+ printf( "template%s\n",line[4] )
+ else if ( device == "troff" )
+ printf( "template%s\n",line[4] )
+ else if ( device == "mml" )
+ {
+ sub( "<", "\\<", line[4] )
+ sub( ">", "\\>", line[4] )
+ printf( "<HardReturn>template%s\n",line[4] )
+ }
+# typestat = line[2] " " line[3]
+ typestat = line[2] " " class
+
+ outspace = ""
+ for (z=1; z<nesting_level; z++)
+ outspace = outspace " "
+ printf( "%s",outspace)
+
+ if ( device == "text" )
+ printf( "%s", typestat )
+ else if ( device == "troff" )
+ printf( "%s", typestat )
+ else if ( device == "mml" )
+ printf( "<HardReturn>%s", typestat )
+ }
+ else
+ {
+ #
+ # ADT != template
+ #
+ typestat = type " " class
+ if ( device == "mml" )
+ printf( "<HardReturn>" )
+ 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( "<HardReturn>" )
+ 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( "<HardReturn>" )
+ }
+ }
+ }
+ 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<nesting_level; z++)
+ outspace = outspace " "
+ if ( device == "text" )
+ print( outspace "{\ " )
+ else if ( device == "troff" )
+ print( outspace "{\\fP" )
+ else if ( device == "mml" )
+ print( outspace "<HardReturn>{<Family Times>")
+ 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<nesting_level; z++)
+ outspace = outspace " "
+ lastaccess = "public"
+ if ( start == 0 )
+ {
+ start = 1
+ if ( device == "text" )
+ print( outspace "\ \n" outspace "public:\n")
+ else if ( device == "troff" )
+ print( outspace " \\f(COpublic:\\fP")
+ else if ( device == "mml" )
+ print( outspace "<HardReturn><Family Courier>\\ \\ public:<Family Times>" )
+ }
+ 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( "<HardReturn>" )
+ 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<nesting_level; z++)
+ outspace = outspace " "
+ lastaccess = "protected"
+ if ( start == 0 )
+ {
+ start = 1
+ if ( device == "text" )
+ print( outspace "\ \n" outspace "protected:\n")
+ else if ( device == "troff" )
+ print( outspace " \\f(COprotected:\\fP")
+ else if ( device == "mml" )
+ print(outspace "<HardReturn><Family Courier>\\ \\ protected:<Family Times>" )
+ }
+ 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( "<HardReturn>" )
+ 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<nesting_level; z++)
+ outspace = outspace " "
+ lastaccess = "private"
+ if ( start == 0 )
+ {
+ start = 1
+ if ( device == "text" )
+ print( outspace "\ \n" outspace "private:\n")
+ else if ( device == "troff" )
+ print( outspace " \\f(COprivate:\\fP")
+ else if ( device == "mml" )
+ print(outspace "<HardReturn><Family Courier>\\ \\ private:<Family Times>" )
+ }
+ 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( "<HardReturn>" )
+ outputPrototype( outspace line[4] )
+ }
+ }
+ }
+ }
+ outspace = ""
+ for (z=1; z<nesting_level; z++)
+ outspace = outspace " "
+ if ( device == "text" )
+ {
+ print( outspace "};" )
+ print( "\n" )
+ }
+ else if ( device == "troff" )
+ {
+ print( outspace "\\f(CO};" )
+ print( "\\fP\n.fi" )
+ }
+ else if ( device == "mml" )
+ {
+ print( outspace "<HardReturn><Family Courier>};<Family Times>" )
+ }
+ 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 <class>.hxx and <class>.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 <class>.hxx and <class>.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: <class hans,class otto> folgendes:
+ # <hans,otto>
+
+ 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: <class hans,class otto> folgendes:
+# <hans,otto>
+#
+# 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/&/\&amp;/g' \
+ -e 's/</\&lt;/g' \
+ -e 's/>/\&gt;/g' \
+ -e 's/\\|//g' \
+ -e 's/\\e/\\/g' |
+ /bin/nawk -f ${LIBDIR}/man2html1.awk |
+ sed -e 's^\\fB\([^\\]*\)\\fR^<B>\1</B></I>^g' \
+ -e 's^\\f(CO\(.[^\\]*\)\\fR^<CODE>\1</CODE>^g' \
+ -e 's^\\fI\(.[^\\]*\)\\fR^<I>\1</I></B>^g' \
+ -e 's^\\fB^<B>^g' \
+ -e 's^\\f(CO^<CODE>^g' \
+ -e 's^\\fI^<I>^g' \
+ -e 's^\\f[RP]^</B></I></CODE>^g' \
+ -e 's/^.[LP]P/<P>/' \
+ -e 's/^.br/<BR>/' \
+ -e 's/^\.DS.*/<pre>/' \
+ -e 's$^\.DE.*$</pre>$' \
+ -e 's/^\.nf */<pre>/' \
+ -e 's$^\.fi *$</pre>$' \
+ -e 's$^\.BE *$</pre><HR>$' \
+ -e 's/^\.RS.*/<UL>/' \
+ -e 's$^\.RE.*$</UL>$' \
+ -e 's^\.SH *"*\([^"]*\)"*^</pre><H2>\1</H2>^' \
+ -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 "<TITLE>" $0 "</TITLE>"
+ print "<H1>" $0 "</H1>\n"
+ next
+
+#-e 's/^.SH *NAME */{N;s#.*\n\(.*\)#<H1>\1</H1>#;}' \
+ }
+
+
+# Convert .IP Paragraphs upto next .cmd to hanging indents
+# using <DL></DL> pairs without intervening <LI>
+
+/^\.IP */ {
+ if ( inIP > 0 )
+ {
+ print "</DL>"
+ }
+ inIP = 1
+ startIP = 1
+ print "<DL>"
+ match($0, /".*"/ )
+ if ( RSTART > 0 )
+ {
+ arg = substr( $0, RSTART+1, RLENGTH-2)
+
+ print "<DT> " arg
+ }
+ else if ( length( $2 ) > 0 )
+ {
+ print "<DT> " $2
+ }
+ next
+ }
+
+$0 ~ /^\.[a-zA-Z]*/ && inIP > 0 {
+ inIP = 0
+ print "</DL>"
+ }
+
+# Convert
+# .TP
+# Line1
+# line 2 - n
+# .Any
+#
+# to
+# <DL>
+# <DT> Line1
+# <DD> lines 2 - n
+# <DT>
+
+/^\.TP */ {
+ if ( inTP > 0 )
+ {
+ print "</DL>"
+ }
+ inTP = 1
+ print "<DL>"
+ next
+ }
+
+inTP == 1 && $1 !~ /\.[a-zA-Z]*/ {
+ print "<DT> " $0
+ inTP = 2
+ next
+ }
+
+inTP == 2 && $1 !~ /\.[a-zA-Z]*/{
+ print "</I></B>" # Belt and suspenders
+ print "<DD> " $0
+ inTP = 3
+ next
+ }
+
+$0 ~ /^\.[a-zA-Z]*/ && inTP > 0 {
+ inTP = 0
+ print "</DL>"
+ }
+
+
+
+$1 == ".AP" {
+ $1=""
+ print "<DL >"
+ print "<DT> " $2 "\t\t" $3 "\t\t("$4")"
+ inTP = 2
+ next
+ }
+
+# make a blank line
+$1 == ".sp" {
+ print "<BR>"
+ next # print "<BR>"
+ }
+
+
+$1 == ".ta" { next }
+
+# just pass everything else on
+
+ {
+ if ( startIP > 0 )
+ {
+ print "<DD> " $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 ~ "</pre><H2>SEE ALSO</H2>" {
+ print $0
+ getline
+ while ( $0 !~ "^<P>$" && $0 !~ "^[ \t]*$" ) {
+ gsub("OTC[_a-zA-Z0-9]*_[_a-zA-Z0-9]*","<A HREF=\"&.html\">&</A>",$0)
+ gsub("OUX[_a-zA-Z0-9]*_[_a-zA-Z0-9]*","<A HREF=\"&.html\">&</A>",$0)
+ gsub("OTK[_a-zA-Z0-9]*_[_a-zA-Z0-9]*","<A HREF=\"&.html\">&</A>",$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 <vendor>
+#
+# 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) <Vendor> 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) <Vendor> 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<ACE_SYNCH> MT_Task;
+typedef ACE_Stream<ACE_SYNCH> MT_Stream;
+typedef ACE_Module<ACE_SYNCH> 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_Handler, CONSUMER_KEY> CONSUMER_FACTORY;
+
+int
+Consumer_Handler::open (void *a)
+{
+ CONSUMER_FACTORY *af = (CONSUMER_FACTORY *) a;
+ this->router_task_ = af->router ();
+ return this->Peer_Handler<CONSUMER_ROUTER, CONSUMER_KEY>::open (a);
+}
+
+Consumer_Handler::Consumer_Handler (ACE_Thread_Manager *tm)
+ : Peer_Handler<CONSUMER_ROUTER, CONSUMER_KEY> (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_Handler, CONSUMER_KEY> CONSUMER_ROUTER;
+
+class Consumer_Handler : public Peer_Handler<CONSUMER_ROUTER, CONSUMER_KEY>
+{
+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<ACE_MT_SYNCH>
+{
+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 <class PH, class PK> int
+Acceptor_Factory<PH, PK>::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 <class PH, class PK>
+Acceptor_Factory<PH, PK>::Acceptor_Factory (Peer_Router<PH, PK> *pr)
+ : pr_ (pr)
+{
+}
+
+template <class PH, class PK> Peer_Router<PH, PK> *
+Acceptor_Factory<PH, PK>::router (void)
+{
+ return this->pr_;
+}
+
+template <class ROUTER, class KEY>
+Peer_Handler<ROUTER, KEY>::Peer_Handler (ACE_Thread_Manager *tm)
+ : inherited (tm)
+{
+}
+
+template <class ROUTER, class KEY> int
+Peer_Handler<ROUTER, KEY>::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 <class ROUTER, class KEY> int
+Peer_Handler<ROUTER, KEY>::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 <class ROUTER, class KEY> int
+Peer_Handler<ROUTER, KEY>::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 <class ROUTER, class KEY> int
+Peer_Handler<ROUTER, KEY>::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 <class PH, class PK>
+Peer_Router<PH, PK>::Peer_Router (ACE_Thread_Manager *tm)
+ : ACE_Task<ACE_MT_SYNCH> (tm)
+{
+}
+
+template <class PH, class PK> int
+Peer_Router<PH, PK>::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<PK, PH *> *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 <class PH, class PK>
+Peer_Router<PH, PK>::~Peer_Router (void)
+{
+}
+
+template <class PH, class PK> ACE_INLINE int
+Peer_Router<PH, PK>::fini (void)
+{
+ delete this->acceptor_;
+ return 0;
+}
+
+template <class PH, class PK> ACE_INLINE int
+Peer_Router<PH, PK>::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 <class PH, class PK> ACE_INLINE int
+Peer_Router<PH, PK>::unbind_peer (PK key)
+{
+ return this->peer_map_.unbind (key);
+}
+
+template <class PH, class PK> ACE_INLINE int
+Peer_Router<PH, PK>::bind_peer (PK key, Peer_Handler<Peer_Router<PH, PK>, PK> *ph)
+{
+ PH *peer_handler = (PH *) ph;
+ return this->peer_map_.bind (key, peer_handler);
+}
+
+template <class PH, class PK> ACE_INLINE int
+Peer_Router<PH, PK>::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_HANDLER, class KEY>
+class Peer_Router;
+
+template <class PEER_HANDLER, class KEY>
+class Acceptor_Factory : public ACE_Acceptor<PEER_HANDLER, ACE_SOCK_ACCEPTOR>
+ // = TITLE
+ // Creates <PEER_HANDLERs>, which route events between peers.
+{
+public:
+ Acceptor_Factory (Peer_Router<PEER_HANDLER, KEY> *pr);
+ Peer_Router<PEER_HANDLER, KEY> *router (void);
+
+ int init (int argc, char *argv[]);
+ // Initialize the acceptor when it's linked dynamically.
+
+private:
+ Peer_Router<PEER_HANDLER, KEY> *pr_;
+};
+
+template <class ROUTER, class KEY>
+class Peer_Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH>
+ // = 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<ACE_SOCK_STREAM, ACE_MT_SYNCH> inherited;
+
+ ROUTER *router_task_;
+ // Pointer to write task.
+
+private:
+ virtual int svc (void);
+ // Don't need this method here...
+};
+
+template <class PEER_HANDLER, class PEER_KEY>
+class Peer_Router : public ACE_Task<ACE_MT_SYNCH>
+ // = 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_Router<PEER_HANDLER, PEER_KEY>, 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_KEY, PEER_HANDLER *, ACE_RW_Mutex> PEER_MAP;
+ typedef ACE_Map_Iterator<PEER_KEY, PEER_HANDLER *, ACE_RW_Mutex> 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<PEER_HANDLER, PEER_KEY> ACCEPTOR;
+
+ ACCEPTOR *acceptor_;
+ // Factory for accepting new PEER_HANDLERs.
+
+private:
+ // = Prevent copies and pass-by-value.
+ Peer_Router (const Peer_Router<PEER_HANDLER, PEER_KEY> &) {}
+ void operator= (const Peer_Router<PEER_HANDLER, PEER_KEY> &) {}
+};
+
+#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_Handler, SUPPLIER_KEY> SUPPLIER_FACTORY;
+
+int
+Supplier_Handler::open (void *a)
+{
+ SUPPLIER_FACTORY *af = (SUPPLIER_FACTORY *) a;
+ this->router_task_ = af->router ();
+ return this->Peer_Handler<SUPPLIER_ROUTER, SUPPLIER_KEY>::open (a);
+}
+
+Supplier_Handler::Supplier_Handler (ACE_Thread_Manager *tm)
+ : Peer_Handler<SUPPLIER_ROUTER, SUPPLIER_KEY> (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_Handler, SUPPLIER_KEY> SUPPLIER_ROUTER;
+
+class Supplier_Handler : public Peer_Handler<SUPPLIER_ROUTER, SUPPLIER_KEY>
+{
+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<ACE_MT_SYNCH> MT_Stream;
+typedef ACE_Module<ACE_MT_SYNCH> 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<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
+ // = 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 <ACE_Connector>.
+ virtual int open (void *);
+ // Initialize the transceiver when we are connected.
+
+ // = Demultplexing hooks from the <ACE_Reactor>.
+ 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<Event_Transceiver, ACE_SOCK_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<ACE_MT_SYNCH> 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<ACE_MT_SYNCH> *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<ACE_MT_SYNCH> *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<ACE_MT_SYNCH> MT_Stream;
+typedef ACE_Module<ACE_MT_SYNCH> MT_Module;
+typedef ACE_Task<ACE_MT_SYNCH> 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<ACE_MT_SYNCH> 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<ACE_MT_SYNCH> *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<ACE_MT_SYNCH> *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_Handler, CONSUMER_KEY> CONSUMER_FACTORY;
+
+int
+Consumer_Handler::open (void *a)
+{
+ CONSUMER_FACTORY *af = (CONSUMER_FACTORY *) a;
+ this->router_task_ = af->router ();
+ return this->Peer_Handler<CONSUMER_ROUTER, CONSUMER_KEY>::open (a);
+}
+
+Consumer_Handler::Consumer_Handler (ACE_Thread_Manager *tm)
+ : Peer_Handler<CONSUMER_ROUTER, CONSUMER_KEY> (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_Handler, CONSUMER_KEY> CONSUMER_ROUTER;
+
+class Consumer_Handler
+ : public Peer_Handler<CONSUMER_ROUTER, CONSUMER_KEY>
+{
+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<ACE_MT_SYNCH>
+{
+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 <class PH, class PK> int
+Acceptor_Factory<PH, PK>::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 <class PH, class PK>
+Acceptor_Factory<PH, PK>::Acceptor_Factory (Peer_Router<PH, PK> *pr)
+ : pr_ (pr)
+{
+}
+
+template <class PH, class PK> Peer_Router<PH, PK> *
+Acceptor_Factory<PH, PK>::router (void)
+{
+ return this->pr_;
+}
+
+template <class ROUTER, class KEY>
+Peer_Handler<ROUTER, KEY>::Peer_Handler (ACE_Thread_Manager *tm)
+ : ACE_Svc_Handler<ACE_UPIPE_Stream, ACE_UPIPE_Addr, ACE_MT_SYNCH> (tm)
+{
+}
+
+template <class ROUTER, class KEY> int
+Peer_Handler<ROUTER, KEY>::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 <class ROUTER, class KEY> int
+Peer_Handler<ROUTER, KEY>::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 <class ROUTER, class KEY> int
+Peer_Handler<ROUTER, KEY>::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 <class ROUTER, class KEY> int
+Peer_Handler<ROUTER, KEY>::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 <class PH, class PK>
+Peer_Router<PH, PK>::Peer_Router (ACE_Thread_Manager *tm)
+ : ACE_Task<ACE_MT_SYNCH> (tm)
+{
+}
+
+template <class PH, class PK> int
+Peer_Router<PH, PK>::send_peers (ACE_Message_Block *mb)
+{
+ ACE_Map_Iterator<PK, PH *, ACE_RW_Mutex> map_iter = this->peer_map_;
+ int bytes = 0;
+ int iterations = 0;
+ ACE_Message_Block *data_block = mb->cont ();
+ for (ACE_Map_Entry<PK, PH *> *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 <class PH, class PK>
+Peer_Router<PH, PK>::~Peer_Router (void)
+{
+}
+
+template <class PH, class PK> ACE_INLINE int
+Peer_Router<PH, PK>::fini (void)
+{
+ delete this->acceptor_;
+ return 0;
+}
+
+template <class PH, class PK> ACE_INLINE int
+Peer_Router<PH, PK>::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 <class PH, class PK> ACE_INLINE int
+Peer_Router<PH, PK>::unbind_peer (PK key)
+{
+ return this->peer_map_.unbind (key);
+}
+
+template <class PH, class PK> ACE_INLINE int
+Peer_Router<PH, PK>::bind_peer (PK key, Peer_Handler<Peer_Router<PH, PK>, PK> *ph)
+{
+ PH *peer_handler = (PH *) ph;
+ return this->peer_map_.bind (key, peer_handler);
+}
+
+template <class PH, class PK> ACE_INLINE int
+Peer_Router<PH, PK>::init (int argc, char *argv[])
+{
+ this->acceptor_ = new Acceptor_Factory <PH, PK> (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_HANDLER, class KEY>
+class Peer_Router;
+
+template <class PEER_HANDLER, class KEY>
+class Acceptor_Factory : public ACE_Acceptor<PEER_HANDLER, ACE_UPIPE_ACCEPTOR>
+{
+public:
+ Acceptor_Factory (Peer_Router<PEER_HANDLER, KEY> *pr);
+ Peer_Router<PEER_HANDLER, KEY> *router (void);
+
+ int init (int argc, char *argv[]);
+ // Initialize the acceptor when it's linked dynamically.
+
+private:
+ Peer_Router<PEER_HANDLER, KEY> *pr_;
+};
+
+// Receive input from a Peer..
+template <class ROUTER, class KEY>
+class Peer_Handler : public ACE_Svc_Handler<ACE_UPIPE_STREAM, ACE_MT_SYNCH>
+{
+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_HANDLER, class PEER_KEY>
+class Peer_Router : public ACE_Task<ACE_MT_SYNCH>
+{
+public:
+ Peer_Router (ACE_Thread_Manager * = 0);
+ ~Peer_Router (void);
+
+ typedef Peer_Handler<Peer_Router<PEER_HANDLER, PEER_KEY>, 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_KEY, PEER_HANDLER *, ACE_RW_Mutex> 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<PEER_HANDLER, PEER_KEY> *acceptor_;
+
+private:
+// Prevent copies and pass-by-value.
+ Peer_Router (const Peer_Router<PEER_HANDLER, PEER_KEY> &);
+ void operator= (const Peer_Router<PEER_HANDLER, PEER_KEY> &);
+};
+
+#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_Handler, SUPPLIER_KEY> SUPPLIER_FACTORY;
+
+int
+Supplier_Handler::open (void *a)
+{
+ SUPPLIER_FACTORY *af = (SUPPLIER_FACTORY *) a;
+ this->router_task_ = af->router ();
+ return this->Peer_Handler<SUPPLIER_ROUTER, SUPPLIER_KEY>::open (a);
+}
+
+Supplier_Handler::Supplier_Handler (ACE_Thread_Manager *tm)
+ : Peer_Handler<SUPPLIER_ROUTER, SUPPLIER_KEY> (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_Handler, SUPPLIER_KEY> SUPPLIER_ROUTER;
+
+class Supplier_Handler
+ : public Peer_Handler<SUPPLIER_ROUTER, SUPPLIER_KEY>
+{
+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<ACE_MT_SYNCH> MT_Stream;
+typedef ACE_Module<ACE_MT_SYNCH> 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 <threads>
+
+<threads> 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 <threads>\n"
+ "-r <rendezvous>\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 <ACE_SPIPE_STREAM, ACE_NULL_SYNCH>
+{
+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<Svc_Handler, ACE_SPIPE_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 <iterations>\n"
+ "-r <rendezvous>\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<ACE_SPIPE_STREAM, ACE_NULL_SYNCH>
+{
+public:
+ // = Initialization
+
+ Peer_Handler (int iterations);
+ // <iterations> is the number of buffers to send. If <iterations>
+ // == 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<Peer_Handler, ACE_SPIPE_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
--- /dev/null
+++ b/examples/Connection/misc/Makefile
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 <ACE_UPIPE_STREAM, ACE_NULL_SYNCH> 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 <Server_Service, ACE_UPIPE_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<Server_Service> 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 <Client_Service, ACE_UPIPE_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 <PR_ST_1>
+Svc_Handler<PR_ST_2>::Svc_Handler (ACE_Reactor *r)
+ : SVC_HANDLER (0, 0, r)
+{
+}
+
+template <PR_ST_1> int
+Svc_Handler<PR_ST_2>::close (u_long)
+{
+ ACE_DEBUG ((LM_DEBUG, "calling Svc_Handler close\n"));
+
+ // Free up the handle.
+ this->peer ().close ();
+ return 0;
+}
+
+template <PR_ST_1> int
+Svc_Handler<PR_ST_2>::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 <PR_ST_1> int
+Svc_Handler<PR_ST_2>::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 <PR_ST_1> int
+Svc_Handler<PR_ST_2>::handle_timeout (const ACE_Time_Value &,
+ const void *)
+{
+ ACE_DEBUG ((LM_DEBUG, "%p\n", "handle_timeout"));
+ return 0;
+}
+
+template <class SH, PR_AC_1> int
+IPC_Server<SH, PR_AC_2>::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 <class SH, PR_AC_1>
+IPC_Server<SH, PR_AC_2>::IPC_Server (void)
+ : done_handler_ (ACE_Sig_Handler_Ex (ACE_Service_Config::end_reactor_event_loop))
+{
+}
+
+template <class SH, PR_AC_1> int
+IPC_Server<SH, PR_AC_2>::fini (void)
+{
+ return 0;
+}
+
+template <class SH, PR_AC_1>
+IPC_Server<SH, PR_AC_2>::~IPC_Server (void)
+{
+}
+
+// Run the interative service.
+
+template <class SH, PR_AC_1> int
+IPC_Server<SH, PR_AC_2>::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 <ACE_PEER_STREAM_1>
+class Svc_Handler : public ACE_Svc_Handler <ACE_PEER_STREAM_2, ACE_NULL_SYNCH>
+{
+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 <ACE_PEER_STREAM_2, ACE_NULL_SYNCH> SVC_HANDLER;
+};
+
+template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
+class IPC_Server : public ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>
+{
+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<SVC_HANDLER, ACE_PEER_ACCEPTOR_2> 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 <PR_ST_1>
+Peer_Handler<PR_ST_2>::Peer_Handler (ACE_Reactor *r)
+ : action_ (&Peer_Handler<PR_ST_2>::idle)
+{
+ this->reactor (r);
+}
+
+template <PR_ST_1> int
+Peer_Handler<PR_ST_2>::open (void *)
+{
+ ACE_DEBUG ((LM_DEBUG, "activating %d\n", this->get_handle ()));
+ this->action_ = &Peer_Handler<PR_ST_2>::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 <PR_ST_1> ACE_HANDLE
+Peer_Handler<PR_ST_2>::get_handle (void) const
+{
+ return this->peer ().get_handle ();
+}
+
+template <PR_ST_1> int
+Peer_Handler<PR_ST_2>::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<PR_ST_2>::idle;
+ return -1;
+}
+
+template <PR_ST_1> int
+Peer_Handler<PR_ST_2>::idle (void)
+{
+ ACE_DEBUG ((LM_DEBUG, "idle!\n"));
+ return 0;
+}
+
+template <PR_ST_1> int
+Peer_Handler<PR_ST_2>::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<PR_ST_2>::disconnecting;
+ return -1;
+ }
+ else
+ return 0;
+}
+
+template <PR_ST_1> int
+Peer_Handler<PR_ST_2>::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 <PR_ST_1> int
+Peer_Handler<PR_ST_2>::handle_output (ACE_HANDLE)
+{
+ ACE_DEBUG ((LM_DEBUG, "in handle_output\n"));
+
+ return (this->*action_) ();
+}
+
+template <PR_ST_1> int
+Peer_Handler<PR_ST_2>::handle_input (ACE_HANDLE)
+{
+ ACE_DEBUG ((LM_DEBUG, "in handle_input\n"));
+
+ return (this->*action_) ();
+}
+
+template <PR_ST_1> int
+Peer_Handler<PR_ST_2>::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<PR_ST_2>::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 <class SH, PR_CO_1> int
+IPC_Client<SH, PR_CO_2>::svc (void)
+{
+ if (this->reactor ())
+ ACE_Service_Config::run_reactor_event_loop ();
+
+ return 0;
+}
+
+template <class SH, PR_CO_1> int
+IPC_Client<SH, PR_CO_2>::fini (void)
+{
+ return 0;
+}
+
+template <class SH, PR_CO_1>
+IPC_Client<SH, PR_CO_2>::IPC_Client (void)
+ : done_handler_ (ACE_Sig_Handler_Ex (ACE_Service_Config::end_reactor_event_loop))
+{
+}
+
+template <class SH, PR_CO_1> int
+IPC_Client<SH, PR_CO_2>::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 <class SH, PR_CO_1>
+IPC_Client<SH, PR_CO_2>::~IPC_Client (void)
+{
+}
+
+template <class SH, PR_CO_1> int
+IPC_Client<SH, PR_CO_2>::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 <ACE_PEER_STREAM_1>
+class Peer_Handler : public ACE_Svc_Handler<ACE_PEER_STREAM_2, ACE_SYNCH>
+{
+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<ACE_PEER_STREAM_2>::*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 SVC_HANDLER, ACE_PEER_CONNECTOR_1>
+class IPC_Client : public ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>
+{
+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<SVC_HANDLER, ACE_PEER_CONNECTOR_2> 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<ACE_SOCK_STREAM> SVC_HANDLER;
+typedef IPC_Server<SVC_HANDLER, ACE_SOCK_ACCEPTOR> 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<ACE_SOCK_STREAM> PEER_HANDLER;
+typedef IPC_Client<PEER_HANDLER, ACE_SOCK_CONNECTOR> 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<ACE_SPIPE_STREAM> SVC_HANDLER;
+typedef IPC_Server<SVC_HANDLER, ACE_SPIPE_ACCEPTOR> 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<ACE_SPIPE_STREAM> PEER_HANDLER;
+typedef IPC_Client<PEER_HANDLER, ACE_SPIPE_CONNECTOR> 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<ACE_TLI_STREAM> SVC_HANDLER;
+typedef IPC_Server<SVC_HANDLER, ACE_TLI_ACCEPTOR> 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<ACE_TLI_STREAM> PEER_HANDLER;
+typedef IPC_Client<PEER_HANDLER, ACE_TLI_CONNECTOR> 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 <stdio.h>
+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 <stdio.h>
+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 <stdio.h>
+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 <stdio.h>
+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 <stdio.h>
+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 <stdio.h>
+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 <stdio.h>
+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 <stdio.h>
+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 <stdio.h>
+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 <stdio.h>
+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 <stdio.h>
+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 <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <thread.h>
+#include <synch.h>
+#include <unistd.h>
+
+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 X>
+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 <fstream.h>
+#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 <char> 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 <fstream.h>
+#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 <char> 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 <char> 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<ACE_Reactor, ACE_Null_Mutex>
+ REACTOR;
+
+// Our Options Singleton.
+typedef ACE_Singleton<Options, ACE_Null_Mutex>
+ OPTIONS;
+
+// Our ACE_Test_and_Set Singleton.
+typedef ACE_Singleton<ACE_Test_and_Set <ACE_Null_Mutex, sig_atomic_t>, ACE_Null_Mutex>
+ QUIT_HANDLER;
+
+// ----------------------------------------
+
+class Logging_Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
+ // = 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
+ // <ACE_Reactor>. In addition, it also illustrates how to
+ // utilize the <ACE_Reactor> 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_Handler, ACE_SOCK_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
+ // <ACE_Reactor>. In addition, it also illustrates how to
+ // utilize the <ACE_Reactor> 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<ACE_Reactor, ACE_Null_Mutex> 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
+
+// <ecn@clark.net> XtReactor implementation.
+
+#include "ace/Log_Msg.h"
+#include "ace/XtReactor.h"
+#include "ace/Message_Block.h"
+
+#if defined (ACE_HAS_XT)
+#include <Xm/PushB.h>
+
+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 <ecn@clark.net>
+// @(#)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 <Xm/PushB.h>
+
+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<SOCK_Stream>;
+template class ACE_Dumpable_Adapter<SOCK>;
+template class ACE_Dumpable_Adapter<SOCK_Acceptor>;
+#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<ACE_Null_Mutex, ACE_Null_Condition_Mutex>;
+#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
--- /dev/null
+++ b/examples/OS/Process/Process.mdp
Binary files 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 <filename> (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 <executable>.
+ 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<ACE_Null_Mutex, sig_atomic_t>
+{
+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<ACE_Sig_Handler> 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<ACE_MT_SYNCH>
+{
+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<ACE_Thread_Mutex, u_long> 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<ACE_Thread_Mutex, u_long>;
+#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 < <filename>
+% 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
--- /dev/null
+++ b/examples/Reactor/ReactorEx/reactorex.mdp
Binary files 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<ACE_MT_SYNCH> 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<ACE_NULL_SYNCH>
+ // = 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
--- /dev/null
+++ b/examples/Reactor/WFMO_Reactor/reactorex.mdp
Binary files 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<ACE_MT_SYNCH> 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<ACE_NULL_SYNCH>
+ // = 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 <stdio.h>
+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 <class SH, PR_AC_1>
+Handle_Thr_Stream<SH, PR_AC_2>::~Handle_Thr_Stream (void)
+{
+}
+
+template <class SH, PR_AC_1>
+Handle_Thr_Stream<SH, PR_AC_2>::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 <class SH, PR_AC_1> int
+Handle_Thr_Stream<SH, PR_AC_2>::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 <class SH, PR_AC_1> int
+Handle_Thr_Stream<SH, PR_AC_2>::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 <class SH, PR_AC_1> int
+Handle_Thr_Stream<SH, PR_AC_2>::fini (void)
+{
+ return ACE_Service_Config::reactor ()->remove_handler
+ (this, ACE_Event_Handler::READ_MASK);
+}
+
+template <PR_ST_1>
+CLI_Stream<PR_ST_2>::CLI_Stream (ACE_Thread_Manager *thr_mgr)
+ : inherited (thr_mgr)
+{
+}
+
+template <PR_ST_1> int
+CLI_Stream<PR_ST_2>::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 <PR_ST_1> int
+CLI_Stream<PR_ST_2>::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 <PR_ST_1> int
+CLI_Stream<PR_ST_2>::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 <THR_STREAM> CLI_STREAM;
+typedef Handle_Thr_Stream<CLI_STREAM, THR_ACCEPTOR> 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<THR_STREAM>;
+template class Handle_Thr_Stream<CLI_Stream<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 SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
+class Handle_Thr_Stream : public ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>
+{
+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<SVC_HANDLER, ACE_PEER_ACCEPTOR_2> inherited;
+
+ static u_short DEFAULT_PORT_;
+
+ ACE_Thread_Manager thr_mgr_;
+ // Thread manager.
+
+ ACE_Thread_Strategy<SVC_HANDLER> thr_strategy_;
+ // Threading strategy.
+
+ int thr_flags_;
+ // Threading flags.
+};
+
+// This class interacts with the client, running in a separate
+// thread...
+template <ACE_PEER_STREAM_1>
+class CLI_Stream : public ACE_Svc_Handler<ACE_PEER_STREAM_2, ACE_MT_SYNCH>
+{
+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<ACE_PEER_STREAM_2, ACE_MT_SYNCH> 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 <ACE_Local_Memory_Pool, THREAD_MUTEX> L_ALLOCATOR;
+
+#if !defined (ACE_WIN32)
+typedef ACE_Malloc <MMAP_POOL, PROCESS_MUTEX> M_ALLOCATOR;
+typedef ACE_Malloc <ACE_Shared_Memory_Pool, PROCESS_MUTEX> SP_ALLOCATOR;
+typedef ACE_Malloc <ACE_Shared_Memory_Pool, THREAD_MUTEX> ST_ALLOCATOR;
+typedef ACE_Malloc <ACE_Sbrk_Memory_Pool, THREAD_MUTEX> SB_ALLOCATOR;
+#else
+typedef ACE_Malloc <MMAP_POOL, THREAD_MUTEX> M_ALLOCATOR;
+typedef ACE_Malloc <MMAP_POOL, THREAD_MUTEX> SP_ALLOCATOR;
+typedef ACE_Malloc <MMAP_POOL, THREAD_MUTEX> ST_ALLOCATOR;
+typedef ACE_Malloc <ACE_Local_Memory_Pool, THREAD_MUTEX> 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<M_ALLOCATOR>;
+ else if (Options::instance ()->spawn_threads ())
+ {
+ if (Options::instance ()->use_sbrk ())
+ Malloc::instance_ = new ACE_Allocator_Adapter<SB_ALLOCATOR>;
+ else if (Options::instance ()->use_shmem ())
+ Malloc::instance_ = new ACE_Allocator_Adapter<ST_ALLOCATOR>;
+ else
+ Malloc::instance_ = new ACE_Allocator_Adapter<L_ALLOCATOR>;
+ }
+ else if (Options::instance ()->use_mmap ())
+ Malloc::instance_ = new ACE_Allocator_Adapter<M_ALLOCATOR>;
+ else // Use Shared_Memory_Pool.
+ Malloc::instance_ = new ACE_Allocator_Adapter<SP_ALLOCATOR>;
+ }
+
+ 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 <ACE_MMAP_Memory_Pool, ACE_Null_Mutex> MALLOC;
+typedef ACE_Malloc_Iterator <ACE_MMAP_Memory_Pool, ACE_Null_Mutex> 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<I> Insert <name> <id> " << endl;
+ cout << "\t<D> Delete <name> " << endl;
+ cout << "\t<F> Find <name> " << endl;
+ cout << endl;
+ cout << "\t<L> List all employees " << endl;
+ cout << endl;
+ cout << "\t<Q> 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 <ACE_MMAP_Memory_Pool, ACE_Null_Mutex>;
+template class ACE_Malloc_Iterator <ACE_MMAP_Memory_Pool, ACE_Null_Mutex>;
+#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<Message_Data> msgque (key_t (SRV_KEY));
+
+ Message_Data msg_data (pid, ACE_OS::cuserid (0), "did you get this?");
+
+ ACE_Typed_SV_Message<Message_Data> 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<Message_Data>;
+template class ACE_Typed_SV_Message<Message_Data>;
+#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<Message_Data> msgque
+ (SRV_KEY, ACE_Typed_SV_Message_Queue<Message_Data>::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<Message_Data> send_msg (msg_data, 0, msg_data.length ());
+ ACE_Typed_SV_Message<Message_Data> 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<Message_Data>;
+template class ACE_Typed_SV_Message<Message_Data>;
+#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<ACE_Shared_Memory_Pool, ACE_SV_Semaphore_Simple> 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<ACE_Shared_Memory_Pool, ACE_SV_Semaphore_Simple>;
+#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 <ACE_Auto_Event, ACE_Thread_Mutex> 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 <n_iterations> 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 <iostream.h>
+#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 BARRIER>
+class Worker_Task : public ACE_Task<ACE_MT_SYNCH>
+{
+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 <n_iterations> 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 <class BARRIER>
+Worker_Task<BARRIER>::Worker_Task (ACE_Thread_Manager *thr_mgr,
+ int n_threads,
+ int inp_serialize)
+ : ACE_Task<ACE_MT_SYNCH> (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 <class BARRIER> int
+Worker_Task<BARRIER>::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 <class BARRIER> int
+Worker_Task<BARRIER>::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 <n_iterations> time printing off a message and "waiting"
+// for all other threads to complete this iteration.
+
+template <class BARRIER> int
+Worker_Task<BARRIER>::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 <class BARRIER> int
+Worker_Task<BARRIER>::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 <class BARRIER>int
+Worker_Task<BARRIER>::output (ACE_Message_Block *mb)
+{
+ return this->put_next (mb);
+}
+
+template <class BARRIER>int
+Worker_Task<BARRIER>::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;i<nt_;i++)
+ {
+ ACE_DEBUG ((LM_DEBUG,"(%t) eof, sending block for thread=%d\n",i+1));
+ mb1 = new ACE_Message_Block (2);
+ mb1->length (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<BARRIER_TYPE> *worker_task =
+ new Worker_Task<BARRIER_TYPE> (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 <Andres.Kruse@cern.ch> and Douglas C. Schmidt
+// <schmidt@cs.wustl.edu>
+//
+// ============================================================================
+
+#include <math.h>
+#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<ACE_Thread_Mutex, u_long> 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<ACE_MT_SYNCH>
+ // = 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<float> work (float param, int count);
+ ACE_Future<const char*> 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 <work> method.
+{
+public:
+ Method_Object_work (Scheduler *, float, int, ACE_Future<float> &);
+ ~Method_Object_work (void);
+ virtual int call (void);
+
+private:
+ Scheduler *scheduler_;
+ float param_;
+ int count_;
+ ACE_Future<float> future_result_;
+};
+
+Method_Object_work::Method_Object_work (Scheduler* new_Scheduler,
+ float new_param,
+ int new_count,
+ ACE_Future<float> &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 <name> method.
+{
+public:
+ Method_Object_name (Scheduler *, ACE_Future<const char*> &);
+ ~Method_Object_name (void);
+ virtual int call (void);
+
+private:
+ Scheduler *scheduler_;
+ ACE_Future<const char*> future_result_;
+};
+
+Method_Object_name::Method_Object_name (Scheduler *new_scheduler,
+ ACE_Future<const char*> &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 <end> 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 <call>).
+ auto_ptr<ACE_Method_Object> 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<const char *>
+Scheduler::name (void)
+{
+ if (this->scheduler_)
+ // Delegate to the Scheduler.
+ return this->scheduler_->name ();
+ else
+ {
+ ACE_Future<const char*> new_future;
+
+ // @@ What happens if new fails here?
+ this->activation_queue_.enqueue
+ (new Method_Object_name (this, new_future));
+
+ return new_future;
+ }
+}
+
+ACE_Future<float>
+Scheduler::work (float newparam, int newcount)
+{
+ if (this->scheduler_) {
+ return this->scheduler_->work (newparam, newcount);
+ }
+ else {
+ ACE_Future<float> 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 <work>
+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<float> fresulta, fresultb, fresultc, fresultd, fresulte;
+ ACE_Future<const char*> 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<ACE_Thread_Mutex, u_long>;
+#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 <Andres.Kruse@cern.ch> and Douglas C. Schmidt
+// <schmidt@cs.wustl.edu>
+//
+// 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 <math.h>
+#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<ACE_Thread_Mutex, u_long> 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<ACE_MT_SYNCH>
+ // = 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>.
+ ACE_Future<float> work (float param, int count);
+ ACE_Future<char*> 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 <work> method.
+{
+public:
+ Method_Object_work (Scheduler *, float, int, ACE_Future<float> &);
+ ~Method_Object_work (void);
+ virtual int call (void);
+
+private:
+ Scheduler *scheduler_;
+ float param_;
+ int count_;
+ ACE_Future<float> future_result_;
+};
+
+Method_Object_work::Method_Object_work (Scheduler* new_Scheduler,
+ float new_param,
+ int new_count,
+ ACE_Future<float> &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 <name> method.
+{
+public:
+ Method_Object_name (Scheduler *, ACE_Future<char*> &);
+ ~Method_Object_name (void);
+ virtual int call (void);
+
+private:
+ Scheduler *scheduler_;
+ ACE_Future<char*> future_result_;
+};
+
+
+Method_Object_name::Method_Object_name (Scheduler *new_scheduler,
+ ACE_Future<char*> &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 <end> 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 <call>).
+ auto_ptr<ACE_Method_Object> 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<char *>
+Scheduler::name (void)
+{
+ if (this->scheduler_)
+ // Delegate to the other scheduler
+ return this->scheduler_->name ();
+ else
+ {
+ ACE_Future<char*> new_future;
+
+ if (this->thr_count () == 0)
+ {
+ // This scheduler is inactive... so we execute the user
+ // request right away...
+
+ auto_ptr<ACE_Method_Object> 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<float>
+Scheduler::work (float newparam, int newcount)
+{
+ if (this->scheduler_)
+ return this->scheduler_->work (newparam, newcount);
+ else
+ {
+ ACE_Future<float> new_future;
+
+ if (this->thr_count () == 0)
+ {
+ auto_ptr<ACE_Method_Object> 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<float> fresulta = worker_a->work (0.01, n_iterations);
+ ACE_Future<float> fresultb = worker_b->work (0.02, n_iterations);
+ ACE_Future<float> 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<char *> fnamea = worker_a->name ();
+ ACE_Future<char *> fnameb = worker_b->name ();
+ ACE_Future<char *> 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<float> fresulta = worker_a->work (0.01, n_iterations);
+
+ // save the result by copying the future
+ ACE_Future<float> 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<float> 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<ACE_Thread_Mutex, u_long>;
+#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 <ACE_Thread_Mutex, u_long> 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 <ACE_Thread_Mutex, u_long> 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<ACE_Thread_Mutex, int> 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 <n_iterations> 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<ACE_RW_Mutex> 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 <n_iterations> 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<ACE_RW_Mutex> 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<ACE_Thread_Mutex, int>;
+#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<LOCK> 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<ACE_MT_SYNCH>
+{
+public:
+ Barrier_Task (ACE_Thread_Manager *thr_mgr,
+ int n_threads,
+ int n_iterations);
+
+ virtual int svc (void);
+ // Iterate <n_iterations> 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<ACE_MT_SYNCH> (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 <n_iterations> 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 <fstream.h>
+#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<ACE_MT_SYNCH>
+{
+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<ACE_MT_SYNCH>::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<ACE_Thread_Mutex, u_long> 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<ACE_MT_SYNCH>
+{
+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<ACE_Thread_Mutex, u_long>;
+#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<ACE_MT_SYNCH>
+{
+public:
+ Thread_Pool (ACE_Thread_Manager *thr_mgr, int n_threads);
+
+ virtual int svc (void);
+ // Iterate <n_iterations> 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 <Thread_Pool>.
+
+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<ACE_MT_SYNCH> (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 <n_iterations> 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<Errno> TSS_Error;
+
+#if defined (ACE_HAS_THREADS)
+// Serializes output via cout.
+static ACE_Thread_Mutex lock;
+
+typedef ACE_TSS_Guard<ACE_Thread_Mutex> GUARD;
+#else
+// Serializes output via cout.
+static ACE_Null_Mutex lock;
+
+typedef ACE_Guard<ACE_Null_Mutex> 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<Errno>;
+#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<ACE_MT_SYNCH>
+{
+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_Obj> 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 <gonzo@ing.puc.cl>) 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 <bgrigg@opus.bcbnet.com>, 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 <jwr@icm.edu.pl>
+
+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 <bgrigg@opus.bcbnet.com>, 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 @@
+<HTML>
+
+<HEAD>
+<TITLE>Overview of the ACE Network Services</TITLE>
+
+<BODY text = "#000000"
+link="#000fff"
+vlink="#ff0f0f"
+bgcolor="#ffffff">
+
+<HR>
+<H3>Overview of the ACE Network Services</H3>
+
+ACE provides a <A
+HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/netsvcs/">
+standard library</A> of <A HREF="#service-overviews">network
+services</A>:<P>
+
+<TABLE>
+<TD>
+<UL>
+<LI><A HREF="#name-overview">Naming Service</A>
+<LI><A HREF="#time-overview">Time Service</A>
+<LI><A HREF="#token-overview">Token Service</A>
+</UL>
+</TD>
+
+<TD>
+<UL>
+<LI><A HREF="#server-logging-overview">Server Logging Service</A>
+<LI><A HREF="#client-logging-overview">Client Logging Service</A>
+<LI><A HREF="#logging-strategy-overview">Logging Strategy Service</A>
+</UL>
+</TD>
+</TABLE>
+
+These services play two roles in ACE:<P>
+
+<UL>
+<LI> They provide reusable components for common distributed system
+ tasks such as logging, naming, locking, and time synchronization.<P>
+<LI> They illustrate how to utilize ACE features such as the <A
+ HREF="ACE-papers.html#ipc">IPC wrappers</A>, <A HREF="ACE-papers.html#reactor">Reactor</A>,
+ <A HREF="ACE-papers.html#config">Service Configurator</A>, <A
+ HREF="ACE-papers.html#initialize">Service Initialization</A>, and <A HREF="ACE-papers.html#concurrency">Concurrency</A> components. <P>
+</UL>
+
+The heart of the ACE network services is the <A
+HREF="http://www.cs.wustl.edu/~schmidt/ACE-papers#config">Service
+Configurator</A>, 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 <A
+HREF="NETSVC-INSTALL.html">online documentation</a> for more
+information on installing and testing the ACE network services.<P>
+
+<P><HR>
+<A NAME="name-overview">
+<H3> Overview of Naming Service</H3>
+
+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 <I> Name Binding </I>. Name
+bindings are defined relative to a <I> Naming Context </I>. 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: <P>
+
+<OL>
+<LI> Process Local Naming Context: Name bindings are accessible from
+processes with the same name running on the same host. <P>
+<LI> Node Local Naming Context: Name bindings are accessible from all
+processes running on the same host. <P>
+<LI> Network Local Naming Context: Name bindings are accessible from
+all processes running on any machine within a (sub)network. <P>
+</OL>
+
+<P>
+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. <P>
+
+The following are the key classes in the ACE Naming Service: <P>
+
+<UL>
+<LI> <B><TT> Class Naming_Context </TT></B> <P>
+
+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. <P>
+
+<LI> <B><TT> Class Name_Acceptor </TT></B> <P>
+
+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. <P>
+
+<LI> <B><TT> Class Name_Handler </TT></B> <P>
+
+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.<P>
+
+<LI> <B> Dependencies </B> <P>
+
+The ACE Naming Service uses ACE_WString String classes since it must
+handle wide character strings in order to support
+internationalization. <P>
+</UL>
+
+The following describes how to configure the Name_Server server and
+client test applications. <P>
+
+<UL>
+<LI> <B> Startup configuration </B> <P>
+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:<P>
+
+<TABLE cellpadding = 10 cellspacing = 0 border = 5>
+<TD VALIGN = TOP ALIGN = LEFT>
+<B> Option </B>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+<B> Description </B>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+<B> Default value </B>
+</TD>
+<TR>
+<TD VALIGN = TOP ALIGN = LEFT>
+-c &ltnaming context&gt <BR>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+Naming Context to use. Can be either "PROC_LOCAL" or "NODE_LOCAL" or
+"NET_LOCAL" <BR>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+PROC_LOCAL
+</TD>
+<TR>
+<TD VALIGN = TOP ALIGN = LEFT>
+-h &lthostname&gt
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+Specify the server hostname (needed by Name Server clients for
+PROC_LOCAL naming context)
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+ACE_DEFAULT_SERVER_HOST
+</TD>
+<TR>
+<TD VALIGN = TOP ALIGN = LEFT>
+-p &ltnameserver port&gt <BR>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+Port number where the server process expects requests <BR>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+ACE_DEFAULT_SERVER_PORT
+</TD>
+<TR>
+<TD VALIGN = TOP ALIGN = LEFT>
+-l &ltnamespace dir&gt <BR>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+Directory that holds the NameBinding databases <BR>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+ACE_DEFAULT_NAMESPACE_DIR
+</TD>
+<TR>
+<TD VALIGN = TOP ALIGN = LEFT>
+-P &ltprocess name&gt <BR>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+Name of the client process
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+argv[0]
+</TD>
+<TR>
+<TD VALIGN = TOP ALIGN = LEFT>
+-s &ltdatabase name&gt <BR>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+Name of the database. NameBindings for the appropriate naming context
+are stored in file &ltnamespace_dir&gt/&ltdatabase name&gt.
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+<I> null </I>
+</TD>
+<TR>
+<TD VALIGN = TOP ALIGN = LEFT>
+-d &ltdebug&gt
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+Turn debugging on/off
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+0 (off)
+</TD>
+<TR>
+<TD VALIGN = TOP ALIGN = LEFT>
+-T &lttrace&gt
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+Turn tracing on/off
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+0 (off)
+</TD>
+<TR>
+<TD VALIGN = TOP ALIGN = LEFT>
+-v &ltverbose&gt
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+Turn verbose on/off
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+0 (off)
+</TD>
+
+</TABLE>
+<P>
+
+<LI><B>Examples</B><P>
+<OL>
+<LI> 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:
+
+<PRE> <CODE>
+dynamic Naming_Service Service_Object *
+ ../lib/libnetsvcs.so:_make_ACE_Name_Acceptor()
+ "-p 20222 -c NET_LOCAL -l /tmp -s MYDATABASE"
+</PRE> </CODE>
+
+<LI> 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:
+
+<PRE> <CODE>
+dynamic Naming_Service_Client Service_Object *
+ ../lib/libnetsvcs.so:_make_Client_Test()
+ "-h tango.cs.wustl.edu -p 20222"
+</PRE> </CODE>
+</OL>
+
+Note:<P>
+<UL>
+<LI> These files would vary if the services are run on NT. For
+example, instead of using *.so, we would have to use *.dll.<P>
+<LI> 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). <P>
+<LI> 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.
+</UL>
+
+</UL>
+
+<P><HR><P>
+<A NAME="time-overview">
+<H3> Overview of Time Service</H3>
+
+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: <P>
+
+<UL>
+<LI> <I> Time Server </I> answers queries about the time made by
+Clerks. <P>
+
+<LI> <I> Clerk </I> 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. <P>
+
+<LI> <I> Client </I> uses the global time information maintained by
+a Clerk to provide consistency with the notion of time used by clients
+on other hosts. <P>
+</UL>
+<P>
+The following are the key classes in the ACE Time Service: <P>
+
+<UL>
+<LI> <B><TT> Class TS_Server_Handler </TT></B> <P>
+
+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.<P>
+
+<LI> <B><TT> Class TS_Server_Acceptor </TT></B> <P>
+
+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.<P>
+
+<LI> <B><TT> Class TS_Clerk_Handler </TT></B> <P>
+
+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.<P>
+
+<LI> <B><TT> Class TS_Clerk_Processor </TT></B> <P>
+
+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.<P>
+
+<LI> <B> Algorithms </B> <P>
+
+Currently, updating the system time involves taking the average of all
+the times received from the servers.<P>
+</UL>
+
+The following is a description of how to configure the Time Server
+clerk and server services: <P>
+
+<UL>
+
+<LI> <B> Startup configuration </B> <P>
+
+Configuring a server requires specifying the port number of the
+server. This can be specified as a command line argument as follows: <P>
+
+ -p &ltport number&gt
+
+<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: <P>
+
+ -h &ltserver host1&gt:&ltserver port1&gt -h &ltserver host2&gt:&ltserver port2&gt ...
+<P>
+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:
+<P>
+
+ -t timeout
+
+<P>
+The timeout value specifies the time interval at which the clerk
+should query the servers for time updates.
+<P>
+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.
+<P>
+
+<LI> <B>Examples</B> <P>
+<OL>
+<LI> Here is what a config file would look like for starting up a
+server at port 20202:
+
+<PRE> <CODE>
+dynamic Time_Service Service_Object *
+ ../lib/libnetsvcs.so:_make_ACE_TS_Server_Acceptor()
+ "-p 20202"
+</PRE> </CODE>
+
+<LI> 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:
+
+<PRE> <CODE>
+dynamic Time_Server_test Service_Object *
+ ../lib/libnetsvcs.so:_make_ACE_TS_Clerk_Connector ()
+ "-h tango:20202 -h lambada:20202 -t 4"
+</PRE> </CODE>
+</OL>
+
+Note:<P>
+<UL>
+<LI> These files would vary if the services are run on NT. For
+example, instead of using *.so, we would have to use *.dll.<P>
+<LI> 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). <P>
+<LI> 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.
+</UL>
+<P>
+
+</UL>
+
+<P><HR><P>
+<H3><A NAME="token-overview">Token Service</A></H3>
+
+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:<P>
+
+<UL>
+ <LI> <B><TT>ACE_Local_Mutex</TT></B><P>
+
+ 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.<p>
+
+ <LI> <B><TT>ACE_Remote_Mutex</TT></B><P>
+
+ 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.<p>
+
+ <LI> <B><TT>ACE_Local_RLock</TT></B><P>
+
+ 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).<P>
+
+ <LI> <B><TT>ACE_Local_WLock</TT></B><P>
+
+ 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).<P>
+
+ <LI> <B><TT>ACE_Remote_RLock</TT></B><P>
+
+ 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.<P>
+
+ <LI> <B><TT>ACE_Remote_RLock</TT></B><P>
+
+ This is the remote equivalent to ACE_Local_WLock.<P>
+</UL>
+
+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:<P>
+
+<UL>
+ <LI> <B><TT>class Token_Acceptor</TT></B><P>
+
+ The Token_Acceptor is a Token_Handler factory. It accepts
+ connections and passes the service responsibilities off to a
+ new Token_Handler.<p>
+
+ <LI> <B><TT>class Token_Handler</TT></B><P>
+
+ 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.<P>
+</UL>
+
+The following describes how to configure the Token Server:<P>
+<UL>
+ <LI> <b>Startup configuration</B><P>
+
+ The only parameter that the Token Server takes is a listen port
+ number. You can specify a port number by passing a "-p
+ <port_number>" to the application. This can be done via the
+ svc.conf file.<P>
+
+ <LI> <B>Examples </B><P>
+
+ Here is an example NT svc.conf entry that dynamically loads the
+ Token Server specifying port number to listen on for client
+ connections:<P>
+
+ <code><pre>
+ dynamic Token_Service Service_Object *
+ ../../ace/libnet_svcs.dll:_make_ACE_Token_Acceptor()
+ "-p 10202"
+ </code></pre>
+ <P>
+
+ 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:<P>
+
+ <code><pre>
+ dynamic Token_Service Service_Object *
+ ../../ace/netsvcs.so:_make_ACE_Token_Acceptor()
+ "-p 10202"
+ </code></pre>
+</UL>
+Note:<P>
+<UL>
+<LI> These files would vary if the services are run on NT. For
+example, instead of using *.so, we would have to use *.dll.<P>
+<LI> 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). <P>
+<LI> 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.
+</UL>
+
+
+<P><HR><P>
+<A NAME="server-logging-overview">
+<H3>Overview of Server Logging Service</H3>
+
+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. <P>
+
+The following are the key classes in the Server Logging Service: <P>
+<UL>
+<LI> <B> <TT> Server_Logging_Handler </TT> </B> <P>
+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. <P>
+
+<LI> <B> <TT> Server_Logging_Acceptor </TT> </B> <P>
+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. <P>
+</UL>
+
+The following describes how to configure the Logging Server:<P>
+<UL>
+ <LI> <b>Startup configuration</B><P>
+
+ The only parameter that the Logging Server takes is a listen
+ port number. You can specify a port number by passing a "-p
+ <port_number>" to the application. This can be done via the
+ svc.conf file.<P>
+
+ <LI> <B>Examples </B><P>
+
+ Here is an example NT svc.conf entry that dynamically loads the
+ Logging Server specifying port number to listen on for client
+ connections:<P>
+
+ <PRE> <CODE>
+ dynamic Server_Logging_Service Service_Object *
+ ../../ace/libnet_svcs.dll:_make_ACE_Server_Logging_Acceptor()
+ "-p 10202"
+ </PRE></CODE>
+ <P>
+
+ 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:<P>
+
+ <PRE> <CODE>
+ dynamic Server_Logging_Service Service_Object *
+ ../../ace/netsvcs.so:_make_ACE_Server_Logging_Acceptor()
+ "-p 10202"
+ </PRE></CODE>
+</UL>
+Note:<P>
+<UL>
+<LI> These files would vary if the services are run on NT. For
+example, instead of using *.so, we would have to use *.dll.<P>
+<LI> 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). <P>
+<LI> 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.
+</UL>
+
+<P><HR><P>
+<A NAME="client-logging-overview">
+<H3>Overview of Client Logging Service</H3>
+
+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: <P>
+<UL>
+<LI> <B> <TT> Client_Logging_Handler </TT> </B> <P>
+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. <P>
+
+<LI> <B> <TT> Client_Logging_Connector </TT> </B> <P>
+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. <P>
+</UL>
+
+The following describes how to configure the Logging Client:<P>
+<UL>
+ <LI> <b>Startup configuration</B><P>
+
+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:<P>
+
+<TABLE cellpadding = 10 cellspacing = 0 border = 5>
+<TD VALIGN = TOP ALIGN = LEFT>
+<B> Option </B>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+<B> Description </B>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+<B> Default value </B>
+</TD>
+<TR>
+<TD VALIGN = TOP ALIGN = LEFT>
+-h &hostname&gt <BR>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+Hostname of the Server Logging Daemon <BR>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+ACE_DEFAULT_SERVER_HOST
+</TD>
+<TR>
+<TD VALIGN = TOP ALIGN = LEFT>
+-p &ltport number&gt
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+Port number of the Server Logging Daemon <BR>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+ACE_DEFAULT_LOGGING_SERVER_PORT
+</TD>
+<TR>
+<TD VALIGN = TOP ALIGN = LEFT>
+-p &ltrendezvous key&gt
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+Rendezvous key used to create named pipe
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+ACE_DEFAULT_RENDEZVOUS
+</TD>
+</TABLE>
+<P>
+
+ <LI> <B>Examples </B><P>
+
+ Here is an example NT svc.conf entry that dynamically loads the
+ Logging Client specifying host name and port number of the
+ Logging Server: <P>
+
+ <PRE> <CODE>
+ dynamic Client_Logging_Service Service_Object *
+ ../../ace/libnet_svcs.dll:_make_ACE_Client_Logging_Connector()
+ "-h tango.cs.wustl.edu -p 10202"
+ </PRE></CODE>
+ <P>
+
+ 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:<P>
+
+ <PRE> <CODE>
+ dynamic Client_Logging_Service Service_Object *
+ ../../ace/netsvcs.so:_make_ACE_Client_Logging_Connector()
+ "-h tango.cs.wustl.edu -p 10202"
+ </PRE></CODE>
+</UL>
+Note:<P>
+<UL>
+<LI> These files would vary if the services are run on NT. For
+example, instead of using *.so, we would have to use *.dll.<P>
+<LI> 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). <P>
+<LI> 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.
+</UL>
+
+<P><HR><P>
+<A NAME="logging-strategy-overview">
+<H3> Overview of Logging Strategy Service</H3>
+
+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. <P>
+
+The following describes how to configure the Logging Strategy
+Service:<p>
+
+<UL>
+<LI> <b>Startup configuration</B><P>
+
+Here are the command line arguments that can be given to the Logging
+Strategy Service: <P>
+
+ -f &ltflag1&gt|&ltflag2&gt|&ltflag3&gt (etc...) <P>
+
+ where a flag can be any of the following: <P>
+
+<TABLE cellpadding = 10 cellspacing = 0 border = 5>
+<TD VALIGN = TOP ALIGN = LEFT>
+ <B> Flags </B>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+ <B> Description </B>
+</TD>
+<TR>
+<TD VALIGN = TOP ALIGN = LEFT>
+ STDERR <BR>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+ Write messages to stderr. <BR>
+</TD>
+<TR>
+<TD VALIGN = TOP ALIGN = LEFT>
+ LOGGER <BR>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+ Write messages to the local client logger deamon. <BR>
+</TD>
+<TR>
+<TD VALIGN = TOP ALIGN = LEFT>
+ OSTREAM <BR>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+ Write messages to the ostream that gets created by specifying a
+ filename (see below) <BR>
+</TD>
+<TR>
+<TD VALIGN = TOP ALIGN = LEFT>
+ VERBOSE <BR>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+ Display messages in a verbose manner <BR>
+</TD>
+<TR>
+<TD VALIGN = TOP ALIGN = LEFT>
+ SILENT <BR>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+ Do not print messages at all <BR>
+</TD>
+
+</TABLE>
+<P>
+
+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 '|'. <P>
+
+ -s filename
+ <P>
+
+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. <P>
+
+<LI> <B> Examples: </B> <P>
+<OL>
+<LI> To direct output only to STDERR, specify command line arguments as: <P>
+ "-f STDERR"
+<P>
+
+<LI> To direct output to both STDERR and a file called "mylog", specify
+command line arguments as: <P>
+ "-f STDERR|OSTREAM -s mylog"
+</OL>
+Note:<P>
+<UL>
+<LI> These files would vary if the services are run on NT. For
+example, instead of using *.so, we would have to use *.dll.<P>
+<LI> 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). <P>
+<LI> 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.
+</UL>
+</UL>
+
+<P><HR><P>
+Back to the <A HREF="http://www.cs.wustl.edu/~schmidt/ACE.html">
+ACE</A> 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<ACE_Naming_Context>::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, "<P> Use Process Local Database\n"));
+ ACE_DEBUG ((LM_DEBUG, "<N> Use Node Local Database\n"));;
+ ACE_DEBUG ((LM_DEBUG, "<H> Set Remote Name server <host> and <port>\n\n"));
+ ACE_DEBUG ((LM_DEBUG, "<B> Bind <key> <value> [<type>]\n"));
+ ACE_DEBUG ((LM_DEBUG, "<U> Unbind <key>\n"));
+ ACE_DEBUG ((LM_DEBUG, "<R> Rebind <key> <value> [<type>]\n"));
+ ACE_DEBUG ((LM_DEBUG, "<F> Find <key>\n"));
+ ACE_DEBUG ((LM_DEBUG, "<J> Lookup keys matching <pattern>\n"));
+ ACE_DEBUG ((LM_DEBUG, "<K> Lookup values matching <pattern>\n"));
+ ACE_DEBUG ((LM_DEBUG, "<L> Lookup types matching <pattern>\n"));
+ ACE_DEBUG ((LM_DEBUG, "<C> Complete lookup keys matching <pattern>\n"));
+ ACE_DEBUG ((LM_DEBUG, "<D> Complete lookup values matching <pattern>\n"));
+ ACE_DEBUG ((LM_DEBUG, "<E> Complete lookup types matching <pattern>\n"));
+
+ ACE_DEBUG ((LM_DEBUG, "<Q> 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 <fstream.h>
+// @(#)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 << "<P> Use Process Local Database" << endl;
+ cout << "<N> Use Node Local Database" << endl;
+ cout << "<H> Set Remote Name server <host> and <port>" << endl;
+ cout << "<F> Set Input File <file name>" << endl << endl;
+ cout << "<B> Bind" << endl;
+ cout << "<U> Unbind" << endl;
+ cout << "<R> Rebind" << endl;
+ cout << "<D> Dump <file name>" << endl;
+ cout << "<Q> 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 **
+<P> Use Process Local Database
+<N> Use Node Local Database
+<H> Set Remote Name server <host> and <port>
+<F> Set Input File <file name>
+
+<B> Bind
+<U> Unbind
+<R> Rebind
+<D> Dump <file name>
+<Q> or ^C (exit)
+
+Initially, the user can select the type of database from the menu:
+
+<P> uses the process local database (i.e., the
+ database is called the same name as the process
+ and stored in /tmp).
+<N> uses the node local database (which defaults
+ to /tmp/localnames).
+<H> 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).
+<F> 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=<name1>
+ value=<value1>
+ type=[<type1>]
+ name=<name2>
+ value=<value2>
+ type=[<type2>]
+ .
+ .
+ .
+
+ 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:
+
+<B> Bind -- bind all the bindings in the file to the database.
+ This can be used to "restore" the state of the
+ Name Server.
+<U> Unbind -- unbind all the bindings in the file from the database.
+<R> Rebind -- rebind all the bindings in the file to the database.
+<D> Dump <file name> -- dump the state of the database to <filename>.
+<Q> 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 <stdio.h>
+// @(#)createfile.cpp 1.1 10/18/96
+
+#include <string.h>
+#include <math.h>
+
+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<ACE_Name_Server_Proxy *> (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 ***
+
+<P> Use Process Local Database
+<N> Use Node Local Database
+<H> Set Remote Name server <host> and <port>
+
+<B> Bind <key> <value> [<type>]
+<U> Unbind <key>
+<R> Rebind <key> <value> [<type>]
+<F> Find <key>
+<J> Lookup keys matching <pattern>
+<K> Lookup values matching <pattern>
+<L> Lookup types matching <pattern>
+<C> Complete lookup keys matching <pattern>
+<D> Complete lookup values matching <pattern>
+<E> Complete lookup types matching <pattern>
+
+<Q> or ^C (exit)
+
+Initially, the user can select the type of database -- process local,
+node local, or net local -- from the menu.
+
+<P> uses the process local database (i.e., the database is called the
+ same name as the process and stored in /tmp).
+<N> uses the node local database (which defaults to /tmp/localnames).
+<H> 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:
+
+<B> Bind <key> <value> [<type>]
+ -- binds the key to the value and adds the
+ binding to the database. Note that type
+ information is optional.
+<U> Unbind <key> -- unbind a binding whose key is <key>
+<R> Rebind <key> <value> [<type>]
+ -- rebind <key> to <value>. Once again <type> is optional.
+<F> Find <key> -- find the binding associated with key <key>
+<Q> 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.
+
+<J> Lookup keys matching <pattern>
+ -- find all keys that match <pattern>
+<K> Lookup values matching <pattern>
+ -- find all values that match <pattern>
+<L> Lookup types matching <pattern>
+ -- find all types that match <pattern>
+
+<C> Complete lookup keys matching <pattern>
+ -- find all bindings whose keys match <pattern>
+<D> Complete lookup values matching <pattern>
+ -- find all bindings whose values match <pattern>
+<E> Complete lookup types matching <pattern>
+ -- find all bindings whose types match <pattern>
+
+-------------------------
+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 <remote host>]
+[-p <remote port>]
+[-n <iterations>]
+[-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 <token-server-host> -p <token-server-port>
+
+The -n <iterations> 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 <remote host>]\n"
+ "[-p <remote port>]\n"
+ "[-n <iterations>]\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 <iterations>]\n"
+ "[-R <reads>]\n"
+ "[-r use remote locks]\n"
+ "[-d debug]\n"
+ "[-s sleep during writes]\n"
+ "[-t <threads>\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 <iterations>]
+[-h <remote host>]
+[-p <remote port>]
+[-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 <tid>" (where <tid> 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 <iterations>]\n"
+ "[-h <remote host>]\n"
+ "[-p <remote port>]\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 <remote host>]
+[-p <remote port>]
+[-i ignore deadlock]
+[-d debug]
+
+./manual gives you the following prompt.
+<tid> <token> <type> <operation>
+
+<tid> This is the client id of the current operation. This is set
+ manually by ./manual for every operation. Be careful when
+ using multiple <tid>'s during a remote session (see BUGS
+ below).
+
+<token> This is the name of the token for the operation.
+
+<type> 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 <token> 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.
+
+<operation> This is the operation to perform on the
+ <tid>-<token>-<type> 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 <tid>'s. The Token Server client
+connection policy is currently, one per thread. The Token Server
+assumes that the same <tid> 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
+<tid> <token> <type> <operation>
+tid1 tokenA M A
+ACE_TSS_Connection new connection
+(1) acquired tokenA remotely.
+Succeeded.
+<tid> <token> <type> <operation>
+tid2 tokenA M A
+(1) acquired tokenA remotely. <------ This is remote BADness!!!
+Succeeded.
+Violated invariant. <------ Locally detected badness.
+<tid> <token> <type> <operation>
+
+
+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 <token> with a <tid> client id.
+
+ ACE_Token_Proxy *create_proxy (const char *token, char type);
+ // Create a proxy to <token> with a <tid> client id.
+
+ typedef ACE_CString TID;
+
+ // = Mapping from tid to Token_Collection.
+ typedef ACE_Map_Manager<TID, ACE_Token_Collection *, ACE_Null_Mutex>
+ COLLECTIONS;
+ // COLLECTION maintains a mapping from tid to a collection.
+
+ typedef ACE_Map_Iterator<TID, ACE_Token_Collection *, ACE_Null_Mutex>
+ COLLECTIONS_ITERATOR;
+ // Allows iterations through collections_.
+
+ typedef ACE_Map_Entry<TID, ACE_Token_Collection *>
+ COLLECTIONS_ENTRY;
+ // Allows iterations through collections_.
+
+ COLLECTIONS collections_;
+ // A collection for each <tid>.
+
+ 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 <remote host>]\n"
+ "[-p <remote port>]\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 ("<tid> <token> <type> <operation>\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 <remote host>]\n"
+ "[-p <remote port>]\n"
+ "[-n <iterations>]\n"
+ "[-t <threads>]\n"
+ "[-h <remote host>]\n"
+ "[-p <remote port>]\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 <iterations>
+ -r <reads>
+ -d debug
+ -s sleep during writes
+ -t <threads>
+
+test_rw_locks spawns <threads> number of threads which perform the
+following algorithm:
+
+for <iterations>
+ {
+ for <reads>
+ acquire read lock
+ for <reads>
+ 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 <remote host>]\n"
+ "[-p <remote port>]\n"
+ "[-i ignore deadlock]\n"
+ "[-n <iterations>]\n"
+ "[-R perform renews]\n"
+ "[-r <reads>]\n"
+ "[-d debug]\n"
+ "[-s sleep during writes]\n"
+ "[-t <threads>\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<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
+ // = 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 <ACE_Client_Logging_Handler>
+ // (called by the <ACE_Client_Logging_Connector>).
+
+ 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 <handle_input>.
+
+ virtual int handle_output (ACE_HANDLE);
+ // Called back when it's ok to send.
+
+ int send (ACE_Log_Record &log_record);
+ // Send the <log_record> 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 <send> 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 ("<localhost>", 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<ACE_Client_Logging_Handler, ACE_SOCK_CONNECTOR>
+ // = TITLE
+ // This class contains the service-specific methods that can't
+ // easily be factored into the <ACE_Connector>.
+{
+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<ACE_Client_Logging_Handler, ACE_SOCK_Connector, ACE_INET_Addr>;
+#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<ACE_TS_Server_Handler, ACE_SOCK_Acceptor, ACE_INET_Addr>;
+template class ACE_Schedule_All_Reactive_Strategy<ACE_TS_Server_Handler>;
+#if defined (ACE_HAS_THREADS)
+template class ACE_Svc_Handler<ACE_SOCK_Stream, ACE_INET_Addr, ACE_Null_Mutex, ACE_Null_Condition_Mutex>;
+template class ACE_Task<ACE_Null_Mutex, ACE_Null_Condition_Mutex>;
+template class ACE_Message_Queue<ACE_Null_Mutex, ACE_Null_Condition_Mutex>;
+template class ACE_Module<ACE_Null_Mutex, ACE_Null_Condition_Mutex>;
+template class ACE_Task_Exit<ACE_Null_Mutex, ACE_Null_Condition_Mutex>;
+template class ACE_TSS<ACE_Task_Exit<ACE_Null_Mutex, ACE_Null_Condition_Mutex> >;
+template class ACE_Thru_Task<ACE_Null_Mutex, ACE_Null_Condition_Mutex>;
+#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<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
+ // = TITLE
+ // Product object created by <ACE_Name_Acceptor>. An
+ // <ACE_Name_Handler> exchanges messages with a <ACE_Name_Proxy>
+ // object on the client-side.
+ //
+ // = DESCRIPTION
+ // This class is the main workhorse of the <ACE_Name_Server>. 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 <ACE_Name_Handler> (called by the
+ // <ACE_Strategy_Acceptor>).
+
+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 <ACE_HANDLE>.
+
+ virtual int handle_input (ACE_HANDLE);
+ // Callback method invoked by the <ACE_Reactor> 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<ACE_Name_Handler, ACE_SOCK_ACCEPTOR>
+ // = TITLE
+ // This class contains the service-specific methods that can't
+ // easily be factored into the <ACE_Strategy_Acceptor>.
+{
+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<ACE_Name_Handler> 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 <SVC_HANDLER> 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<ACE_SOCK_STREAM, ACE_NULL_SYNCH> (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<ACE_SOCK_STREAM, ACE_NULL_SYNCH>::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<ACE_WString> 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<ACE_Name_Binding> 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<ACE_Name_Handler, ACE_SOCK_Acceptor, ACE_INET_Addr>;
+template class ACE_Schedule_All_Reactive_Strategy<ACE_Name_Handler>;
+#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:
+<CODE>
+
+ -f <flag1>|<flag2>|<flag3> (etc...)
+</CODE>
+ 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 <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.
+
+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 <ACE_PEER_STREAM_1, class COUNTER, ACE_SYNCH_1>
+class ACE_Server_Logging_Handler : public ACE_Svc_Handler<ACE_PEER_STREAM_2, ACE_SYNCH_2>
+{
+ // = TITLE
+ // Product object created by an <ACE_Server_Logging_Acceptor>. An
+ // <ACE_Server_Logging_Handler> 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 <ACE_PEER_STREAM_1, class COUNTER, ACE_SYNCH_1>
+COUNTER ACE_Server_Logging_Handler<ACE_PEER_STREAM_2, COUNTER, ACE_SYNCH_2>::request_count_ = 0L;
+#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */
+
+typedef ACE_Server_Logging_Handler<LOGGING_PEER_STREAM, u_long, ACE_NULL_SYNCH>
+ SERVER_LOGGING_HANDLER;
+
+class ACE_Server_Logging_Acceptor : public ACE_Strategy_Acceptor<SERVER_LOGGING_HANDLER, LOGGING_PEER_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 <ACE_Strategy_Acceptor>.
+{
+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<SERVER_LOGGING_HANDLER> 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 <SVC_HANDLER> 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_PEER_STREAM_1, class COUNTER, ACE_SYNCH_1>
+ACE_Server_Logging_Handler<ACE_PEER_STREAM_2, COUNTER, ACE_SYNCH_2>::ACE_Server_Logging_Handler (ACE_Thread_Manager *)
+{
+ this->host_name_[0] = '\0'; // Initialize to a known state.
+}
+
+template <ACE_PEER_STREAM_1, class COUNTER, ACE_SYNCH_1> int
+ACE_Server_Logging_Handler<ACE_PEER_STREAM_2, COUNTER, ACE_SYNCH_2>::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 <ACE_PEER_STREAM_1, class COUNTER, ACE_SYNCH_1> int
+ACE_Server_Logging_Handler<ACE_PEER_STREAM_2, COUNTER, ACE_SYNCH_2>::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 <ACE_PEER_STREAM_1, class COUNTER, ACE_SYNCH_1> int
+ACE_Server_Logging_Handler<ACE_PEER_STREAM_2, COUNTER, ACE_SYNCH_2>::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 <ACE_Thread_Mutex, u_long> 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<LOGGING_PEER_STREAM, COUNTER, ACE_LOGGER_SYNCH>
+ // = TITLE
+ // Product object created by a <ACE_Thr_Server_Logging_Acceptor>. An
+ // <ACE_Thr_Server_Logging_Handler> 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<ACE_Thr_Server_Logging_Handler, LOGGING_PEER_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 <ACE_Strategy_Acceptor>.
+{
+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<ACE_Thr_Server_Logging_Handler> 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 <SVC_HANDLER> 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<ACE_Thr_Server_Logging_Handler, LOGGING_PEER_ACCEPTOR>;
+template class ACE_Schedule_All_Threaded_Strategy<ACE_Thr_Server_Logging_Handler>;
+template class ACE_Strategy_Acceptor<ACE_Server_Logging_Handler<LOGGING_PEER_STREAM, unsigned long, ACE_Null_Mutex, ACE_Null_Condition_Mutex>, LOGGING_PEER_ACCEPTOR>;
+template class ACE_Schedule_All_Reactive_Strategy<ACE_Server_Logging_Handler<LOGGING_PEER_STREAM, unsigned long, ACE_Null_Mutex, ACE_Null_Condition_Mutex> >;
+#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<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
+ // = 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 <ACE_TS_Clerk_Handler>
+ // (called by the <ACE_TS_Clerk_Processor>).
+
+ 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 <ACE_TS_Clerk_Handler, ACE_SOCK_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 <ACE_MMAP_Memory_Pool, ACE_Null_Mutex> MALLOC;
+ typedef ACE_Allocator_Adapter<MALLOC> ALLOCATOR;
+ ALLOCATOR *shmem_;
+ // Allocator (used for reading/writing system time from/to shared memory)
+
+ typedef ACE_Unbounded_Set <ACE_TS_Clerk_Handler *> HANDLER_SET;
+ typedef ACE_Unbounded_Set_Iterator <ACE_TS_Clerk_Handler *> 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 <send> 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<ACE_TS_Clerk_Handler, ACE_SOCK_Connector, ACE_INET_Addr>;
+#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<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
+ // = TITLE
+ // Product object created by <ACE_TS_Server_Acceptor>.
+ //
+ // = 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 <ACE_TS_Server_Handler> (called by the
+ // <ACE_Strategy_Acceptor>).
+
+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 <ACE_HANDLE>.
+
+ virtual int handle_input (ACE_HANDLE);
+ // Callback method invoked by the <ACE_Reactor> 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<ACE_TS_Server_Handler, ACE_SOCK_ACCEPTOR>
+ // = TITLE
+ // This class contains the service-specific methods that can't
+ // easily be factored into the <ACE_Strategy_Acceptor>.
+{
+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<ACE_TS_Server_Handler> 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 <SVC_HANDLER> 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<ACE_SOCK_STREAM, ACE_NULL_SYNCH> (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<ACE_SOCK_STREAM, ACE_NULL_SYNCH>::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<ACE_TS_Server_Handler, ACE_SOCK_Acceptor, ACE_INET_Addr>;
+template class ACE_Schedule_All_Reactive_Strategy<ACE_TS_Server_Handler>;
+#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<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
+ // = TITLE
+ // Product object created by an <ACE_Token_Acceptor>. A
+ // <Token_Handler> exchanges messages with a <Token_Proxy> 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 <ACE_Reactor> 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<ACE_Token_Handler, ACE_SOCK_ACCEPTOR>
+ // = TITLE
+ // This class contains the service-specific methods that can't
+ // easily be factored into the <ACE_Strategy_Acceptor>.
+{
+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<ACE_Token_Handler> 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 <SVC_HANDLER> 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<ACE_SOCK_STREAM, ACE_NULL_SYNCH> (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<ACE_Token_Handler, ACE_SOCK_Acceptor, ACE_INET_Addr>;
+template class ACE_Schedule_All_Reactive_Strategy<ACE_Token_Handler>;
+#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
--- /dev/null
+++ b/netsvcs/lib/netsvcs.mdp
Binary files 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
--- /dev/null
+++ b/netsvcs/servers/servers.mdp
Binary files 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 <DC_Singleton, ACE_Thread_Mutex> 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<DC_Singleton, ACE_Thread_Mutex>;
+#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<Thr_ID>;
+template class ACE_Atomic_Op<ACE_Thread_Mutex, int>;
+#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<ACE_Thread_Mutex, int> 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 <Thr_ID> 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<ACE_Thread_Mutex, size_t> 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 <stdio.h>
+// @(#)context.c 1.1 10/18/96
+
+#include <stdlib.h>
+#include <thread.h>
+
+#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 <Max msg size> <destination> <TitleOfThisTest> <port>" $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.h>
+ACE_SOCK_Connector connector_factory;
+
+#include <ace/SOCK_Acceptor.h>
+ACE_SOCK_Acceptor acceptor_factory;
+
+#include <ace/INET_Addr.h>
+ACE_INET_Addr address;
+
+#include <stdio.h>
+#include <signal.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <malloc.h>
+#include <string.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/time.h> /* struct itimerval */
+#include <limits.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#if defined(SYSV)
+#define bcopy(b1,b2,n) memcpy(b2,b1,n)
+#define bzero(b1,n) memset(b1,0,n)
+#include <sys/times.h>
+#include <sys/param.h>
+struct rusage
+ {
+ struct timeval ru_utime, ru_stime;
+ };
+#define RUSAGE_SELF 0
+
+#else
+#include <sys/resource.h>
+#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.h>
+ACE_SOCK_Connector connector_factory;
+
+#include <ace/SOCK_Acceptor.h>
+ACE_SOCK_Acceptor acceptor_factory;
+
+#include <ace/INET_Addr.h>
+ACE_INET_Addr address;
+
+#include <stdio.h>
+#include <signal.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <malloc.h>
+#include <string.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/time.h> /* struct itimerval */
+#include <limits.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#if defined(SYSV)
+#define bcopy(b1,b2,n) memcpy(b2,b1,n)
+#define bzero(b1,n) memset(b1,0,n)
+#include <sys/times.h>
+#include <sys/param.h>
+struct rusage
+ {
+ struct timeval ru_utime, ru_stime;
+ };
+#define RUSAGE_SELF 0
+
+#else
+#include <sys/resource.h>
+#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 <Max msg size> <destination> <TitleOfThisTest> <port>" $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 <Max msg size> <destination> <TitleOfThisTest> -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<char> 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 <ttcp_c.hh>
+
+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 <corba.h>
+#include <arrmac.h>
+#include <seqmac.h>
+
+
+
+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 <stdio.h>
+#include <signal.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <malloc.h>
+#include <string.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/time.h> /* struct itimerval */
+#include <limits.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#if defined(SYSV)
+#define bcopy(b1,b2,n) memcpy(b2,b1,n)
+#define bzero(b1,n) memset(b1,0,n)
+#include <sys/times.h>
+#include <sys/param.h>
+struct rusage
+ {
+ struct timeval ru_utime, ru_stime;
+ };
+#define RUSAGE_SELF 0
+
+#else
+#include <sys/resource.h>
+#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 <iostream.h>
+#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<test_title> 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 <ttcp_s.hh>
+
+
+
+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 <ttcp_c.hh>
+#include <corba.h>
+
+/* 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 <Max msg size> <destination> <TitleOfThisTest> -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 <CORBA.h>
+
+#include <string.h>
+
+
+#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<char> 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 <stdio.h>
+#include <signal.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <malloc.h>
+#include <string.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/time.h> /* struct itimerval */
+#include <limits.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#if defined(SYSV)
+#define bcopy(b1,b2,n) memcpy(b2,b1,n)
+#define bzero(b1,n) memset(b1,0,n)
+#include <sys/times.h>
+#include <sys/param.h>
+struct rusage
+ {
+ struct timeval ru_utime, ru_stime;
+ };
+#define RUSAGE_SELF 0
+
+#else
+#include <sys/resource.h>
+#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 <iostream.h>
+#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<test_title> 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.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <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.
+
+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.
+
+ <signature of Ty Coon>, 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
+
+<mnl@dtro.e-technik.th-darmstadt.de>
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 <rpc/c_types.h>
+
+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 <rpc/pmap_clnt.h>
+
+/*
+ * 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 <rpc/c_types.h>
+
+#include <rpc/types.h>
+/*
+ * 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;
+ * <type> *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 <stream.h>
+#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 <stream.h>
+#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 <unistd.h>
+#include <stream.h>
+#include <string.h>
+#include <malloc.h>
+
+#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, &calc.Add));
+ svc.Register (CalcRequests::Sub, RpcMethodCall<Calc> (&calc, &calc.Sub));
+ svc.Register (CalcRequests::Times, RpcMethodCall<Calc> (&calc, &calc.Times));
+ svc.Register (CalcRequests::Div, RpcMethodCall<Calc> (&calc, &calc.Div));
+ svc.Register (CalcRequests::Inc, RpcMethodCall<Calc> (&calc, &calc.Inc));
+ svc.Register (CalcRequests::IToA,RpcMethodCall<Calc>(&calc, &calc.IToA));
+ svc.Register (CalcRequests::Reset, RpcMethodCall<Calc> (&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 T> 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<Test> (&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: <mnl>
+Date: Wed, 10 Jun 92 19:31:13 +0200
+From: "Michael N. Lipp" <mnl>
+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 T> 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<Test> (&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 <assert.h>
+
+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
--- /dev/null
+++ b/rpc++/rpc++.ky
diff --git a/rpc++/rpc++.pg b/rpc++/rpc++.pg
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/rpc++/rpc++.pg
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 <class T> (void* (T::*)() @var{proc})
+@end deftypefn
+@deftypefn Constructor {} RpcMethodCall <class T> (void* (T::*)(void*) @var{proc})
+@end deftypefn
+@deftypefn Constructor {} RpcMethodCall <class T> (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 <class T> (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 <class T> (void (T::*)() @var{proc})
+@end deftypefn
+@deftypefn Constructor {} RpcMethodCall <class T> (void (T::*)(void*) @var{proc})
+@end deftypefn
+@deftypefn Constructor {} RpcMethodCall <class T> (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 <class T> (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 <class T> (void* (T::*)(RpcService*) @var{proc})
+@end deftypefn
+@deftypefn Constructor {} RpcMethodCall <class T> (void* (T::*)(void*, RpcService*) @var{proc})
+@end deftypefn
+@deftypefn Constructor {} RpcMethodCall <class T> (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 <class T> (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 <class T> (void (T::*)(RpcService*) @var{proc})
+@end deftypefn
+@deftypefn Constructor {} RpcMethodCall <class T> (void (T::*)(void*, RpcService*) @var{proc})
+@end deftypefn
+@deftypefn Constructor {} RpcMethodCall <class T> (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 <class T> (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*)&sum;
+@}
+@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<C> (&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 T> 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 <bool.h>
+#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 <bool.h>
+#include <String.h>
+#include <sys/time.h>
+#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 <rpc/rpc.h>
+
+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 <assert.h>
+#include <stream.h>
+#include <memory.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <rpc/rpc.h>
+#include <rpc/svc.h>
+#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 (&reg[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 <stream.h>
+#include <memory.h>
+#include <assert.h>
+#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 <n_iterations> 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<ACE_MT_SYNCH> MT_Stream;
+typedef ACE_Module<ACE_MT_SYNCH> MT_Module;
+typedef ACE_Task<ACE_MT_SYNCH> 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 <Andres.Kruse@cern.ch> and Douglas C. Schmidt
+// <schmidt@cs.wustl.edu>
+//
+// ============================================================================
+
+#include <math.h>
+#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<ACE_Thread_Mutex, u_long> 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<ACE_MT_SYNCH>
+ // = 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<double> work (double param, int count);
+ ACE_Future<const char*> 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 <work> method.
+{
+public:
+ Method_Object_work (Scheduler *, double, int, ACE_Future<double> &);
+ ~Method_Object_work (void);
+ virtual int call (void);
+
+private:
+ Scheduler *scheduler_;
+ double param_;
+ int count_;
+ ACE_Future<double> future_result_;
+};
+
+Method_Object_work::Method_Object_work (Scheduler* new_Scheduler,
+ double new_param,
+ int new_count,
+ ACE_Future<double> &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 <name> method.
+{
+public:
+ Method_Object_name (Scheduler *, ACE_Future<const char*> &);
+ ~Method_Object_name (void);
+ virtual int call (void);
+
+private:
+ Scheduler *scheduler_;
+ ACE_Future<const char*> future_result_;
+};
+
+Method_Object_name::Method_Object_name (Scheduler *new_scheduler,
+ ACE_Future<const char*> &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 <end> 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 <call>).
+ auto_ptr<ACE_Method_Object> 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<const char *>
+Scheduler::name (void)
+{
+ if (this->scheduler_)
+ // Delegate to the Scheduler.
+ return this->scheduler_->name ();
+ else
+ {
+ ACE_Future<const char*> new_future;
+
+ // @@ What happens if new fails here?
+ this->activation_queue_.enqueue
+ (new Method_Object_name (this, new_future));
+
+ return new_future;
+ }
+}
+
+ACE_Future<double>
+Scheduler::work (double newparam, int newcount)
+{
+ if (this->scheduler_) {
+ return this->scheduler_->work (newparam, newcount);
+ }
+ else {
+ ACE_Future<double> 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 <work>
+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<double> fresulta, fresultb, fresultc, fresultd, fresulte;
+ ACE_Future<const char*> 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<ACE_Thread_Mutex, u_long>;
+#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<ACE_MT_SYNCH> *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<ACE_MT_SYNCH> *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<ACE_MT_SYNCH> 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<ACE_MT_SYNCH>
+{
+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<ACE_Thread_Mutex, u_long> 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<ACE_Thread_Mutex, u_long>;
+#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<ACE_Thread_Mutex, int> 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 <n_iterations> 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<ACE_RW_Mutex> 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 <n_iterations> 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<ACE_RW_Mutex> 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<ACE_Thread_Mutex, int>;
+#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<Errno> TSS_Error;
+
+#if defined (ACE_HAS_THREADS)
+// Serializes output via cout.
+static ACE_Thread_Mutex lock;
+
+typedef ACE_TSS_Guard<ACE_Thread_Mutex> GUARD;
+#else
+// Serializes output via cout.
+static ACE_Null_Mutex lock;
+
+typedef ACE_Guard<ACE_Null_Mutex> 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<Errno>;
+#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<ACE_MT_SYNCH>
+{
+public:
+ Barrier_Task (ACE_Thread_Manager *thr_mgr,
+ int n_threads,
+ int n_iterations);
+
+ virtual int svc (void);
+ // Iterate <n_iterations> 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<ACE_MT_SYNCH> (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 <n_iterations> 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<ACE_MT_SYNCH>
+{
+public:
+ Thread_Pool (ACE_Thread_Manager *thr_mgr, int n_threads);
+
+ virtual int svc (void);
+ // Iterate <n_iterations> 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 <Thread_Pool>.
+
+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<ACE_MT_SYNCH> (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 <n_iterations> 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 <mike@SYSCOMP.DE>
+
+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 <pjain@cs.wustl.edu> and Tim Harrison <harrison@cs.wustl.edu>
+//
+// ============================================================================
+
+#if !defined (ACE_TEST_CONFIG_H)
+#define ACE_TEST_CONFIG_H
+
+#include <iostream.h>
+#include <fstream.h>
+
+#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
--- /dev/null
+++ b/tests/tests.mdp
Binary files differ