summaryrefslogtreecommitdiff
path: root/ace
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 /ace
downloadATCD-a5fdebc5f6375078ec1763850a4ca23ec7fe6458.tar.gz
Initial revision
Diffstat (limited to 'ace')
-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
453 files changed, 85982 insertions, 0 deletions
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